2015-04-17 61 views
0

需要一些幫助,因爲我無法獲得一個樣本工作(檢查所有其他問題,並搜索了我的屁股,也嘗試了我找到的所有解決方案)。我想我已經犯了一個或多個邏輯錯誤(和代碼中的一些錯誤)。Android AudioRecord/AudioTrack:從緩衝區播放錄音

public class MainActivity extends ActionBarActivity { 

private static final String TAG = MainActivity.class.getName(); 

private AudioTrack track = null; 

private static final int SAMPLERATE = 8000; 
private static final int TRACK_CHANNELS = AudioFormat.CHANNEL_OUT_MONO; 
private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

byte[] buffer; 

private Thread myThread; 
private boolean isRunning = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    setButtonHandlers(); 

    enableButton(R.id.btnStartRecording,true); 
    enableButton(R.id.btnStopRecording,false); 

} 

private void enableButton(int id,boolean isEnable){ 
    ((Button)findViewById(id)).setEnabled(isEnable); 
} 

private void setButtonHandlers() { 
    ((Button)findViewById(R.id.btnStartRecording)).setOnClickListener(btnClick); 
    ((Button)findViewById(R.id.btnStopRecording)).setOnClickListener(btnClick); 
} 

private View.OnClickListener btnClick = new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     switch(v.getId()){ 
      case R.id.btnStartRecording:{ 
       isRunning = true; 
       runThread(isRunning); 
       enableButton(R.id.btnStartRecording,false); 
       enableButton(R.id.btnStopRecording, true); 
       break; 
      } 
      case R.id.btnStopRecording:{ 
       isRunning = false; 
       runThread(isRunning); 
       enableButton(R.id.btnStartRecording,true); 
       enableButton(R.id.btnStopRecording, false); 
       break; 
      } 
     } 
    } 
}; 

private void runThread(final boolean flag){ 
    myThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      runRunnable(flag); 
     } 
    }); 
    myThread.start(); 
} 

public AudioTrack findAudioTrack (AudioTrack track) { 

    int myBufferSize = AudioTrack.getMinBufferSize(SAMPLERATE, TRACK_CHANNELS, AUDIO_ENCODING); 

    track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLERATE, TRACK_CHANNELS, AUDIO_ENCODING, myBufferSize, AudioTrack.MODE_STREAM); 

    return track; 
} 

public void runRunnable(boolean isRunning){ 

    if (isRunning == false) { 

     if (AudioRecord.STATE_INITIALIZED == recorder.getState()) { 
      recorder.stop(); 
      recorder.release(); 
     } 

     if (AudioTrack.STATE_INITIALIZED == track.getState()) { 
      track.stop(); 
      track.release(); 
     } 
     return; 
    } 

    recorder = findAudioRecord(); 

    track = findAudioTrack(track); 

    if ((AudioRecord.STATE_INITIALIZED == recorder.getState()) && (AudioTrack.STATE_INITIALIZED == track.getState())) { 

     recorder.startRecording(); 

     recorder.stop(); 
     recorder.read(buffer, 0, buffer.length); 

     track.play(); 
     track.write(buffer, 0, buffer.length); 

     for (int i = 0; i <minBufferSize; i++) { 
      Log.d(TAG,"data " + i + " content : " + buffer[i]); 
     } 

    } 

    return; 

} 

private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 }; 
public AudioRecord findAudioRecord() { 
    for (int rate : mSampleRates) { 
     for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) { 
      for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { 
       try { 
        int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

        if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
         AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize); 

         if (recorder.getState() == AudioRecord.STATE_INITIALIZED) 
          return recorder; 
        } 
       } catch (Exception e) { 
        Log.e(TAG, rate + "Exception, keep trying.",e); 
       } 
      } 
     } 
    } 
    return null; 
} 

}

沒有任何人知道,爲什麼沒有在緩衝裏面寫能向我解釋?

我昨天調整了一些代碼,並在緩衝區內獲得了一些值,但今天再次搞砸了代碼。昨天仍然沒有播放。

非常感謝您的幫助!

編輯:

好涼千恩萬謝:>讀現在似乎正常工作。

你是什麼意思是由isRunning作爲靜態成員?變量?

public class MainActivity extends ActionBarActivity { 

private static final String TAG = MainActivity.class.getName(); 

private AudioRecord recorder = null; 
private AudioTrack track = null; 

private static final int SAMPLERATE = 8000; // 44100 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; // stereo 
private static final int TRACK_CHANNELS = AudioFormat.CHANNEL_OUT_MONO; // stereo 
private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

private int minBufferSize; 
byte[] buffer; 

private Thread myThread; 
private boolean isRunning = false; 

private AudioManager manager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    setButtonHandlers(); 

    enableButton(R.id.btnStartRecording,true); 
    enableButton(R.id.btnStopRecording,false); 

    minBufferSize = AudioRecord.getMinBufferSize(SAMPLERATE,RECORDER_CHANNELS,AUDIO_ENCODING); 
    buffer = new byte[minBufferSize]; 

    manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE); 
    manager.setMode(AudioManager.MODE_NORMAL); 
    setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); 

} 

private void enableButton(int id,boolean isEnable){ 
    ((Button)findViewById(id)).setEnabled(isEnable); 
} 

private void setButtonHandlers() { 
    ((Button)findViewById(R.id.btnStartRecording)).setOnClickListener(btnClick); 
    ((Button)findViewById(R.id.btnStopRecording)).setOnClickListener(btnClick); 
} 

private View.OnClickListener btnClick = new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     switch(v.getId()){ 
      case R.id.btnStartRecording:{ 
       isRunning = true; 
       runThread(isRunning); 
       enableButton(R.id.btnStartRecording,false); 
       enableButton(R.id.btnStopRecording, true); 
       break; 
      } 
      case R.id.btnStopRecording:{ 
       isRunning = false; 
       runThread(isRunning); 
       enableButton(R.id.btnStartRecording,true); 
       enableButton(R.id.btnStopRecording, false); 
       break; 
      } 
     } 
    } 
}; 

private void runThread(final boolean flag){ 
    myThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      runRunnable(flag); 
     } 
    }); 
    myThread.start(); 
} 

public AudioTrack findAudioTrack (AudioTrack track) { 
    int myBufferSize = AudioTrack.getMinBufferSize(SAMPLERATE, TRACK_CHANNELS, AUDIO_ENCODING); 

    if (myBufferSize != AudioTrack.ERROR_BAD_VALUE) { 
     track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLERATE, TRACK_CHANNELS, AUDIO_ENCODING, myBufferSize, AudioTrack.MODE_STREAM); 

     if (track.getState() == AudioTrack.STATE_UNINITIALIZED) { 
      Log.e(TAG, "AudioTrack Uninit"); 
      return null; 
     } 
    } 
    return track; 
} 

public void runRunnable(boolean isRunning){ 

    if (isRunning == false) { 

     for (int i = 0; i <minBufferSize; i++) { 
      Log.d(TAG,"data " + i + " content : " + buffer[i]); 
     } 

     if (AudioRecord.STATE_INITIALIZED == recorder.getState()) { 
      recorder.stop(); 
      recorder.release(); 
     } 

     if (track != null && AudioTrack.STATE_INITIALIZED == track.getState()) { 

      if (track.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) { 

       try{ 
        track.stop(); 
       }catch (IllegalStateException e) 
       { 
        e.printStackTrace(); 
       } 

      } 

      track.release(); 
      manager.setMode(AudioManager.MODE_NORMAL); 
     } 
     return; 
    } 

    recorder = findAudioRecord(); 
    if (recorder == null) { 
     Log.e(TAG, "findAudioRecord error"); 
     return; 
    } 

    track = findAudioTrack(track); 
    if (track == null) { 
     Log.e(TAG, "findAudioTrack error"); 
     return; 
    } 
    track.setPlaybackRate(SAMPLERATE); 

    if ((AudioRecord.STATE_INITIALIZED == recorder.getState()) && (AudioTrack.STATE_INITIALIZED == track.getState())) { 
     recorder.startRecording(); 
     track.play(); 

     while (isRunning) { 
      recorder.read(buffer, 0, minBufferSize); 
      track.write(buffer, 0, buffer.length); 
     } 

    } else { 
     Log.d(TAG, "Init for Recorder and Track failed"); 
     return; 
    } 
    return; 

} 

private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 }; 
public AudioRecord findAudioRecord() { 
    for (int rate : mSampleRates) { 
     for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) { 
      for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { 
       try { 
        Log.d(TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " 
          + channelConfig); 
        int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

        if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
         Log.d(TAG, "Found rate " + rate + "Hz, bits: " + audioFormat + ", channel: " 
           + channelConfig); 
         AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize); 

         if (recorder.getState() == AudioRecord.STATE_INITIALIZED) 
          return recorder; 
        } 
       } catch (Exception e) { 
        Log.e(TAG, rate + "Exception, keep trying.",e); 
       } 
      } 
     } 
    } 
    return null; 
} 
} 

在audiotrack修復工作,因爲我得到一個「無法檢索AudioTrack指針寫入()」錯誤。

編輯2:

對不起我的答案花了這麼長時間。 所以謝謝第二個緩衝區很好! 如果有人有興趣的代碼(僅適用於Nexus 5測試,但工作真棒那裏):

public class MainActivity extends ActionBarActivity { 

private AudioRecord recorder = null; 
private AudioTrack track = null; 

private static final int SAMPLERATE = 8000; 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; 
private static final int TRACK_CHANNELS = AudioFormat.CHANNEL_OUT_MONO; 
private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

private int minBufferSizeRec; 
short[] bufferRec; 

private Thread myThread; 
private boolean isRunning = false; 

private AudioManager manager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    setButtonHandlers(); 

    enableButton(R.id.btnStartRecording,true); 
    enableButton(R.id.btnStopRecording,false); 

    minBufferSizeRec = AudioRecord.getMinBufferSize(SAMPLERATE,RECORDER_CHANNELS,AUDIO_ENCODING); 
    bufferRec = new short[minBufferSizeRec/2]; 

    manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE); 
    manager.setMode(AudioManager.MODE_NORMAL); 
    setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); 

} 

private void enableButton(int id,boolean isEnable){ 
    ((Button)findViewById(id)).setEnabled(isEnable); 
} 

private void setButtonHandlers() { 
((Button)findViewById(R.id.btnStartRecording)).setOnClickListener(btnClick);       
((Button)findViewById(R.id.btnStopRecording)).setOnClickListener(btnClick); 
} 

private View.OnClickListener btnClick = new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     switch(v.getId()){ 
      case R.id.btnStartRecording:{ 
       isRunning = true; 
       runThread(isRunning); 
       enableButton(R.id.btnStartRecording,false); 
       enableButton(R.id.btnStopRecording, true); 
       break; 
      } 
      case R.id.btnStopRecording:{ 
       isRunning = false; 
       runThread(isRunning); 
       enableButton(R.id.btnStartRecording,true); 
       enableButton(R.id.btnStopRecording, false); 
       break; 
      } 
     } 
    } 
}; 

private void runThread(final boolean flag){ 
    myThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      runRunnable(flag); 
     } 
    }); 
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
    myThread.start(); 
} 

public AudioTrack findAudioTrack (AudioTrack track) { 
    int myBufferSize = AudioTrack.getMinBufferSize(SAMPLERATE, TRACK_CHANNELS, AUDIO_ENCODING); 
    if (myBufferSize != AudioTrack.ERROR_BAD_VALUE) { 
     track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLERATE, TRACK_CHANNELS, AUDIO_ENCODING, myBufferSize, AudioTrack.MODE_STREAM); 

     track.setPlaybackRate(SAMPLERATE); 

     if (track.getState() == AudioTrack.STATE_UNINITIALIZED) { 
      Log.e(TAG, "AudioTrack Uninitialized"); 
      return null; 
     } 
    } 
    return track; 
} 

public void runRunnable(boolean isRunning){ 
    if (isRunning == false) { 
     if (AudioRecord.STATE_INITIALIZED == recorder.getState()) { 
      recorder.stop(); 
      recorder.release(); 
     } 

     if (track != null && AudioTrack.STATE_INITIALIZED == track.getState()) { 

      if (track.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) { 

       try{ 
        track.stop(); 
       }catch (IllegalStateException e) 
       { 
        e.printStackTrace(); 
       } 

      } 
      track.release(); 
      manager.setMode(AudioManager.MODE_NORMAL); 
     } 
     return; 

    } else if (isRunning == true) { 

     recorder = findAudioRecord(); 
     if (recorder == null) { 
      Log.e(TAG, "findAudioRecord error"); 
      return; 
     } 

     track = findAudioTrack(track); 
     if (track == null) { 
      Log.e(TAG, "findAudioTrack error"); 
      return; 
     } 
     track.setPlaybackRate(SAMPLERATE); 

     if ((AudioRecord.STATE_INITIALIZED == recorder.getState()) && (AudioTrack.STATE_INITIALIZED == track.getState())) { 

      short[] data = new short[minBufferSizeRec/2]; 

      recorder.startRecording(); 
      track.play(); 

      while (isRunning) { 
       recorder.read(bufferRec, 0, (minBufferSizeRec/2)); 
       for (int i = 0; i < data.length; i++) { 
        data[i] = bufferRec[i]; 
       } 
       track.write(data, 0, data.length); 
       bufferRec = new short[minBufferSizeRec/2]; 
       data = new short[minBufferSizeRec/2]; 
      } 

     } else { 
      Log.d(TAG, "Init for Recorder and Track failed"); 
      return; 
     } 
     return; 

    } 
    myThread.interrupt(); 
} 

private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 }; 
public AudioRecord findAudioRecord() { 

    for (int rate : mSampleRates) { 
     for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) { 
      for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { 
       try { 
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

        if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
         AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize); 

         if (recorder.getState() == AudioRecord.STATE_INITIALIZED) 
          return recorder; 
        } 
       } catch (Exception e) { 
        Log.e(TAG, rate + "Exception, keep trying.",e); 
       } 
      } 
     } 
    } 
    return null; 
} 

}

+0

你爲什麼要停止錄製! –

回答

1

刪除停止錄製!

track.play(); 

    while(isRunning) 
    { 
    buffer = new Byte[mBufferSize]; 

     recorder.read(buffer, 0, buffer.length); 


     track.write(buffer, 0, buffer.length); 

     for (int i = 0; i <minBufferSize; i++) { 
      Log.d(TAG,"data " + i + " content : " + buffer[i]); 
     } 
} 

即使你想停止錄音把它看完後..

+0

哦,非常感謝* facepalmmyself。我仍然不明白爲什麼什麼都沒有播放,並且緩衝區的前300條目總是0. – dmkscr

+0

那是因爲你在閱讀了一組樣本後返回了 –

+0

保持您的isRunning爲靜態成員變量..並且當它使其爲false它會自動出來循環 –

0

您需要在錄音機輸入,不只是做一個一次性的閱讀!

看一看here

+0

非常感謝(:幫助! – dmkscr

相關問題