android降噪回路测试

在android手机上,如果喇叭和mic离得过近,没有采取硬件上的降噪手段(比如采取双mic,一个装在上面,一个装在下面,利用两个mic录取声音时的音量差来过滤掉远处的噪音),那么在回路测试的过程中,mic会将你对着mic说话的声音,和喇叭发出的声音全部录入,从而产生尖锐的回声,也就是啸叫声。针对这个情况,要么硬件上来修改,要么在软件上,利用AcousticEchoCanceler接口来消除部份噪音. 完整代码如下:

import com.android.autotest.R;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
import android.util.Log;

import android.media.audiofx.AcousticEchoCanceler;
import android.media.AudioSystem;


public class LoopActivity extends BaseItemActivity {
    private String TAG = "LoopActivity";
    boolean isRecording = false;
    boolean isExit = false;
    static final int frequency = 16000;
    static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_DEFAULT;
    static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
    int recBufSize, playBufSize;
    AudioRecord mAudioRecord;
    AudioTrack mAudioTrack;
    RecordPlayThread mRecordPlayThread = null;
    int note = 0;
   // Handler mHandler;
    AudioManager mAudioManager;
   // Runnable mNotiRunnable = null;

    private BroadcastReceiver mHeadsetPlugReceiver;
    boolean isHeadSetPlugIn = false;
    Toast mToast = null;
    
    private AcousticEchoCanceler canceler;
	private int audioSession = -1;
	
    public class HeadsetPlugReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.hasExtra("state")) {
                if (intent.getIntExtra("state", 0) == 0) {
                    isHeadSetPlugIn = false;
                    isRecording = false;
                    note = R.string.loop_headset_plug_out;
                } else if (intent.getIntExtra("state", 0) == 1) {
                    isHeadSetPlugIn = true;
                    isRecording = true;
                    note = R.string.loop_headset_plug_in;
                    if(mRecordPlayThread == null){
                        mRecordPlayThread = new RecordPlayThread();
                        mRecordPlayThread.start();
                    }
                }
                if(mToast == null){
                    mToast = Toast.makeText(LoopActivity.this, note, Toast.LENGTH_SHORT);
                }
                mToast.setText(note);
                mToast.show();
            }

        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addItemView(R.layout.activity_item_loop);

      //  recBufSize = AudioRecord.getMinBufferSize(frequency,
      //          channelConfiguration, audioEncoding);

   //     playBufSize = AudioTrack.getMinBufferSize(frequency,
   //             channelConfiguration, audioEncoding);
		
		int bufferSize = AudioRecord
                .getMinBufferSize(frequency, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT,
                        AudioFormat.ENCODING_PCM_16BIT);
	    recBufSize = bufferSize;
        playBufSize = Math.max(bufferSize, AudioTrack.getMinBufferSize(
                frequency, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT,
                AudioFormat.ENCODING_PCM_16BIT));


		
        mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
                frequency, channelConfiguration, audioEncoding, recBufSize);

        audioSession = mAudioRecord.getAudioSessionId();
		Log.d(TAG, "onCreate audioSession is: "+audioSession);
        if(audioSession == -1)
        {
	        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
	                AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, audioEncoding, playBufSize,
	                AudioTrack.MODE_STREAM);
        }
		else
		{
	        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
	                AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, audioEncoding, playBufSize,
	                AudioTrack.MODE_STREAM, audioSession);
	        if(isDeviceSupport())
	        {
			    boolean result = initAEC(audioSession);
				Log.d(TAG, "onCreate initAEC result is: "+result);
				result = setAECEnabled(true);
				Log.d(TAG, "onCreate setAECEnabled result is: "+result);
	        }			
		}			
        mAudioTrack.setStereoVolume(1f, 1f);
		mAudioTrack.setPlaybackRate(frequency);
        isRecording = true;
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
		mAudioManager.setSpeakerphoneOn(true);
		
        isHeadSetPlugIn = true;//mAudioManager.isWiredHeadsetOn();
        if (!isHeadSetPlugIn) {
        } else {
            mRecordPlayThread = new RecordPlayThread();
            mRecordPlayThread.start();
        }
    /*    mHandler = new Handler();
        mNotiRunnable = new Runnable() {
            
            @Override
            public void run() {
                isHeadSetPlugIn = mAudioManager.isWiredHeadsetOn();
                if (!isHeadSetPlugIn) {
                    note = R.string.loop_headset_plug_please;
                } else {
                    note = R.string.loop_headset_plug_in;
                }
                if(mToast == null){
                    mToast = Toast.makeText(LoopActivity.this, note, Toast.LENGTH_SHORT);
                    mToast.show();
                }
            }
        };
        mHandler.postDelayed(mNotiRunnable, 1000);*/
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
       // mAudioTrack.stop();
       // mAudioRecord.stop();
      
       mAudioTrack.release();
       mAudioRecord.release(); 
	   
      // mHandler.removeCallbacks(mNotiRunnable);
        isExit = true;
        isRecording = false;
		release();
		
    }

    @Override
    protected void onResume() {
        super.onResume();
      //  registerHeadsetPlugReceiver();
    }

    @Override
    protected void onPause() {
        super.onPause();
     //   unregisterReceiver(mHeadsetPlugReceiver);
		
    }

    private void registerHeadsetPlugReceiver() {
        mHeadsetPlugReceiver = new HeadsetPlugReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.intent.action.HEADSET_PLUG");
        registerReceiver(mHeadsetPlugReceiver, intentFilter);
    }

    class RecordPlayThread extends Thread {
        public void run() {
            //if (isHeadSetPlugIn)
            if(true)
			{
                try {
                    byte[] buffer = new byte[recBufSize];
                    mAudioRecord.startRecording();
                    mAudioTrack.play();

                    while (isRecording) {
                        int bufferReadResult = mAudioRecord.read(buffer, 0,
                                recBufSize);
                        byte[] tmpBuf = new byte[bufferReadResult];
                        System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);
                        mAudioTrack.write(tmpBuf, 0, tmpBuf.length);				
                    }
                    mAudioTrack.stop();
                    mAudioRecord.stop();
                    mRecordPlayThread = null;
                    //if (isExit) {
                      //  mAudioTrack.release();
                      //  mAudioRecord.release();
                    //}
                } catch (Throwable t) {
                    // cannot be call at not mainthread
                    // Toast.makeText(LoopActivity.this, t.getMessage(),
                    // Toast.LENGTH_SHORT).show();
                }
            }

        }
    };

	public  boolean isDeviceSupport()
	{
	    boolean isSupport = AcousticEchoCanceler.isAvailable();
		Log.d(TAG, "isDeviceSupport isSupport is: "+isSupport);
	    return isSupport;
	}

 
	public boolean initAEC( int audioSession)
	{
		if(canceler != null)
		{
		    return false;
	    }
	    canceler = AcousticEchoCanceler.create(audioSession);
		if(canceler == null)
		{
		    return false;
		}
	    canceler.setEnabled(true);
	    return canceler.getEnabled();
	}

	public boolean setAECEnabled( boolean enable)
	{
	    if( null == canceler)
		{
	        return false;
	    }
	    canceler.setEnabled(enable);
	    return canceler.getEnabled();
	}	

	public boolean release()
	{
	    if( null == canceler)
		{
	        return false;
	    }
	    canceler.setEnabled(false);
	    canceler.release();
	    return true;
	}	
}

 

你可能感兴趣的:(android降噪,回路测试)