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

private void playSound() {
    // AudioTrack definition
    int mBufferSize = AudioTrack.getMinBufferSize(44100,
                        AudioFormat.CHANNEL_OUT_MONO,    
                        AudioFormat.ENCODING_PCM_8BIT);

    mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
                        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT,
                        mBufferSize, AudioTrack.MODE_STREAM);

     // Sine wave
     double[] mSound = new double[4410];
     short[] mBuffer = new short[4410];
     for (int i = 0; i < mSound.length; i++) {
         mSound[i] = Math.sin((2.0*Math.PI * 440.0/44100.0*(double)i));
         mBuffer[i] = (short) (mSound[i]*Short.MAX_VALUE);
     }

     mAudioTrack.setStereoVolume(0.1f, 0.1f);
     mAudioTrack.play();

     mAudioTrack.write(mBuffer, 0, mSound.length);
     mAudioTrack.stop();
     mAudioTrack.release();

}

Когда я вызываю функцию playSound(), я получаю только короткое жужжание, которое совсем не похоже на чистую синусоидальную волну. Я пробовал разные частоты дискретизации от 8000 Гц до 44100 Гц, а также разные размеры буфера.

Экспорт содержимого mBuffer показывает, что синусоида генерируется правильно. Он также играет правильно, если я играю его с Matlab, хотя высота звука слишком высока.

Что-то я делаю неправильно? Кроме того, если я попробую 16-битную кодировку, я не получу звука вообще.

3
Iodestar 19 Апр 2014 в 23:03

2 ответа

Лучший ответ

Придерживайтесь ENCODING_PCM_16BIT вместо ENCODING_PCM_8BIT (как указано в документации, его поддержка устройствами не гарантируется).

Отрегулируйте громкость до максимума (1.0f или используйте getMaxVolume ()) на левом и правом канале вместо 0.1f (что действительно низкая амплитуда).

Увеличьте буфер с 4410 (что составляет всего 100 мс воспроизведения) до 2 * 44100 (что должно соответствовать 2 секундам воспроизведения).

2
Aladin Q 23 Апр 2014 в 14:45

Вы должны вызвать play () ПОСЛЕ write (). Ваш код в его нынешнем виде будет играть чушь.

0
Graeme Colman 21 Апр 2019 в 08:36