簡體   English   中英

Android AudioRecord / AudioTrack:從緩沖區播放錄音

[英]Android AudioRecord/AudioTrack: Playing recording from buffer

需要一些幫助,因為我無法獲取樣本來工作(請檢查所有其他問題並用谷歌搜索,還嘗試了我發現的所有解決方案)。 我認為我犯了一個或多個邏輯錯誤(包括代碼中的某些錯誤)。

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;
}
}

由於我收到“無法檢索write()的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;
}

}

刪除停止錄制!

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

即使您想停止錄制,也要在閱讀后將其放好。

您需要遍歷記錄器輸入,而不僅僅是一次讀取!

在這里看看。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM