Add support for Noise suppression on iOS
This commit is contained in:
parent
6faba0e4f5
commit
a62a9b2ada
|
@ -135,3 +135,87 @@ const ProxyPlugin* MediaSessionMgr::findProxyPlugin(twrap_media_type_t media, bo
|
|||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
bool MediaSessionMgr::defaultsSetBandwidthLevel(tmedia_bandwidth_level_t bl)
|
||||
{
|
||||
return tmedia_defaults_set_bl(bl) == 0;
|
||||
}
|
||||
|
||||
tmedia_bandwidth_level_t MediaSessionMgr::defaultsGetBandwidthLevel()
|
||||
{
|
||||
return tmedia_defaults_get_bl();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetEchoTail(uint32_t echo_tail)
|
||||
{
|
||||
return tmedia_defaults_set_echo_tail(echo_tail) == 0;
|
||||
}
|
||||
|
||||
uint32_t MediaSessionMgr::defaultsGetEchoTail()
|
||||
{
|
||||
return tmedia_defaults_get_echo_tail();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetEchoSuppEnabled(bool echo_supp_enabled)
|
||||
{
|
||||
return tmedia_defaults_set_echo_supp_enabled(echo_supp_enabled) == 0;
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsGetEchoSuppEnabled()
|
||||
{
|
||||
return tmedia_defaults_get_echo_supp_enabled();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetAgcEnabled(bool agc_enabled)
|
||||
{
|
||||
return tmedia_defaults_set_agc_enabled(agc_enabled ? tsk_true : tsk_false) == 0;
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsGetAgcEnabled()
|
||||
{
|
||||
return tmedia_defaults_get_agc_enabled();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetAgcLevel(float agc_level)
|
||||
{
|
||||
return tmedia_defaults_set_agc_level(agc_level) == 0;
|
||||
}
|
||||
|
||||
float MediaSessionMgr::defaultsGetAgcLevel()
|
||||
{
|
||||
return tmedia_defaults_get_agc_enabled();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetVadEnabled(bool vad_enabled)
|
||||
{
|
||||
return tmedia_defaults_set_vad_enabled(vad_enabled ? tsk_true : tsk_false) == 0;
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsGetGetVadEnabled()
|
||||
{
|
||||
return tmedia_defaults_get_vad_enabled();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetNoiseSuppEnabled(bool noise_supp_enabled)
|
||||
{
|
||||
return tmedia_defaults_set_noise_supp_enabled(noise_supp_enabled ? tsk_true : tsk_false) == 0;
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsGetNoiseSuppEnabled()
|
||||
{
|
||||
return tmedia_defaults_get_noise_supp_enabled();
|
||||
}
|
||||
|
||||
bool MediaSessionMgr::defaultsSetNoiseSuppLevel(int32_t noise_supp_level)
|
||||
{
|
||||
return tmedia_defaults_set_noise_supp_level(noise_supp_level) == 0;
|
||||
}
|
||||
|
||||
int32_t MediaSessionMgr::defaultsGetNoiseSuppLevel()
|
||||
{
|
||||
return tmedia_defaults_get_noise_supp_level();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,25 @@ public:
|
|||
const ProxyPlugin* findProxyPluginProducer(twrap_media_type_t media)const{
|
||||
return this->findProxyPlugin(media, false);
|
||||
}
|
||||
|
||||
// Defaults
|
||||
static bool defaultsSetBandwidthLevel(tmedia_bandwidth_level_t bl);
|
||||
static tmedia_bandwidth_level_t defaultsGetBandwidthLevel();
|
||||
static bool defaultsSetEchoTail(uint32_t echo_tail);
|
||||
static uint32_t defaultsGetEchoTail();
|
||||
static bool defaultsSetEchoSuppEnabled(bool echo_supp_enabled);
|
||||
static bool defaultsGetEchoSuppEnabled();
|
||||
static bool defaultsSetAgcEnabled(bool agc_enabled);
|
||||
static bool defaultsGetAgcEnabled();
|
||||
static bool defaultsSetAgcLevel(float agc_level);
|
||||
static float defaultsGetAgcLevel();
|
||||
static bool defaultsSetVadEnabled(bool vad_enabled);
|
||||
static bool defaultsGetGetVadEnabled();
|
||||
static bool defaultsSetNoiseSuppEnabled(bool noise_supp_enabled);
|
||||
static bool defaultsGetNoiseSuppEnabled();
|
||||
static bool defaultsSetNoiseSuppLevel(int32_t noise_supp_level);
|
||||
static int32_t defaultsGetNoiseSuppLevel();
|
||||
|
||||
|
||||
private:
|
||||
tmedia_session_mgr_t* mgr;
|
||||
|
|
|
@ -46,12 +46,12 @@ typedef struct tdav_speex_denoise_s
|
|||
{
|
||||
TMEDIA_DECLARE_DENOISE;
|
||||
|
||||
SpeexPreprocessState *preprocess_state;
|
||||
SpeexPreprocessState *preprocess_state_record;
|
||||
SpeexPreprocessState *preprocess_state_playback;
|
||||
SpeexEchoState *echo_state;
|
||||
|
||||
spx_int16_t* echo_output_frame;
|
||||
uint32_t frame_size;
|
||||
tsk_bool_t vad_on;
|
||||
}
|
||||
tdav_speex_denoise_t;
|
||||
|
||||
|
|
|
@ -40,12 +40,17 @@ static int tdav_apple_init()
|
|||
return -1;
|
||||
}
|
||||
|
||||
// enable record/playback
|
||||
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
|
||||
status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
|
||||
if(status){
|
||||
TSK_DEBUG_ERROR("AudioSessionSetProperty(kAudioSessionProperty_AudioCategory) failed with status code=%d", (int32_t)status);
|
||||
return -2;
|
||||
}
|
||||
|
||||
// duck other mixable audio
|
||||
// kAudioSessionProperty_OtherMixableAudioShouldDuck
|
||||
|
||||
// enable audio session
|
||||
status = AudioSessionSetActive(true);
|
||||
if(status){
|
||||
|
|
|
@ -174,7 +174,7 @@ tdav_audiounit_handle_t* tdav_audiounit_handle_create(uint64_t session_id, uint3
|
|||
//status = AudioUnitSetProperty(inst->audioUnit, kAUVoiceIOProperty_VoiceProcessingEnableAGC,
|
||||
// kAudioUnitScope_Global, kInputBus, &kOne, sizeof(kOne));
|
||||
//status = AudioUnitSetProperty(inst->audioUnit, kAUVoiceIOProperty_DuckNonVoiceAudio,
|
||||
// kAudioUnitScope_Global, kInputBus, &kOne, sizeof(kOne));
|
||||
// kAudioUnitScope_Global, kInputBus, &kZero, sizeof(kZero));
|
||||
// status = AudioUnitSetProperty(inst->audioUnit, kAUVoiceIOProperty_VoiceProcessingQuality,
|
||||
// kAudioUnitScope_Global, kInputBus, &kVoiceQuality, sizeof(kVoiceQuality));
|
||||
#endif /* TARGET_OS_IPHONE */
|
||||
|
|
|
@ -173,12 +173,13 @@ tsk_size_t tdav_consumer_audio_get(tdav_consumer_audio_t* self, void* out_data,
|
|||
|
||||
tsk_safeobj_unlock(self);
|
||||
|
||||
// Denoise()
|
||||
//if(ret_size == 320){
|
||||
if(ret_size && self->denoise && self->denoise->opened){
|
||||
tmedia_denoise_echo_playback(self->denoise, out_data);
|
||||
}
|
||||
//}
|
||||
// denoiser
|
||||
if(ret_size && self->denoise && self->denoise->opened){
|
||||
// echo playback
|
||||
tmedia_denoise_echo_playback(self->denoise, out_data);
|
||||
// suppress noise
|
||||
tmedia_denoise_process_playback(self->denoise, out_data);
|
||||
}
|
||||
|
||||
return ret_size;
|
||||
}
|
||||
|
|
|
@ -143,8 +143,8 @@ static int tdav_session_audio_producer_enc_cb(const void* callback_data, const v
|
|||
/* Denoise */
|
||||
if(audio->denoise && !audio->denoise->opened){
|
||||
ret = tmedia_denoise_open(audio->denoise,
|
||||
TMEDIA_CODEC_PCM_FRAME_SIZE(audio->encoder.codec), //160 if 20ms at 8khz
|
||||
TMEDIA_CODEC_RATE(audio->encoder.codec), tsk_true, 8000.0f, tsk_true, tsk_false);
|
||||
TMEDIA_CODEC_PCM_FRAME_SIZE(audio->encoder.codec), //160 (shorts) if 20ms at 8khz
|
||||
TMEDIA_CODEC_RATE(audio->encoder.codec));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -168,9 +168,9 @@ static int tdav_session_audio_producer_enc_cb(const void* callback_data, const v
|
|||
// Denoise (VAD, AGC, Noise suppression, ...)
|
||||
if(audio->denoise){
|
||||
tsk_bool_t silence_or_noise = tsk_false;
|
||||
ret = tmedia_denoise_process(TMEDIA_DENOISE(audio->denoise), (void*)buffer, &silence_or_noise);
|
||||
ret = tmedia_denoise_process_record(TMEDIA_DENOISE(audio->denoise), (void*)buffer, &silence_or_noise);
|
||||
if(silence_or_noise && (ret == 0)){
|
||||
//FIXME:
|
||||
//FIXME: Fixed-point implementation don't support VAD
|
||||
TSK_DEBUG_INFO("Silence or Noise buffer");
|
||||
return 0;
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ int tdav_session_audio_start(tmedia_session_t* self)
|
|||
|
||||
/* Denoise (AEC, Noise Suppression, AGC) */
|
||||
if(audio->denoise && audio->encoder.codec){
|
||||
tmedia_denoise_open(audio->denoise, TMEDIA_CODEC_PCM_FRAME_SIZE(audio->encoder.codec), TMEDIA_CODEC_RATE(audio->encoder.codec), tsk_true, 8000.0f, tsk_true, tsk_true);
|
||||
tmedia_denoise_open(audio->denoise, TMEDIA_CODEC_PCM_FRAME_SIZE(audio->encoder.codec), TMEDIA_CODEC_RATE(audio->encoder.codec));
|
||||
}
|
||||
|
||||
/* for test */
|
||||
|
|
|
@ -34,76 +34,74 @@
|
|||
#include "tsk_memory.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
#include "tinymedia/tmedia_defaults.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define ECHO_TAIL 20
|
||||
static int tdav_speex_denoise_set(tmedia_denoise_t* self, const tmedia_param_t* param)
|
||||
{
|
||||
/* tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self; */
|
||||
return tmedia_denoise_set(self, param);
|
||||
}
|
||||
|
||||
int tdav_speex_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate, tsk_bool_t denoise, float agc_level, tsk_bool_t aec, tsk_bool_t vad)
|
||||
static int tdav_speex_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate)
|
||||
{
|
||||
tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
|
||||
float f;
|
||||
int i;
|
||||
|
||||
if(!denoiser->echo_state){
|
||||
if((denoiser->echo_state = speex_echo_state_init(frame_size, ECHO_TAIL*frame_size))){
|
||||
if(!denoiser->echo_state && TMEDIA_DENOISE(denoiser)->echo_supp_enabled){
|
||||
if((denoiser->echo_state = speex_echo_state_init(frame_size, TMEDIA_DENOISE(denoiser)->echo_tail*frame_size))){
|
||||
speex_echo_ctl(denoiser->echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &sampling_rate);
|
||||
}
|
||||
}
|
||||
|
||||
if(!denoiser->preprocess_state){
|
||||
denoiser->vad_on = vad;
|
||||
if(!denoiser->preprocess_state_record && !denoiser->preprocess_state_playback){
|
||||
denoiser->frame_size = frame_size;
|
||||
|
||||
if((denoiser->preprocess_state = speex_preprocess_state_init(frame_size, sampling_rate))){
|
||||
if((denoiser->preprocess_state_record = speex_preprocess_state_init(frame_size, sampling_rate))
|
||||
&& (denoiser->preprocess_state_playback = speex_preprocess_state_init(frame_size, sampling_rate))
|
||||
){
|
||||
|
||||
// Echo suppression
|
||||
if(denoiser->echo_state){
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE, denoiser->echo_state);
|
||||
|
||||
i = -40;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &i);
|
||||
i = -15;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_ECHO_STATE, denoiser->echo_state);
|
||||
|
||||
TSK_FREE(denoiser->echo_output_frame);
|
||||
denoiser->echo_output_frame = tsk_calloc(denoiser->frame_size, sizeof(spx_int16_t));
|
||||
}
|
||||
|
||||
if(denoise){
|
||||
|
||||
// Noise suppression
|
||||
if(TMEDIA_DENOISE(denoiser)->noise_supp_enabled){
|
||||
i = 1;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
i = -30;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_playback, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
i = TMEDIA_DENOISE(denoiser)->noise_supp_level;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_playback, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
|
||||
}
|
||||
else{
|
||||
i = 0;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_playback, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
}
|
||||
|
||||
if(agc_level){
|
||||
// Automatic gain control
|
||||
if(TMEDIA_DENOISE(denoiser)->agc_enabled){
|
||||
i = 1;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &agc_level);
|
||||
//speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC_TARGET, &agc_level);
|
||||
i = 30;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &i);
|
||||
i = 12;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC_INCREMENT, &i);
|
||||
i = -40;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC_DECREMENT, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||
float agc_level = TMEDIA_DENOISE(denoiser)->agc_level;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC_LEVEL, &agc_level);
|
||||
}
|
||||
else{
|
||||
i = 0, f = 8000.0f;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
|
||||
}
|
||||
i = vad ? 1 : 2;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_VAD, &i);
|
||||
//i=1;
|
||||
//speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DEREVERB, &i);
|
||||
//i=1;
|
||||
//speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &i);
|
||||
//i=1;
|
||||
//speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &i);
|
||||
|
||||
// Voice Activity detection
|
||||
i = TMEDIA_DENOISE(denoiser)->vad_enabled ? 1 : 0;
|
||||
speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_VAD, &i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -116,7 +114,7 @@ int tdav_speex_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tdav_speex_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame)
|
||||
static int tdav_speex_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame)
|
||||
{
|
||||
tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
|
||||
if(denoiser->echo_state){
|
||||
|
@ -125,18 +123,20 @@ int tdav_speex_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_fr
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tdav_speex_denoise_process(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise)
|
||||
|
||||
|
||||
static int tdav_speex_denoise_process_record(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise)
|
||||
{
|
||||
tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
|
||||
int vad;
|
||||
|
||||
if(denoiser->preprocess_state){
|
||||
if(denoiser->preprocess_state_record){
|
||||
if(denoiser->echo_state && denoiser->echo_output_frame){
|
||||
speex_echo_capture(denoiser->echo_state, audio_frame, denoiser->echo_output_frame);
|
||||
memcpy(audio_frame, denoiser->echo_output_frame, denoiser->frame_size*sizeof(spx_int16_t));
|
||||
}
|
||||
vad = speex_preprocess_run(denoiser->preprocess_state, audio_frame);
|
||||
if(!vad && denoiser->vad_on){
|
||||
vad = speex_preprocess_run(denoiser->preprocess_state_record, audio_frame);
|
||||
if(!vad && TMEDIA_DENOISE(denoiser)->vad_enabled){
|
||||
*silence_or_noise = tsk_true;
|
||||
}
|
||||
}
|
||||
|
@ -144,13 +144,27 @@ int tdav_speex_denoise_process(tmedia_denoise_t* self, void* audio_frame, tsk_bo
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tdav_speex_denoise_close(tmedia_denoise_t* self)
|
||||
static int tdav_speex_denoise_process_playback(tmedia_denoise_t* self, void* audio_frame)
|
||||
{
|
||||
tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
|
||||
|
||||
if(denoiser->preprocess_state){
|
||||
speex_preprocess_state_destroy(denoiser->preprocess_state);
|
||||
denoiser->preprocess_state = tsk_null;
|
||||
if(denoiser->preprocess_state_playback){
|
||||
speex_preprocess_run(denoiser->preprocess_state_playback, audio_frame);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdav_speex_denoise_close(tmedia_denoise_t* self)
|
||||
{
|
||||
tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
|
||||
|
||||
if(denoiser->preprocess_state_record){
|
||||
speex_preprocess_state_destroy(denoiser->preprocess_state_record);
|
||||
denoiser->preprocess_state_record = tsk_null;
|
||||
}
|
||||
if(denoiser->preprocess_state_playback){
|
||||
speex_preprocess_state_destroy(denoiser->preprocess_state_playback);
|
||||
denoiser->preprocess_state_playback = tsk_null;
|
||||
}
|
||||
if(denoiser->echo_state){
|
||||
speex_echo_state_destroy(denoiser->echo_state);
|
||||
|
@ -186,11 +200,17 @@ static tsk_object_t* tdav_speex_denoise_dtor(tsk_object_t * self)
|
|||
/* deinit base */
|
||||
tmedia_denoise_deinit(TMEDIA_DENOISE(denoise));
|
||||
/* deinit self */
|
||||
if(denoise->preprocess_state){ // already done by close() ...but who know?
|
||||
speex_preprocess_state_destroy(denoise->preprocess_state);
|
||||
if(denoise->preprocess_state_record){
|
||||
speex_preprocess_state_destroy(denoise->preprocess_state_record);
|
||||
denoise->preprocess_state_record = tsk_null;
|
||||
}
|
||||
if(denoise->preprocess_state_playback){
|
||||
speex_preprocess_state_destroy(denoise->preprocess_state_playback);
|
||||
denoise->preprocess_state_playback = tsk_null;
|
||||
}
|
||||
if(denoise->echo_state){
|
||||
speex_echo_state_destroy(denoise->echo_state);
|
||||
denoise->echo_state = tsk_null;
|
||||
}
|
||||
TSK_FREE(denoise->echo_output_frame);
|
||||
}
|
||||
|
@ -212,9 +232,11 @@ static const tmedia_denoise_plugin_def_t tdav_speex_denoise_plugin_def_s =
|
|||
|
||||
"Audio Denoiser based on Speex",
|
||||
|
||||
tdav_speex_denoise_set,
|
||||
tdav_speex_denoise_open,
|
||||
tdav_speex_denoise_echo_playback,
|
||||
tdav_speex_denoise_process,
|
||||
tdav_speex_denoise_process_record,
|
||||
tdav_speex_denoise_process_playback,
|
||||
tdav_speex_denoise_close,
|
||||
};
|
||||
const tmedia_denoise_plugin_def_t *tdav_speex_denoise_plugin_def_t = &tdav_speex_denoise_plugin_def_s;
|
||||
|
|
|
@ -33,12 +33,14 @@
|
|||
#include "tsk_memory.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
#define TDAV_SPEEX_RESAMPLER_MAX_QUALITY 10
|
||||
|
||||
int tdav_speex_resampler_open(tmedia_resampler_t* self, uint32_t in_freq, uint32_t out_freq, tsk_size_t frame_duration, int8_t _channels, uint32_t quality)
|
||||
{
|
||||
tdav_speex_resampler_t *resampler = (tdav_speex_resampler_t *)self;
|
||||
int ret = 0;
|
||||
|
||||
if(!(resampler->state = speex_resampler_init(_channels, in_freq, out_freq, quality>10 ? TMEDIA_RESAMPLER_QUALITY : quality, &ret))){
|
||||
if(!(resampler->state = speex_resampler_init(_channels, in_freq, out_freq, quality>10 ? TDAV_SPEEX_RESAMPLER_MAX_QUALITY : quality, &ret))){
|
||||
TSK_DEBUG_ERROR("speex_resampler_init() returned %d", ret);
|
||||
return -2;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,32 @@
|
|||
|
||||
#include "tmedia_common.h"
|
||||
|
||||
TMEDIA_BEGIN_DECLS
|
||||
|
||||
//
|
||||
// Codecs: Bandwidth
|
||||
//
|
||||
TINYMEDIA_API int tmedia_defaults_set_bl(tmedia_bandwidth_level_t bl);
|
||||
TINYMEDIA_API tmedia_bandwidth_level_t tmedia_defaults_get_bl();
|
||||
|
||||
//
|
||||
// Denoiser: Echo suppression, AEC, Noise redution, AGC, ...
|
||||
//
|
||||
TINYMEDIA_API int tmedia_defaults_set_echo_tail(uint32_t echo_tail);
|
||||
TINYMEDIA_API uint32_t tmedia_defaults_get_echo_tail();
|
||||
TINYMEDIA_API int tmedia_defaults_set_echo_supp_enabled(tsk_bool_t echo_supp_enabled);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_echo_supp_enabled();
|
||||
TINYMEDIA_API int tmedia_defaults_set_agc_enabled(tsk_bool_t agc_enabled);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_agc_enabled();
|
||||
TINYMEDIA_API int tmedia_defaults_set_agc_level(float agc_level);
|
||||
TINYMEDIA_API float tmedia_defaults_get_agc_level();
|
||||
TINYMEDIA_API int tmedia_defaults_set_vad_enabled(tsk_bool_t vad_enabled);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_vad_enabled();
|
||||
TINYMEDIA_API int tmedia_defaults_set_noise_supp_enabled(tsk_bool_t noise_supp_enabled);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_noise_supp_enabled();
|
||||
TINYMEDIA_API int tmedia_defaults_set_noise_supp_level(int32_t noise_supp_level);
|
||||
TINYMEDIA_API int32_t tmedia_defaults_get_noise_supp_level();
|
||||
|
||||
TMEDIA_END_DECLS
|
||||
|
||||
#endif /* TINYMEDIA_DEFAULTS_H */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define TINYMEDIA_DENOISE_H
|
||||
|
||||
#include "tinymedia_config.h"
|
||||
#include "tinymedia/tmedia_params.h"
|
||||
|
||||
#include "tsk_object.h"
|
||||
|
||||
|
@ -43,6 +44,14 @@ typedef struct tmedia_denoise_s
|
|||
TSK_DECLARE_OBJECT;
|
||||
|
||||
tsk_bool_t opened;
|
||||
|
||||
uint32_t echo_tail;
|
||||
tsk_bool_t echo_supp_enabled;
|
||||
tsk_bool_t agc_enabled ;
|
||||
float agc_level;
|
||||
tsk_bool_t vad_enabled;
|
||||
tsk_bool_t noise_supp_enabled;
|
||||
int32_t noise_supp_level;
|
||||
|
||||
const struct tmedia_denoise_plugin_def_s* plugin;
|
||||
}
|
||||
|
@ -59,17 +68,23 @@ typedef struct tmedia_denoise_plugin_def_s
|
|||
//! full description (usefull for debugging)
|
||||
const char* desc;
|
||||
|
||||
int (* open) (tmedia_denoise_t*, uint32_t frame_size, uint32_t sampling_rate, tsk_bool_t denoise, float agc_level, tsk_bool_t aec, tsk_bool_t vad);
|
||||
int (*set) (tmedia_denoise_t* , const tmedia_param_t*);
|
||||
int (* open) (tmedia_denoise_t*, uint32_t frame_size, uint32_t sampling_rate);
|
||||
int (*echo_playback) (tmedia_denoise_t* self, const void* echo_frame);
|
||||
int (* process) (tmedia_denoise_t*, void* audio_frame, tsk_bool_t* silence_or_noise);
|
||||
//! aec, vad, noise suppression, echo cancellation before sending packet over network
|
||||
int (* process_record) (tmedia_denoise_t*, void* audio_frame, tsk_bool_t* silence_or_noise);
|
||||
//! noise suppression before playing sound
|
||||
int (* process_playback) (tmedia_denoise_t*, void* audio_frame);
|
||||
int (* close) (tmedia_denoise_t* );
|
||||
}
|
||||
tmedia_denoise_plugin_def_t;
|
||||
|
||||
TINYMEDIA_API int tmedia_denoise_init(tmedia_denoise_t* self);
|
||||
TINYMEDIA_API int tmedia_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate, tsk_bool_t denoise, float agc_level, tsk_bool_t aec, tsk_bool_t vad);
|
||||
TINYMEDIA_API int tmedia_denoise_set(tmedia_denoise_t* self, const tmedia_param_t* param);
|
||||
TINYMEDIA_API int tmedia_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate);
|
||||
TINYMEDIA_API int tmedia_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame);
|
||||
TINYMEDIA_API int tmedia_denoise_process(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise);
|
||||
TINYMEDIA_API int tmedia_denoise_process_record(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise);
|
||||
TINYMEDIA_API int tmedia_denoise_process_playback(tmedia_denoise_t* self, void* audio_frame);
|
||||
TINYMEDIA_API int tmedia_denoise_close(tmedia_denoise_t* self);
|
||||
TINYMEDIA_API int tmedia_denoise_deinit(tmedia_denoise_t* self);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct tmedia_resampler_plugin_def_s
|
|||
//! full description (usefull for debugging)
|
||||
const char* desc;
|
||||
|
||||
// ! quality is from 0-10
|
||||
int (* open) (tmedia_resampler_t*, uint32_t in_freq, uint32_t out_freq, tsk_size_t frame_duration, int8_t channels, uint32_t quality);
|
||||
tsk_size_t (* process) (tmedia_resampler_t*, const uint16_t* in_data, tsk_size_t in_size, uint16_t* out_data, tsk_size_t out_size);
|
||||
int (* close) (tmedia_resampler_t* );
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
*/
|
||||
#include "tinymedia/tmedia_defaults.h"
|
||||
|
||||
|
||||
//
|
||||
// Codecs: Bandwidth
|
||||
//
|
||||
|
||||
static tmedia_bandwidth_level_t __bl = tmedia_bl_unrestricted;
|
||||
|
||||
int tmedia_defaults_set_bl(tmedia_bandwidth_level_t bl)
|
||||
|
@ -32,4 +37,96 @@ int tmedia_defaults_set_bl(tmedia_bandwidth_level_t bl)
|
|||
tmedia_bandwidth_level_t tmedia_defaults_get_bl()
|
||||
{
|
||||
return __bl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Denoiser: Echo suppression, AEC, Noise redution, AGC, ...
|
||||
//
|
||||
static uint32_t __echo_tail = 20;
|
||||
static tsk_bool_t __echo_supp_enabled;
|
||||
static tsk_bool_t __agc_enabled = tsk_false;
|
||||
static float __agc_level = 8000.0f;
|
||||
static tsk_bool_t __vad_enabled = tsk_false;
|
||||
static tsk_bool_t __noise_supp_enabled = tsk_true;
|
||||
static int32_t __noise_supp_level = -30;
|
||||
|
||||
int tmedia_defaults_set_echo_tail(uint32_t echo_tail)
|
||||
{
|
||||
__echo_tail = echo_tail;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t tmedia_defaults_get_echo_tail()
|
||||
{
|
||||
return __echo_tail;
|
||||
}
|
||||
|
||||
int tmedia_defaults_set_echo_supp_enabled(tsk_bool_t echo_supp_enabled)
|
||||
{
|
||||
__echo_supp_enabled = echo_supp_enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_defaults_get_echo_supp_enabled()
|
||||
{
|
||||
return __echo_supp_enabled;
|
||||
}
|
||||
|
||||
int tmedia_defaults_set_agc_enabled(tsk_bool_t agc_enabled)
|
||||
{
|
||||
__agc_enabled = agc_enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_defaults_get_agc_enabled()
|
||||
{
|
||||
return __agc_enabled;
|
||||
}
|
||||
|
||||
int tmedia_defaults_set_agc_level(float agc_level)
|
||||
{
|
||||
return __agc_level = agc_level;
|
||||
}
|
||||
|
||||
float tmedia_defaults_get_agc_level()
|
||||
{
|
||||
return __agc_level;
|
||||
}
|
||||
|
||||
int tmedia_defaults_set_vad_enabled(tsk_bool_t vad_enabled)
|
||||
{
|
||||
__vad_enabled = vad_enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_defaults_get_vad_enabled()
|
||||
{
|
||||
return __vad_enabled;
|
||||
}
|
||||
|
||||
int tmedia_defaults_set_noise_supp_enabled(tsk_bool_t noise_supp_enabled)
|
||||
{
|
||||
__noise_supp_enabled = noise_supp_enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_defaults_get_noise_supp_enabled()
|
||||
{
|
||||
return __noise_supp_enabled;
|
||||
}
|
||||
|
||||
int tmedia_defaults_set_noise_supp_level(int32_t noise_supp_level)
|
||||
{
|
||||
__noise_supp_level = noise_supp_level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tmedia_defaults_get_noise_supp_level()
|
||||
{
|
||||
return __noise_supp_level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
*/
|
||||
#include "tinymedia/tmedia_denoise.h"
|
||||
#include "tinymedia/tmedia_defaults.h"
|
||||
|
||||
#include "tsk_debug.h"
|
||||
|
||||
|
@ -40,10 +41,35 @@ int tmedia_denoise_init(tmedia_denoise_t* self)
|
|||
return -1;
|
||||
}
|
||||
|
||||
self->echo_tail = tmedia_defaults_get_echo_tail();
|
||||
self->echo_supp_enabled = tmedia_defaults_get_echo_supp_enabled();
|
||||
self->agc_enabled = tmedia_defaults_get_agc_enabled();
|
||||
self->agc_level = tmedia_defaults_get_agc_level();
|
||||
self->vad_enabled = tmedia_defaults_get_vad_enabled();
|
||||
self->noise_supp_enabled = tmedia_defaults_get_noise_supp_enabled();
|
||||
self->noise_supp_level = tmedia_defaults_get_noise_supp_level();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate, tsk_bool_t denoise, float agc_level, tsk_bool_t aec, tsk_bool_t vad)
|
||||
int tmedia_denoise_set(tmedia_denoise_t* self, const tmedia_param_t* param)
|
||||
{
|
||||
if(!self || !self->plugin){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(self->plugin->set){
|
||||
|
||||
// FIXME: to be implemnted
|
||||
TSK_DEBUG_ERROR("Not implemented");
|
||||
|
||||
return self->plugin->set(self, param);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate)
|
||||
{
|
||||
if(!self || !self->plugin){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
|
@ -56,7 +82,7 @@ int tmedia_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sa
|
|||
|
||||
if(self->plugin->open){
|
||||
int ret;
|
||||
if((ret = self->plugin->open(self, frame_size, sampling_rate, denoise, agc_level, aec, vad))){
|
||||
if((ret = self->plugin->open(self, frame_size, sampling_rate))){
|
||||
TSK_DEBUG_ERROR("Failed to open [%s] denoiser", self->plugin->desc);
|
||||
return ret;
|
||||
}
|
||||
|
@ -83,7 +109,7 @@ int tmedia_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame)
|
|||
return -2;
|
||||
}
|
||||
|
||||
if(self->plugin->process){
|
||||
if(self->plugin->echo_playback){
|
||||
return self->plugin->echo_playback(self, echo_frame);
|
||||
}
|
||||
else{
|
||||
|
@ -91,8 +117,7 @@ int tmedia_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int tmedia_denoise_process(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise)
|
||||
int tmedia_denoise_process_record(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise)
|
||||
{
|
||||
if(!self || !self->plugin || !silence_or_noise){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
|
@ -104,8 +129,8 @@ int tmedia_denoise_process(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t
|
|||
return -2;
|
||||
}
|
||||
|
||||
if(self->plugin->process){
|
||||
return self->plugin->process(self, audio_frame, silence_or_noise);
|
||||
if(self->plugin->process_record){
|
||||
return self->plugin->process_record(self, audio_frame, silence_or_noise);
|
||||
}
|
||||
else{
|
||||
*silence_or_noise = tsk_false;
|
||||
|
@ -113,6 +138,24 @@ int tmedia_denoise_process(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t
|
|||
}
|
||||
}
|
||||
|
||||
int tmedia_denoise_process_playback(tmedia_denoise_t* self, void* audio_frame)
|
||||
{
|
||||
if(!self || !self->plugin){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!self->opened){
|
||||
TSK_DEBUG_ERROR("Denoiser not opened");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(self->plugin->process_playback){
|
||||
return self->plugin->process_playback(self, audio_frame);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_denoise_close(tmedia_denoise_t* self)
|
||||
{
|
||||
if(!self || !self->plugin){
|
||||
|
|
Loading…
Reference in New Issue