Enhance audio quality by adding support for AEC, VAD, AGC and Noise suppression.

This commit is contained in:
bossiel 2010-07-01 01:33:39 +00:00
parent 5570d41320
commit 106fc9f42e
28 changed files with 713 additions and 31 deletions

View File

@ -2,7 +2,7 @@
## Root configuration file shared by all android projects.
######
export ANDROID_NDK_ROOT=/cygdrive/c/android-ndk-r3
export ANDROID_NDK_ROOT=/cygdrive/c/android-ndk-r4
export ANDROID_SDK_ROOT=/cygdrive/c/android-sdk
export ANDROID_PLATFORM=android-3
export ANDROID_HOST=windows

View File

@ -0,0 +1,44 @@
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
* Version 1.3.39
*
* Do not make changes to this file unless you know what you are doing--modify
* the SWIG interface file instead.
* ----------------------------------------------------------------------------- */
package org.doubango.tinyWRAP;
public class ProxyVideoFrame {
private long swigCPtr;
protected boolean swigCMemOwn;
protected ProxyVideoFrame(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(ProxyVideoFrame obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if(swigCPtr != 0 && swigCMemOwn) {
swigCMemOwn = false;
tinyWRAPJNI.delete_ProxyVideoFrame(swigCPtr);
}
swigCPtr = 0;
}
public long getSize() {
return tinyWRAPJNI.ProxyVideoFrame_getSize(swigCPtr, this);
}
public long getContent(java.nio.ByteBuffer output, long maxsize) {
return tinyWRAPJNI.ProxyVideoFrame_getContent(swigCPtr, this, output, maxsize);
}
}

View File

@ -1,8 +1,6 @@
#!/bin/bash
# Build tinyWRAP for Google Android Systems
export CFLAGS="-O3 $CFLAGS"
for project in tinySAK tinyNET tinyIPSec tinySMS tinyHTTP tinySIGCOMP tinySDP tinyRTP tinyMEDIA tinyDAV tinySIP
do
echo -e building "$project....\n"

View File

@ -4,8 +4,14 @@ CFLAGS := $(CFLAGS_LIB) -fno-rtti -fno-exceptions -I../../_common -I../../. -I..
-I../../../tinySDP/include -I../../../tinyMEDIA/include -I../../../tinyDAV/include -I../../../tinySIP/include
# Because of the static build, you need all librarires
FFMPEG_LDFLAGS := -L../../../thirdparties/android/lib -lavutil -lswscale -lavcodec -lgcc
LDFLAGS := $(LDFLAGS_LIB) $(FFMPEG_LDFLAGS) -lstdc++ -llog -ltinySAK -ltinyHTTP -ltinyIPSec -ltinySIGCOMP -ltinyNET -ltinySDP -ltinyRTP -ltinyMEDIA -ltinyDAV -ltinySIP -lm
THIRDPARTIES_LIB := ../../../thirdparties/android/lib
FFMPEG_LDFLAGS := -lavutil -lswscale -lavcodec -lx264
SPEEX_LDFLAGS := -lspeexdsp
LDFLAGS := $(LDFLAGS_LIB) -L$(THIRDPARTIES_LIB) $(FFMPEG_LDFLAGS) $(SPEEX_LDFLAGS) \
-ltinySAK -ltinyHTTP -ltinyIPSec -ltinySIGCOMP -ltinyNET -ltinySDP -ltinyRTP -ltinyMEDIA -ltinyDAV -ltinySIP \
-lm -lstdc++ -llog -lgcc

View File

@ -1,10 +1,16 @@
APP := lib$(PROJECT).$(EXT)
FFMPEG_CFLAGS := -I../thirdparties/android/include -DHAVE_FFMPEG=1
FFMPEG_LDFLAGS := -L../thirdparties/android/lib -lavutil -lswscale -lavcodec -lx264 -lgcc
THIRDPARTIES_INC := ../thirdparties/android/include
THIRDPARTIES_LIB := ../thirdparties/android/lib
CFLAGS := $(CFLAGS_LIB) $(FFMPEG_CFLAGS) -I../tinySAK/src -I../tinyNET/src -I../tinySDP/include -I../tinyRTP/include -I../tinyMEDIA/include -I./include
LDFLAGS := $(LDFLAGS_LIB) -lm $(FFMPEG_LDFLAGS) -ltinySAK -ltinyNET -ltinySDP -ltinyRTP -ltinyMEDIA
FFMPEG_CFLAGS := -DHAVE_FFMPEG=1
FFMPEG_LDFLAGS := -lavutil -lswscale -lavcodec -lx264
SPEEX_CFLAGS := -DHAVE_SPEEX_DSP
SPEEX_LDFLAGS := -lspeexdsp
CFLAGS := $(CFLAGS_LIB) -I$(THIRDPARTIES_INC) $(FFMPEG_CFLAGS) $(SPEEX_CFLAGS) -I../tinySAK/src -I../tinyNET/src -I../tinySDP/include -I../tinyRTP/include -I../tinyMEDIA/include -I./include
LDFLAGS := $(LDFLAGS_LIB) -L$(THIRDPARTIES_LIB) $(FFMPEG_LDFLAGS) $(SPEEX_LDFLAGS) -ltinySAK -ltinyNET -ltinySDP -ltinyRTP -ltinyMEDIA -lm -lgcc
all: $(APP)
@ -15,7 +21,8 @@ OBJS = \
OBJS += src/audio/tdav_consumer_audio.o \
src/audio/tdav_jitterbuffer.o \
src/audio/tdav_producer_audio.o \
src/audio/tdav_session_audio.o
src/audio/tdav_session_audio.o \
src/audio/tdav_speex_denoise.o
### video
OBJS += src/video/tdav_converter_video.o \
@ -26,7 +33,7 @@ OBJS += src/video/tdav_converter_video.o \
OBJS += src/msrp/tdav_consumer_msrp.o \
src/msrp/tdav_producer_msrp.o \
src/msrp/tdav_session_msrp.o
### codecs (G.711)
OBJS += src/codecs/g711/g711.o \
@ -44,7 +51,7 @@ OBJS += src/codecs/h263/tdav_codec_h263.o
### codecs (H.264)
OBJS += src/codecs/h264/tdav_codec_h264.o
### codecs (MSRP)
### codecs (MSRP)
OBJS += src/codecs/msrp/tdav_codec_msrp.o

View File

@ -67,6 +67,7 @@ typedef struct tdav_session_audio_s
struct tmedia_consumer_s* consumer;
struct tmedia_producer_s* producer;
struct tmedia_denoise_s* denoise;
tdav_session_audio_dtmfe_L_t* dtmf_events;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tdav_speex_denoise.h
* @brief Speex Denoiser (Noise suppression, AGC, AEC) Plugin
*
* @author Mamadou Diop <diopmamadou(at)doubango.org>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#ifndef TINYDAV_SPEEX_DENOISE_H
#define TINYDAV_SPEEX_DENOISE_H
#include "tinydav_config.h"
#if HAVE_SPEEX_DSP
#include "tinymedia/tmedia_denoise.h"
#include <speex/speex_preprocess.h>
#include <speex/speex_echo.h>
TDAV_BEGIN_DECLS
/** Speex denoiser*/
typedef struct tdav_speex_denoise_s
{
TMEDIA_DECLARE_DENOISE;
SpeexPreprocessState *preprocess_state;
SpeexEchoState *echo_state;
spx_int16_t* echo_output_frame;
uint32_t frame_size;
tsk_bool_t vad_on;
}
tdav_speex_denoise_t;
const tmedia_denoise_plugin_def_t *tdav_speex_denoise_plugin_def_t;
TDAV_END_DECLS
#endif /* #if HAVE_SPEEX_DSP */
#endif /* TINYDAV_SPEEX_DENOISE_H */

View File

@ -29,6 +29,7 @@
*/
#include "tinydav/audio/tdav_session_audio.h"
#include "tinymedia/tmedia_denoise.h"
#include "tinymedia/tmedia_consumer.h"
#include "tinymedia/tmedia_producer.h"
@ -87,6 +88,10 @@ static int tdav_session_audio_rtp_cb(const void* callback_data, const struct trt
// Decode data
out_size = codec->plugin->decode(codec, packet->payload.data, packet->payload.size, &out_data, packet->header);
if(out_size){
// Denoise (VAD, AGC, Noise suppression, ...)
if(audio->denoise && TMEDIA_DENOISE(audio->denoise)->opened){
tmedia_denoise_echo_playback(TMEDIA_DENOISE(audio->denoise), out_data);
}
tmedia_consumer_consume(audio->consumer, &out_data, out_size, packet->header);
}
TSK_FREE(out_data);
@ -98,6 +103,8 @@ static int tdav_session_audio_rtp_cb(const void* callback_data, const struct trt
// Producer callback (From the producer to the network)
static int tdav_session_audio_producer_cb(const void* callback_data, const void* buffer, tsk_size_t size)
{
int ret;
tdav_session_audio_t* audio = (tdav_session_audio_t*)callback_data;
if(audio->rtp_manager){
@ -105,6 +112,8 @@ static int tdav_session_audio_producer_cb(const void* callback_data, const void*
void* out_data = tsk_null;
tsk_size_t out_size = 0;
ret = 0;
//
// Find Encoder (call one time)
//
@ -115,6 +124,10 @@ static int tdav_session_audio_producer_cb(const void* callback_data, const void*
!tsk_striequals(TMEDIA_CODEC(item->data)->format, TMEDIA_CODEC_FORMAT_DTMF)){
audio->encoder = tsk_object_ref(item->data);
trtp_manager_set_payload_type(audio->rtp_manager, audio->encoder->neg_format ? atoi(audio->encoder->neg_format) : atoi(audio->encoder->format));
/* Denoise */
if(audio->denoise && !audio->denoise->opened){
ret = tmedia_denoise_open(audio->denoise, TMEDIA_CODEC_FRAME_SIZE(audio->encoder), TMEDIA_CODEC_RATE(audio->encoder), tsk_true, 8000.0f, tsk_true, tsk_true);
}
break;
}
}
@ -129,15 +142,31 @@ static int tdav_session_audio_producer_cb(const void* callback_data, const void*
TSK_DEBUG_ERROR("Failed to open [%s] codec", audio->encoder->plugin->desc);
return -4;
}
// 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);
if(silence_or_noise && (ret == 0)){
TSK_DEBUG_INFO("Silence or Noise buffer");
return 0;
}
}
// Encode data
out_size = audio->encoder->plugin->encode(audio->encoder, buffer, size, &out_data);
if(out_size){
trtp_manager_send_rtp(audio->rtp_manager, out_data, out_size, (20*audio->encoder->plugin->rate)/1000/*FIXME*/, tsk_false);
if((audio->encoder = tsk_object_ref(audio->encoder))){ /* Thread safeness (SIP reINVITE or UPDATE could update the encoder) */
out_size = audio->encoder->plugin->encode(audio->encoder, buffer, size, &out_data);
if(out_size){
ret = trtp_manager_send_rtp(audio->rtp_manager, out_data, out_size, (20*audio->encoder->plugin->rate)/1000/*FIXME*/, tsk_false);
}
tsk_object_unref(audio->encoder);
}
else{
TSK_DEBUG_WARN("No encoder");
}
TSK_FREE(out_data);
}
return 0;
return ret;
}
@ -230,6 +259,10 @@ int tdav_session_audio_start(tmedia_session_t* self)
tmedia_producer_prepare(audio->producer, codec);
tmedia_producer_start(audio->producer);
}
/* Denoise (AEC, Noise Suppression, AGC) */
if(audio->denoise && audio->encoder){
tmedia_denoise_open(audio->denoise, TMEDIA_CODEC_FRAME_SIZE(audio->encoder), TMEDIA_CODEC_RATE(audio->encoder), tsk_true, 8000.0f, tsk_true, tsk_true);
}
/* for test */
//trtp_manager_send_rtp(audio->rtp_manager, "test", 4, tsk_true);
@ -652,15 +685,18 @@ static tsk_object_t* tdav_session_audio_ctor(tsk_object_t * self, va_list * app)
if(session){
/* init base: called by tmedia_session_create() */
/* init self */
if(!(session->consumer = tmedia_consumer_create(tdav_session_audio_plugin_def_t->type))){
if(!(session->consumer = tmedia_consumer_create(tmedia_audio))){
TSK_DEBUG_ERROR("Failed to create Audio consumer");
}
if((session->producer = tmedia_producer_create(tdav_session_audio_plugin_def_t->type))){
if((session->producer = tmedia_producer_create(tmedia_audio))){
tmedia_producer_set_callback(session->producer, tdav_session_audio_producer_cb, self);
}
else{
TSK_DEBUG_ERROR("Failed to create Audio producer");
}
if(!(session->denoise = tmedia_denoise_create())){
TSK_DEBUG_WARN("No Audio denoiser found");
}
}
return self;
}
@ -696,6 +732,7 @@ static tsk_object_t* tdav_session_audio_dtor(tsk_object_t * self)
TSK_FREE(session->remote_ip);
TSK_FREE(session->local_ip);
TSK_OBJECT_SAFE_FREE(session->encoder);
TSK_OBJECT_SAFE_FREE(session->denoise);
/* deinit base */
tmedia_session_deinit(self);

View File

@ -0,0 +1,208 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tdav_speex_denoise.c
* @brief Speex Denoiser (Noise suppression, AGC, AEC) Plugin
*
* @author Mamadou Diop <diopmamadou(at)doubango.org>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#include "tinydav/audio/tdav_speex_denoise.h"
#if HAVE_SPEEX_DSP
#include "tsk_memory.h"
#include "tsk_debug.h"
#define ECHO_TAIL 20
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)
{
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, 1200/*(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;
denoiser->frame_size = frame_size;
if((denoiser->preprocess_state = speex_preprocess_state_init(frame_size, sampling_rate))){
if(denoiser->echo_state){
speex_preprocess_ctl(denoiser->preprocess_state, 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){
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);
}
else{
i = 0;
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DENOISE, &i);
}
if(agc_level){
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);
}
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);
}
i = vad ? 1 : 2;
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_VAD, &i);
i=0;
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DEREVERB, &i);
f=.0;
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
f=.0;
speex_preprocess_ctl(denoiser->preprocess_state, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
return 0;
}
else{
TSK_DEBUG_ERROR("Failed to create Speex preprocessor state");
return -2;
}
}
return 0;
}
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){
speex_echo_playback(denoiser->echo_state, echo_frame);
}
return 0;
}
int tdav_speex_denoise_process(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->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){
*silence_or_noise = tsk_true;
}
}
return 0;
}
int tdav_speex_denoise_close(tmedia_denoise_t* self)
{
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->echo_state){
speex_echo_state_destroy(denoiser->echo_state);
denoiser->echo_state = tsk_null;
}
TSK_FREE(denoiser->echo_output_frame);
return 0;
}
//
// Speex denoiser Plugin definition
//
/* constructor */
static tsk_object_t* tdav_speex_denoise_ctor(tsk_object_t * self, va_list * app)
{
tdav_speex_denoise_t *denoise = self;
if(denoise){
/* init base */
tmedia_denoise_init(TMEDIA_DENOISE(denoise));
/* init self */
}
return self;
}
/* destructor */
static tsk_object_t* tdav_speex_denoise_dtor(tsk_object_t * self)
{
tdav_speex_denoise_t *denoise = self;
if(denoise){
/* 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->echo_state){
speex_echo_state_destroy(denoise->echo_state);
}
TSK_FREE(denoise->echo_output_frame);
}
return self;
}
/* object definition */
static const tsk_object_def_t tdav_speex_denoise_def_s =
{
sizeof(tdav_speex_denoise_t),
tdav_speex_denoise_ctor,
tdav_speex_denoise_dtor,
tsk_null,
};
/* plugin definition*/
static const tmedia_denoise_plugin_def_t tdav_speex_denoise_plugin_def_s =
{
&tdav_speex_denoise_def_s,
"Audio Denoiser based on Speex",
tdav_speex_denoise_open,
tdav_speex_denoise_echo_playback,
tdav_speex_denoise_process,
tdav_speex_denoise_close,
};
const tmedia_denoise_plugin_def_t *tdav_speex_denoise_plugin_def_t = &tdav_speex_denoise_plugin_def_s;
#endif /* HAVE_SPEEX_DSP */

View File

@ -145,7 +145,8 @@ static const tmedia_codec_plugin_def_t tdav_codec_g711u_plugin_def_s =
8000, // rate
{ /* audio */
1 // channels
1, // channels
20 // ptime
},
/* video */
@ -182,7 +183,7 @@ tsk_size_t tdav_codec_g711a_encode(tmedia_codec_t* self, const void* in_data, ts
}
/* allocate new buffer */
if(!(*out_data = tsk_calloc(in_size/2, sizeof(uint8_t)))){
if(!(*out_data = tsk_calloc(in_size/2, 1))){
TSK_DEBUG_ERROR("Failed to allocate new buffer");
return 0;
}
@ -289,7 +290,8 @@ static const tmedia_codec_plugin_def_t tdav_codec_g711a_plugin_def_s =
8000, // rate
{ /* audio */
1 // channels
1, // channels
20, // ptime
},
/* video */

View File

@ -39,8 +39,6 @@
#include "tinydav/codecs/g711/tdav_codec_g711.h"
#include "tinydav/codecs/h263/tdav_codec_h263.h"
// Consumers
#include "tinydav/audio/waveapi/tdav_consumer_waveapi.h"
#include "tinydav/audio/directsound/tdav_consumer_dsound.h"
@ -57,6 +55,11 @@
# include "tinydshow/plugin/DSProducer.h"
#endif
// Audio Denoise (AGC, Noise Suppression, VAD and AEC)
#if HAVE_SPEEX_DSP
#include "tinydav/audio/tdav_speex_denoise.h"
#endif
#if HAVE_FFMPEG
# include <libavcodec/avcodec.h>
#endif
@ -117,6 +120,11 @@ int tdav_init()
tmedia_producer_plugin_register(tdshow_producer_plugin_def_t);
#endif
/* === Register Audio Denoise (AGC, VAD, Noise Suppression and AEC) === */
#if HAVE_SPEEX_DSP
tmedia_denoise_plugin_register(tdav_speex_denoise_plugin_def_t);
#endif
return 0;
}
@ -168,5 +176,10 @@ int tdav_deinit()
tmedia_consumer_plugin_unregister(tmedia_consumer_oss_plugin_def_t);
#endif
/* === UnRegister Audio Denoise (AGC, VAD, Noise Suppression and AEC) === */
#if HAVE_SPEEX_DSP
tmedia_denoise_plugin_unregister(tdav_speex_denoise_plugin_def_t);
#endif
return 0;
}

View File

@ -73,7 +73,7 @@ void test_sessions_client()
const tsdp_message_t* sdp_lo;
tsdp_message_t* sdp_ro;
char* temp;
tmedia_type_t type = tmedia_audio | tmedia_video;
tmedia_type_t type = tmedia_audio /*| tmedia_video*/;
mgr = tmedia_session_mgr_create(type,
"0.0.0.0", tsk_false, tsk_true/* offerer */);

View File

@ -42,7 +42,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(PSDK_DIR)include&quot;;&quot;$(DXSDK_DIR)include&quot;;..\thirdparties\win32\include;include;..\tinyRTP\include;..\tinyMEDIA\include;..\tinySDP\include;..\tinyNET\src;..\tinyDSHOW\include;..\tinySAK\src"
PreprocessorDefinitions="HAVE_TINYDSHOW=1;HAVE_DSOUND_H=1;HAVE_FFMPEG=1;DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0501;TINYDAV_EXPORTS"
PreprocessorDefinitions="HAVE_TINYDSHOW=1;HAVE_DSOUND_H=1;HAVE_FFMPEG=1;HAVE_SPEEX_DSP=1;DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0501;TINYDAV_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@ -64,8 +64,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Winmm.lib $(OutDir)\tinySAK.lib $(OutDir)\tinyNET.lib $(OutDir)\tinyRTP.lib $(OutDir)\tinySDP.lib $(OutDir)\tinyMEDIA.lib $(OutDir)\tinyDSHOW.lib ..\thirdparties\win32\lib\libgcc.a ..\thirdparties\win32\lib\libmingwex.a &quot;..\thirdparties\win32\lib\ffmpeg\libavcodec.a&quot; &quot;..\thirdparties\win32\lib\ffmpeg\libavutil.a&quot; &quot;..\thirdparties\win32\lib\ffmpeg\libswscale.a&quot; &quot;..\thirdparties\win32\lib\ffmpeg\libx264.a&quot;"
AdditionalDependencies="Winmm.lib $(OutDir)\tinySAK.lib $(OutDir)\tinyNET.lib $(OutDir)\tinyRTP.lib $(OutDir)\tinySDP.lib $(OutDir)\tinyMEDIA.lib $(OutDir)\tinyDSHOW.lib &quot;..\thirdparties\win32\lib\speex\libspeexdsp.a&quot; ..\thirdparties\win32\lib\libgcc.a ..\thirdparties\win32\lib\libmingwex.a &quot;..\thirdparties\win32\lib\ffmpeg\libavcodec.a&quot; &quot;..\thirdparties\win32\lib\ffmpeg\libavutil.a&quot; &quot;..\thirdparties\win32\lib\ffmpeg\libswscale.a&quot; &quot;..\thirdparties\win32\lib\ffmpeg\libx264.a&quot;"
LinkIncremental="2"
IgnoreDefaultLibraryNames=""
GenerateDebugInformation="true"
SubSystem="2"
RandomizedBaseAddress="1"
@ -296,6 +297,10 @@
RelativePath=".\include\tinydav\audio\tdav_session_audio.h"
>
</File>
<File
RelativePath=".\include\tinydav\audio\tdav_speex_denoise.h"
>
</File>
<Filter
Name="android"
>
@ -496,6 +501,10 @@
RelativePath=".\src\audio\tdav_session_audio.c"
>
</File>
<File
RelativePath=".\src\audio\tdav_speex_denoise.c"
>
</File>
<Filter
Name="android"
>

View File

@ -11,6 +11,7 @@ OBJS = \
src/tmedia_codec_dummy.o \
src/tmedia_common.o \
src/tmedia_consumer.o \
src/tmedia_denoise.o \
src/tmedia_params.o \
src/tmedia_producer.o \
src/tmedia_qos.o \

View File

@ -113,6 +113,9 @@ TMEDIA_BEGIN_DECLS
/** cast any pointer to @ref tmedia_codec_t* object */
#define TMEDIA_CODEC(self) ((tmedia_codec_t*)(self))
#define TMEDIA_CODEC_FRAME_SIZE(self) ((TMEDIA_CODEC((self))->plugin->audio.ptime * TMEDIA_CODEC((self))->plugin->rate)/1000)
#define TMEDIA_CODEC_RATE(self) (TMEDIA_CODEC((self))->plugin->rate)
/** callback for video codecs */
typedef int (*tmedia_codec_video_rtpcb_f)(const void* callback_data, const void* buffer, tsk_size_t size, uint32_t duration, tsk_bool_t marker);
@ -161,6 +164,7 @@ typedef struct tmedia_codec_plugin_def_s
/* default values could be updated at any time */
struct{
int8_t channels;
uint8_t ptime;
/* ...to be continued */
} audio;
@ -171,7 +175,7 @@ typedef struct tmedia_codec_plugin_def_s
unsigned fps;
/* ...to be continued */
} video;
//! open the codec
int (*open) (tmedia_codec_t*);
//! close the codec

View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tmedia_denoise.h
* @brief Denoiser (Noise suppression, AGC, AEC, VAD) Plugin
*
* @author Mamadou Diop <diopmamadou(at)doubango.org>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#ifndef TINYMEDIA_DENOISE_H
#define TINYMEDIA_DENOISE_H
#include "tinymedia_config.h"
#include "tsk_object.h"
TMEDIA_BEGIN_DECLS
/** cast any pointer to @ref tmedia_denoise_t* object */
#define TMEDIA_DENOISE(self) ((tmedia_denoise_t*)(self))
/** Base object for all Denoisers */
typedef struct tmedia_denoise_s
{
TSK_DECLARE_OBJECT;
tsk_bool_t opened;
const struct tmedia_denoise_plugin_def_s* plugin;
}
tmedia_denoise_t;
#define TMEDIA_DECLARE_DENOISE tmedia_denoise_t __denoise__
/** Virtual table used to define a consumer plugin */
typedef struct tmedia_denoise_plugin_def_s
{
//! object definition used to create an instance of the denoiser
const tsk_object_def_t* objdef;
//! 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 (*echo_playback) (tmedia_denoise_t* self, const void* echo_frame);
int (* process) (tmedia_denoise_t*, void* audio_frame, tsk_bool_t* silence_or_noise);
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_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_close(tmedia_denoise_t* self);
TINYMEDIA_API int tmedia_denoise_deinit(tmedia_denoise_t* self);
TINYMEDIA_API int tmedia_denoise_plugin_register(const tmedia_denoise_plugin_def_t* plugin);
TINYMEDIA_API int tmedia_denoise_plugin_unregister();
TINYMEDIA_API tmedia_denoise_t* tmedia_denoise_create();
TMEDIA_END_DECLS
#endif /* TINYMEDIA_DENOISE_H */

View File

@ -537,11 +537,11 @@ int tmedia_codec_parse_fmtp(const char* fmtp, unsigned* maxbr, unsigned* fps, un
// to be continued
if(found){
found = tsk_false;
//found = tsk_false;
pch = strtok(tsk_null, "; ");
while(pch){
if(sscanf(pch, "MaxBR=%u", maxbr) == 1){
found = tsk_true;
//found = tsk_true;
break;
}
pch = strtok(tsk_null, "; /");

View File

@ -88,7 +88,8 @@ static const tmedia_codec_plugin_def_t tmedia_codec_dpcmu_plugin_def_s =
8000, // rate
{ /* audio */
1 // channels
1, // channels
20 // ptime
},
/* video */
@ -161,7 +162,8 @@ static const tmedia_codec_plugin_def_t tmedia_codec_dpcma_plugin_def_s =
8000, // rate
{ /* audio */
1 // channels
1, // channels
20 // ptime
},
/* video */

View File

@ -0,0 +1,185 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tmedia_denoise.c
* @brief Denoiser (Noise suppression, AGC, AEC, VAD) Plugin
*
* @author Mamadou Diop <diopmamadou(at)doubango.org>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#include "tinymedia/tmedia_denoise.h"
#include "tsk_debug.h"
static const tmedia_denoise_plugin_def_t* __tmedia_denoise_plugin = tsk_null;
int tmedia_denoise_init(tmedia_denoise_t* self)
{
if(!self){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
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)
{
if(!self || !self->plugin){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(self->opened){
TSK_DEBUG_WARN("Denoiser already opened");
return 0;
}
if(self->plugin->open){
int ret;
if((ret = self->plugin->open(self, frame_size, sampling_rate, denoise, agc_level, aec, vad))){
TSK_DEBUG_ERROR("Failed to open [%s] denoiser", self->plugin->desc);
return ret;
}
else{
self->opened = tsk_true;
return 0;
}
}
else{
self->opened = tsk_true;
return 0;
}
}
int tmedia_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_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){
return self->plugin->echo_playback(self, echo_frame);
}
else{
return 0;
}
}
int tmedia_denoise_process(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");
return -1;
}
if(!self->opened){
TSK_DEBUG_ERROR("Denoiser not opened");
return -2;
}
if(self->plugin->process){
return self->plugin->process(self, audio_frame, silence_or_noise);
}
else{
*silence_or_noise = tsk_false;
return 0;
}
}
int tmedia_denoise_close(tmedia_denoise_t* self)
{
if(!self || !self->plugin){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(!self->opened){
TSK_DEBUG_WARN("Denoiser not opened");
return 0;
}
if(self->plugin->close){
int ret;
if((ret = self->plugin->close(self))){
TSK_DEBUG_ERROR("Failed to close [%s] denoiser", self->plugin->desc);
return ret;
}
else{
self->opened = tsk_false;
return 0;
}
}
else{
self->opened = tsk_false;
return 0;
}
}
int tmedia_denoise_deinit(tmedia_denoise_t* self)
{
if(!self){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(self->opened){
tmedia_denoise_close(self);
}
return 0;
}
int tmedia_denoise_plugin_register(const tmedia_denoise_plugin_def_t* plugin)
{
if(!plugin){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
__tmedia_denoise_plugin = plugin;
return 0;
}
int tmedia_denoise_plugin_unregister()
{
__tmedia_denoise_plugin = tsk_null;
return 0;
}
tmedia_denoise_t* tmedia_denoise_create()
{
tmedia_denoise_t* denoise = tsk_null;
if(__tmedia_denoise_plugin){
if((denoise = tsk_object_new(__tmedia_denoise_plugin->objdef))){
denoise->plugin = __tmedia_denoise_plugin;
}
}
return denoise;
}

View File

View File

@ -206,6 +206,10 @@
RelativePath=".\include\tinymedia\tmedia_consumer.h"
>
</File>
<File
RelativePath=".\include\tinymedia\tmedia_denoise.h"
>
</File>
<File
RelativePath=".\include\tinymedia\tmedia_params.h"
>
@ -230,6 +234,10 @@
RelativePath=".\include\tinymedia\tmedia_session_ghost.h"
>
</File>
<File
RelativePath=".\include\tinymedia\tmedia_vad.h"
>
</File>
</Filter>
<Filter
Name="source(*.c)"
@ -256,6 +264,10 @@
RelativePath=".\src\tmedia_consumer.c"
>
</File>
<File
RelativePath=".\src\tmedia_denoise.c"
>
</File>
<File
RelativePath=".\src\tmedia_params.c"
>
@ -280,6 +292,10 @@
RelativePath=".\src\tmedia_session_ghost.c"
>
</File>
<File
RelativePath=".\src\tmedia_vad.c"
>
</File>
</Filter>
</Files>
<Globals>