Reputation: 7193
I am trying to build a real time noise reduction program in Android
I use AudioRecord to obtain raw input sound data and AudioTrack to play it back.
While initializing Audiorecord, I use the code
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
and when playing it back I use the code
track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
These settings work great for my Nexus 7 tablet (NOT phone), but when I tried to run it an LG Optimus (or any other mobile phone), the output volume is very low, even at hardware's maximum. If I change AudioManager.MODE_IN_COMMUNICATION to some other values, sometimes there is no output at all, or sometimes there is loud output when the program is executed the first time, then no output in the subsequent runs. This problem is not seen in the Nexus 7 (while some options do cause no sound output in the Nexus 7 as well)
(I perform FFT on the raw audio data, then run it through a noise reduction algorithm function to calculate gain values for each frequency component after FFT, and multiply the final output with thsi gain value. I have been able to figure out that whenever there is no output from the speakers, it is usually due to these gain values getting a value of NaN, but that is a different problem).
What I want to know is, what exactly is the difference between the various types of audio output sources defined in Audiomanager
, such as AudioManager.MODE_IN_COMMUNICATION
and the audio input sources in MediaRecorder.AudioSource
? Why do some of their options cause different behavior in tablet and phone?
--- EDIT ---
Also I was recently told that, in the phone, after this program is executed, the output in the phone sounds small, and after exiting the program, the sound in the normal operation of the phone continues to stay at that small volume. How do I make sure that all the sound related (or any other of the phone's resources) go back to their original settings once the program is terminated ?
--- EDIT 2 ---
Old initialization code:
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION); // ORIGINAL AudioManager.MODE_IN_COMMUNICATION
--- EDIT 3 ---
Current initialization scheme
am.setMode(AudioManager.MODE_IN_COMMUNICATION); // ADDED LATER: DELETE THIS LINE IF IT CAUSES PROBLEMS
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
--- EDIT 4 ---
Code in onResume()
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
currentAudioManagerMode = am.getMode();
... // (function with initialization code from EDIT 3)
Code in onPause()
am.setMode(currentAudioManagerMode);
Upvotes: 2
Views: 3065
Reputation: 6564
If you need more information that what's given in the SDK API documentation, then may i suggest you refer the respective source code? Likewise, you can do the same for MediaRecorder class.
WRT to your issue that the audio settings are changed after you run your app, i would suggest you first read the modes when you start your app (using respective getMode()
methods on the hardware resource) and save them and restore the same when you exit/go-into-background your app (using respective setMode()
methods on the hardware resource). The hardware resource here are MediaRecorder and AudioManager.
HTH.
Upvotes: 1