Сложность при переносе исходного кода вывода PCM с Java на Android AudioTrack API

Я пытаюсь перенести приложение, которое воспроизводит музыкальные файлы chiptunes (NSF, SPC и т. Д.) С Java SE на Android. В Android API, похоже, отсутствуют классы мультимедиа 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 );

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


person alexanderfb    schedule 25.04.2010    source источник
comment
Даже несмотря на то, что вы становитесь статичными, вы проверяли правильность длины дорожки?   -  person nvuono    schedule 25.04.2010
comment
Рассматриваемые музыкальные файлы на самом деле не имеют определенной длины трека. То есть они представляют собой код для DSP, который просто продолжает воспроизводить цикл, пока ему не скажут остановиться.   -  person alexanderfb    schedule 25.04.2010


Ответы (1)


Так что сегодня у меня было немного времени, чтобы взглянуть на это дальше, и я думаю, что я это решил. В объявлении AudioFormat в первом примере кода выше для параметра big endian установлено значение true, но Android AudioTrack ожидает, что данные PCM будут в формате little endian.

Поэтому я написал небольшой цикл, чтобы проверить свою догадку вот так:

 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, но это, похоже, не переворачивает байты в отдельных образцах.

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

person alexanderfb    schedule 28.04.2010
comment
Удалось ли вам что-нибудь придумать для беспокойства? - person StackOverflowed; 04.03.2013