I'm constantly getting the following error on my app:
09-25 15:52:24.875: E/AudioHardware(144): -----AudioStreamInALSA::read(0x42db0040, 512) END ERROR
09-25 15:52:24.875: E/AudioFlinger(144): Error reading audio input
09-25 15:52:24.882: D/AudioHardware(144): AudioStreamInALSA::setParameters() routing=0
09-25 15:52:25.394: W/AudioRecord(7359): obtainBuffer timed out (is the CPU pegged?) user=00000000, server=00000000
09-25 15:52:25.398: D/AudioHardware(144): AudioStreamInALSA::setParameters() input_source=1;routing=262144
My code to create the AudioRecord instance is:
int minValue = AudioRecord.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
// Gets a buffer size that is greater than the minimun required and is multiple of the chunk size
BUFFER_SIZE_IN_BYTES = getBufferSizeInChunks(minValue);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT ,
BUFFER_SIZE_IN_BYTES );
And the AudioRecord instance like this:
@Override
public void run() {
try{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recorder = initAudioRecord();
if (recorder.getState() != AudioRecord.STATE_INITIALIZED) {
return;
}
// Audio input buffer
byte[] audio_data = new byte[BUFFER_SIZE_IN_BYTES];
while (!Thread.interrupted() && keepRunning) {
recorder.startRecording();
recorder.read(audio_data, 0, BUFFER_SIZE_IN_BYTES);
recorder.stop();
// Here I deal with the audio_data ...
// UI feedback
PostToUI(frequency);
}
}
catch(Exception e){
e.printStackTrace();
}
}
private void PostToUI(final double frequency) {
handler.post(new Runnable() {
public void run() {
uiHandler.updateUi(frequency);
}
});
}
A separated Thread constantly deals with the audio input as shown (as long as the Activity's onPause()
is not called)
Does anybody have some clue?
FULL LOG:
09-27 14:05:29.246: D/AudioHardware(144): AudioStreamInALSA::setParameters() input_source=1;routing=262144
09-27 14:05:29.246: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
09-27 14:05:29.246: V/AudioHardware(144): setInputSource_l(1)
09-27 14:05:29.246: V/AudioHardware(144): closeMixer_l() mMixerOpenCnt: 1
09-27 14:05:29.246: D/AudioHardware(144): AudioHardware pcm capture is exiting standby.
09-27 14:05:29.246: V/AudioHardware(144): AudioStreamInALSA exit standby mNeedEchoReference 0 mEchoReference 0x0
09-27 14:05:29.246: V/AudioHardware(144): open pcm_in driver
09-27 14:05:29.312: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
09-27 14:05:29.312: V/AudioHardware(144): read() wakeup setting route Main Mic
09-27 14:05:41.593: D/Finsky(12273): [1] 5.onFinished: Installation state replication succeeded.
09-27 14:05:49.332: W/AudioHardware(144): read error: -1
09-27 14:05:49.332: D/AudioHardware(144): AudioHardware pcm capture is going to standby.
09-27 14:05:49.332: V/AudioHardware(144): closeMixer_l() mMixerOpenCnt: 1
09-27 14:05:49.375: E/AudioHardware(144): -----AudioStreamInALSA::read(0x42b2d040, 512) END ERROR
09-27 14:05:49.375: E/AudioFlinger(144): Error reading audio input
09-27 14:05:49.386: D/AudioHardware(144): AudioStreamInALSA::setParameters() routing=0
09-27 14:05:49.906: W/AudioRecord(13013): obtainBuffer timed out (is the CPU pegged?) user=00000000, server=00000000
09-27 14:05:49.910: D/AudioHardware(144): AudioStreamInALSA::setParameters() input_source=1;routing=262144
09-27 14:05:49.914: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
09-27 14:05:49.914: V/AudioHardware(144): setInputSource_l(1)
09-27 14:05:49.914: V/AudioHardware(144): closeMixer_l() mMixerOpenCnt: 1
09-27 14:05:49.921: D/AudioHardware(144): AudioHardware pcm capture is exiting standby.
09-27 14:05:49.921: V/AudioHardware(144): AudioStreamInALSA exit standby mNeedEchoReference 0 mEchoReference 0x0
09-27 14:05:49.921: V/AudioHardware(144): open pcm_in driver
09-27 14:05:50.000: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
Is there any reason, why you continously turn recorder on and off? I would have put it like this:
// Audio input buffer
byte[] audio_data = new byte[BUFFER_SIZE_IN_BYTES];
recorder.startRecording();
while (!Thread.interrupted() && keepRunning) {
recorder.read(audio_data, 0, BUFFER_SIZE_IN_BYTES);
// Here I deal with the audio_data ...
// UI feedback
PostToUI(frequency);
}
recorder.stop();
I could imagine, that the recorder could deliver more than only buffer size, but you always just read that amount of bytes.
In my app, I have methods to start and stop the recorder from outside my run() method (I think you do similar with setting keepRunning). When stopping recorder somewhere else, you just have to adjust your while-loop like this:
while(recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING){