44import android .media .AudioFormat ;
55import android .media .AudioRecord ;
66import android .media .MediaRecorder ;
7+ import android .media .audiofx .AcousticEchoCanceler ;
8+ import android .media .audiofx .AutomaticGainControl ;
79import android .text .TextUtils ;
810import android .util .Log ;
911
@@ -27,6 +29,8 @@ public class AudioRecordUtil implements EncoderListener, FLVListener {
2729 private volatile boolean recorderState = true ; //录制状态
2830 private byte [] buffer ;
2931 private AudioRecord audioRecord ;
32+ private AcousticEchoCanceler canceler ;
33+ private AutomaticGainControl control ;
3034 private volatile PCMEncoder pcmEncoder ;
3135 private volatile FLVPacker flvPacker ;
3236 private Context context ;
@@ -37,6 +41,8 @@ public class AudioRecordUtil implements EncoderListener, FLVListener {
3741 private int bitDepth ;
3842 private int channelCount ; //声道数
3943 private int pitch = 0 ; //变调【-12~12】
44+ private boolean enableAEC = false ;
45+ private boolean enableAGC = false ;
4046
4147 private boolean isRecord = false ;
4248 private final ExecutorService executor = Executors .newSingleThreadExecutor ();
@@ -61,6 +67,21 @@ public AudioRecordUtil(Context ctx, String id, int sampleRate, int channel, int
6167 this .pitch = pitch ;
6268 init (sampleRate , channel , bitDepth );
6369 }
70+ public AudioRecordUtil (Context ctx , String id , int sampleRate , int channel , int bitDepth , boolean enableAEC , boolean enableAGC ) {
71+ context = ctx ;
72+ deviceId = id ;
73+ this .enableAEC = enableAEC ;
74+ this .enableAGC = enableAGC ;
75+ init (sampleRate , channel , bitDepth );
76+ }
77+ public AudioRecordUtil (Context ctx , String id , int sampleRate , int channel , int bitDepth , int pitch , boolean enableAEC , boolean enableAGC ) {
78+ context = ctx ;
79+ deviceId = id ;
80+ this .pitch = pitch ;
81+ this .enableAEC = enableAEC ;
82+ this .enableAGC = enableAGC ;
83+ init (sampleRate , channel , bitDepth );
84+ }
6485
6586 private void init (int sampleRate , int channel , int bitDepth ) {
6687 recordMinBufferSize = AudioRecord .getMinBufferSize (sampleRate , channel , bitDepth );
@@ -111,9 +132,20 @@ public void start() {
111132
112133 private void reset () {
113134 buffer = new byte [recordMinBufferSize ];
114- audioRecord = new AudioRecord (MediaRecorder .AudioSource .MIC , sampleRate , channel , bitDepth , recordMinBufferSize );
135+ if (enableAEC ) {
136+ audioRecord = new AudioRecord (MediaRecorder .AudioSource .VOICE_COMMUNICATION , sampleRate , channel , bitDepth , recordMinBufferSize );
137+ } else {
138+ audioRecord = new AudioRecord (MediaRecorder .AudioSource .MIC , sampleRate , channel , bitDepth , recordMinBufferSize );
139+ }
115140 pcmEncoder = new PCMEncoder (sampleRate , channelCount , this , PCMEncoder .AAC_FORMAT );
116141 flvPacker = new FLVPacker (this , true , false );
142+ int audioSessionId = audioRecord .getAudioSessionId ();
143+ if (enableAEC ) {
144+ Log .e (TAG , "=====initAEC result: " + initAEC (audioSessionId ));
145+ }
146+ if (enableAGC ) {
147+ Log .e (TAG , "=====initAGC result: " + initAGC (audioSessionId ));
148+ }
117149 }
118150
119151 /**
@@ -136,6 +168,16 @@ public void stop() {
136168 pcmEncoder = null ;
137169 flvPacker .release ();
138170 flvPacker = null ;
171+ if (canceler != null ) {
172+ canceler .setEnabled (false );
173+ canceler .release ();
174+ canceler = null ;
175+ }
176+ if (control != null ) {
177+ control .setEnabled (false );
178+ control .release ();
179+ control = null ;
180+ }
139181 }
140182
141183 public void release () {
@@ -183,4 +225,37 @@ public void run() {
183225 }
184226 }
185227 }
228+
229+ public boolean isDevicesSupportAEC () {
230+ return AcousticEchoCanceler .isAvailable ();
231+ }
232+ private boolean initAEC (int audioSession ) {
233+ boolean isDevicesSupportAEC = isDevicesSupportAEC ();
234+ Log .e (TAG , "isDevicesSupportAEC: " +isDevicesSupportAEC );
235+ if (!isDevicesSupportAEC ) {
236+ return false ;
237+ }
238+ if (canceler != null ) {
239+ return false ;
240+ }
241+ canceler = AcousticEchoCanceler .create (audioSession );
242+ canceler .setEnabled (true );
243+ return canceler .getEnabled ();
244+ }
245+ public boolean isDevicesSupportAGC () {
246+ return AutomaticGainControl .isAvailable ();
247+ }
248+ private boolean initAGC (int audioSession ) {
249+ boolean isDevicesSupportAGC = isDevicesSupportAGC ();
250+ Log .e (TAG , "isDevicesSupportAGC: " +isDevicesSupportAGC );
251+ if (!isDevicesSupportAGC ) {
252+ return false ;
253+ }
254+ if (control != null ) {
255+ return false ;
256+ }
257+ control = AutomaticGainControl .create (audioSession );
258+ control .setEnabled (true );
259+ return control .getEnabled ();
260+ }
186261}
0 commit comments