Android Java: how to disable microphone input while streaming system audio?

Basically, my program records user input via the microphone and store it as a .pcm file in the sdcard/ directory. It'll be overwritten should there be an existing one. The file is then later sent for playback and analysis (mainly FFT, RMS computation).

I have added another function which allows the program to record system audio, so it allows user's mp3 files to be analyzed as well. It streams the system audio and store it as a .pcm file for later playback and analysis.

It's all functioning well. However, there's a slight issue, when the program streams audio, it captures input from the mic and there'll be noises in the playback. I do not want this as it'll affect the analysis reading. I googled for a solution and found that I can actually mute the mic. So now, I want to mute the mic when the mp3 file is being streamed.

The code I have found is,

AudioManager.setMicrophoneMute(true);

I tried to implement it but it just crashes my application. I tried to find for solutions these few days but I cannot seem to get any.

Here is my code snippet for the part where I want to stream system audio and muting the microphone before it starts streaming.

//create a new AudioRecord object to record the audio data of an mp3 file
int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);

      audioRecord = new AudioRecord(AudioManager.STREAM_MUSIC, 
              frequency, channelConfiguration, 
              audioEncoding, bufferSize);

      //a short array to store raw pcm data
      short[] buffer = new short[bufferSize];   
      Log.i("decoder", "The audio record created fine ready to record");

      try {
          audioManager.setMicrophoneMute(true);
      } catch (Exception e) {
          e.printStackTrace();
      }


      audioRecord.startRecording();
      isDecoding = true;

When the setMicrophoneMute(true) line is surrounded with try-catch, the program would only crash when I want to send the recording for play back. Errors are as follow:
"AudioFlinger could not create track, status: -12"
"Error initializing AudioTrack"
"[android.media.AudioTrack] Error code -20 when initializing AudioTrack."

When it is not surrounded with try-catch, the program would just crash the moment I click on the start streaming button. "Decoding failed" < this is an error log from catching a throwable.

How can I mute the microphone input while streaming the system audio? Let me know if I can provide you with more codes. Thank you!

**EDIT I have implemented my mutemicrophone successfully, it even returns me a true for isMicrophoneMute(), however, it's not muted as it still records from the microphone; it's a false true.

Based on the suggested answer, I have already created a class for audio focus as below:

private final Context c;

private final AudioManager.OnAudioFocusChangeListener changeListener =
    new AudioManager.OnAudioFocusChangeListener()
    {
        public void onAudioFocusChange(int focusChange)
        {
            //nothing to do
        }
    };


AudioFocus(Context context)
{
    c = context;
}


public void grabFocus()
{
    final AudioManager am = (AudioManager) c.getSystemService(Context.AUDIO_SERVICE);
    final int result = am.requestAudioFocus(changeListener,
                                            AudioManager.STREAM_MUSIC,
                                            AudioManager.AUDIOFOCUS_GAIN);
    Log.d("audiofocus","Grab audio focus: " + result);
}


public void releaseFocus()
{
    final AudioManager am = (AudioManager) c.getSystemService(Context.AUDIO_SERVICE);
    final int result = am.abandonAudioFocus(changeListener);
    Log.d("audiofocus","Abandon audio focus: " + result);
}

I then call the method from my Decoder class to request for audio focus:

        int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration,  audioEncoding);

        audioFocus.grabFocus();

        audioRecord = new AudioRecord(AudioManager.STREAM_MUSIC, 
                frequency, channelConfiguration, 
                audioEncoding, bufferSize);

        //a short array to store raw pcm data
        short[] buffer = new short[bufferSize];   
        Log.i("decoder", "The audio record created fine ready to record");


            audioRecord.startRecording();
            isDecoding = true;

            Log.i("decoder", "Start recording fine");

And then release the focus when stop decoding is pressed:

//stops recording
public void stopDecoding(){
    isDecoding = false;
    Log.i("decoder", "Out of recording");
    audioRecord.stop();

    try {
        dos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    mp.stop();
    mp.release();
    audioFocus.releaseFocus();
}

However, this makes my application crash. Where did I went wrong?


The following snippet requests permanent audio focus on the music audio stream. You should request the audio focus immediately before you begin playback, such as when the user presses play. I think this would be the way to go rather than muting the input microphone. Check out the developer audio focus docs for more information

AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
...

// Request audio focus for playback
int result = am.requestAudioFocus(afChangeListener,
                                 // Use the music stream.
                                 AudioManager.STREAM_MUSIC,
                                 // Request permanent focus.
                                 AudioManager.AUDIOFOCUS_GAIN);

if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    am.registerMediaButtonEventReceiver(RemoteControlReceiver);
    // Start playback.
}
链接地址: http://www.djcxy.com/p/60182.html

上一篇: 列出所有打开AL的设备不起作用

下一篇: Android Java:如何在传输系统音频时禁用麦克风输入?