├── Audio3APorcessTest ├── Audio3APorcessTest.sln ├── Audio3APorcessTest.vcxproj ├── Audio3APorcessTest.vcxproj.filters └── Audio3APorcessTest.vcxproj.user ├── README.md ├── bin ├── AGC_16K.pcm ├── AGC_32K.pcm ├── AGC_48K.pcm ├── AGC_8K.pcm ├── Audio3APorcessTest.exe ├── NS_16K.pcm ├── NS_32K.pcm ├── NS_48K.pcm ├── SDAudio3AProcess.dll ├── mic16k-1ch.pcm ├── mic32k-1ch.pcm ├── mic32k-2ch.pcm ├── mic48k-1ch.pcm ├── mic48k-2ch.pcm ├── mic8k-1ch.pcm ├── ref16k-1ch.pcm ├── ref32k-1ch.pcm ├── ref32k-2ch.pcm ├── ref48k-1ch.pcm ├── ref48k-2ch.pcm └── ref8k-1ch.pcm ├── include └── SDAecAgcAnsProcessSdk.h ├── lib └── SDAudio3AProcess.lib └── source └── main.cpp /Audio3APorcessTest/Audio3APorcessTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Audio3APorcessTest", "Audio3APorcessTest.vcxproj", "{DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Debug|x64.ActiveCfg = Debug|x64 17 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Debug|x64.Build.0 = Debug|x64 18 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Debug|x86.ActiveCfg = Debug|Win32 19 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Debug|x86.Build.0 = Debug|Win32 20 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Release|x64.ActiveCfg = Release|x64 21 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Release|x64.Build.0 = Release|x64 22 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Release|x86.ActiveCfg = Release|Win32 23 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /Audio3APorcessTest/Audio3APorcessTest.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {DC54C9A4-E70F-4EF2-8F92-BEA1B94A023D} 23 | Audio3APorcessTest 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | $(SolutionDir)$(Configuration)\ 73 | 74 | 75 | 76 | Level3 77 | Disabled 78 | true 79 | WIN32;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 80 | ..\include; 81 | 82 | 83 | true 84 | ..\lib\SDAudio3AProcess.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 85 | ..\bin\$(TargetName)$(TargetExt) 86 | 87 | 88 | 89 | 90 | Level3 91 | Disabled 92 | true 93 | 94 | 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | MaxSpeed 102 | true 103 | true 104 | true 105 | WIN32;_CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) 106 | ..\include 107 | 108 | 109 | true 110 | true 111 | true 112 | ..\lib\SDAudio3AProcess.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 113 | ..\bin\$(TargetName)$(TargetExt) 114 | 115 | 116 | 117 | 118 | Level3 119 | MaxSpeed 120 | true 121 | true 122 | true 123 | 124 | 125 | true 126 | true 127 | true 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Audio3APorcessTest/Audio3APorcessTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /Audio3APorcessTest/Audio3APorcessTest.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | mic16k-1ch.pcm ref16k-1ch.pcm aec16k-1ch.pcm 16000 1 70 5 | WindowsLocalDebugger 6 | $(OutDir)..\..\bin\$(TargetName)$(TargetExt) 7 | ..\bin 8 | 9 | 10 | $(OutDir)..\..\bin\$(TargetName)$(TargetExt) 11 | WindowsLocalDebugger 12 | mic16k-1ch.pcm ref16k-1ch.pcm aec16k-1ch.pcm 16000 1 70 13 | ..\bin 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # audio 3A (AGC\AEC\ANS\VAD) process with simple api and single lib 2 | 3 | 4 | ## Audio3AProcessSdk简介 5 | 极简的音频3A(AGC AEC ANS VAD)处理封装接口: 6 | 7 | * 1、基于Webrtc AEC\AECM 8 | * 2、支持8KHZ、16KHZ、32KHZ、44.1KHZ、48KHZ,支持单声道、双声道。 9 | * 3、支持AEC自动延时估计。 10 | * 4、仅6个API,仅一个DLL组成,占用空间小,无第三方依赖,集成简易。 11 | * 5、C++开发,支持C、C++、C#,可移植Android等平台 12 | 13 | Webrtc中关于延时自动估计的说明:
14 | WebRtc is very dependent on delay calculation, a poor estimate, even by as little as 15 | 40ms, may affect the echo cancellation results greatly. Still, with the delay agnostic feature, it may take some time (5-10s or more) for 16 | the Aec module to learn the optimal delay, thus a good initial estimate is necessary for good EC quality in the beginning of a call. 17 | 自动延时估计需要一定的收敛时间,通过SD3AProcess_EnableDebugMode接口生成的Ref文件、Mic文件,使用cool edit确定二者延时作为初始值传入, 18 | 将有利于尽快收敛获得较好效果。

19 | 20 | #### 集成了采集和渲染的3A一体库:https://github.com/waterfoxfox/Audio3ACapRender 21 | 22 | ## Audio3AProcessSdk C API 23 | 24 | ### 25 | * 环境初始化,系统只需调用一次
26 | @param: outputPath:日志文件输出的目录,若目录不存在将自动创建
27 | @param: outputLevel:日志输出的级别,只有等于或者高于该级别的日志输出到文件
28 | @return:
29 | void `SD3AProcess_Enviroment_Init`(const char * outputPath, int outputLevel); 30 | 31 | ### 32 | * 环境反初始化,系统只需调用一次
33 | @return:
34 | void  `SD3AProcess_Enviroment_Free`(); 35 | 36 | ### 37 | * 创建SD3AProcess
38 | @param eAecMethod: AEC方法,其中AEC定点方法对应AECM,AEC浮点方法对应AEC
39 | @return: 返回模块指针,为NULL则失败
40 | void*  `SD3AProcess_New`(SD_AEC_METHOD_TYPE eAecMethod); 41 | 42 | ### 43 | * 销毁SD3AProcess,使用者应该做好与其他API之间的互斥保护
44 | @param pp3AProcess: 模块指针
45 | @return: 
46 | void  `SD3AProcess_Delete`(void** pp3AProcess); 47 | 48 | ### 49 | * 开始启动SD3AProcess,仅支持16bit short音频3A处理
50 | @param p3AProcess: 模块指针
51 | @param nSampleRate: 输入待处理数据采样率
52 | @param nChannelNum: 输入待处理数据声道数
53 | @param nAecDelayInitMs: MIC信号与REF扬声器输出信号之间的延时差,将作为内部AEC自动延时估计的初始值。 54 | 建议通过SD3AProcess_EnableDebugMode接口保存MIC、REF文件后观测得到 55 | 准确的延时估计初始值有利于自动延时估计尽快收敛
56 | @param bEnableAec: 是否使能AEC
57 | @param bEnableAgc: 是否使能AGC
58 | @param bEnableAns: 是否使能ANS
59 | @param bEnableVad: 是否使能VAD
60 | @param pfOutput3ACallback: 经过3A处理后的音频数据输出回调接口
61 | @param pObject: 上述输出回调接口的透传指针,将通过回调函数形参方式透传外层
62 | @return: TRUE-成功, FALSE-失败
63 | 64 | BOOL `SD3AProcess_Start`(void* p3AProcess, int nSampleRate, int nChannelNum, int nAecDelayInitMs, BOOL bEnableAec, BOOL bEnableAgc, BOOL bEnableAns, BOOL bEnableVad, 65 | Output3AProcessedData pfOutput3ACallback, void* pObject); 66 | 67 | ### 68 | * 停止SD3AProcess
69 | @param p3AProcess: 模块指针
70 | @return: 
71 | void  `SD3AProcess_Stop`(void* p3AProcess); 72 | 73 | 74 | ### 75 | * 存入REF扬声器数据作为AEC处理参考信号
76 | @param p3AProcess: 模块指针
77 | @param psRefData: REF扬声器数据
78 | @param nRefCount: REF扬声器数据大小(非字节数,而是psRefData 中 short数据的数目)
79 | @return: 
80 | void  `SD3AProcess_PutRefData`(void* p3AProcess, const short *psRefData, int nRefCount); 81 | 82 | ### 83 | * 存入待3A处理的麦克风采集信号
84 | @param p3AProcess: 模块指针
85 | @param psMicData: MIC数据
86 | @param nMicCount: MIC数据大小(非字节数,而是psRefData 中 short数据的数目)
87 | @return: 
88 | void  `SD3AProcess_PutMicData`(void* p3AProcess, const short *psMicData, int nMicCount); 89 | 90 | ### 91 | * 启用AEC调试模式,此时将生成AEC处理前的Ref信号和Mic信号到指定的路径,便于观察二者延时差
92 | @param p3AProcess: 模块指针
93 | @param pcTempFileSaveDir: 调试文件存放路径
94 | @return: TRUE-使能成功, FALSE-使能失败
95 | BOOL  `SD3AProcess_EnableDebugMode`(void* p3AProcess, const char *pcTempFileSaveDir); 96 | 97 | ### 本库仅做演示用途,若需要商业用途与技术支持请联系 www.mediapro.cc 98 | ### 更多资源见: https://mediapro.apifox.cn/ 99 | -------------------------------------------------------------------------------- /bin/AGC_16K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/AGC_16K.pcm -------------------------------------------------------------------------------- /bin/AGC_32K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/AGC_32K.pcm -------------------------------------------------------------------------------- /bin/AGC_48K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/AGC_48K.pcm -------------------------------------------------------------------------------- /bin/AGC_8K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/AGC_8K.pcm -------------------------------------------------------------------------------- /bin/Audio3APorcessTest.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/Audio3APorcessTest.exe -------------------------------------------------------------------------------- /bin/NS_16K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/NS_16K.pcm -------------------------------------------------------------------------------- /bin/NS_32K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/NS_32K.pcm -------------------------------------------------------------------------------- /bin/NS_48K.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/NS_48K.pcm -------------------------------------------------------------------------------- /bin/SDAudio3AProcess.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/SDAudio3AProcess.dll -------------------------------------------------------------------------------- /bin/mic16k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/mic16k-1ch.pcm -------------------------------------------------------------------------------- /bin/mic32k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/mic32k-1ch.pcm -------------------------------------------------------------------------------- /bin/mic32k-2ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/mic32k-2ch.pcm -------------------------------------------------------------------------------- /bin/mic48k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/mic48k-1ch.pcm -------------------------------------------------------------------------------- /bin/mic48k-2ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/mic48k-2ch.pcm -------------------------------------------------------------------------------- /bin/mic8k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/mic8k-1ch.pcm -------------------------------------------------------------------------------- /bin/ref16k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/ref16k-1ch.pcm -------------------------------------------------------------------------------- /bin/ref32k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/ref32k-1ch.pcm -------------------------------------------------------------------------------- /bin/ref32k-2ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/ref32k-2ch.pcm -------------------------------------------------------------------------------- /bin/ref48k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/ref48k-1ch.pcm -------------------------------------------------------------------------------- /bin/ref48k-2ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/ref48k-2ch.pcm -------------------------------------------------------------------------------- /bin/ref8k-1ch.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/bin/ref8k-1ch.pcm -------------------------------------------------------------------------------- /include/SDAecAgcAnsProcessSdk.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************// 2 | //* 版权所有 www.mediapro.cc 3 | //* 4 | //* 内容摘要:音频3A处理对外DLL封装接口 5 | //* 6 | //* 当前版本:V1.0 7 | //* 作 者:mediapro 8 | //* 完成日期:2020-5-18 9 | //**************************************************************************// 10 | 11 | #ifndef _SD_AUDIO_3A_PROCESS_SDK_H_ 12 | #define _SD_AUDIO_3A_PROCESS_SDK_H_ 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #if defined _WIN32 || defined __CYGWIN__ 19 | #ifdef DLL_EXPORTS 20 | #ifdef __GNUC__ 21 | #define DLLIMPORT_3A __attribute__ ((dllexport)) 22 | #else 23 | #define DLLIMPORT_3A __declspec(dllexport) 24 | #endif 25 | #else 26 | #ifdef __GNUC__ 27 | #define DLLIMPORT_3A 28 | #else 29 | #define DLLIMPORT_3A 30 | #endif 31 | #endif 32 | #else 33 | #if __GNUC__ >= 4 34 | #define DLLIMPORT_3A __attribute__ ((visibility ("default"))) 35 | #else 36 | #define DLLIMPORT_3A 37 | #endif 38 | #endif 39 | 40 | #ifdef __APPLE__ 41 | #ifndef OBJC_BOOL_DEFINED 42 | typedef int BOOL; 43 | #endif 44 | #else 45 | #ifndef BOOL 46 | typedef int BOOL; 47 | #endif 48 | #endif 49 | 50 | #ifndef TRUE 51 | #define TRUE 1 52 | #endif 53 | #ifndef FALSE 54 | #define FALSE 0 55 | #endif 56 | 57 | //日志输出的级别 58 | typedef enum AUDIO3A_LOG_OUTPUT_LEVEL 59 | { 60 | AUDIO3ALOG_OUTPUT_LEVEL_DEBUG = 1, 61 | AUDIO3ALOG_OUTPUT_LEVEL_INFO, 62 | AUDIO3ALOG_OUTPUT_LEVEL_WARNING, 63 | AUDIO3ALOG_OUTPUT_LEVEL_ERROR, 64 | AUDIO3ALOG_OUTPUT_LEVEL_ALARM, 65 | AUDIO3ALOG_OUTPUT_LEVEL_FATAL, 66 | AUDIO3ALOG_OUTPUT_LEVEL_NONE 67 | } AUDIO3A_LOG_OUTPUT_LEVEL; 68 | 69 | //AEC方法 70 | typedef enum SD_AEC_METHOD_TYPE 71 | { 72 | //AECM定点型 73 | SD_AECM_METHOD = 0, 74 | //AEC浮点型 75 | SD_AEC_METHOD = 1, 76 | } SD_AEC_METHOD_TYPE; 77 | 78 | 79 | //3A处理后的数据输出回调,注意nSamplesCount为psSamples中short型数据的数目 80 | typedef void (*Output3AProcessedData)(short *psSamples, int nSamplesCount, BOOL bInVoiceStatus, void *pObject); 81 | 82 | 83 | ////////////////////////////////////////////////////////////////////////// 84 | // 音频3A处理封装接口 85 | 86 | /*** 87 | * 环境初始化,系统只需调用一次,主要用于日志模块的初始化 88 | * @param: outputPath表示日志存放路径,支持相对路径和绝对路径,若目录不存在将自动创建 89 | * @param: outputLevel表示日志输出的级别,只有等于或者高于该级别的日志输出到文件,取值范围参考3A_LOG_OUTPUT_LEVEL 90 | * @return: 91 | */ 92 | DLLIMPORT_3A void SD3AProcess_Enviroment_Init(const char* outputPath, int outputLevel); 93 | 94 | DLLIMPORT_3A void SD3AProcess_Enviroment_Free(); 95 | 96 | 97 | 98 | /*** 99 | * 创建SD3AProcess对象 100 | * @param eAecMethod: AEC方法类型 101 | * @return: 返回模块指针,为NULL则失败 102 | */ 103 | DLLIMPORT_3A void* SD3AProcess_New(SD_AEC_METHOD_TYPE eAecMethod); 104 | 105 | 106 | /*** 107 | * 销毁SD3AProcess,使用者应该做好与其他API之间的互斥保护 108 | * @param pp3AProcess: 模块指针指针 109 | * @return: 110 | */ 111 | DLLIMPORT_3A void SD3AProcess_Delete(void** pp3AProcess); 112 | 113 | 114 | 115 | /*** 116 | * 开始启动SD3AProcess,仅支持16bit short音频3A处理 117 | * @param p3AProcess: 模块指针 118 | * @param nSampleRate: 输入待处理数据采样率 119 | * @param nChannelNum: 输入待处理数据声道数 120 | * @param nAecDelayInitMs: MIC信号与REF扬声器输出信号之间的延时差,将作为内部AEC自动延时估计的初始值。 121 | * 建议通过SD3AProcess_EnableDebugMode接口保存MIC、REF文件后观测得到 122 | * 准确的延时估计初始值有利于自动延时估计尽快收敛 123 | * @param bEnableAec: 是否使能AEC 124 | * @param bEnableAgc: 是否使能AGC 125 | * @param bEnableAns: 是否使能ANS 126 | * @param bEnableVad: 是否使能VAD 127 | * @param pfOutput3ACallback: 经过3A处理后的音频数据输出回调接口 128 | * @param pObject: 上述输出回调接口的透传指针,将通过回调函数形参方式透传外层 129 | * @return: TRUE-成功, FALSE-失败 130 | */ 131 | DLLIMPORT_3A BOOL SD3AProcess_Start(void* p3AProcess, int nSampleRate, int nChannelNum, int nAecDelayInitMs, BOOL bEnableAec, BOOL bEnableAgc, BOOL bEnableAns, BOOL bEnableVad, 132 | Output3AProcessedData pfOutput3ACallback, void* pObject); 133 | 134 | 135 | 136 | /*** 137 | * 停止SD3AProcess 138 | * @param p3AProcess: 模块指针 139 | * @return: 140 | */ 141 | DLLIMPORT_3A void SD3AProcess_Stop(void* p3AProcess); 142 | 143 | 144 | /*** 145 | * 存入REF扬声器数据作为AEC处理参考信号 146 | * @param p3AProcess: 模块指针 147 | * @param psRefData: REF扬声器数据 148 | * @param nRefCount: REF扬声器数据大小(非字节数,而是psRefData 中 short数据的数目) 149 | * @return: 150 | */ 151 | DLLIMPORT_3A BOOL SD3AProcess_PutRefData(void* p3AProcess, const short *psRefData, int nRefCount); 152 | 153 | 154 | /*** 155 | * 存入待3A处理的麦克风采集信号 156 | * @param p3AProcess: 模块指针 157 | * @param psMicData: MIC数据 158 | * @param nMicCount: MIC数据大小(非字节数,而是psRefData 中 short数据的数目) 159 | * @return: 160 | */ 161 | DLLIMPORT_3A BOOL SD3AProcess_PutMicData(void* p3AProcess, const short *psMicData, int nMicCount); 162 | 163 | 164 | /////////////////////////////////////// 高级or调试 API ////////////////////////////////////// 165 | /*** 166 | * 启用AEC调试模式,此时将生成AEC处理前的Ref信号和Mic信号到指定的路径,便于观察二者延时差 167 | * @param p3AProcess: 模块指针 168 | * @param pcTempFileSaveDir: 调试文件存放路径 169 | * @return: TRUE-使能成功, FALSE-使能失败 170 | */ 171 | DLLIMPORT_3A BOOL SD3AProcess_EnableDebugMode(void* p3AProcess, const char *pcTempFileSaveDir); 172 | 173 | 174 | /*** 175 | * 设置AGC参数,若需要调用本API,请于Start接口之前调用。未调用本API时将使用WEBRTC默认值 176 | * @param p3AProcess: 模块指针 177 | * @param nCompressionGaindB: 见WEBRTC定义,默认值9 178 | * @param nTargetLevelDbfs: 见WEBRTC定义,默认值3 179 | * @return: 180 | */ 181 | DLLIMPORT_3A void SD3AProcess_ConfigAgc(void* p3AProcess, short nCompressionGaindB, short nTargetLevelDbfs); 182 | 183 | 184 | /*** 185 | * 设置ANS参数,若需要调用本API,请于Start接口之前调用。未调用本API时将使用WEBRTC默认值 186 | * @param p3AProcess: 模块指针 187 | * @param nMode: 噪声消除强度, 0: Mild, 1: Medium , 2: Aggressive,默认值1 188 | * @return: 189 | */ 190 | DLLIMPORT_3A void SD3AProcess_ConfigAns(void* p3AProcess, short nMode); 191 | 192 | 193 | /*** 194 | * 设置VAD参数,若需要调用本API,请于Start接口之前调用。未调用本API时将使用WEBRTC默认值 195 | * @param p3AProcess: 模块指针 196 | * @param nMode: 四种模式,用数字0~3来区分,数字越大越不敏感,默认值3 197 | * @return: 198 | */ 199 | DLLIMPORT_3A void SD3AProcess_ConfigVad(void* p3AProcess, short nMode); 200 | 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | 206 | #endif // _SD_AUDIO_3A_PROCESS_SDK_H_ 207 | -------------------------------------------------------------------------------- /lib/SDAudio3AProcess.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waterfoxfox/Audio3AProcess/062589bbebe5efba5ef733a7cc2f1e9487e1d968/lib/SDAudio3AProcess.lib -------------------------------------------------------------------------------- /source/main.cpp: -------------------------------------------------------------------------------- 1 | //***************************************************************************// 2 | //* 版权所有 www.mediapro.cc 3 | //* 4 | //* 内容摘要:音频3A处理演示DEMO 5 | //* 6 | //* 当前版本:V1.0 7 | //* 作 者:mediapro 8 | //* 完成日期:2020-5-18 9 | //**************************************************************************// 10 | #include 11 | #include 12 | #include 13 | #ifdef WIN32 14 | #include 15 | #pragma comment(lib, "shlwapi") 16 | #endif 17 | 18 | #include "SDAecAgcAnsProcessSdk.h" 19 | 20 | 21 | 22 | 23 | static void SD_Sleep(DWORD dwMilliseconds) 24 | { 25 | #ifdef WIN32 26 | Sleep(dwMilliseconds); 27 | #else 28 | // usleep(dwMilliseconds*1000); 29 | // POSIX has both a usleep() and a nanosleep(), but the former is deprecated, 30 | // so we use nanosleep() even though it has greater precision than necessary. 31 | struct timespec ts; 32 | ts.tv_sec = dwMilliseconds / 1000; 33 | ts.tv_nsec = (dwMilliseconds % 1000) * 1000000; 34 | int ret = nanosleep(&ts, NULL); 35 | if (ret != 0) 36 | { 37 | static int nCount = 0; 38 | if ((nCount % 5000) == 0) 39 | { 40 | SDLOG_PRINTF_U(0, SD_LOG_LEVEL_ERROR, "nanosleep() returning early!!!"); 41 | } 42 | nCount++; 43 | 44 | usleep(dwMilliseconds * 1000); 45 | } 46 | #endif 47 | } 48 | 49 | 50 | //3A处理输出回调 51 | void Output3AProcessedDataFunc(short *psSamples, int nSamplesCount, BOOL bInVoiceStatus, void *pObject) 52 | { 53 | FILE *pfOutput = (FILE *)pObject; 54 | if (pfOutput) 55 | { 56 | fwrite(psSamples, sizeof(short), nSamplesCount, pfOutput); 57 | } 58 | } 59 | 60 | 61 | int main(int argc, char **argv) 62 | { 63 | FILE *fref = NULL; 64 | FILE *fmic = NULL; 65 | FILE *faec = NULL; 66 | short* sref = NULL; 67 | short* smic = NULL; 68 | void* h3A = NULL; 69 | 70 | //单次读入的参考信号、麦克信号样点数 71 | int framesamples = 0; 72 | 73 | int samplerate = 0; 74 | int delay = 0; 75 | int channels = 1; 76 | 77 | if (argc != 7) 78 | { 79 | printf("usage: 3Aprocess.exe mic.pcm ref.pcm aec.pcm samplerate channels delay(ms)\n"); 80 | return -1; 81 | } 82 | 83 | //支持的常规采样率 84 | samplerate = atoi(argv[4]); 85 | if (samplerate != 8000 && samplerate != 16000 && samplerate != 32000 && samplerate != 48000 && samplerate != 44100) 86 | { 87 | printf("samplerate %d unsupported(%s)\n", samplerate, argv[4]); 88 | return -1; 89 | } 90 | 91 | //支持的声道数 92 | channels = atoi(argv[5]); 93 | if ((channels != 1) && (channels != 2)) 94 | { 95 | printf("channels %d unsupported(%s)\n", channels, argv[5]); 96 | return -1; 97 | } 98 | 99 | //初始延时估计值,若不能准确提供,可设置为默认值0 100 | delay = atoi(argv[6]); 101 | 102 | 103 | //相关文件读写打开 104 | fmic = fopen(argv[1], "rb"); 105 | if (NULL == fmic) 106 | { 107 | printf("fopen %s failed\n", argv[1]); 108 | goto exitproc; 109 | } 110 | 111 | fref = fopen(argv[2], "rb"); 112 | if (NULL == fref) 113 | { 114 | printf("fopen %s failed\n", argv[2]); 115 | goto exitproc; 116 | } 117 | 118 | faec = fopen(argv[3], "wb"); 119 | if (NULL == faec) 120 | { 121 | printf("fopen %s failed\n", argv[3]); 122 | goto exitproc; 123 | } 124 | 125 | //单次读取的样点数, 假设为10ms 126 | framesamples = samplerate / 100; 127 | //分配临时缓存 128 | sref = (short*)malloc(sizeof(short) * framesamples * channels); 129 | smic = (short*)malloc(sizeof(short) * framesamples * channels); 130 | if ((sref == NULL) || (smic == NULL)) 131 | { 132 | printf("malloc %d failed\n", sizeof(short) * framesamples * channels); 133 | goto exitproc; 134 | } 135 | 136 | 137 | //初始化SDK日志输出级别、目录 138 | SD3AProcess_Enviroment_Init("./log", AUDIO3ALOG_OUTPUT_LEVEL_INFO); 139 | 140 | 141 | //创建3A对象 142 | h3A = SD3AProcess_New(SD_AEC_METHOD); 143 | if (NULL == h3A) 144 | { 145 | printf("SD3AProcess_New failed!\n"); 146 | goto exitproc; 147 | } 148 | 149 | //SD3AProcess_EnableDebugMode(h3A, "./debug"); 150 | 151 | //启动3A对象 152 | BOOL bRet = SD3AProcess_Start(h3A, samplerate, channels, delay, TRUE, TRUE, TRUE, TRUE, Output3AProcessedDataFunc, faec); 153 | if (bRet == FALSE) 154 | { 155 | goto exitproc; 156 | } 157 | 158 | 159 | while(1) 160 | { 161 | //读文件模拟获取参考信号 162 | if (fread(sref, sizeof(short), framesamples * channels, fref) != framesamples * channels) 163 | { 164 | printf("process all data, exiting...\n"); 165 | goto exitproc; 166 | } 167 | 168 | //读文件模拟获取麦克信号 169 | if (fread(smic, sizeof(short), framesamples * channels, fmic) != framesamples * channels) 170 | { 171 | printf("process all data, exiting...\n"); 172 | goto exitproc; 173 | } 174 | 175 | //送3A对象处理,处理后数据通过回调输出 176 | SD3AProcess_PutRefData(h3A, sref, framesamples * channels); 177 | SD3AProcess_PutMicData(h3A, smic, framesamples * channels); 178 | 179 | Sleep(10); 180 | } 181 | 182 | exitproc: 183 | if (fref) 184 | { 185 | fclose(fref); 186 | } 187 | if (fmic) 188 | { 189 | fclose(fmic); 190 | } 191 | if (faec) 192 | { 193 | fclose(faec); 194 | } 195 | 196 | if (sref) 197 | { 198 | free(sref); 199 | } 200 | if (smic) 201 | { 202 | free(smic); 203 | } 204 | 205 | //资源回收 206 | SD3AProcess_Delete(&h3A); 207 | 208 | SD3AProcess_Enviroment_Free(); 209 | 210 | return 0; 211 | } 212 | 213 | 214 | 215 | --------------------------------------------------------------------------------