Add support for Noise suppression on iOS

This commit is contained in:
bossiel 2011-06-03 21:28:04 +00:00
parent 6faba0e4f5
commit a62a9b2ada
14 changed files with 392 additions and 78 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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;

View File

@ -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){

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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* );

View File

@ -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;
}

View File

@ -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){