diff options
Diffstat (limited to 'tinyDAV/src/audio/tdav_webrtc_denoise.c')
-rwxr-xr-x | tinyDAV/src/audio/tdav_webrtc_denoise.c | 898 |
1 files changed, 446 insertions, 452 deletions
diff --git a/tinyDAV/src/audio/tdav_webrtc_denoise.c b/tinyDAV/src/audio/tdav_webrtc_denoise.c index 598470a..c69ab9e 100755 --- a/tinyDAV/src/audio/tdav_webrtc_denoise.c +++ b/tinyDAV/src/audio/tdav_webrtc_denoise.c @@ -51,34 +51,32 @@ typedef int16_t sample_t; typedef float sample_t; #endif -typedef struct tdav_webrtc_pin_xs -{ - uint32_t n_duration; - uint32_t n_rate; - uint32_t n_channels; - uint32_t n_sample_size; +typedef struct tdav_webrtc_pin_xs { + uint32_t n_duration; + uint32_t n_rate; + uint32_t n_channels; + uint32_t n_sample_size; } tdav_webrtc_pin_xt; -typedef struct tdav_webrtc_resampler_s -{ - TSK_DECLARE_OBJECT; - - tmedia_resampler_t* p_resampler; - void* p_bufftmp_ptr; // used to convert float <->int16 - tsk_size_t n_bufftmp_size_in_bytes; - - struct { - tdav_webrtc_pin_xt x_pin; - tsk_size_t n_buff_size_in_bytes; - tsk_size_t n_buff_size_in_samples; - } in; - struct { - tdav_webrtc_pin_xt x_pin; - void* p_buff_ptr; - tsk_size_t n_buff_size_in_bytes; - tsk_size_t n_buff_size_in_samples; - } out; +typedef struct tdav_webrtc_resampler_s { + TSK_DECLARE_OBJECT; + + tmedia_resampler_t* p_resampler; + void* p_bufftmp_ptr; // used to convert float <->int16 + tsk_size_t n_bufftmp_size_in_bytes; + + struct { + tdav_webrtc_pin_xt x_pin; + tsk_size_t n_buff_size_in_bytes; + tsk_size_t n_buff_size_in_samples; + } in; + struct { + tdav_webrtc_pin_xt x_pin; + void* p_buff_ptr; + tsk_size_t n_buff_size_in_bytes; + tsk_size_t n_buff_size_in_samples; + } out; } tdav_webrtc_resampler_t; @@ -86,447 +84,446 @@ static int _tdav_webrtc_resampler_create(const tdav_webrtc_pin_xt* p_pin_in, con static int _tdav_webrtc_resampler_process(tdav_webrtc_resampler_t* p_self, const void* p_buff_ptr, tsk_size_t n_buff_size_in_bytes); /** WebRTC denoiser (AEC, NS, AGC...) */ -typedef struct tdav_webrtc_denoise_s -{ - TMEDIA_DECLARE_DENOISE; +typedef struct tdav_webrtc_denoise_s { + TMEDIA_DECLARE_DENOISE; - void *AEC_inst; + void *AEC_inst; #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER - SpeexPreprocessState *SpeexDenoiser_proc; + SpeexPreprocessState *SpeexDenoiser_proc; #else - TDAV_NsHandle *NS_inst; + TDAV_NsHandle *NS_inst; #endif - uint32_t echo_tail; - uint32_t echo_skew; - - struct { - tdav_webrtc_resampler_t* p_rpl_in2den; // input -> denoiser - tdav_webrtc_resampler_t* p_rpl_den2in; // denoiser -> input - } record; - struct { - tdav_webrtc_resampler_t* p_rpl_in2den; // input -> denoiser - tdav_webrtc_resampler_t* p_rpl_den2in; // denoiser -> input - } playback; - - struct { - uint32_t nb_samples_per_process; - uint32_t sampling_rate; - uint32_t channels; // always "1" - } neg; - - TSK_DECLARE_SAFEOBJ; + uint32_t echo_tail; + uint32_t echo_skew; + + struct { + tdav_webrtc_resampler_t* p_rpl_in2den; // input -> denoiser + tdav_webrtc_resampler_t* p_rpl_den2in; // denoiser -> input + } record; + struct { + tdav_webrtc_resampler_t* p_rpl_in2den; // input -> denoiser + tdav_webrtc_resampler_t* p_rpl_den2in; // denoiser -> input + } playback; + + struct { + uint32_t nb_samples_per_process; + uint32_t sampling_rate; + uint32_t channels; // always "1" + } neg; + + TSK_DECLARE_SAFEOBJ; } tdav_webrtc_denoise_t; static int tdav_webrtc_denoise_set(tmedia_denoise_t* _self, const tmedia_param_t* param) { - tdav_webrtc_denoise_t *self = (tdav_webrtc_denoise_t *)_self; - if (!self || !param) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (param->value_type == tmedia_pvt_int32) { - if (tsk_striequals(param->key, "echo-tail")) { - int32_t echo_tail = *((int32_t*)param->value); - self->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, echo_tail, WEBRTC_MAX_ECHO_TAIL); - TSK_DEBUG_INFO("set_echo_tail (%d->%d)", echo_tail, self->echo_tail); - return 0; - } - } - return -1; + tdav_webrtc_denoise_t *self = (tdav_webrtc_denoise_t *)_self; + if (!self || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (param->value_type == tmedia_pvt_int32) { + if (tsk_striequals(param->key, "echo-tail")) { + int32_t echo_tail = *((int32_t*)param->value); + self->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, echo_tail, WEBRTC_MAX_ECHO_TAIL); + TSK_DEBUG_INFO("set_echo_tail (%d->%d)", echo_tail, self->echo_tail); + return 0; + } + } + return -1; } static int tdav_webrtc_denoise_open(tmedia_denoise_t* self, uint32_t record_frame_size_samples, uint32_t record_sampling_rate, uint32_t record_channels, uint32_t playback_frame_size_samples, uint32_t playback_sampling_rate, uint32_t playback_channels) { - tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; - int ret; - tdav_webrtc_pin_xt pin_record_in = { 0 }, pin_record_den = { 0 }, pin_playback_in = { 0 }, pin_playback_den = { 0 }; + tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; + int ret; + tdav_webrtc_pin_xt pin_record_in = { 0 }, pin_record_den = { 0 }, pin_playback_in = { 0 }, pin_playback_den = { 0 }; - if (!denoiser) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!denoiser) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if (denoiser->AEC_inst || + if (denoiser->AEC_inst || #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER - denoiser->SpeexDenoiser_proc + denoiser->SpeexDenoiser_proc #else - denoiser->NS_inst + denoiser->NS_inst #endif - ){ - TSK_DEBUG_ERROR("Denoiser already initialized"); - return -2; - } - - denoiser->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, TMEDIA_DENOISE(denoiser)->echo_tail, WEBRTC_MAX_ECHO_TAIL); - denoiser->echo_skew = TMEDIA_DENOISE(denoiser)->echo_skew; - TSK_DEBUG_INFO("echo_tail=%d, echo_skew=%d, echo_supp_enabled=%d, noise_supp_enabled=%d", denoiser->echo_tail, denoiser->echo_skew, self->echo_supp_enabled, self->noise_supp_enabled); - - // - // DENOISER - // + ) { + TSK_DEBUG_ERROR("Denoiser already initialized"); + return -2; + } + + denoiser->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, TMEDIA_DENOISE(denoiser)->echo_tail, WEBRTC_MAX_ECHO_TAIL); + denoiser->echo_skew = TMEDIA_DENOISE(denoiser)->echo_skew; + TSK_DEBUG_INFO("echo_tail=%d, echo_skew=%d, echo_supp_enabled=%d, noise_supp_enabled=%d", denoiser->echo_tail, denoiser->echo_skew, self->echo_supp_enabled, self->noise_supp_enabled); + + // + // DENOISER + // #if TDAV_UNDER_MOBILE // AECM= [8-16]k, AEC=[8-32]k - denoiser->neg.sampling_rate = TSK_MIN(TSK_MAX(record_sampling_rate, playback_sampling_rate), 16000); + denoiser->neg.sampling_rate = TSK_MIN(TSK_MAX(record_sampling_rate, playback_sampling_rate), 16000); #else - denoiser->neg.sampling_rate = TSK_MIN(TSK_MAX(record_sampling_rate, playback_sampling_rate), 16000); // FIXME: 32000 accepted by echo_process fails + denoiser->neg.sampling_rate = TSK_MIN(TSK_MAX(record_sampling_rate, playback_sampling_rate), 16000); // FIXME: 32000 accepted by echo_process fails #endif - denoiser->neg.nb_samples_per_process = /*TSK_CLAMP(80,*/ ((denoiser->neg.sampling_rate * 10) / 1000)/*, 160)*/; // Supported by the module: "80"(10ms) and "160"(20ms) - denoiser->neg.channels = 1; - - // - // RECORD - // - TSK_OBJECT_SAFE_FREE(denoiser->record.p_rpl_den2in); - TSK_OBJECT_SAFE_FREE(denoiser->record.p_rpl_in2den); - pin_record_in.n_sample_size = sizeof(int16_t); - pin_record_in.n_rate = record_sampling_rate; - pin_record_in.n_channels = record_channels; - pin_record_in.n_duration = (((record_frame_size_samples * 1000) / record_sampling_rate)) / record_channels; - pin_record_den.n_sample_size = sizeof(sample_t); - pin_record_den.n_rate = denoiser->neg.sampling_rate; - - pin_record_den.n_channels = 1; - pin_record_den.n_duration = pin_record_in.n_duration; - if (pin_record_in.n_sample_size != pin_record_den.n_sample_size || pin_record_in.n_rate != pin_record_den.n_rate || pin_record_in.n_channels != pin_record_den.n_channels) { - if ((ret = _tdav_webrtc_resampler_create(&pin_record_in, &pin_record_den, &denoiser->record.p_rpl_in2den))) { - return ret; - } - if ((ret = _tdav_webrtc_resampler_create(&pin_record_den, &pin_record_in, &denoiser->record.p_rpl_den2in))) { - return ret; - } - } - // - // PLAYBACK - // - TSK_OBJECT_SAFE_FREE(denoiser->playback.p_rpl_den2in); - TSK_OBJECT_SAFE_FREE(denoiser->playback.p_rpl_in2den); - pin_playback_in.n_sample_size = sizeof(int16_t); - pin_playback_in.n_rate = playback_sampling_rate; - pin_playback_in.n_channels = playback_channels; - pin_playback_in.n_duration = (((playback_frame_size_samples * 1000) / playback_sampling_rate)) / playback_channels; - pin_playback_den.n_sample_size = sizeof(sample_t); - pin_playback_den.n_rate = denoiser->neg.sampling_rate; - pin_playback_den.n_channels = 1; - pin_playback_den.n_duration = pin_playback_in.n_duration; - if (pin_playback_in.n_sample_size != pin_playback_den.n_sample_size || pin_playback_in.n_rate != pin_playback_den.n_rate || pin_playback_in.n_channels != pin_playback_den.n_channels) { - if ((ret = _tdav_webrtc_resampler_create(&pin_playback_in, &pin_playback_den, &denoiser->playback.p_rpl_in2den))) { - return ret; - } - if ((ret = _tdav_webrtc_resampler_create(&pin_playback_den, &pin_playback_in, &denoiser->playback.p_rpl_den2in))) { - return ret; - } - } - - // - // AEC instance - // - if ((ret = TDAV_WebRtcAec_Create(&denoiser->AEC_inst))) { - TSK_DEBUG_ERROR("WebRtcAec_Create failed with error code = %d", ret); - return ret; - } - if ((ret = TDAV_WebRtcAec_Init(denoiser->AEC_inst, denoiser->neg.sampling_rate, denoiser->neg.sampling_rate))) { - TSK_DEBUG_ERROR("WebRtcAec_Init failed with error code = %d", ret); - return ret; - } + denoiser->neg.nb_samples_per_process = /*TSK_CLAMP(80,*/ ((denoiser->neg.sampling_rate * 10) / 1000)/*, 160)*/; // Supported by the module: "80"(10ms) and "160"(20ms) + denoiser->neg.channels = 1; + + // + // RECORD + // + TSK_OBJECT_SAFE_FREE(denoiser->record.p_rpl_den2in); + TSK_OBJECT_SAFE_FREE(denoiser->record.p_rpl_in2den); + pin_record_in.n_sample_size = sizeof(int16_t); + pin_record_in.n_rate = record_sampling_rate; + pin_record_in.n_channels = record_channels; + pin_record_in.n_duration = (((record_frame_size_samples * 1000) / record_sampling_rate)) / record_channels; + pin_record_den.n_sample_size = sizeof(sample_t); + pin_record_den.n_rate = denoiser->neg.sampling_rate; + + pin_record_den.n_channels = 1; + pin_record_den.n_duration = pin_record_in.n_duration; + if (pin_record_in.n_sample_size != pin_record_den.n_sample_size || pin_record_in.n_rate != pin_record_den.n_rate || pin_record_in.n_channels != pin_record_den.n_channels) { + if ((ret = _tdav_webrtc_resampler_create(&pin_record_in, &pin_record_den, &denoiser->record.p_rpl_in2den))) { + return ret; + } + if ((ret = _tdav_webrtc_resampler_create(&pin_record_den, &pin_record_in, &denoiser->record.p_rpl_den2in))) { + return ret; + } + } + // + // PLAYBACK + // + TSK_OBJECT_SAFE_FREE(denoiser->playback.p_rpl_den2in); + TSK_OBJECT_SAFE_FREE(denoiser->playback.p_rpl_in2den); + pin_playback_in.n_sample_size = sizeof(int16_t); + pin_playback_in.n_rate = playback_sampling_rate; + pin_playback_in.n_channels = playback_channels; + pin_playback_in.n_duration = (((playback_frame_size_samples * 1000) / playback_sampling_rate)) / playback_channels; + pin_playback_den.n_sample_size = sizeof(sample_t); + pin_playback_den.n_rate = denoiser->neg.sampling_rate; + pin_playback_den.n_channels = 1; + pin_playback_den.n_duration = pin_playback_in.n_duration; + if (pin_playback_in.n_sample_size != pin_playback_den.n_sample_size || pin_playback_in.n_rate != pin_playback_den.n_rate || pin_playback_in.n_channels != pin_playback_den.n_channels) { + if ((ret = _tdav_webrtc_resampler_create(&pin_playback_in, &pin_playback_den, &denoiser->playback.p_rpl_in2den))) { + return ret; + } + if ((ret = _tdav_webrtc_resampler_create(&pin_playback_den, &pin_playback_in, &denoiser->playback.p_rpl_den2in))) { + return ret; + } + } + + // + // AEC instance + // + if ((ret = TDAV_WebRtcAec_Create(&denoiser->AEC_inst))) { + TSK_DEBUG_ERROR("WebRtcAec_Create failed with error code = %d", ret); + return ret; + } + if ((ret = TDAV_WebRtcAec_Init(denoiser->AEC_inst, denoiser->neg.sampling_rate, denoiser->neg.sampling_rate))) { + TSK_DEBUG_ERROR("WebRtcAec_Init failed with error code = %d", ret); + return ret; + } #if TDAV_UNDER_MOBILE #else - { - AecConfig aecConfig; + { + AecConfig aecConfig; #if WEBRTC_AEC_AGGRESSIVE - aecConfig.nlpMode = kAecNlpAggressive; + aecConfig.nlpMode = kAecNlpAggressive; #else - aecConfig.nlpMode = kAecNlpModerate; + aecConfig.nlpMode = kAecNlpModerate; #endif - aecConfig.skewMode = kAecFalse; - aecConfig.metricsMode = kAecTrue; - aecConfig.delay_logging = kAecFalse; - if ((ret = WebRtcAec_set_config(denoiser->AEC_inst, aecConfig))) { - TSK_DEBUG_ERROR("WebRtcAec_set_config failed with error code = %d", ret); - } - } + aecConfig.skewMode = kAecFalse; + aecConfig.metricsMode = kAecTrue; + aecConfig.delay_logging = kAecFalse; + if ((ret = WebRtcAec_set_config(denoiser->AEC_inst, aecConfig))) { + TSK_DEBUG_ERROR("WebRtcAec_set_config failed with error code = %d", ret); + } + } #endif - // - // Noise Suppression instance - // - if (TMEDIA_DENOISE(denoiser)->noise_supp_enabled) { + // + // Noise Suppression instance + // + if (TMEDIA_DENOISE(denoiser)->noise_supp_enabled) { #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER - if ((denoiser->SpeexDenoiser_proc = speex_preprocess_state_init((pin_record_den.n_rate / 1000) * pin_record_den.n_duration, pin_record_den.n_rate))) { - int i = 1; - speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_DENOISE, &i); - i = TMEDIA_DENOISE(denoiser)->noise_supp_level; - speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i); - } + if ((denoiser->SpeexDenoiser_proc = speex_preprocess_state_init((pin_record_den.n_rate / 1000) * pin_record_den.n_duration, pin_record_den.n_rate))) { + int i = 1; + speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_DENOISE, &i); + i = TMEDIA_DENOISE(denoiser)->noise_supp_level; + speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i); + } #else - if ((ret = TDAV_WebRtcNs_Create(&denoiser->NS_inst))) { - TSK_DEBUG_ERROR("WebRtcNs_Create failed with error code = %d", ret); - return ret; - } - if ((ret = TDAV_WebRtcNs_Init(denoiser->NS_inst, 80))) { - TSK_DEBUG_ERROR("WebRtcNs_Init failed with error code = %d", ret); - return ret; - } + if ((ret = TDAV_WebRtcNs_Create(&denoiser->NS_inst))) { + TSK_DEBUG_ERROR("WebRtcNs_Create failed with error code = %d", ret); + return ret; + } + if ((ret = TDAV_WebRtcNs_Init(denoiser->NS_inst, 80))) { + TSK_DEBUG_ERROR("WebRtcNs_Init failed with error code = %d", ret); + return ret; + } #endif - } + } - TSK_DEBUG_INFO("WebRTC denoiser opened: record:%uHz,%uchannels // playback:%uHz,%uchannels // neg:%uHz,%uchannels", - record_sampling_rate, record_channels, - playback_sampling_rate, playback_channels, - denoiser->neg.sampling_rate, denoiser->neg.channels); + TSK_DEBUG_INFO("WebRTC denoiser opened: record:%uHz,%uchannels // playback:%uHz,%uchannels // neg:%uHz,%uchannels", + record_sampling_rate, record_channels, + playback_sampling_rate, playback_channels, + denoiser->neg.sampling_rate, denoiser->neg.channels); - return ret; + return ret; } static int tdav_webrtc_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame, uint32_t echo_frame_size_bytes) { - tdav_webrtc_denoise_t *p_self = (tdav_webrtc_denoise_t *)self; - int ret = 0; - - tsk_safeobj_lock(p_self); - if (p_self->AEC_inst && echo_frame && echo_frame_size_bytes) { - const sample_t* _echo_frame = (const sample_t*)echo_frame; - tsk_size_t _echo_frame_size_bytes = echo_frame_size_bytes; - tsk_size_t _echo_frame_size_samples = (_echo_frame_size_bytes / sizeof(int16_t)); - // IN -> DEN - if (p_self->playback.p_rpl_in2den) { - if ((ret = _tdav_webrtc_resampler_process(p_self->playback.p_rpl_in2den, _echo_frame, _echo_frame_size_bytes))) { - goto bail; - } - _echo_frame = p_self->playback.p_rpl_in2den->out.p_buff_ptr; - _echo_frame_size_bytes = p_self->playback.p_rpl_in2den->out.n_buff_size_in_bytes; - _echo_frame_size_samples = p_self->playback.p_rpl_in2den->out.n_buff_size_in_samples; - } - // PROCESS - if (_echo_frame_size_samples && _echo_frame) { - uint32_t _samples; - for (_samples = 0; _samples < _echo_frame_size_samples; _samples += p_self->neg.nb_samples_per_process) { - if ((ret = TDAV_WebRtcAec_BufferFarend(p_self->AEC_inst, &_echo_frame[_samples], p_self->neg.nb_samples_per_process))){ - TSK_DEBUG_ERROR("WebRtcAec_BufferFarend failed with error code = %d, nb_samples_per_process=%u", ret, p_self->neg.nb_samples_per_process); - goto bail; - } - } - } - } + tdav_webrtc_denoise_t *p_self = (tdav_webrtc_denoise_t *)self; + int ret = 0; + + tsk_safeobj_lock(p_self); + if (p_self->AEC_inst && echo_frame && echo_frame_size_bytes) { + const sample_t* _echo_frame = (const sample_t*)echo_frame; + tsk_size_t _echo_frame_size_bytes = echo_frame_size_bytes; + tsk_size_t _echo_frame_size_samples = (_echo_frame_size_bytes / sizeof(int16_t)); + // IN -> DEN + if (p_self->playback.p_rpl_in2den) { + if ((ret = _tdav_webrtc_resampler_process(p_self->playback.p_rpl_in2den, _echo_frame, _echo_frame_size_bytes))) { + goto bail; + } + _echo_frame = p_self->playback.p_rpl_in2den->out.p_buff_ptr; + _echo_frame_size_bytes = p_self->playback.p_rpl_in2den->out.n_buff_size_in_bytes; + _echo_frame_size_samples = p_self->playback.p_rpl_in2den->out.n_buff_size_in_samples; + } + // PROCESS + if (_echo_frame_size_samples && _echo_frame) { + uint32_t _samples; + for (_samples = 0; _samples < _echo_frame_size_samples; _samples += p_self->neg.nb_samples_per_process) { + if ((ret = TDAV_WebRtcAec_BufferFarend(p_self->AEC_inst, &_echo_frame[_samples], p_self->neg.nb_samples_per_process))) { + TSK_DEBUG_ERROR("WebRtcAec_BufferFarend failed with error code = %d, nb_samples_per_process=%u", ret, p_self->neg.nb_samples_per_process); + goto bail; + } + } + } + } bail: - tsk_safeobj_unlock(p_self); - return ret; + tsk_safeobj_unlock(p_self); + return ret; } static int tdav_webrtc_denoise_process_record(tmedia_denoise_t* self, void* audio_frame, uint32_t audio_frame_size_bytes, tsk_bool_t* silence_or_noise) { - tdav_webrtc_denoise_t *p_self = (tdav_webrtc_denoise_t *)self; - int ret = 0; - - *silence_or_noise = tsk_false; - - tsk_safeobj_lock(p_self); - - if (p_self->AEC_inst && audio_frame && audio_frame_size_bytes) { - tsk_size_t _samples; - const sample_t* _audio_frame = (const sample_t*)audio_frame; - tsk_size_t _audio_frame_size_bytes = audio_frame_size_bytes; - tsk_size_t _audio_frame_size_samples = (_audio_frame_size_bytes / sizeof(int16_t)); - // IN -> DEN - if (p_self->record.p_rpl_in2den) { - if ((ret = _tdav_webrtc_resampler_process(p_self->record.p_rpl_in2den, _audio_frame, _audio_frame_size_bytes))) { - goto bail; - } - _audio_frame = p_self->record.p_rpl_in2den->out.p_buff_ptr; - _audio_frame_size_bytes = p_self->record.p_rpl_in2den->out.n_buff_size_in_bytes; - _audio_frame_size_samples = p_self->record.p_rpl_in2den->out.n_buff_size_in_samples; - } - // NOISE SUPPRESSION + tdav_webrtc_denoise_t *p_self = (tdav_webrtc_denoise_t *)self; + int ret = 0; + + *silence_or_noise = tsk_false; + + tsk_safeobj_lock(p_self); + + if (p_self->AEC_inst && audio_frame && audio_frame_size_bytes) { + tsk_size_t _samples; + const sample_t* _audio_frame = (const sample_t*)audio_frame; + tsk_size_t _audio_frame_size_bytes = audio_frame_size_bytes; + tsk_size_t _audio_frame_size_samples = (_audio_frame_size_bytes / sizeof(int16_t)); + // IN -> DEN + if (p_self->record.p_rpl_in2den) { + if ((ret = _tdav_webrtc_resampler_process(p_self->record.p_rpl_in2den, _audio_frame, _audio_frame_size_bytes))) { + goto bail; + } + _audio_frame = p_self->record.p_rpl_in2den->out.p_buff_ptr; + _audio_frame_size_bytes = p_self->record.p_rpl_in2den->out.n_buff_size_in_bytes; + _audio_frame_size_samples = p_self->record.p_rpl_in2den->out.n_buff_size_in_samples; + } + // NOISE SUPPRESSION #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER - if (p_self->SpeexDenoiser_proc) { - speex_preprocess_run(p_self->SpeexDenoiser_proc, (spx_int16_t*)_audio_frame); - } + if (p_self->SpeexDenoiser_proc) { + speex_preprocess_run(p_self->SpeexDenoiser_proc, (spx_int16_t*)_audio_frame); + } #else - // WebRTC NoiseSupp only accept 10ms frames - // Our encoder will always output 20ms frames ==> execute 2x noise_supp - if (p_self->NS_inst) { - for (_samples = 0; _samples < _audio_frame_size_samples; _samples+= p_self->neg.nb_samples_per_process) { - if ((ret = TDAV_WebRtcNs_Process(p_self->NS_inst, &_audio_frame[_samples], tsk_null, _audio_frame, tsk_null))) { - TSK_DEBUG_ERROR("WebRtcNs_Process with error code = %d", ret); - goto bail; - } - } - } + // WebRTC NoiseSupp only accept 10ms frames + // Our encoder will always output 20ms frames ==> execute 2x noise_supp + if (p_self->NS_inst) { + for (_samples = 0; _samples < _audio_frame_size_samples; _samples+= p_self->neg.nb_samples_per_process) { + if ((ret = TDAV_WebRtcNs_Process(p_self->NS_inst, &_audio_frame[_samples], tsk_null, _audio_frame, tsk_null))) { + TSK_DEBUG_ERROR("WebRtcNs_Process with error code = %d", ret); + goto bail; + } + } + } #endif - // PROCESS - if (_audio_frame_size_samples && _audio_frame) { - for (_samples = 0; _samples < _audio_frame_size_samples; _samples += p_self->neg.nb_samples_per_process) { - if ((ret = TDAV_WebRtcAec_Process(p_self->AEC_inst, &_audio_frame[_samples], tsk_null, (sample_t*)&_audio_frame[_samples], tsk_null, p_self->neg.nb_samples_per_process, p_self->echo_tail, p_self->echo_skew))){ - TSK_DEBUG_ERROR("WebRtcAec_Process with error code = %d, nb_samples_per_process=%u", ret, p_self->neg.nb_samples_per_process); - goto bail; - } - } - } - // DEN -> IN - if (p_self->record.p_rpl_den2in) { - if ((ret = _tdav_webrtc_resampler_process(p_self->record.p_rpl_den2in, _audio_frame, _audio_frame_size_bytes))) { - goto bail; - } - _audio_frame = p_self->record.p_rpl_den2in->out.p_buff_ptr; - _audio_frame_size_bytes = p_self->record.p_rpl_den2in->out.n_buff_size_in_bytes; - _audio_frame_size_samples = p_self->record.p_rpl_den2in->out.n_buff_size_in_samples; - } - // Sanity check - if (_audio_frame_size_bytes != audio_frame_size_bytes) { - TSK_DEBUG_ERROR("Size mismatch: %u <> %u", _audio_frame_size_bytes, audio_frame_size_bytes); - ret = -3; - goto bail; - } - if (audio_frame != (const void*)_audio_frame) { - memcpy(audio_frame, _audio_frame, _audio_frame_size_bytes); - } - } + // PROCESS + if (_audio_frame_size_samples && _audio_frame) { + for (_samples = 0; _samples < _audio_frame_size_samples; _samples += p_self->neg.nb_samples_per_process) { + if ((ret = TDAV_WebRtcAec_Process(p_self->AEC_inst, &_audio_frame[_samples], tsk_null, (sample_t*)&_audio_frame[_samples], tsk_null, p_self->neg.nb_samples_per_process, p_self->echo_tail, p_self->echo_skew))) { + TSK_DEBUG_ERROR("WebRtcAec_Process with error code = %d, nb_samples_per_process=%u", ret, p_self->neg.nb_samples_per_process); + goto bail; + } + } + } + // DEN -> IN + if (p_self->record.p_rpl_den2in) { + if ((ret = _tdav_webrtc_resampler_process(p_self->record.p_rpl_den2in, _audio_frame, _audio_frame_size_bytes))) { + goto bail; + } + _audio_frame = p_self->record.p_rpl_den2in->out.p_buff_ptr; + _audio_frame_size_bytes = p_self->record.p_rpl_den2in->out.n_buff_size_in_bytes; + _audio_frame_size_samples = p_self->record.p_rpl_den2in->out.n_buff_size_in_samples; + } + // Sanity check + if (_audio_frame_size_bytes != audio_frame_size_bytes) { + TSK_DEBUG_ERROR("Size mismatch: %u <> %u", _audio_frame_size_bytes, audio_frame_size_bytes); + ret = -3; + goto bail; + } + if (audio_frame != (const void*)_audio_frame) { + memcpy(audio_frame, _audio_frame, _audio_frame_size_bytes); + } + } bail: - tsk_safeobj_unlock(p_self); - return ret; + tsk_safeobj_unlock(p_self); + return ret; } static int tdav_webrtc_denoise_process_playback(tmedia_denoise_t* self, void* audio_frame, uint32_t audio_frame_size_bytes) { - tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; + tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; - (void)(denoiser); + (void)(denoiser); - // Not mandatory to denoise audio before playback. - // All Doubango clients support noise suppression. - return 0; + // Not mandatory to denoise audio before playback. + // All Doubango clients support noise suppression. + return 0; } static int tdav_webrtc_denoise_close(tmedia_denoise_t* self) { - tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; + tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; - tsk_safeobj_lock(denoiser); - if (denoiser->AEC_inst) { - TDAV_WebRtcAec_Free(denoiser->AEC_inst); - denoiser->AEC_inst = tsk_null; - } + tsk_safeobj_lock(denoiser); + if (denoiser->AEC_inst) { + TDAV_WebRtcAec_Free(denoiser->AEC_inst); + denoiser->AEC_inst = tsk_null; + } #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER - if (denoiser->SpeexDenoiser_proc) { - speex_preprocess_state_destroy(denoiser->SpeexDenoiser_proc); - denoiser->SpeexDenoiser_proc = tsk_null; - } + if (denoiser->SpeexDenoiser_proc) { + speex_preprocess_state_destroy(denoiser->SpeexDenoiser_proc); + denoiser->SpeexDenoiser_proc = tsk_null; + } #else - if (denoiser->NS_inst) { - TDAV_WebRtcNs_Free(denoiser->NS_inst); - denoiser->NS_inst = tsk_null; - } + if (denoiser->NS_inst) { + TDAV_WebRtcNs_Free(denoiser->NS_inst); + denoiser->NS_inst = tsk_null; + } #endif - tsk_safeobj_unlock(denoiser); + tsk_safeobj_unlock(denoiser); - return 0; + return 0; } static int _tdav_webrtc_resampler_create(const tdav_webrtc_pin_xt* p_pin_in, const tdav_webrtc_pin_xt* p_pin_out, tdav_webrtc_resampler_t **pp_resampler) { - extern const tsk_object_def_t *tdav_webrtc_resampler_def_t; - int ret = 0; - if (!p_pin_in || !p_pin_out || !pp_resampler || *pp_resampler) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (!(*pp_resampler = tsk_object_new(tdav_webrtc_resampler_def_t))) { - TSK_DEBUG_ERROR("Failed to create resampler object"); - ret = -3; - goto bail; - } - if (!((*pp_resampler)->p_resampler = tmedia_resampler_create())) { - ret = -3; - goto bail; - } - ret = tmedia_resampler_open((*pp_resampler)->p_resampler, - p_pin_in->n_rate, p_pin_out->n_rate, - p_pin_in->n_duration, - p_pin_in->n_channels, p_pin_out->n_channels, - TMEDIA_RESAMPLER_QUALITY, - (p_pin_out->n_sample_size << 3)); - if (ret) { - TSK_DEBUG_ERROR("Failed to open resampler: in_rate=%u,in_duration=%u,in_channels=%u /// out_rate=%u,out_duration=%u,out_channels=%u", - p_pin_in->n_rate, p_pin_in->n_duration, p_pin_in->n_channels, - p_pin_out->n_rate, p_pin_out->n_duration, p_pin_out->n_channels); - goto bail; - } - - (*pp_resampler)->out.n_buff_size_in_bytes = ((((p_pin_out->n_rate * p_pin_out->n_duration) / 1000)) * p_pin_out->n_channels) * p_pin_out->n_sample_size; - (*pp_resampler)->out.p_buff_ptr = tsk_malloc((*pp_resampler)->out.n_buff_size_in_bytes); - if (!(*pp_resampler)->out.p_buff_ptr) { - TSK_DEBUG_ERROR("Failed to allocate buffer with size=%u", (*pp_resampler)->out.n_buff_size_in_bytes); - ret = -3; - goto bail; - } - (*pp_resampler)->out.n_buff_size_in_samples = (*pp_resampler)->out.n_buff_size_in_bytes / p_pin_out->n_sample_size; - (*pp_resampler)->in.n_buff_size_in_bytes = ((((p_pin_in->n_rate * p_pin_in->n_duration) / 1000)) * p_pin_in->n_channels) * p_pin_in->n_sample_size; - (*pp_resampler)->in.n_buff_size_in_samples = (*pp_resampler)->in.n_buff_size_in_bytes / p_pin_in->n_sample_size; - - (*pp_resampler)->n_bufftmp_size_in_bytes = (((48000 * TSK_MAX(p_pin_in->n_duration, p_pin_out->n_duration)) / 1000) * 2/*channels*/) * sizeof(float); // Max - (*pp_resampler)->p_bufftmp_ptr = tsk_malloc((*pp_resampler)->n_bufftmp_size_in_bytes); - if (!(*pp_resampler)->p_bufftmp_ptr) { - TSK_DEBUG_ERROR("Failed to allocate buffer with size:%u", (*pp_resampler)->n_bufftmp_size_in_bytes); - ret = -3; - goto bail; - } - - memcpy(&(*pp_resampler)->in.x_pin, p_pin_in, sizeof(tdav_webrtc_pin_xt)); - memcpy(&(*pp_resampler)->out.x_pin, p_pin_out, sizeof(tdav_webrtc_pin_xt)); + extern const tsk_object_def_t *tdav_webrtc_resampler_def_t; + int ret = 0; + if (!p_pin_in || !p_pin_out || !pp_resampler || *pp_resampler) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (!(*pp_resampler = tsk_object_new(tdav_webrtc_resampler_def_t))) { + TSK_DEBUG_ERROR("Failed to create resampler object"); + ret = -3; + goto bail; + } + if (!((*pp_resampler)->p_resampler = tmedia_resampler_create())) { + ret = -3; + goto bail; + } + ret = tmedia_resampler_open((*pp_resampler)->p_resampler, + p_pin_in->n_rate, p_pin_out->n_rate, + p_pin_in->n_duration, + p_pin_in->n_channels, p_pin_out->n_channels, + TMEDIA_RESAMPLER_QUALITY, + (p_pin_out->n_sample_size << 3)); + if (ret) { + TSK_DEBUG_ERROR("Failed to open resampler: in_rate=%u,in_duration=%u,in_channels=%u /// out_rate=%u,out_duration=%u,out_channels=%u", + p_pin_in->n_rate, p_pin_in->n_duration, p_pin_in->n_channels, + p_pin_out->n_rate, p_pin_out->n_duration, p_pin_out->n_channels); + goto bail; + } + + (*pp_resampler)->out.n_buff_size_in_bytes = ((((p_pin_out->n_rate * p_pin_out->n_duration) / 1000)) * p_pin_out->n_channels) * p_pin_out->n_sample_size; + (*pp_resampler)->out.p_buff_ptr = tsk_malloc((*pp_resampler)->out.n_buff_size_in_bytes); + if (!(*pp_resampler)->out.p_buff_ptr) { + TSK_DEBUG_ERROR("Failed to allocate buffer with size=%u", (*pp_resampler)->out.n_buff_size_in_bytes); + ret = -3; + goto bail; + } + (*pp_resampler)->out.n_buff_size_in_samples = (*pp_resampler)->out.n_buff_size_in_bytes / p_pin_out->n_sample_size; + (*pp_resampler)->in.n_buff_size_in_bytes = ((((p_pin_in->n_rate * p_pin_in->n_duration) / 1000)) * p_pin_in->n_channels) * p_pin_in->n_sample_size; + (*pp_resampler)->in.n_buff_size_in_samples = (*pp_resampler)->in.n_buff_size_in_bytes / p_pin_in->n_sample_size; + + (*pp_resampler)->n_bufftmp_size_in_bytes = (((48000 * TSK_MAX(p_pin_in->n_duration, p_pin_out->n_duration)) / 1000) * 2/*channels*/) * sizeof(float); // Max + (*pp_resampler)->p_bufftmp_ptr = tsk_malloc((*pp_resampler)->n_bufftmp_size_in_bytes); + if (!(*pp_resampler)->p_bufftmp_ptr) { + TSK_DEBUG_ERROR("Failed to allocate buffer with size:%u", (*pp_resampler)->n_bufftmp_size_in_bytes); + ret = -3; + goto bail; + } + + memcpy(&(*pp_resampler)->in.x_pin, p_pin_in, sizeof(tdav_webrtc_pin_xt)); + memcpy(&(*pp_resampler)->out.x_pin, p_pin_out, sizeof(tdav_webrtc_pin_xt)); bail: - if (ret) { - TSK_OBJECT_SAFE_FREE((*pp_resampler)); - } - return ret; + if (ret) { + TSK_OBJECT_SAFE_FREE((*pp_resampler)); + } + return ret; } static int _tdav_webrtc_resampler_process(tdav_webrtc_resampler_t *p_self, const void* p_buff_ptr, tsk_size_t n_buff_size_in_bytes) { - tsk_size_t n_out_size; - const void* _p_buff_ptr = p_buff_ptr; - tsk_size_t _n_buff_size_in_bytes = n_buff_size_in_bytes; - tsk_size_t _n_buff_size_in_samples; - - if (!p_self || !p_buff_ptr || !n_buff_size_in_bytes) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (p_self->in.n_buff_size_in_bytes != n_buff_size_in_bytes) { - TSK_DEBUG_ERROR("Invalid input size: %u <> %u", p_self->in.n_buff_size_in_bytes, n_buff_size_in_bytes); - return -2; - } - _n_buff_size_in_samples = p_self->in.n_buff_size_in_samples; - if (p_self->in.x_pin.n_sample_size != p_self->out.x_pin.n_sample_size) { - tsk_size_t index; - if (p_self->in.x_pin.n_sample_size == sizeof(int16_t)) { - // int16_t -> float - const int16_t* p_src = (const int16_t*)p_buff_ptr; - float* p_dst = (float*)p_self->p_bufftmp_ptr; - for (index = 0; index < _n_buff_size_in_samples; ++index) { - p_dst[index] = (float)p_src[index]; - } - } - else { - // float -> int16_t - const float* p_src = (const float*)p_buff_ptr; - int16_t* p_dst = (int16_t*)p_self->p_bufftmp_ptr; - for (index = 0; index < _n_buff_size_in_samples; ++index) { - p_dst[index] = (int16_t)p_src[index]; - } - } - _p_buff_ptr = p_self->p_bufftmp_ptr; - _n_buff_size_in_bytes = p_self->in.n_buff_size_in_bytes; - } - n_out_size = tmedia_resampler_process(p_self->p_resampler, _p_buff_ptr, _n_buff_size_in_samples, (int16_t*)p_self->out.p_buff_ptr, p_self->out.n_buff_size_in_samples); - if (n_out_size != p_self->out.n_buff_size_in_samples) { - TSK_DEBUG_ERROR("Invalid output size: %u <> %u", n_out_size, p_self->out.n_buff_size_in_bytes); - return -4; - } - return 0; + tsk_size_t n_out_size; + const void* _p_buff_ptr = p_buff_ptr; + tsk_size_t _n_buff_size_in_bytes = n_buff_size_in_bytes; + tsk_size_t _n_buff_size_in_samples; + + if (!p_self || !p_buff_ptr || !n_buff_size_in_bytes) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (p_self->in.n_buff_size_in_bytes != n_buff_size_in_bytes) { + TSK_DEBUG_ERROR("Invalid input size: %u <> %u", p_self->in.n_buff_size_in_bytes, n_buff_size_in_bytes); + return -2; + } + _n_buff_size_in_samples = p_self->in.n_buff_size_in_samples; + if (p_self->in.x_pin.n_sample_size != p_self->out.x_pin.n_sample_size) { + tsk_size_t index; + if (p_self->in.x_pin.n_sample_size == sizeof(int16_t)) { + // int16_t -> float + const int16_t* p_src = (const int16_t*)p_buff_ptr; + float* p_dst = (float*)p_self->p_bufftmp_ptr; + for (index = 0; index < _n_buff_size_in_samples; ++index) { + p_dst[index] = (float)p_src[index]; + } + } + else { + // float -> int16_t + const float* p_src = (const float*)p_buff_ptr; + int16_t* p_dst = (int16_t*)p_self->p_bufftmp_ptr; + for (index = 0; index < _n_buff_size_in_samples; ++index) { + p_dst[index] = (int16_t)p_src[index]; + } + } + _p_buff_ptr = p_self->p_bufftmp_ptr; + _n_buff_size_in_bytes = p_self->in.n_buff_size_in_bytes; + } + n_out_size = tmedia_resampler_process(p_self->p_resampler, _p_buff_ptr, _n_buff_size_in_samples, (int16_t*)p_self->out.p_buff_ptr, p_self->out.n_buff_size_in_samples); + if (n_out_size != p_self->out.n_buff_size_in_samples) { + TSK_DEBUG_ERROR("Invalid output size: %u <> %u", n_out_size, p_self->out.n_buff_size_in_bytes); + return -4; + } + return 0; } // @@ -534,28 +531,27 @@ static int _tdav_webrtc_resampler_process(tdav_webrtc_resampler_t *p_self, const // static tsk_object_t* tdav_webrtc_resampler_ctor(tsk_object_t * self, va_list * app) { - tdav_webrtc_resampler_t *p_resampler = (tdav_webrtc_resampler_t*)self; - if (p_resampler) { + tdav_webrtc_resampler_t *p_resampler = (tdav_webrtc_resampler_t*)self; + if (p_resampler) { - } - return self; + } + return self; } static tsk_object_t* tdav_webrtc_resampler_dtor(tsk_object_t * self) { - tdav_webrtc_resampler_t *p_resampler = (tdav_webrtc_resampler_t*)self; - if (p_resampler) { - TSK_OBJECT_SAFE_FREE(p_resampler->p_resampler); - TSK_FREE(p_resampler->out.p_buff_ptr); - TSK_FREE(p_resampler->p_bufftmp_ptr); - } - return self; + tdav_webrtc_resampler_t *p_resampler = (tdav_webrtc_resampler_t*)self; + if (p_resampler) { + TSK_OBJECT_SAFE_FREE(p_resampler->p_resampler); + TSK_FREE(p_resampler->out.p_buff_ptr); + TSK_FREE(p_resampler->p_bufftmp_ptr); + } + return self; } -static const tsk_object_def_t tdav_webrtc_resampler_def_s = -{ - sizeof(tdav_webrtc_resampler_t), - tdav_webrtc_resampler_ctor, - tdav_webrtc_resampler_dtor, - tsk_object_cmp, +static const tsk_object_def_t tdav_webrtc_resampler_def_s = { + sizeof(tdav_webrtc_resampler_t), + tdav_webrtc_resampler_ctor, + tdav_webrtc_resampler_dtor, + tsk_object_cmp, }; const tsk_object_def_t *tdav_webrtc_resampler_def_t = &tdav_webrtc_resampler_def_s; @@ -567,59 +563,57 @@ const tsk_object_def_t *tdav_webrtc_resampler_def_t = &tdav_webrtc_resampler_def /* constructor */ static tsk_object_t* tdav_webrtc_denoise_ctor(tsk_object_t * _self, va_list * app) { - tdav_webrtc_denoise_t *self = _self; - if (self){ - /* init base */ - tmedia_denoise_init(TMEDIA_DENOISE(self)); - /* init self */ - tsk_safeobj_init(self); - self->neg.channels = 1; - - TSK_DEBUG_INFO("Create WebRTC denoiser"); - } - return self; + tdav_webrtc_denoise_t *self = _self; + if (self) { + /* init base */ + tmedia_denoise_init(TMEDIA_DENOISE(self)); + /* init self */ + tsk_safeobj_init(self); + self->neg.channels = 1; + + TSK_DEBUG_INFO("Create WebRTC denoiser"); + } + return self; } /* destructor */ static tsk_object_t* tdav_webrtc_denoise_dtor(tsk_object_t * _self) { - tdav_webrtc_denoise_t *self = _self; - if (self){ - /* deinit base (will close the denoise if not done yet) */ - tmedia_denoise_deinit(TMEDIA_DENOISE(self)); - /* deinit self */ - tdav_webrtc_denoise_close(TMEDIA_DENOISE(self)); - TSK_OBJECT_SAFE_FREE(self->record.p_rpl_in2den); - TSK_OBJECT_SAFE_FREE(self->record.p_rpl_den2in); - TSK_OBJECT_SAFE_FREE(self->playback.p_rpl_in2den); - TSK_OBJECT_SAFE_FREE(self->playback.p_rpl_den2in); - tsk_safeobj_deinit(self); - - TSK_DEBUG_INFO("*** Destroy WebRTC denoiser ***"); - } - - return self; + tdav_webrtc_denoise_t *self = _self; + if (self) { + /* deinit base (will close the denoise if not done yet) */ + tmedia_denoise_deinit(TMEDIA_DENOISE(self)); + /* deinit self */ + tdav_webrtc_denoise_close(TMEDIA_DENOISE(self)); + TSK_OBJECT_SAFE_FREE(self->record.p_rpl_in2den); + TSK_OBJECT_SAFE_FREE(self->record.p_rpl_den2in); + TSK_OBJECT_SAFE_FREE(self->playback.p_rpl_in2den); + TSK_OBJECT_SAFE_FREE(self->playback.p_rpl_den2in); + tsk_safeobj_deinit(self); + + TSK_DEBUG_INFO("*** Destroy WebRTC denoiser ***"); + } + + return self; } /* object definition */ -static const tsk_object_def_t tdav_webrtc_denoise_def_s = -{ - sizeof(tdav_webrtc_denoise_t), - tdav_webrtc_denoise_ctor, - tdav_webrtc_denoise_dtor, - tsk_null, +static const tsk_object_def_t tdav_webrtc_denoise_def_s = { + sizeof(tdav_webrtc_denoise_t), + tdav_webrtc_denoise_ctor, + tdav_webrtc_denoise_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_denoise_plugin_def_t tdav_webrtc_denoise_plugin_def_s = -{ - &tdav_webrtc_denoise_def_s, +static const tmedia_denoise_plugin_def_t tdav_webrtc_denoise_plugin_def_s = { + &tdav_webrtc_denoise_def_s, - "Audio Denoiser based on Google WebRTC", + "Audio Denoiser based on Google WebRTC", - tdav_webrtc_denoise_set, - tdav_webrtc_denoise_open, - tdav_webrtc_denoise_echo_playback, - tdav_webrtc_denoise_process_record, - tdav_webrtc_denoise_process_playback, - tdav_webrtc_denoise_close, + tdav_webrtc_denoise_set, + tdav_webrtc_denoise_open, + tdav_webrtc_denoise_echo_playback, + tdav_webrtc_denoise_process_record, + tdav_webrtc_denoise_process_playback, + tdav_webrtc_denoise_close, }; const tmedia_denoise_plugin_def_t *tdav_webrtc_denoise_plugin_def_t = &tdav_webrtc_denoise_plugin_def_s; |