hackster84
Lurker
Hi,
I am writing an app that does data communication through the 3.5mm audio port on the device. I have the system working great on most of the phones that I've tested it on (these are all working personal cell phones that belong to people I work with) but I'm having trouble getting it to work on the Motorola Droid Mini.
The problem is that I can't initialize the AudioRecord source for any of the possible sample rates, audio formats or configurations (stereo or mono) that are supposed to be standard for every Android device on either the DEFAULT or MIC input sources (Error code -20 when initializing native AudioRecord object). I can get the instance to initialize properly when I set the input source to VOICE_RECOGNITION, however, on only the Droid Mini, the data that I receive from that input source is pure gibberish. the VOICE_RECOGNITION source does work for every other phone that I've tried it on, however - even phones whose OS goes back as far as Android 2.3.
Here's the interesting part: if I reset the phone and start my app immediately, I can get full communication to work properly (only when using the DEFAULT input source), but if I wait a couple of minutes or I restart my app, it crashes again. This behavior coupled with the research I've been doing on the matter lead me to believe that there is something else which is tying up that resource and thus making it impossible for me to start an AudioRecord instance using that input. (Maybe something like google voice control or another voice control related app - I looked to see what was running, but I couldn't find anything) I don't believe that the problem is due to my app, as every time the app exits or something is unplugged from the audio jack, I have the code set up to release all of the audio resources - including calling AudioRecord.stop() and AudioRecord.release(). (This was something I was doing before but was suggested in many forum posts as a possible solution).
That brings me to my question: is there a way to find out what process/service/app may be using that resource, and is there a way to change focus or gain priority access to it over the app that is running in the background? There is a way to gain audio focus for output - one would assume that there is a way to do so for input.
The reason that I'm using the AudioRecord function instead of the MediaRecorder is that I need to be able to have direct access to the input audio buffer in order to process the data and turn it into my binary data stream. As far as I can tell, this is something that the MediaRecorder class is incapable of doing.
I've included my AudioRecord initialization and release routines just in case someone can think of something that I'm not doing properly. Once again, this only happens on one phone - the Motorola Droid Mini. My app works flawlessly on every other phone I've tried it on, including the Samsung Galaxy S3 and the S5, the Motorola Droid RAZR M, the Kyocera Event, and a couple of others. (The Galaxys were a chore to get working correctly, as Samsung uses their own special audio hardware).
As always, thank you in advance for any help that you can offer on this situation. My code is include below.
-Chris
Here is my AudioRecord initialization routine:
that is called by
When the headphone jack is unplugged or the app is closed, this is called:
Again, thanks in advance for any assistance and all assistance you can offer.
I am writing an app that does data communication through the 3.5mm audio port on the device. I have the system working great on most of the phones that I've tested it on (these are all working personal cell phones that belong to people I work with) but I'm having trouble getting it to work on the Motorola Droid Mini.
The problem is that I can't initialize the AudioRecord source for any of the possible sample rates, audio formats or configurations (stereo or mono) that are supposed to be standard for every Android device on either the DEFAULT or MIC input sources (Error code -20 when initializing native AudioRecord object). I can get the instance to initialize properly when I set the input source to VOICE_RECOGNITION, however, on only the Droid Mini, the data that I receive from that input source is pure gibberish. the VOICE_RECOGNITION source does work for every other phone that I've tried it on, however - even phones whose OS goes back as far as Android 2.3.
Here's the interesting part: if I reset the phone and start my app immediately, I can get full communication to work properly (only when using the DEFAULT input source), but if I wait a couple of minutes or I restart my app, it crashes again. This behavior coupled with the research I've been doing on the matter lead me to believe that there is something else which is tying up that resource and thus making it impossible for me to start an AudioRecord instance using that input. (Maybe something like google voice control or another voice control related app - I looked to see what was running, but I couldn't find anything) I don't believe that the problem is due to my app, as every time the app exits or something is unplugged from the audio jack, I have the code set up to release all of the audio resources - including calling AudioRecord.stop() and AudioRecord.release(). (This was something I was doing before but was suggested in many forum posts as a possible solution).
That brings me to my question: is there a way to find out what process/service/app may be using that resource, and is there a way to change focus or gain priority access to it over the app that is running in the background? There is a way to gain audio focus for output - one would assume that there is a way to do so for input.
The reason that I'm using the AudioRecord function instead of the MediaRecorder is that I need to be able to have direct access to the input audio buffer in order to process the data and turn it into my binary data stream. As far as I can tell, this is something that the MediaRecorder class is incapable of doing.
I've included my AudioRecord initialization and release routines just in case someone can think of something that I'm not doing properly. Once again, this only happens on one phone - the Motorola Droid Mini. My app works flawlessly on every other phone I've tried it on, including the Samsung Galaxy S3 and the S5, the Motorola Droid RAZR M, the Kyocera Event, and a couple of others. (The Galaxys were a chore to get working correctly, as Samsung uses their own special audio hardware).
As always, thank you in advance for any help that you can offer on this situation. My code is include below.
-Chris
Here is my AudioRecord initialization routine:
Code:
private static int[] mSampleRates = new int[] {44100, 22050, 11025, 8000};
public AudioRecord findAudioRecord() {
AudioRecord recorder = null;
int source;
// This is here because I found that I can use the VOICE_RECOGNITION
//input source on every phone but the Droid Mini, which (when it works)
//only works using the DEFAULT audio source
if (android.os.Build.MODEL.equals("XT1030")){
source = MediaRecorder.AudioSource.DEFAULT;
}
else
source = MediaRecorder.AudioSource.VOICE_RECOGNITION;
_mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
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) {
// check if we can instantiate and have a success
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recorder = new AudioRecord(source, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED){
_inputSampleFrequency = recorder.getSampleRate();
_inputEncoding = recorder.getAudioFormat();
_inputChannelConfig = recorder.getChannelConfiguration();
recBufferSize = bufferSize;
return recorder;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return null;
}
that is called by
Code:
AudioRecord _audioRecord = findAudioRecord();
_audioRecord.startRecording();
_audioTrack.play();
When the headphone jack is unplugged or the app is closed, this is called:
Code:
_audioRecord.stop();
if (_audioRecord != null)_audioRecord.release();
_audioRecord = null;
Again, thanks in advance for any assistance and all assistance you can offer.