如何判断AudioTrack对象何时完成播放?

问题描述:

我试图在Android中使用AudioTrack类播放PCM文件。我可以让文件播放得很好,但我无法可靠地判断播放何时完成。 AudioTrack.getPlayState表示播放未完成播放时已停止播放。我与AudioTrack.setNotificationMarkerPosition有同样的问题,并且我很确定我的标记被设置为文件的末尾(虽然我不完全确定我是正确的)。同样,当getPlaybackHeadPosition位于文件末尾并停止递增时,将继续播放。谁能帮忙?如何判断AudioTrack对象何时完成播放?

我发现使用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 
      } 
     } 
    } 

这个工作对我来说:

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