Android 音频降噪 webrtc 去回声

  • 集成AECM模块
  • 集成NS模块
  • 需要源码请留言

集成AECM模块

1.通过 webrtc官网下载需要模块\modules\audio_processing\aecm
2.新建eclipse工程,新建jni文件夹将webrtc aecm模块拷贝到jni文件夹下

3.编写本地接口

package com.wrtcmy.webrtc.aecm;/*** This class supports the acoustic echo cancellation for mobile edition. Please <b>bug me</b> if you find any bugs in* this toolkit.<br>* <br>* <b>[Notice]</b><br>* 1. there are 5 more native interface that I'm not trying to provide in this MobileAEC toolkit.<br>* But I think I should mention it out as a list below, for secondary development if necessary: <br>* <ul>* <li>WebRtc_Word32 WebRtcAecm_get_config(void *, AecmConfig *);</li>* <li>WebRtc_Word32 WebRtcAecm_InitEchoPath(void* , const void* , size_t);</li>* <li>WebRtc_Word32 WebRtcAecm_GetEchoPath(void* , void* , size_t);</li>* <li>size_t WebRtcAecm_echo_path_size_bytes();</li>* <li>WebRtc_Word32 WebRtcAecm_get_error_code(void *);</li>* </ul>* 2. if you are working on an android platform, put the shared library "libwebrtc_aecm.so"<br>* into path "/your project/libs/armeabi/", if the dir does not exist, you should create it, otherwise you<br>* will get a "unsatisfied link error" at run time.<br>* 3. you should always call <b>close()</b> method <b>manually</b> when all things are finished.<br>* <br>* <b>[Usage]</b> <br>* <ul>* 1. You create a MobileAEC object first(set the parameters to constructor or null are both Ok, if null are set, then* we will use default values instead).<br>* 2. change the aggressiveness or sampling frequency of the AECM instance if necessary.<br>* 3. call <b>prepare()</b> method to make the AECM instance prepared. <br>* 4. then call "farendBuffer" to set far-end signal to AECM instance. <br>* 5. now you call "echoCancellation()" to deal with the acoustic echo things.<br>* The order of step 1,2,3,4 and 5 is significant, when all settings are done or you changed previous<br>* settings, <b>DO NOT</b> forget to call prepare() method, otherwise your new settings will be ignored by AECM* instance. <br>* 6. finally you should call <b>close()</b> method <b>manually</b> when all things are done, after that, the AECM* instance is no longer available until next <b>prepare()</b> is called.<br>* </ul>* * @version 0.1 2013-3-8* */
public class AECM {static {System.loadLibrary("webrtc_aecm"); // to load the libwebrtc_aecm.so library.}// /// PUBLIC CONSTANTS/*** constant unable mode for Aecm configuration settings.*/public static final short AECM_UNABLE = 0;/*** constant enable mode for Aecm configuration settings.*/public static final short AECM_ENABLE = 1;// /// PUBLIC NESTED CLASSES/*** For security reason, this class supports constant sampling frequency values in* {@link SamplingFrequency#FS_8000Hz FS_8000Hz}, {@link SamplingFrequency#FS_16000Hz FS_16000Hz}*/public static final class SamplingFrequency {public long getFS() {return mSamplingFrequency;}/*** This constant represents sampling frequency in 8000Hz*/public static final SamplingFrequency FS_8000Hz  = new SamplingFrequency(8000);/*** This constant represents sampling frequency in 16000Hz*/public static final SamplingFrequency FS_16000Hz = new SamplingFrequency(16000);private final long                    mSamplingFrequency;private SamplingFrequency(long fs) {this.mSamplingFrequency = fs;}}/*** For security reason, this class supports constant aggressiveness of the AECM instance in* {@link AggressiveMode#MILD MILD}, {@link AggressiveMode#MEDIUM MEDIUM}, {@link AggressiveMode#HIGH HIGH},* {@link AggressiveMode#AGGRESSIVE AGGRESSIVE}, {@link AggressiveMode#MOST_AGGRESSIVE MOST_AGGRESSIVE}.*/public static final class AggressiveMode {public int getMode() {return mMode;}/*** This constant represents the aggressiveness of the AECM instance in MILD_MODE*/public static final AggressiveMode MILD            = new AggressiveMode(0);/*** This constant represents the aggressiveness of the AECM instance in MEDIUM_MODE*/public static final AggressiveMode MEDIUM          = new AggressiveMode(1);/*** This constant represents the aggressiveness of the AECM instance in HIGH_MODE*/public static final AggressiveMode HIGH            = new AggressiveMode(2);/*** This constant represents the aggressiveness of the AECM instance in AGGRESSIVE_MODE*/public static final AggressiveMode AGGRESSIVE      = new AggressiveMode(3);/*** This constant represents the aggressiveness of the AECM instance in MOST_AGGRESSIVE_MODE*/public static final AggressiveMode MOST_AGGRESSIVE = new AggressiveMode(4);private final int                  mMode;private AggressiveMode(int mode) {mMode = mode;}}// /// PRIVATE MEMBERSprivate int               mAecmHandler = -1;   // the handler of AECM instance.private AecmConfig        mAecmConfig  = null; // the configurations of AECM instance.private SamplingFrequency mSampFreq    = null; // sampling frequency of input speech data.private boolean           mIsInit      = false; // whether the AECM instance is initialized or not.// /// CONSTRUCTOR/*** To generate a new AECM instance, whether you set the sampling frequency of each parameter or not are both ok.* * @param sampFreqOfData*            - sampling frequency of input audio data. if null, then {@link SamplingFrequency#FS_16000Hz*            FS_16000Hz} is set.*/public AECM(SamplingFrequency sampFreqOfData) {setSampFreq(sampFreqOfData);mAecmConfig = new AecmConfig();// create new AECM instance but without initialize. Init things are in prepare() method instead.mAecmHandler = nativeCreateAecmInstance();}// /// PUBLIC METHODS/*** set the sampling rate of speech data.* * @param fs*            - sampling frequency of speech data, if null then {@link SamplingFrequency#FS_16000Hz FS_16000Hz} is*            set.*/public void setSampFreq(SamplingFrequency fs) {if (fs == null)mSampFreq = SamplingFrequency.FS_16000Hz;elsemSampFreq = fs;}/*** set the far-end signal of AECM instance.* * @param farendBuf* @param numOfSamples* @return the {@link AECM MobileAEC} object itself.* @throws Exception*             - if farendBuffer() is called on an unprepared AECM instance or you pass an invalid parameter.<br>*/public AECM farendBuffer(short[] farendBuf, int numOfSamples)throws Exception {// check if AECM instance is not initialized.if (!mIsInit) {// TODO(billhoo) - create a custom exception instead of using java.lang.Exceptionthrow new Exception("setFarendBuffer() called on an unprepared AECM instance.");}if (nativeBufferFarend(mAecmHandler, farendBuf, numOfSamples) == -1)// TODO(billhoo) - create a custom exception instead of using java.lang.Exceptionthrow new Exception("setFarendBuffer() failed due to invalid arguments.");return this;}/*** core process of AECM instance, must called on a prepared AECM instance. we only support 80 or 160 sample blocks* of data.* * @param nearendNoisy*            - In buffer containing one frame of reference nearend+echo signal. If noise reduction is active,*            provide the noisy signal here.* @param nearendClean*            - In buffer containing one frame of nearend+echo signal. If noise reduction is active, provide the*            clean signal here. Otherwise pass a NULL pointer.* @param out*            - Out buffer, one frame of processed nearend.* @param numOfSamples*            - Number of samples in nearend buffer* @param delay*            - Delay estimate for sound card and system buffers <br>*            delay = (t_render - t_analyze) + (t_process - t_capture)<br>*            where<br>*            - t_analyze is the time a frame is passed to farendBuffer() and t_render is the time the first sample*            of the same frame is rendered by the audio hardware.<br>*            - t_capture is the time the first sample of a frame is captured by the audio hardware and t_process is*            the time the same frame is passed to echoCancellation().* * @throws Exception*             - if echoCancellation() is called on an unprepared AECM instance or you pass an invalid parameter.<br>*/public void echoCancellation(short[] nearendNoisy, short[] nearendClean,short[] out, short numOfSamples, short delay) throws Exception {// check if AECM instance is not initialized.if (!mIsInit) {// TODO(billhoo) - create a custom exception instead of using java.lang.Exceptionthrow new Exception("echoCancelling() called on an unprepared AECM instance.");}if (nativeAecmProcess(mAecmHandler, nearendNoisy, nearendClean, out,numOfSamples, delay) == -1)// TODO(billhoo) - create a custom exception instead of using java.lang.Exceptionthrow new Exception("echoCancellation() failed due to invalid arguments.");}/*** Set the aggressiveness mode of AECM instance, more higher the mode is, more aggressive the instance will be.* * @param mode* @return the {@link AECM MobileAEC} object itself.* @throws NullPointerException*             - if mode is null.*/public AECM setAecmMode(AggressiveMode mode)throws NullPointerException {// check the mode argument.if (mode == null)throw new NullPointerException("setAecMode() failed due to null argument.");mAecmConfig.mAecmMode = (short) mode.getMode();return this;}/*** When finished the pre-works or any settings are changed, call this to make AECM instance prepared. Otherwise your* new settings will be ignored by the AECM instance.* * @return the {@link AECM MobileAEC} object itself.*/public AECM prepare() {if (mIsInit) {close();mAecmHandler = nativeCreateAecmInstance();}mInitAecmInstance((int) mSampFreq.getFS());mIsInit = true;// set AecConfig to native side.nativeSetConfig(mAecmHandler, mAecmConfig);return this;}/*** Release the resources in AECM instance and the AECM instance is no longer available until next <b>prepare()</b>* is called.<br>* You should <b>always</b> call this <b>manually</b> when all things are done.*/public void close() {if (mIsInit) {nativeFreeAecmInstance(mAecmHandler);mAecmHandler = -1;mIsInit = false;}}// // PROTECTED METHODS@Overrideprotected void finalize() throws Throwable {super.finalize();// TODO(billhoo) need a safety one.if (mIsInit) {close();}}// // PRIVATE METHODS/*** initialize the AECM instance* * @param SampFreq*/private void mInitAecmInstance(int SampFreq) {if (!mIsInit) {nativeInitializeAecmInstance(mAecmHandler, SampFreq);// initialize configurations of AECM instance.mAecmConfig = new AecmConfig();// set default configuration of AECM instancenativeSetConfig(mAecmHandler, mAecmConfig);mIsInit = true;}}// // PRIVATE NESTED CLASSES/*** Acoustic Echo Cancellation for Mobile Configuration class, holds the config Info. of AECM instance.<br>* [NOTE] <b>DO NOT</b> modify the name of members, or you must change the native code to match your modifying.* Otherwise the native code could not find pre-binding members name.<br>* */@SuppressWarnings("unused")public class AecmConfig {private short mAecmMode = (short) AggressiveMode.AGGRESSIVE.getMode(); // default AggressiveMode.AGGRESSIVEprivate short mCngMode  = AECM_ENABLE;                                // AECM_UNABLE, AECM_ENABLE (default)}// ///// PRIVATE NATIVE INTERFACES/*** Allocates the memory needed by the AECM. The memory needs to be initialized separately using the* nativeInitializeAecmInstance() method.* * @return -1: error<br>*         other values: created AECM instance handler.* */private static native int nativeCreateAecmInstance();/*** Release the memory allocated by nativeCreateAecmInstance().* * @param aecmHandler*            - handler of the AECM instance created by nativeCreateAecmInstance()* @return 0: OK<br>*         -1: error*/private static native int nativeFreeAecmInstance(int aecmHandler);/*** Initializes an AECM instance.* * @param aecmHandler*            - Handler of AECM instance* @param samplingFrequency*            - Sampling frequency of data* @return: 0: OK<br>*          -1: error*/private static native int nativeInitializeAecmInstance(int aecmHandler,int samplingFrequency);/*** Inserts an 80 or 160 sample block of data into the farend buffer.* * @param aecmHandler*            - Handler to the AECM instance* @param farend*            - In buffer containing one frame of farend signal for L band* @param nrOfSamples*            - Number of samples in farend buffer* @return: 0: OK<br>*          -1: error*/private static native int nativeBufferFarend(int aecmHandler,short[] farend, int nrOfSamples);/*** Runs the AECM on an 80 or 160 sample blocks of data.* * @param aecmHandler*            - Handler to the AECM handler* @param nearendNoisy*            - In buffer containing one frame of reference nearend+echo signal. If noise reduction is active,*            provide the noisy signal here.* @param nearendClean*            - In buffer containing one frame of nearend+echo signal. If noise reduction is active, provide the*            clean signal here.Otherwise pass a NULL pointer.* @param out*            - Out buffer, one frame of processed nearend.* @param nrOfSamples*            - Number of samples in nearend buffer* @param msInSndCardBuf*            - Delay estimate for sound card and system buffers <br>* @return: 0: OK<br>*          -1: error*/private static native int nativeAecmProcess(int aecmHandler,short[] nearendNoisy, short[] nearendClean, short[] out,short nrOfSamples, short msInSndCardBuf);/*** Enables the user to set certain parameters on-the-fly.* * @param aecmHandler*            - Handler to the AECM instance* @param aecmConfig*            - the new configuration of AECM instance to set.* * @return 0: OK<br>*         -1: error*/private static native int nativeSetConfig(int aecmHandler,AecmConfig aecmConfig);
}

4.在jni文件夹下新建Android.mk与Application.mk并在对应模块下新建Android.mk
Android.mk

include $(call all-subdir-makefiles)

Application.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
APP_PROJECT_PATH := $(call my-dir)/../
APP_STL := gnustl_staticAPP_BUILD_SCRIPT:=$(call my-dir)/Android.mk
APP_PLATFORM := android-22
APP_ABI := armeabi-v7a,armeabi
APP_CFLAGS:=-DDISABLE_NEON

aecm\Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := webrtc_aecm
LOCAL_CFLAGS += -DWEBRTC_POSIX
LOCAL_SRC_FILES := \randomization_functions.c \spl_sqrt_floor.c \division_operations.c \vector_scaling_operations.c \downsample_fast.c \cross_correlation.c \spl_init.c \min_max_operations.c \complex_fft.c \complex_bit_reverse.c \real_fft.c \delay_estimator.c \delay_estimator_wrapper.c \ring_buffer.c \aecm_core.c \echo_control_mobile.c \com_wrtcmy_webrtc_aecm_AECM.c#aecm_wrapper.cLOCAL_LDLIBS :=-lloginclude $(BUILD_SHARED_LIBRARY)

5.编译生成头文件可参考: Android源码下编译apk、jar与jni ndk-build
6.通过c文件实现

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <stdlib.h> // for NULL
#include <assert.h>
#include <echo_control_mobile.h>
#include "com_wrtcmy_webrtc_aecm_AECM.h"
/* Header for class com_wrtcmy_webrtc_aecm_AECM *//** Class:     com_wrtcmy_webrtc_aecm_AECM* Method:    nativeCreateAecmInstance* Signature: ()I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_aecm_AECM_nativeCreateAecmInstance(JNIEnv *env,jclass jclazz) {void *aecmInstHandler = NULL;if (WebRtcAecm_Create(&aecmInstHandler) == -1)return -1;elsereturn ((int) aecmInstHandler); //returns the pointer which points to created AECM instance to JAVA layer.}/** Class:     com_wrtcmy_webrtc_aecm_AECM* Method:    nativeFreeAecmInstance* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_aecm_AECM_nativeFreeAecmInstance(JNIEnv *env, jclass jclazz, jint aecmHandler) {void *aecmInst = (void *) aecmHandler;if (aecmInst == NULL)return -1;int ret = WebRtcAecm_Free(aecmInst);aecmInst = NULL;return ret;
}/** Class:     com_wrtcmy_webrtc_aecm_AECM* Method:    nativeInitializeAecmInstance* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_aecm_AECM_nativeInitializeAecmInstance(JNIEnv *env, jclass jclazz, jint aecmHandler, jint sampFreq) {void *aecmInst = (void *) aecmHandler;if (aecmInst == NULL)return -1;return WebRtcAecm_Init(aecmInst, sampFreq);
}/** Class:     com_wrtcmy_webrtc_aecm_AECM* Method:    nativeBufferFarend* Signature: (I[SI)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_aecm_AECM_nativeBufferFarend(JNIEnv *env, jclass jclazz, jint aecmHandler, jshortArray farend,jint nrOfSamples) {void *aecmInst = (void *) aecmHandler;if (aecmInst == NULL)return -1;int ret = -1;if (farend != NULL) {short *arrFarend = (*env)->GetShortArrayElements(env, farend, NULL);ret = WebRtcAecm_BufferFarend(aecmInst, arrFarend, nrOfSamples);//TODO(billhoo) should use JNI_ABORT instead of 0 in 4th param.//I think there is no need to copy this array back to Java layer.(*env)->ReleaseShortArrayElements(env, farend, arrFarend, 0);}return ret;}
/** Class:     com_wrtcmy_webrtc_aecm_AECM* Method:    nativeAecmProcess* Signature: (I[S[S[SSS)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_aecm_AECM_nativeAecmProcess(JNIEnv *env, jclass jclazz, jint aecmHandler,const jshortArray nearendNoisy, const jshortArray nearendClean,jshortArray out, jshort nrOfSamples, jshort msInSndCardBuf) {int16_t *arrNearendNoisy = NULL;int16_t *arrNearendClean = NULL;int16_t *arrOut = NULL;void *aecmInst = (void *) aecmHandler;if (aecmInst == NULL)return -1;int ret = -1;//nearendNoisy and out must not be NULL, otherwise process can not be run, return -1 for error.if (nearendNoisy == NULL || out == NULL)return ret;//get data from java side.arrNearendNoisy = (*env)->GetShortArrayElements(env, nearendNoisy, NULL);arrOut = (*env)->GetShortArrayElements(env, out, NULL);if (nearendClean != NULL)arrNearendClean = (*env)->GetShortArrayElements(env, nearendClean,NULL);ret = WebRtcAecm_Process(aecmInst, arrNearendNoisy, arrNearendClean, arrOut,nrOfSamples, msInSndCardBuf);//release and send the changes back to java side.(*env)->ReleaseShortArrayElements(env, nearendNoisy, arrNearendNoisy, 0);(*env)->ReleaseShortArrayElements(env, out, arrOut, 0);if (nearendClean != NULL)(*env)->ReleaseShortArrayElements(env, nearendClean, arrNearendClean,0);return ret;}/** Class:     com_wrtcmy_webrtc_aecm_AECM* Method:    nativeSetConfig* Signature: (ILcom/wrtcmy/webrtc/aecm/AECM/AecmConfig;)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_aecm_AECM_nativeSetConfig(JNIEnv *env, jclass jclazz, jint aecmHandler, jobject aecmConfig) {void * aecmInst = (void *) aecmHandler;if (aecmInst == NULL)return -1;//get reference of AecmConfig class  from java side.jclass JavaAecmConfig = (*env)->GetObjectClass(env, aecmConfig);//assertion that class not be NULL//TODO(billhoo) should use Exception handler to handle this situation instead of assertion.assert(JavaAecmConfig != NULL);//get configuration field IDs from java side.jfieldID mAecmModeID = (*env)->GetFieldID(env, JavaAecmConfig, "mAecmMode","S");jfieldID mCngModeID = (*env)->GetFieldID(env, JavaAecmConfig, "mCngMode","S");//if any ID is NULL, return -1 for error.if (mAecmModeID == NULL || mCngModeID == NULL){LOGD("$$$$$$$$$$nativeSetConfig->(mAecmModeID == NULL || mCngModeID == NULL)");return -1;}//get values of fieldsshort echoMode = (*env)->GetShortField(env, aecmConfig, mAecmModeID);short cngMode = (*env)->GetShortField(env, aecmConfig, mCngModeID);//set new configuration to AECM instance.AecmConfig config;config.echoMode = echoMode;config.cngMode = cngMode;LOGD("$$$$$$$$$$WebRtcAecm_set_config");return WebRtcAecm_set_config(aecmInst, config);
}

7.编译so库可参考: Android源码下编译apk、jar与jni ndk-build可在项目\libs\查看生成文件

集成NS模块

流程严格按照AECM模块只列出不同地方

  1. 源码文件在\modules\audio_processing\ns
  2. 编写本地接口
package com.wrtcmy.webrtc.ns;import android.util.Log;public class NS {private static final String TAG = "$$$NS$$$";static {try {// 加载降噪库System.loadLibrary("webrtc_ns");} catch (UnsatisfiedLinkError e) {e.printStackTrace();}}private int mFrequency;private int mMode;// -----------------------------------------NS// 定点数运算----------------------------------------------//private int nsInstance = -1;private boolean isNsInit = false;/*** 创建ns实例* * @return 成功时返回ns实例,失败返回-1*/public native int nsCreate();/*** 初始化ns* * @param frequency*            采样率*/public native int nsInit(int nsInstance, int frequency);/*** 设置降噪策略 等级越高,效果越明显* * @param mode*            0: Mild, 1: Medium , 2: Aggressive*/public native int nsSetPolicy(int nsInstance, int mode);/*** 核心处理方法 sample_H与outData_H 我不是很懂,希望有明白的可以指点下* * @param sample*            低频段音频数据-输入* @param sample_H*            高频段音频数据-输入(demo中传的是null)* @param outData*            低频段音频数据-输出* @param outData_H*            高频段音频数据-输出(demo中传的是null)*/public native int nsProcess(int nsInstance, short[] sample,short[] sample_H, short[] outData, short[] outData_H);/*** 销毁实例*/public native int nsFree(int nsInstance);public NS useNs() {nsInstance = nsCreate();Log.d(TAG, "nsInstance = " + nsInstance);return this;}public NS setNsConfig(int frequency, int mode) {this.mFrequency = frequency;this.mMode = mode;return this;}public NS prepareNs() {if (isNsInit) {closeNs();nsInstance = nsCreate();}int initStatus = nsInit(nsInstance, mFrequency);Log.e(TAG, "nsInitStatus = " + initStatus);isNsInit = true;int setStatus = nsSetPolicy(nsInstance, mMode);Log.e(TAG, "nsSetStatus = " + setStatus);return this;}public int nsProcess(short[] sample, short[] sample_H, short[] outData,short[] outData_H) {return nsProcess(nsInstance, sample, sample_H, outData, outData_H);}public void closeNs() {if (isNsInit) {nsFree(nsInstance);nsInstance = -1;isNsInit = false;}}// -------------------------------------------NSX// 浮点数运算------------------------------------------//private int nsxInstance = -1;private boolean isNsxInit = false;public native int nsxCreate();public native int nsxInit(int nsxInstance, int frequency);public native int nsxSetPolicy(int nsxInstance, int mode);public native int nsxProcess(int nsxInstance, short[] sample,short[] sample_H, short[] outData, short[] outData_H);public native int nsxFree(int nsxInstance);public NS useNsx() {nsxInstance = nsxCreate();Log.d(TAG, "nsxInstance = " + nsxInstance);return this;}public NS setNsxConfig(int frequency, int mode) {this.mFrequency = frequency;this.mMode = mode;return this;}public NS prepareNsx() {if (isNsxInit) {closeNsx();nsxInstance = nsxCreate();}int initStatus = nsxInit(nsxInstance, mFrequency);Log.e(TAG, "nsxInitStatus = " + initStatus);isNsxInit = true;int setStatus = nsxSetPolicy(nsxInstance, mMode);Log.e(TAG, "nsxSetStatus = " + setStatus);return this;}public int nsxProcess(short[] sample, short[] sample_H, short[] outData,short[] outData_H) {return nsxProcess(nsxInstance, sample, sample_H, outData, outData_H);}public void closeNsx() {if (isNsxInit) {nsxFree(nsxInstance);nsxInstance = -1;isNsxInit = false;}}}
  1. ns\Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := webrtc_ns
LOCAL_CFLAGS += -DWEBRTC_POSIXLOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.c)LOCAL_LDLIBS :=-lloginclude $(BUILD_SHARED_LIBRARY)
  1. 通过c文件实现
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_wrtcmy_webrtc_ns_NS */#include <stdlib.h> // for NULL
#include "noise_suppression_x.h"
#include "noise_suppression.h"
#include "com_wrtcmy_webrtc_ns_NS.h"/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsCreate* Signature: ()I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsCreate(JNIEnv *env, jobject obj){NsHandle* handle = NULL;WebRtcNs_Create(&handle);LOGD("$$$$$$$$$$WebRtcNs_Create");return (int)handle;
}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsInit* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsInit(JNIEnv *env, jobject obj, jint nsHandler, jint frequency){NsHandle *handler = (NsHandle *) nsHandler;if (handler == NULL){return -3;}return WebRtcNs_Init(handler,frequency);
}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsSetPolicy* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsSetPolicy(JNIEnv *env, jobject obj, jint nsHandler, jint mode){NsHandle *handle = (NsHandle *) nsHandler;if (handle == NULL){return -3;}return WebRtcNs_set_policy(handle,mode);}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsProcess* Signature: (I[S[S[S[S)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsProcess(JNIEnv *env, jobject obj, jint nsHandler, jshortArray sample,jshortArray sample_H, jshortArray out,jshortArray out_H){NsHandle *handle = (NsHandle *) nsHandler;if(handle == NULL){return -3;}short* spframe = NULL;short* outframe = NULL;short* spframe_H = NULL;short* outframe_H = NULL;int ret = -1;spframe = (*env)->GetShortArrayElements(env,sample, NULL);outframe = (*env)->GetShortArrayElements(env,out, NULL);if(sample_H != NULL){spframe_H = (*env)->GetShortArrayElements(env,sample_H, NULL);}if(out_H != NULL){outframe_H = (*env)->GetShortArrayElements(env,out_H, NULL);}ret = WebRtcNs_Process(handle,spframe,spframe_H,outframe,outframe_H);(*env)->ReleaseShortArrayElements(env,sample, spframe, 0);(*env)->ReleaseShortArrayElements(env,out, outframe, 0);if(sample_H != NULL){(*env)->ReleaseShortArrayElements(env,sample_H, spframe_H, 0);}if(out_H != NULL){(*env)->ReleaseShortArrayElements(env,out_H, outframe_H, 0);}return ret;}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsFree* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsFree(JNIEnv *env, jobject obj, jint nsHandler){NsHandle *handle = (NsHandle *) nsHandler;if(handle == NULL){return -3;}return WebRtcNs_Free(handle);}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsxCreate* Signature: ()I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsxCreate(JNIEnv *env, jobject obj){NsHandle* handle = NULL;WebRtcNsx_Create(&handle);return (int)handle;}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsxInit* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsxInit(JNIEnv *env, jobject obj, jint nsxHandler, jint frequency ){NsHandle *handler = (NsHandle *) nsxHandler;if (handler == NULL){return -3;}return WebRtcNsx_Init(handler,frequency);}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsxSetPolicy* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsxSetPolicy(JNIEnv *env, jobject obj, jint nsxHandler, jint mode){NsHandle *handle = (NsHandle *) nsxHandler;if (handle == NULL){return -3;}return WebRtcNsx_set_policy(handle,mode);
}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsxProcess* Signature: (I[S[S[S[S)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsxProcess(JNIEnv *env, jobject obj, jint nsxHandler, jshortArray sample,jshortArray sample_H, jshortArray out,jshortArray out_H){NsHandle *handle = (NsHandle *) nsxHandler;if(handle == NULL){return -3;}short* spframe = NULL;short* outframe = NULL;short* spframe_H = NULL;short* outframe_H = NULL;int ret = -1;spframe = (*env)->GetShortArrayElements(env,sample, NULL);outframe = (*env)->GetShortArrayElements(env,out, NULL);if(sample_H != NULL){spframe_H = (*env)->GetShortArrayElements(env,sample_H, NULL);}if(out_H != NULL){outframe_H = (*env)->GetShortArrayElements(env,out_H, NULL);}ret = WebRtcNsx_Process(handle,spframe,spframe_H,outframe,outframe_H);(*env)->ReleaseShortArrayElements(env,sample, spframe, 0);(*env)->ReleaseShortArrayElements(env,out, outframe, 0);if(sample_H != NULL){(*env)->ReleaseShortArrayElements(env,sample_H, spframe_H, 0);}if(out_H != NULL){(*env)->ReleaseShortArrayElements(env,out_H, outframe_H, 0);}return ret;
}/** Class:     com_wrtcmy_webrtc_ns_NS* Method:    nsxFree* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_wrtcmy_webrtc_ns_NS_nsxFree(JNIEnv *env, jobject obj, jint nsxHandler){NsHandle *handle = (NsHandle *) nsxHandler;if(handle == NULL){return -3;}return WebRtcNsx_Free(handle);
}

需要源码请留言

Android 音频降噪 webrtc 去回声相关推荐

  1. android音频降噪webrtc

    在音频处理的开源项目中,webrtc是一个很不错的例子.它包含降噪,去回声,增益,均衡等音频处理.这里我讲讲我所使用到的如何使用降噪方式.当然,具体它是如何降噪的,大家可以细看源码处理了.好了,线上源 ...

  2. java webrtc降噪_android音频降噪webrtc

    [实例简介] android音频降噪,采用webrtc技术,提供底层源码和so库,亲测效果不错,请戴上耳机测试效果. [实例截图] [核心代码] WebrtcNoise ├── __MACOSX │  ...

  3. java webrtc ns降噪_单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件)...

    webrtc的音频处理模块分为降噪ns,回音消除aec,回声控制acem,音频增益agc,静音检测部分.另外webrtc已经封装好了一套音频处理模块APM,如果不是有特殊必要,使用者如果要用到回声消除 ...

  4. 单独编译和使用webrtc音频降噪模块(NS)

    原文转载于:http://www.cnblogs.com/mod109/p/5469799.html   非常感谢. webrtc的音频处理模块分为降噪ns,回音消除aec(回声控制acem),自动控 ...

  5. 单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件)

    单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件) 单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件) webrtc的音频处理模块分为降噪ns,回音消除aec,回声 ...

  6. android音频杂音问题_直播疑难杂症排查(8)— 播放杂音、噪音、回声问题-阿里云开发者社区...

    1.  问题现象 常见的音频问题现象描述如下: - 电流音,爆音,滋滋声或者嘟嘟声 - 声音断断续续,听不清楚 - 回声,能听到自己说话的声音 2. 问题排查 2.1 参数配置问题 上面也有提到,音频 ...

  7. android降噪算法,面向Android设备的音频降噪系统设计

    摘要: 在语音信号采集过程中,由于系统工作环境及电路设计等原因,采集到的语音信号中无可避免地引入了噪声信号,降低了语音的信噪比.由于Android2.3.1原生音频系统未提供针对语音信号进行降噪处理的 ...

  8. 今日分享:这4款音频降噪去杂音的软件,太好用了

    你知道音频降噪去杂音怎么操作吗?在现代社会,音频处理已经成为了一项重要的技能.无论是语音录音.音乐创作,还是影视制作,我们都需要高质量的音频素材. 但在实际操作中,我们常常会遇到环境噪声.背景杂音等问 ...

  9. 一次搞懂 Android 音频开发

    在接触Android音频开发后,陆陆续续的看了不少的文章,如果说查缺补漏把这些文章梳理清楚,然后逐个整合,那么确实也能完整的推导出音频开发需要掌握的技术.但是对于初学者来说,可能在开发中产生很多障碍以 ...

最新文章

  1. 利用XtraBackup做mysql不停机重做主从复制
  2. VC++6中的一些快捷键(陆续补充中。。。)
  3. leetcode-581-Shortest Unsorted Continuous Subarray
  4. MySQL数据库开发的 36 条军规
  5. jsf 单元测试_构建和测试JSF.next
  6. js密码强度正则表达式_知道这20个前端正则表达式,能让你做项目时少写1000行甚至一万行
  7. Ignite Compute helloworld-分布式计算
  8. 名企面试官精讲典型编程题之数据结构数组篇
  9. 菜鸟Java远程连接腾讯云服务器上面的数据库
  10. 科技美学引领行业发展:欧瑞博发布全新HomeAI操作系统
  11. 计算机网络工程师 考试题,计算机四级网络工程师考试题及答案.docx
  12. 基本绘图全面攻略——turtle(海龟)库 Python
  13. Matlab GUI编程技巧(十八)【实战一】:自定义线条图像绘制
  14. 计算机固态和机械什么意思,固态硬盘和机械硬盘有什么不同?详解固态硬盘和机械硬盘...
  15. 【榆钱】Cantor表C语言题解
  16. 视频照片合成软件哪个好?快速把手机照片做成视频,简单操作,效果精美!
  17. joom erp系统订单管理及刊登哪个好用?无忧易售ERP已完成Joom平台对接
  18. 主机屋投资服务器_开启行业先河 主机屋再推免费云服务器
  19. linux_comand
  20. 开源GIS系统(转载)

热门文章

  1. Android Mms专题之:Mms概览介绍
  2. red hart linux中文,hart是什么意思_hart的翻译_音标_读音_用法_例句_爱词霸在线词典...
  3. 免费赠书啦!逃离帝都,书搬不动,大量AI类、技术类、科幻类书免费送给小伙伴...
  4. SpringBoot 实现手机发送短信验证码
  5. 微信公众号录音功能及录音文件下载到自己服务器 一
  6. java数据结构与算法之双链表设计与实现
  7. android 传输助手 mac,MacDroid for mac(安卓手机数据传输助手)
  8. ABAQUS粘弹性边界及地震荷载施加的简单实现(Matlab生成input文件)
  9. 每天学习Java一点点
  10. 文本三剑客之AWK详解