Android AudioRecord - Won't Initialize 2nd time

前端 未结 5 1690
刺人心
刺人心 2020-12-31 08:52

Hej, im currently trying to get AudioRecord to work. Because I need it in a bigger project. But it seems to mess up a lot. I have been trying alot of things, so I went back

5条回答
  •  北海茫月
    2020-12-31 09:09

    I had the same problem, usually the audRec.release() helps indeed, but if you need to stop and start several times the following code is more robust. Plus, I had an issue that the recording took place in a separate thread and Android sometimes kills threads when running for a long time. So take a look at this code, it makes sure the recording is held even when the other thread is dead and upon the following audRec.start() it stops and releases:

    import android.media.AudioFormat;
    import android.media.AudioRecord;
    import android.media.MediaRecorder; 
    
    public class RecorderSingleton {
    
        private static final int FREQUENCY = 16000;
    
        public static RecorderSingleton instance = new RecorderSingleton();
        private AudioRecord recordInstance = null;
        private int bufferSize;
    
        private RecorderSingleton() {
            bufferSize = AudioRecord.getMinBufferSize(FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        }
    
        public boolean init() {
            recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
            if (recordInstance.getState() == AudioRecord.STATE_UNINITIALIZED) {
                return false;
            }
            return true;
        }
    
        public int getBufferSize() {
            return bufferSize;
        }
        public boolean start() {
            if (recordInstance != null && recordInstance.getState() != AudioRecord.STATE_UNINITIALIZED) {
                if (recordInstance.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) {
                    recordInstance.stop();
                }
                recordInstance.release();
            }
            if (!init()) {
                return false;
            }
            recordInstance.startRecording();
            return true;
        }
    
        public int read(short[] tempBuffer) {
            if (recordInstance == null) {
                return AudioRecord.ERROR_INVALID_OPERATION;
            }
            int ret = recordInstance.read(tempBuffer, 0, bufferSize);
            return ret;
        }
    
        public void stop() {
            if (recordInstance == null) {
                return;
            }
            recordInstance.stop();
            recordInstance.release();
        }
    }
    

    Then if you have a recorder thread you can use it as follows:

    import android.media.AudioRecord;
    
    public class Recorder implements Runnable {
        private int requiredSamples;
        private int takenSamples = 0;
        private boolean cancelled = false;
    
        public void run() {
    
            // We're important...
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
    
            int bufferRead = 0;
            int bufferSize = RecorderSingleton.instance.getBufferSize();
            short[] tempBuffer = new short[bufferSize];
            if (!RecorderSingleton.instance.start()) {
                return;
            }
            try {
                Log.d(RoomieConstants.LOG_TAG, "Recorder Started");
                while (takenSamples < requiredSamples && !cancelled) {
                    bufferRead = RecorderSingleton.instance.read(tempBuffer);
                    if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
                        throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION");
                    } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
                        throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE");
                    }
                    takenSamples += bufferRead;
                    // do something with the samples ...
                    // ...
                    // ...
                }
            } finally {
                // Close resources...
                stop();
            }
        }
    
        public void stop() {
            RecorderSingleton.instance.stop();
        }
    
        public void cancel() {
            cancelled  = true;
        }
    }
    

提交回复
热议问题