Трудность, портирующая необработанный вывод PCM, кодирует от Java до Android AudioTrack API

Я пытаюсь портировать приложение, которое играет чиптюны (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 );

Я заменил константы и переменные в тех так, они имеют смысл максимально кратко, но мой основной вопрос состоит в том, если существуют какие-либо очевидные проблемы в предположениях, я сделал при движении от одного формата до другого.

8
задан alexanderfb 25 April 2010 в 05:50
поделиться

1 ответ

Так что у меня было немного времени, чтобы посмотреть на это дальше сегодня, и я думаю, что я прибил это. Объявление 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, но это, похоже, не переворачивает байты в отдельных примерах.

Я приму что-то еще лучшее в будущем, но основная проблема здесь решена.Надеюсь, кто-то другой найдет это полезным!

7
ответ дан 5 December 2019 в 21:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: