2010-09-04 3 views
12

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

ответ

14

Я нашел, что с помощью 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 
      } 
     } 
    } 
3

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

  do{              // Montior playback to find when done 
       x = audioTrack.getPlaybackHeadPosition(); 
     }while (x< pcmFile.length()/2); 
Смежные вопросы