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

dmkscr

需要一些帮助,因为我无法获得样本来工作(请检查所有其他问题并用谷歌搜索,还尝试了我发现的所有解决方案)。我认为我犯了一个或多个逻辑错误(以及代码中的一些错误)。

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

}

Preethi Rao

删除停止录制!

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

即使您想停止录制,也要在阅读后将其放好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用AudioRecord API的android录音机

来自分类Dev

android AudioRecord类来录制音频并播放

来自分类Dev

在Android AudioTrack中使用缓冲区

来自分类Dev

在Android AudioTrack中使用缓冲区

来自分类Dev

Android AudioRecord的麻烦

来自分类Dev

Android AudioRecord的麻烦

来自分类Dev

Android AudioRecord剪辑

来自分类Dev

android AudioRecord中的BufferSize减小

来自分类Dev

用SoundPool在Android上播放声音,同时用AudioRecord录制麦克风

来自分类Dev

Android:建议在AudioRecord中使用bufferSizeInBytes值

来自分类Dev

在Android上更改AudioRecord的比特率

来自分类Dev

Android AudioRecord无法初始化

来自分类Dev

Android源和AudioRecord的多用途

来自分类Dev

AudioRecord在Android 5.01上产生零的差距

来自分类Dev

调用startRecording()方法时,Android AudioRecord失败

来自分类Dev

在Android上更改AudioRecord的比特率

来自分类Dev

Android:从缓冲区读取,直到收到特定的字符或字符串

来自分类Dev

android上的AudioRecord在棉花糖上不起作用。错误说未初始化的AudioRecord

来自分类Dev

android上的AudioRecord无法在棉花糖上使用。错误说未初始化的AudioRecord

来自分类Dev

Android如何将int值写入缓冲区并使用计时器从缓冲区中获取值?

来自分类Dev

使用Android AudioRecord时java.lang.NullPointerException

来自分类Dev

Android AudioRecord无法找到有效的配置

来自分类Dev

Android的AudioRecord与Java的SE AudioFormat的兼容性

来自分类Dev

Android AudioRecord StartRecording-应用程序挂起

来自分类Dev

Python:从缓冲区播放视频文件

来自分类Dev

如何使QAudioOutput对象从缓冲区播放?

来自分类Dev

Android OpenSLES缓冲区饥饿问题

来自分类Dev

Android DatagramSocket接收缓冲区大小

来自分类Dev

Android AudioRecord无法初始化(其他解决方案无效)

Related 相关文章

  1. 1

    使用AudioRecord API的android录音机

  2. 2

    android AudioRecord类来录制音频并播放

  3. 3

    在Android AudioTrack中使用缓冲区

  4. 4

    在Android AudioTrack中使用缓冲区

  5. 5

    Android AudioRecord的麻烦

  6. 6

    Android AudioRecord的麻烦

  7. 7

    Android AudioRecord剪辑

  8. 8

    android AudioRecord中的BufferSize减小

  9. 9

    用SoundPool在Android上播放声音,同时用AudioRecord录制麦克风

  10. 10

    Android:建议在AudioRecord中使用bufferSizeInBytes值

  11. 11

    在Android上更改AudioRecord的比特率

  12. 12

    Android AudioRecord无法初始化

  13. 13

    Android源和AudioRecord的多用途

  14. 14

    AudioRecord在Android 5.01上产生零的差距

  15. 15

    调用startRecording()方法时,Android AudioRecord失败

  16. 16

    在Android上更改AudioRecord的比特率

  17. 17

    Android:从缓冲区读取,直到收到特定的字符或字符串

  18. 18

    android上的AudioRecord在棉花糖上不起作用。错误说未初始化的AudioRecord

  19. 19

    android上的AudioRecord无法在棉花糖上使用。错误说未初始化的AudioRecord

  20. 20

    Android如何将int值写入缓冲区并使用计时器从缓冲区中获取值?

  21. 21

    使用Android AudioRecord时java.lang.NullPointerException

  22. 22

    Android AudioRecord无法找到有效的配置

  23. 23

    Android的AudioRecord与Java的SE AudioFormat的兼容性

  24. 24

    Android AudioRecord StartRecording-应用程序挂起

  25. 25

    Python:从缓冲区播放视频文件

  26. 26

    如何使QAudioOutput对象从缓冲区播放?

  27. 27

    Android OpenSLES缓冲区饥饿问题

  28. 28

    Android DatagramSocket接收缓冲区大小

  29. 29

    Android AudioRecord无法初始化(其他解决方案无效)

热门标签

归档