Как узнать, когда объект AudioTrack закончил воспроизведение?

Я пытаюсь воспроизвести файл PCM на Android, используя класс AudioTrack. Я могу нормально воспроизвести файл, но не могу точно сказать, когда воспроизведение закончилось. AudioTrack.getPlayState говорит, что воспроизведение остановлено, когда оно еще не закончилось. У меня та же проблема с AudioTrack.setNotificationMarkerPosition, и я почти уверен, что мой маркер установлен в конец файла (хотя я не совсем уверен, что делаю это правильно). Точно так же воспроизведение продолжается, когда getPlaybackHeadPosition находится в конце файла и прекращает увеличиваться. Кто-нибудь может помочь?


person TalkieTalk    schedule 04.09.2010    source источник


Ответы (2)


Я обнаружил, что использование audioTrack.setNotificationMarkerPosition(audioLength) и audioTrack.setPlaybackPositionUpdateListener сработало для меня. См. следующий код:

    // Get the length of the audio stored in the file (16 bit so 2 bytes per short)
    // and create a short array to store the recorded audio.
    int audioLength = (int) (pcmFile.length() / 2);
    short[] audioData = new short[audioLength];
    DataInputStream dis = null;

    try {
        // Create a DataInputStream to read the audio data back from the saved file.
        InputStream is = new FileInputStream(pcmFile);
        BufferedInputStream bis = new BufferedInputStream(is);
        dis = new DataInputStream(bis);

        // Read the file into the music array.
        int i = 0;
        while (dis.available() > 0) {
            audioData[i] = dis.readShort();
            i++;
        }

        // Create a new AudioTrack using the same parameters as the AudioRecord.
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, RECORDER_SAMPLE_RATE, RECORDER_CHANNEL_OUT,
                                    RECORDER_AUDIO_ENCODING, audioLength, AudioTrack.MODE_STREAM);
        audioTrack.setNotificationMarkerPosition(audioLength);
        audioTrack.setPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener() {
            @Override
            public void onPeriodicNotification(AudioTrack track) {
                // nothing to do
            }
            @Override
            public void onMarkerReached(AudioTrack track) {
                Log.d(LOG_TAG, "Audio track end of file reached...");
                messageHandler.sendMessage(messageHandler.obtainMessage(PLAYBACK_END_REACHED));
            }
        });

        // Start playback
        audioTrack.play();

        // Write the music buffer to the AudioTrack object
        audioTrack.write(audioData, 0, audioLength);

    } catch (Exception e) {
        Log.e(LOG_TAG, "Error playing audio.", e);
    } finally {
        if (dis != null) {
            try {
                dis.close();
            } catch (IOException e) {
                // don't care
            }
        }
    }
person John    schedule 11.07.2011

Это работает для меня:

            do{                                                     // Montior playback to find when done
                 x = audioTrack.getPlaybackHeadPosition(); 
        }while (x< pcmFile.length() / 2);
person Xarph    schedule 27.11.2012