From b294d3d11f1acb497025990f38b4bcf532c32306 Mon Sep 17 00:00:00 2001 From: xufuji456 Date: Wed, 23 Mar 2022 17:38:16 +0800 Subject: [PATCH] Feature: add AudioProcessController, include AEC/AGC/NS --- .../controller/AudioEffectController.kt | 10 ++ .../controller/AudioProcessController.kt | 100 ++++++++++++++++++ .../controller/AudioRecordController.kt | 17 +++ 3 files changed, 127 insertions(+) create mode 100644 AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioProcessController.kt diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioEffectController.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioEffectController.kt index 2e80047..6f7db41 100644 --- a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioEffectController.kt +++ b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioEffectController.kt @@ -46,6 +46,16 @@ open class AudioEffectController(audioEffectCallback: AudioEffectCallback) { mAudioEffectCallback = audioEffectCallback } + /****************************************************************** + AudioEffect + | + ______________________|___________________________ + | | | | | + Equalizer Virtualizer BassBoost PresetReverb DynamicsProcessing + + ******************************************************************/ + + /** * Setup AudioEffect of Equalizer, which uses to adjust the gain of frequency. * There are key params of band、bandLevel、centerFrequency in Equalizer. diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioProcessController.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioProcessController.kt new file mode 100644 index 0000000..1ca5882 --- /dev/null +++ b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioProcessController.kt @@ -0,0 +1,100 @@ +package com.frank.androidmedia.controller + +import android.media.audiofx.AcousticEchoCanceler +import android.media.audiofx.AudioEffect +import android.media.audiofx.AutomaticGainControl +import android.media.audiofx.NoiseSuppressor +import android.util.Log +import java.lang.Exception + +/** + * + * @author frank + * @date 2022/3/23 + */ +open class AudioProcessController { + + /************************************************************* + AudioEffect + | + ____________________|___________________ + | | | + AcousticEchoCanceler AutomaticGainControl NoiseSuppressor + + **************************************************************/ + + companion object { + val TAG: String = AudioProcessController::class.java.simpleName + } + + private var noiseSuppressor: NoiseSuppressor? = null + private var automaticGainControl: AutomaticGainControl? = null + private var acousticEchoCanceler: AcousticEchoCanceler? = null + + fun initAEC(audioSessionId: Int): Boolean { + if (!AcousticEchoCanceler.isAvailable()) { + Log.e(TAG, "AEC not available...") + return false + } + try { + acousticEchoCanceler = AcousticEchoCanceler.create(audioSessionId) + } catch (e: Exception) { + Log.e(TAG, "init AcousticEchoCanceler error=$e") + return false + } + val result = acousticEchoCanceler?.setEnabled(true) + if (result != AudioEffect.SUCCESS) { + acousticEchoCanceler?.release() + acousticEchoCanceler = null + return false + } + return true + } + + fun initAGC(audioSessionId: Int): Boolean { + if (!AutomaticGainControl.isAvailable()) { + Log.e(TAG, "AGC not available...") + return false + } + try { + automaticGainControl = AutomaticGainControl.create(audioSessionId) + } catch (e: Exception) { + Log.e(TAG, "init AutomaticGainControl error=$e") + return false + } + val result = automaticGainControl?.setEnabled(true) + if (result != AudioEffect.SUCCESS) { + automaticGainControl?.release() + automaticGainControl = null + return false + } + return true + } + + fun initNS(audioSessionId: Int): Boolean { + if (!NoiseSuppressor.isAvailable()) { + Log.e(TAG, "NS not available...") + return false + } + try { + noiseSuppressor = NoiseSuppressor.create(audioSessionId) + } catch (e: Exception) { + Log.e(TAG, "init NoiseSuppressor error=$e") + return false + } + val result = noiseSuppressor?.setEnabled(true) + if (result != AudioEffect.SUCCESS) { + noiseSuppressor?.release() + noiseSuppressor = null + return false + } + return true + } + + fun release() { + noiseSuppressor?.release() + acousticEchoCanceler?.release() + automaticGainControl?.release() + } + +} \ No newline at end of file diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioRecordController.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioRecordController.kt index ff08970..d3662aa 100644 --- a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioRecordController.kt +++ b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioRecordController.kt @@ -27,6 +27,9 @@ open class AudioRecordController { private var mAudioRecord: AudioRecord? = null private var mRecordThread: RecordThread? = null + private val enableAudioProcessor = false + private var mAudioProcessController: AudioProcessController? = null + private fun initAudioRecord() { val sampleRate = 44100 val audioFormat = AudioFormat.ENCODING_PCM_16BIT @@ -37,6 +40,16 @@ open class AudioRecordController { channelConfig, audioFormat, minBufferSize) + + if (enableAudioProcessor) { + mAudioProcessController = AudioProcessController() + var result:Boolean? = mAudioProcessController?.initAEC(mAudioRecord?.audioSessionId!!) + Log.e(TAG, "init AEC result=$result") + result = mAudioProcessController?.initAGC(mAudioRecord?.audioSessionId!!) + Log.e(TAG, "init AGC result=$result") + result = mAudioProcessController?.initNS(mAudioRecord?.audioSessionId!!) + Log.e(TAG, "init NS result=$result") + } } private class RecordThread(recordPath: String, audioRecord: AudioRecord, bufferSize: Int) : Thread() { @@ -133,5 +146,9 @@ open class AudioRecordController { mAudioRecord!!.release() mAudioRecord = null } + if (mAudioProcessController != null) { + mAudioProcessController!!.release() + mAudioProcessController = null + } } } \ No newline at end of file