Я пытаюсь портировать приложение, которое играет чиптюны (NSF, SPC, и т.д.) музыкальные файлы с Java SE на Android. API Android, кажется, испытывает недостаток в javax мультимедийных классах что это приложение использование для вывода необработанного аудио PCM. Самым близким аналогом, который я нашел в API, является AudioTrack и таким образом, я боролся с этим.
Однако то, когда я пытаюсь выполнить один из своих демонстрационных музыкальных файлов через мое происходящее портом, все, что я возвращаю, статично. Мое подозрение - то, что это - AudioTrack, у меня есть установка, которая виновным. Я судил всевозможных конструкторов, но все это просто выводы, статичные в конце.
Установка DataLine в исходном коде - что-то как:
AudioFormat audioFormat = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
44100, 16, 2, 4, 44100, true );
DataLine.Info lineInfo = new DataLine.Info( SourceDataLine.class, audioFormat );
DataLine line = (SourceDataLine)AudioSystem.getLine( lineInfo );
Конструктор, которого я использую прямо сейчас:
AudioTrack = new AudioTrack( AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
AudioTrack.getMinBufferSize( 44100,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT ),
AudioTrack.MODE_STREAM );
Я заменил константы и переменные в тех так, они имеют смысл максимально кратко, но мой основной вопрос состоит в том, если существуют какие-либо очевидные проблемы в предположениях, я сделал при движении от одного формата до другого.
Так что у меня было немного времени, чтобы посмотреть на это дальше сегодня, и я думаю, что я прибил это. Объявление AudioFormat в первом примере кода выше имеет параметр большого endian, установленный в значение "true", но Android AudioTrack ожидает, что данные PCM будут в формате с маленькими окончаниями.
Поэтому я написал небольшой цикл, чтобы проверить свою догадку следующим образом:
for( int i = 0; i + LEN_PCM_SAMPLE_BYTES < LEN_PCM_BUFFER; i += LEN_PCM_SAMPLE_BYTES ) {
// Really rude endian conversion.
byte bytTemp = a_bytBuffer[i];
a_bytBuffer[i] = a_bytBuffer[i + 1];
a_bytBuffer[i + 1] = bytTemp;
}
По сути, этот цикл переворачивает байты каждого (16-битного) образца в буфере. Это отлично работает, за исключением того, что это немного прерывисто, так как это ужасно неэффективно. Я попробовал использовать ByteBuffer, но это, похоже, не переворачивает байты в отдельных примерах.
Я приму что-то еще лучшее в будущем, но основная проблема здесь решена.Надеюсь, кто-то другой найдет это полезным!