Воспроизведение музыки с буфером AudioTrack за буфером на Eclipse - нет звука - PullRequest
4 голосов
/ 13 декабря 2011

Я программирую для Android 2.1. Не могли бы вы помочь мне решить следующую проблему?

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

Исходный код:

Класс аудиоплеера , который реализует звуковую дорожку.Он получит буфер, в котором содержится звук.

    public AudioPlayer(int sampleRate, int channelConfiguration, int audioFormat) throws ProjectException {
        minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfiguration, audioFormat);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfiguration,
                                    audioFormat, minBufferSize, AudioTrack.MODE_STREAM); 

        if(audioTrack == null)
            throw new ProjectException("Erreur lors de l'instantiation de AudioTrack");

        audioTrack.setStereoVolume((float)1.0, (float)1.0);
    }

    @Override
    public void addToQueue(short[] buffer) {
         audioTrack.write(buffer, 0, buffer.length*Short.SIZE);
         if(!isPlaying ) {
             audioTrack.play();
             isPlaying = true;
         }
    }

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

Размеры буфера выбираются очень свободно;обычно первый размер буфера должен быть 6615, а затем 4410. Это опять-таки только для отладки.

public void onTimeChange() {
    if(begin) {

                    //First fill about 300ms

        begin = false;
        short[][] buffer = new short[channels][numFramesBegin];
                    //numFramesBegin is for example 10000
                    //For debugging only buffer[0] is useful
        fillSimulatedBuffer(buffer, framesRead);
        framesRead += numFramesBegin;
        audioPlayer.addToQueue(buffer[0]);

    }

    else {
        try {
            short[][] buffer = new short[channels][numFrames];

                            //Afterwards fill like 200ms

            fillSimulatedBuffer(buffer, framesRead);
            framesRead += numFrames;
            audioPlayer.addToQueue(buffer[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

private short simulator(int time, short amplitude) {
            //a pure A (frequency=440)
            //this is probably wrong due to sampling rate, but 44 and 4400 won't work either
    return (short)(amplitude*((short)(Math.sin((double)(simulatorFrequency*time)))));
}

private void fillSimulatedBuffer(short[][] buffer, int offset) {
         for(int i = 0; i < buffer[0].length; i++)
        buffer[0][i] = simulator(offset + i, amplitude);
}

Класс timeTask , который вызывает model.ontimechange () каждые 200 мс.

public class ReadMusic extends TimerTask {
private final Model model;

public ReadMusic(Model model) {
    this.model = model;
}


@Override
public void run() {
    System.out.println("Task run");
    model.onTimeChange();
}

}

Что мне показала отладка:

  • timeTask отлично работает, он выполняет свою работу;
  • Значения буфера кажутся согласованными, а размер буфера больше, чем minBufSize;
  • Состояние воспроизведения Audiotrack "играет"
  • В функциях модели не учитываются исключения.

Любые идеи будут высоко оценены!

1 Ответ

2 голосов
/ 17 декабря 2011

ОК. Я обнаружил проблему.

В текущей документации AudioTrack, касающейся AudioTrack и короткого входного буфера, имеется ошибка: указанный размер буфера должен соответствовать размеру самого буфера (buffer.length) и не размер в байтах.

...