Android AudioRecord / AudioTrack:从缓冲区播放录音

时间:2015-04-17 09:24:52

标签: 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;
}

}

是否有人知道并且可以向我解释为什么没有在缓冲区内写入任何内容?

我昨天调整了一些代码并在缓冲区内得到了一些值,但今天再次弄乱了代码。昨天仍然没有播放。

非常感谢您的帮助!

修改

好的很多谢谢:&gt;阅读似乎现在正常工作。

将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修复,因为我得到了一个&#34;无法为write()&#34;检索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;
}

}

2 个答案:

答案 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]);
        }
}

即使你想要停止录音也要在阅读后把它放好..

答案 1 :(得分:0)

您需要循环优先于录音机输入,而不只是一次性阅读!

看看here