I'm trying to implement an app that listens to microphone input (specifically, breathing), and presents data based on it. I'm using the Android class AudioRecord, and when trying to instantiate AudioRecord I get three errors.
AudioRecord: AudioFlinger could not create record track, status: -1
AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -1.
android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
I found this excellent thread: AudioRecord object not initializing
I have borrowed the code from the accepted answer that tries all sample rates, audio formats and channel configurations to try to solve the problem, but it didn't help, I get the above errors for all settings. I have also added a call to AudioRecord.release() on several places according to one of the answers in the thread but it made no difference.
This is my code:
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;
public class SoundMeter {
private AudioRecord ar = null;
private int minSize;
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 32000, 44100 };
public boolean start() {
ar = findAudioRecord();
if(ar != null){
ar.startRecording();
return true;
}
else{
Log.e("SoundMeter", "ERROR, could not create audio recorder");
return false;
}
}
public void stop() {
if (ar != null) {
ar.stop();
ar.release();
}
}
public double getAmplitude() {
short[] buffer = new short[minSize];
ar.read(buffer, 0, minSize);
int max = 0;
for (short s : buffer)
{
if (Math.abs(s) > max)
{
max = Math.abs(s);
}
}
return max;
}
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_PCM_FLOAT }) {
for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
try {
Log.d("SoundMeter", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
Log.d("SoundMeter", "Found a supported bufferSize, attempting to instantiate");
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED){
minSize = bufferSize;
return recorder;
}
else
recorder.release();
}
} catch (Exception e) {
Log.e("SoundMeter", rate + " Exception, keep trying.", e);
}
}
}
}
return null;
}
}
I have also added the
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
tag to my manifest file, as a child to the manifest tag and a sibling to the application tag according to one of the other answers in the thread mentioned above. I have rebuilt the project after adding this tag.
These are the solutions I find when googling the problem, but they unfortunately don't seem to do it for me. I am debugging on my Nexus 5 phone (not an emulator). These errors appear upon calling the contructor of AudioRecord. I have rebooted my phone several times to try to release the microphone, to no avail. The project is based on Android 4.4, and my phone is currently running Android 6.0.1.
Would highly appreciate some tips on what else I can try, what I could have missed. Thank you!