Android功能记录(三) ------ 使用AudioRecord和AudioTrack边录边播(降噪)

2018.8.30补充请求录音权限参考:https://blog.csdn.net/jdfkldjlkjdl/article/details/54618739


参考:

  • http://www.cnblogs.com/mythou/p/3241925.html
  • http://cncoke.iteye.com/blog/1773698

Main.Activity :

package ylcx.com.recordlibrary;

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.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.Toast;

public class Main extends AppCompatActivity
{

    private Button mBtnRecordAudio;
private Button mBtnPlayAudio;
private Chronometer mChronometerTime;
private static final String LOG_TAG = "RecordingService";
    boolean isRecording = false;//是否录放的标记
int frequency = 44100;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize, playBufSize;
AudioRecord audioRecord;
AudioTrack audioTrack;

@Override
    protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mBtnRecordAudio = (Button)findViewById(R.id.main_btn_record_sound);
    mBtnPlayAudio = (Button)findViewById(R.id.main_btn_play_sound);
    mChronometerTime = (Chronometer)findViewById(R.id.record_audio_chronometer_time);
    //这两个值设置小了会导致声音断断续续播放,有杂音的可能性是发声处离录音太近(硬件那边说的),因为我的需求是将录制的声音传送给硬件播放,所以不存在这个问题
    recBufSize = AudioRecord.getMinBufferSize(frequency,
            channelConfiguration, audioEncoding) * 4;
    playBufSize = AudioTrack.getMinBufferSize(frequency,
            channelConfiguration, audioEncoding) * 4;
    audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,
            channelConfiguration, audioEncoding, recBufSize);
    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
            channelConfiguration, audioEncoding,
            playBufSize, AudioTrack.MODE_STREAM);

    mBtnRecordAudio.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
    {
        isRecording = true;
        Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run()
        {
            StartRecord();
            Log.e("tag", "start");
        }
    });
    thread.start();
}
        });

        mBtnPlayAudio.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
{

}
        });
        mChronometerTime.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
            @Override
            public void onChronometerTick(Chronometer chronometer)
{
    // TODO Auto-generated method stub
    //如果从开始计时到现在超过50秒则停止计时
    if (SystemClock.elapsedRealtime() - mChronometerTime.getBase() > 10 * 1000)
    {
        //Log.d("onChronometerTick", mRecorder.toString());
        mChronometerTime.stop();

    }
}
        });
    }
    public void StartRecord()
{
    try
    {
        byte[] buffer = new byte[recBufSize];
        audioRecord.startRecording();//开始录制
        audioTrack.play();//开始播放

        while (isRecording)
        {
            //从MIC保存数据到缓冲区
            int bufferReadResult = audioRecord.read(buffer, 0, recBufSize);

            byte[] tmpBuf = new byte[bufferReadResult];
            System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);
            //写入数据即播放
            audioTrack.write(tmpBuf, 0, tmpBuf.length);
        }
        audioTrack.stop();
        audioRecord.stop();
    }
    catch (Throwable t)
    {
        Toast.makeText(Main.this, t.getMessage(), Toast.LENGTH_SHORT).show();
    }
}
}

因为我的需求只是得到录制的实时byte[]数据即可,因此保存音频文件并没有做,小伙伴需要的自己百度吧~

降噪解决方案:

      1.通过安卓自带的 VOICE_COMMUNICATION模式进行录音,自动消除回音。这种方法我试了,但是硬件上得到的声音特别小,不太符合我的需求

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

      2.使用第三方库进行消除(webRtc、Speex..),消除回音(还未尝试,后续更新)

 

参考链接:

   Android手机直播(三)声音采集 : https://www.jianshu.com/p/2cb75a71009f

你可能感兴趣的:(Android)