From: <sb...@us...> - 2007-09-18 17:56:06
|
Revision: 1140 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1140&view=rev Author: sbalea Date: 2007-09-18 10:55:59 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Move echo cancellation in audio_encode Remove references to SPAN or MEC echo canceller Switch to the new speex 1.2beta2 echo can API Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/audio_encode.h branches/team/mihai/echocan/lib/audio_portaudio.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-14 18:22:02 UTC (rev 1139) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:55:59 UTC (rev 1140) @@ -14,6 +14,7 @@ * the GNU Lesser (Library) General Public License. */ +#include "audio_encode.h" #include "iaxclient_lib.h" #include "iax-client.h" #ifdef CODEC_GSM @@ -24,6 +25,11 @@ #include "codec_speex.h" #include <speex/speex_preprocess.h> +#ifdef SPEEX_EC +#include <speex/speex_echo.h> +#include "ringbuffer.h" +#endif + #ifdef CODEC_ILBC #include "codec_ilbc.h" #endif @@ -33,11 +39,19 @@ static float input_level = 0.0f; static float output_level = 0.0f; +int iaxci_sample_rate = 8000; + static SpeexPreprocessState *st = NULL; static int speex_state_size = 0; static int speex_state_rate = 0; int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN; +#ifdef SPEEX_EC +static SpeexEchoState *ec = NULL; +static rb_RingBuffer ecOutRing; +static char outRingBuf[EC_RING_SIZE]; +#endif + /* use to measure time since last audio was processed */ static struct timeval timeLastInput ; static struct timeval timeLastOutput ; @@ -104,7 +118,7 @@ speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); - + /* make vad more sensitive */ f = 0.30f; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &f); @@ -164,7 +178,7 @@ if ( (i & 0x3f) == 0 ) { - const float loudness; + float loudness; speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_LOUDNESS, &loudness); if ( loudness > 8000.0f || loudness < 4000.0f ) { @@ -401,3 +415,65 @@ set_speex_filters(); } +void audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples) +{ +#ifdef SPEEX_EC + int i; + static long bias = 0; + short delayedBuf[1024]; + short cancelledBuffer[1024]; + + /* remove bias -- whether ec is on or not. */ + for ( i = 0; i < samples; i++ ) + { + bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; + inputBuffer[i] -= (short int) (bias >> 15); + } + + /* if ec is off, clear ec state -- this way, we start fresh if/when + * it's turned back on. */ + if ( !(iaxci_filters & IAXC_FILTER_ECHO) ) + { + if ( ec ) + { + speex_echo_state_destroy(ec); + ec = NULL; + if ( st ) + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, NULL); + } + + return; + } + + /* we want echo cancellation */ + if ( !ec ) + { + rb_InitializeRingBuffer(&ecOutRing, EC_RING_SIZE, &outRingBuf); + ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); + if ( st ) + { + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, ec); + i = ECHO_SUPPRESS; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &i); + i = ECHO_SUPPRESS_ACTIVE; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i); + } + } + + /* fill ecOutRing */ + rb_WriteRingBuffer(&ecOutRing, outputBuffer, samples * 2); + + // Make sure we have enough buffer. + // Currently, just one SAMPLES_PER_FRAME's worth. + if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((samples + SAMPLES_PER_FRAME) * 2) ) + return; + + rb_ReadRingBuffer(&ecOutRing, delayedBuf, samples * 2); + + speex_echo_cancellation(ec, inputBuffer, delayedBuf, cancelledBuffer); + + for ( i = 0; i < samples; i++ ) + inputBuffer[i] = cancelledBuffer[i]; +#endif +} + Modified: branches/team/mihai/echocan/lib/audio_encode.h =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.h 2007-09-14 18:22:02 UTC (rev 1139) +++ branches/team/mihai/echocan/lib/audio_encode.h 2007-09-18 17:55:59 UTC (rev 1140) @@ -15,6 +15,28 @@ #ifndef _AUDIO_ENCODE_H #define _AUDIO_ENCODE_H +/* Some audio parameters */ +#define MAX_SAMPLE_RATE 48000 +#ifndef MS_PER_FRAME +# define MS_PER_FRAME 40 +#endif + +extern int iaxci_sample_rate; +#define SAMPLES_PER_FRAME (MS_PER_FRAME * iaxci_sample_rate / 1000) + +#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) + +/* echo_tail length, in samples */ +#define ECHO_TAIL 1024 + +/* Maximum attenuation of residual echo in dB (negative number) */ +#define ECHO_SUPPRESS -60 +/* Maximum attenuation of residual echo when near end is active, in dB (negative number) */ +#define ECHO_SUPPRESS_ACTIVE -60 + +/* Size of ring buffer used for echo can */ +#define EC_RING_SIZE 8192 /* must be pow(2) */ + struct iaxc_call; struct iax_event; @@ -24,5 +46,7 @@ int audio_decode_audio(struct iaxc_call * p, void * out, void * data, int len, int iEncodeType, int * samples); +void audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples); + #endif Modified: branches/team/mihai/echocan/lib/audio_portaudio.c =================================================================== --- branches/team/mihai/echocan/lib/audio_portaudio.c 2007-09-14 18:22:02 UTC (rev 1139) +++ branches/team/mihai/echocan/lib/audio_portaudio.c 2007-09-18 17:55:59 UTC (rev 1140) @@ -32,29 +32,18 @@ #endif #include "audio_portaudio.h" +#include "audio_encode.h" #include "iaxclient_lib.h" #include "ringbuffer.h" #include "portmixer.h" -#ifdef USE_MEC2 -#include "mec3.h" -static echo_can_state_t *ec; -#endif - -#ifdef SPAN_EC -#include "ec/echo.h" -static echo_can_state_t *ec; -#endif - #ifdef SPEEX_EC #define restrict __restrict #include "speex/speex_echo.h" static SpeexEchoState *ec; #endif -#define EC_RING_SZ 8192 /* must be pow(2) */ - typedef short SAMPLE; static PaStream *iStream, *oStream, *aStream; @@ -62,22 +51,8 @@ static int selectedInput, selectedOutput, selectedRing; -static int sample_rate = 8000; static int mixers_initialized; - -#define MAX_SAMPLE_RATE 48000 -#ifndef MS_PER_FRAME -# define MS_PER_FRAME 40 -#endif -#define SAMPLES_PER_FRAME (MS_PER_FRAME * sample_rate / 1000) - -/* static frame buffer allocation */ -#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) - -/* echo_tail length, in frames must be pow(2) for mec/span ? */ -#define ECHO_TAIL 4096 - /* RingBuffer Size; Needs to be Pow(2), 1024 = 512 samples = 64ms */ #ifndef OUTRBSZ # define OUTRBSZ 32768 @@ -120,7 +95,7 @@ #endif /* size in bytes of ringbuffer target */ -#define RBOUTTARGET_BYTES (RBOUTTARGET * (sample_rate / 1000) * sizeof(SAMPLE)) +#define RBOUTTARGET_BYTES (RBOUTTARGET * (iaxci_sample_rate / 1000) * sizeof(SAMPLE)) static char inRingBuf[INRBSZ], outRingBuf[OUTRBSZ]; static rb_RingBuffer inRing, outRing; @@ -369,82 +344,6 @@ return retval; /* found? */ } -static void iaxc_echo_can(short *inputBuffer, short *outputBuffer, int n) -{ - static rb_RingBuffer ecOutRing; - static char outRingBuf[EC_RING_SZ]; - static long bias = 0; - short delayedBuf[1024]; - int i; - - /* remove bias -- whether ec is on or not. */ - for ( i = 0; i < n; i++ ) - { - bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; - inputBuffer[i] -= (short int) (bias >> 15); - } - - /* if ec is off, clear ec state -- this way, we start fresh if/when - * it's turned back on. */ - if ( !(iaxc_get_filters() & IAXC_FILTER_ECHO) ) - { - if ( ec ) - { -#if defined(USE_MEC2) || defined(SPAN_EC) - echo_can_free(ec); - ec = NULL; -#endif -#if defined(SPEEX_EC) - speex_echo_state_destroy(ec); - ec = NULL; -#endif - } - - return; - } - - /* we want echo cancellation */ - - if ( !ec ) - { - rb_InitializeRingBuffer(&ecOutRing, EC_RING_SZ, &outRingBuf); -#if defined(USE_MEC2) || defined(SPAN_EC) - ec = echo_can_create(ECHO_TAIL, 0); -#endif -#if defined(SPEEX_EC) - ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); -#endif - } - - /* fill ecOutRing */ - rb_WriteRingBuffer(&ecOutRing, outputBuffer, n * 2); - - // Make sure we have enough buffer. - // Currently, just one SAMPLES_PER_FRAME's worth. - if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((n + SAMPLES_PER_FRAME) * 2) ) - return; - - rb_ReadRingBuffer(&ecOutRing, delayedBuf, n * 2); - -#if defined(SPEEX_EC) - { - short cancelledBuffer[1024]; - - speex_echo_cancel(ec, inputBuffer, delayedBuf, - cancelledBuffer, NULL); - - for ( i = 0; i < n; i++ ) - inputBuffer[i] = cancelledBuffer[i]; - } -#endif - -#if defined(USE_MEC2) || defined(SPAN_EC) - for ( i = 0; i < n; i++ ) - inputBuffer[i] = echo_can_update(ec, delayedBuf[i], - inputBuffer[i]); -#endif -} - static int pa_callback(void *inputBuffer, void *outputBuffer, unsigned long samplesPerFrame, const PaStreamCallbackTimeInfo* outTime, @@ -511,17 +410,16 @@ { stereo2mono(virtualInBuffer, (SAMPLE *)inputBuffer, samplesPerFrame); - iaxc_echo_can(virtualInBuffer, virtualOutBuffer, - samplesPerFrame); - + audio_echo_cancellation(virtualInBuffer, + virtualOutBuffer, + samplesPerFrame); rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); } else { - iaxc_echo_can((short *)inputBuffer, - (short *)outputBuffer, - samplesPerFrame); - + audio_echo_cancellation((short *)inputBuffer, + (short *)outputBuffer, + samplesPerFrame); rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); } } @@ -581,7 +479,7 @@ err = Pa_OpenStream(&iStream, &in_stream_params, &out_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -594,7 +492,7 @@ err = Pa_OpenStream(&iStream, &in_stream_params, &no_device, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -604,7 +502,7 @@ err = Pa_OpenStream(&oStream, &no_device, &out_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -711,7 +609,7 @@ err = Pa_OpenStream ( &aStream, &in_stream_params, &ring_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_aux_callback, @@ -724,7 +622,7 @@ err = Pa_OpenStream ( &aStream, &no_device, &ring_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, /* flags */ (PaStreamCallback *)pa_aux_callback, @@ -1059,7 +957,7 @@ { PaError err; - sample_rate = sr; + iaxci_sample_rate = sr; /* initialize portaudio */ if ( paNoError != (err = Pa_Initialize()) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 17:59:39
|
Revision: 1141 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1141&view=rev Author: sbalea Date: 2007-09-18 10:59:43 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Add support for the de-reverb preprocessor filter Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/iaxclient.h Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:55:59 UTC (rev 1140) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:59:43 UTC (rev 1141) @@ -118,6 +118,8 @@ speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); + i = (iaxci_filters & IAXC_FILTER_DEREVERB) ? 1 : 0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); /* make vad more sensitive */ f = 0.30f; Modified: branches/team/mihai/echocan/lib/iaxclient.h =================================================================== --- branches/team/mihai/echocan/lib/iaxclient.h 2007-09-18 17:55:59 UTC (rev 1140) +++ branches/team/mihai/echocan/lib/iaxclient.h 2007-09-18 17:59:43 UTC (rev 1141) @@ -382,6 +382,7 @@ #define IAXC_FILTER_ECHO (1<<2) #define IAXC_FILTER_AAGC (1<<3) /* Analog (mixer-based) AGC */ #define IAXC_FILTER_CN (1<<4) /* Send CN frames when silence detected */ +#define IAXC_FILTER_DEREVERB (1<<5) EXPORT int iaxc_get_filters(void); EXPORT void iaxc_set_filters(int filters); EXPORT int iaxc_set_files(FILE *input, FILE *output); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-26 20:11:09
|
Revision: 1161 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1161&view=rev Author: sbalea Date: 2007-09-26 13:11:06 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Synchronize with trunk Modified Paths: -------------- branches/team/mihai/echocan/lib/codec_theora.c branches/team/mihai/echocan/lib/video.c Modified: branches/team/mihai/echocan/lib/codec_theora.c =================================================================== --- branches/team/mihai/echocan/lib/codec_theora.c 2007-09-26 20:06:30 UTC (rev 1160) +++ branches/team/mihai/echocan/lib/codec_theora.c 2007-09-26 20:11:06 UTC (rev 1161) @@ -349,8 +349,6 @@ if ( !c->encstate ) goto bail; - video_reset_codec_stats(c); - c->format = format; c->width = w; c->height = h; Modified: branches/team/mihai/echocan/lib/video.c =================================================================== --- branches/team/mihai/echocan/lib/video.c 2007-09-26 20:06:30 UTC (rev 1160) +++ branches/team/mihai/echocan/lib/video.c 2007-09-26 20:11:06 UTC (rev 1161) @@ -872,14 +872,6 @@ return 0; } -void video_reset_codec_stats(struct iaxc_video_codec *vcodec) -{ - if ( vcodec == NULL ) return; - - memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats)); - gettimeofday(&vcodec->video_stats.start_time, NULL); -} - static struct slicer_context *sc = NULL; EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-10-23 22:37:58
|
Revision: 1225 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1225&view=rev Author: sbalea Date: 2007-10-23 15:37:55 -0700 (Tue, 23 Oct 2007) Log Message: ----------- Force PA to spit out standard sized buffers Comment out bias removal code Miscellaneous tweaks => Echo cancellation works pretty well on my mac :) Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/audio_encode.h branches/team/mihai/echocan/lib/audio_portaudio.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-10-23 22:20:37 UTC (rev 1224) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-10-23 22:37:55 UTC (rev 1225) @@ -417,7 +417,7 @@ set_speex_filters(); } -void audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples) +int audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples) { #ifdef SPEEX_EC int i; @@ -426,11 +426,11 @@ short cancelledBuffer[1024]; /* remove bias -- whether ec is on or not. */ - for ( i = 0; i < samples; i++ ) - { - bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; - inputBuffer[i] -= (short int) (bias >> 15); - } +// for ( i = 0; i < samples; i++ ) +// { +// bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; +// inputBuffer[i] -= (short int) (bias >> 15); +// } /* if ec is off, clear ec state -- this way, we start fresh if/when * it's turned back on. */ @@ -444,7 +444,7 @@ speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, NULL); } - return; + return 0; } /* we want echo cancellation */ @@ -462,20 +462,21 @@ } } - /* fill ecOutRing */ + // Put our data in the EC ring buffer. + // Echo canceller needs SAMPLES_PER_FRAME samples, so if we don't have enough + // at this time, we just store what we have and return. rb_WriteRingBuffer(&ecOutRing, outputBuffer, samples * 2); + if ( rb_GetRingBufferReadAvailable(&ecOutRing) < (SAMPLES_PER_FRAME * 2) ) + return -1; - // Make sure we have enough buffer. - // Currently, just one SAMPLES_PER_FRAME's worth. - if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((samples + SAMPLES_PER_FRAME) * 2) ) - return; + rb_ReadRingBuffer(&ecOutRing, delayedBuf, SAMPLES_PER_FRAME * 2); - rb_ReadRingBuffer(&ecOutRing, delayedBuf, samples * 2); - + //fprintf(stderr, "Mihai: doing echo cancellation, samples = %d\n", samples); speex_echo_cancellation(ec, inputBuffer, delayedBuf, cancelledBuffer); for ( i = 0; i < samples; i++ ) inputBuffer[i] = cancelledBuffer[i]; #endif + return 0; } Modified: branches/team/mihai/echocan/lib/audio_encode.h =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.h 2007-10-23 22:20:37 UTC (rev 1224) +++ branches/team/mihai/echocan/lib/audio_encode.h 2007-10-23 22:37:55 UTC (rev 1225) @@ -51,7 +51,7 @@ int audio_decode_audio(struct iaxc_call * p, void * out, void * data, int len, int iEncodeType, int * samples); -void audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples); +int audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples); #endif Modified: branches/team/mihai/echocan/lib/audio_portaudio.c =================================================================== --- branches/team/mihai/echocan/lib/audio_portaudio.c 2007-10-23 22:20:37 UTC (rev 1224) +++ branches/team/mihai/echocan/lib/audio_portaudio.c 2007-10-23 22:37:55 UTC (rev 1225) @@ -351,11 +351,10 @@ PaStreamCallbackFlags statusFlags, void *userData) { + short virtualInBuffer[MAX_SAMPLES_PER_FRAME]; + short virtualOutBuffer[MAX_SAMPLES_PER_FRAME]; int totBytes = samplesPerFrame * sizeof(SAMPLE); - short virtualInBuffer[MAX_SAMPLES_PER_FRAME * 2]; - short virtualOutBuffer[MAX_SAMPLES_PER_FRAME * 2]; - #if 0 /* I think this can't happen */ if(virtualMono && samplesPerFrame > SAMPLES_PER_FRAME) { @@ -364,8 +363,10 @@ } #endif + fprintf(stderr, "Mihai: in PA callback\n"); if ( outputBuffer ) { + //fprintf(stderr, "Mihai: PA output buffer size %d samples\n", samplesPerFrame); int bWritten; /* output underflow might happen here */ if (virtualMonoOut) @@ -406,22 +407,31 @@ if ( inputBuffer ) { + int res; + + //fprintf(stderr, "Mihai: PA input buffer size %d samples\n", samplesPerFrame); /* input overflow might happen here */ if ( virtualMonoIn ) { stereo2mono(virtualInBuffer, (SAMPLE *)inputBuffer, samplesPerFrame); - audio_echo_cancellation(virtualInBuffer, - virtualOutBuffer, - samplesPerFrame); - rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); + res = audio_echo_cancellation(virtualInBuffer, + virtualOutBuffer, + samplesPerFrame); + if ( !res ) + rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); + //else + // fprintf(stderr, "Mihai: EC does not have enough data\n"); } else { - audio_echo_cancellation((short *)inputBuffer, - (short *)outputBuffer, - samplesPerFrame); - rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); + res = audio_echo_cancellation((short *)inputBuffer, + (short *)outputBuffer, + samplesPerFrame); + if ( !res) + rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); + //else + // fprintf(stderr, "Mihai: EC does not have enough data\n"); } } @@ -480,7 +490,8 @@ &in_stream_params, &out_stream_params, iaxci_sample_rate, - paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + //paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + SAMPLES_PER_FRAME, paNoFlag, (PaStreamCallback *)pa_callback, NULL); @@ -493,7 +504,8 @@ &in_stream_params, &no_device, iaxci_sample_rate, - paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + //paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + SAMPLES_PER_FRAME, paNoFlag, (PaStreamCallback *)pa_callback, NULL); @@ -503,7 +515,8 @@ &no_device, &out_stream_params, iaxci_sample_rate, - paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + //paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + SAMPLES_PER_FRAME, paNoFlag, (PaStreamCallback *)pa_callback, NULL); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-10-24 18:56:04
|
Revision: 1230 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1230&view=rev Author: sbalea Date: 2007-10-24 11:56:07 -0700 (Wed, 24 Oct 2007) Log Message: ----------- Make sure that we link the echo canceller to the preprocessor in all situations. Reduce tail to 512 frames. Miscellaneous code cleanups. Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/audio_encode.h branches/team/mihai/echocan/lib/audio_portaudio.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-10-24 15:31:46 UTC (rev 1229) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-10-24 18:56:07 UTC (rev 1230) @@ -154,6 +154,16 @@ if (st) speex_preprocess_state_destroy(st); st = speex_preprocess_state_init(len,rate); + if ( ec ) + { + int i; + + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, ec); + i = ECHO_SUPPRESS; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &i); + i = ECHO_SUPPRESS_ACTIVE; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i); + } speex_state_size = len; speex_state_rate = rate; set_speex_filters(); @@ -431,7 +441,7 @@ // bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; // inputBuffer[i] -= (short int) (bias >> 15); // } - + /* if ec is off, clear ec state -- this way, we start fresh if/when * it's turned back on. */ if ( !(iaxci_filters & IAXC_FILTER_ECHO) ) @@ -441,7 +451,9 @@ speex_echo_state_destroy(ec); ec = NULL; if ( st ) + { speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, NULL); + } } return 0; @@ -452,6 +464,10 @@ { rb_InitializeRingBuffer(&ecOutRing, EC_RING_SIZE, &outRingBuf); ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); + + // st and ec can be created and destroyed from two separate threads + // and thus we have possible race conditions here. + // TODO: verify that this is the case and add synchronization code. if ( st ) { speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, ec); @@ -471,7 +487,6 @@ rb_ReadRingBuffer(&ecOutRing, delayedBuf, SAMPLES_PER_FRAME * 2); - //fprintf(stderr, "Mihai: doing echo cancellation, samples = %d\n", samples); speex_echo_cancellation(ec, inputBuffer, delayedBuf, cancelledBuffer); for ( i = 0; i < samples; i++ ) Modified: branches/team/mihai/echocan/lib/audio_encode.h =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.h 2007-10-24 15:31:46 UTC (rev 1229) +++ branches/team/mihai/echocan/lib/audio_encode.h 2007-10-24 18:56:07 UTC (rev 1230) @@ -27,7 +27,7 @@ #define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) /* echo_tail length, in samples */ -#define ECHO_TAIL 1024 +#define ECHO_TAIL 512 /* Maximum attenuation of residual echo in dB (negative number) */ #define ECHO_SUPPRESS -60 Modified: branches/team/mihai/echocan/lib/audio_portaudio.c =================================================================== --- branches/team/mihai/echocan/lib/audio_portaudio.c 2007-10-24 15:31:46 UTC (rev 1229) +++ branches/team/mihai/echocan/lib/audio_portaudio.c 2007-10-24 18:56:07 UTC (rev 1230) @@ -365,7 +365,6 @@ if ( outputBuffer ) { - //fprintf(stderr, "Mihai: PA output buffer size %d samples\n", samplesPerFrame); int bWritten; /* output underflow might happen here */ if (virtualMonoOut) @@ -408,7 +407,6 @@ { int res; - //fprintf(stderr, "Mihai: PA input buffer size %d samples\n", samplesPerFrame); /* input overflow might happen here */ if ( virtualMonoIn ) { @@ -419,8 +417,6 @@ samplesPerFrame); if ( !res ) rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); - //else - // fprintf(stderr, "Mihai: EC does not have enough data\n"); } else { @@ -429,8 +425,6 @@ samplesPerFrame); if ( !res) rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); - //else - // fprintf(stderr, "Mihai: EC does not have enough data\n"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-11-02 14:27:00
|
Revision: 1257 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1257&view=rev Author: sbalea Date: 2007-11-02 07:26:56 -0700 (Fri, 02 Nov 2007) Log Message: ----------- Initialize and destroy audio_lock. Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/audio_encode.h branches/team/mihai/echocan/lib/iaxclient_lib.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-11-01 21:15:30 UTC (rev 1256) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-11-02 14:26:56 UTC (rev 1257) @@ -491,3 +491,15 @@ return 0; } +int audio_initialize() +{ + MUTEXINIT(&audio_lock); + return 0; +} + +int audio_destroy() +{ + MUTEXDESTROY(&audio_lock); + return 0; +} + Modified: branches/team/mihai/echocan/lib/audio_encode.h =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.h 2007-11-01 21:15:30 UTC (rev 1256) +++ branches/team/mihai/echocan/lib/audio_encode.h 2007-11-02 14:26:56 UTC (rev 1257) @@ -55,6 +55,9 @@ struct iaxc_call; struct iax_event; +int audio_initialize(); +int audio_destroy(); + int audio_send_encoded_audio(struct iaxc_call * most_recent_answer, int callNo, void * data, int iEncodeType, int samples); Modified: branches/team/mihai/echocan/lib/iaxclient_lib.c =================================================================== --- branches/team/mihai/echocan/lib/iaxclient_lib.c 2007-11-01 21:15:30 UTC (rev 1256) +++ branches/team/mihai/echocan/lib/iaxclient_lib.c 2007-11-02 14:26:56 UTC (rev 1257) @@ -620,6 +620,7 @@ if ( !test_mode ) { + audio_initialize(); #ifndef AUDIO_ALSA if ( pa_initialize(&audio_driver, 8000) ) { @@ -666,6 +667,7 @@ if ( !test_mode ) { audio_driver.destroy(&audio_driver); + audio_destroy(); #ifdef USE_VIDEO video_destroy(); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-11-05 15:29:10
|
Revision: 1266 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1266&view=rev Author: sbalea Date: 2007-11-05 07:29:12 -0800 (Mon, 05 Nov 2007) Log Message: ----------- Synchronize with trunk rev 1265 Revision Links: -------------- http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1265&view=rev Modified Paths: -------------- branches/team/mihai/echocan/lib/iaxclient.h branches/team/mihai/echocan/lib/iaxclient_lib.c branches/team/mihai/echocan/lib/video.c Modified: branches/team/mihai/echocan/lib/iaxclient.h =================================================================== --- branches/team/mihai/echocan/lib/iaxclient.h 2007-11-05 15:09:32 UTC (rev 1265) +++ branches/team/mihai/echocan/lib/iaxclient.h 2007-11-05 15:29:12 UTC (rev 1266) @@ -819,6 +819,11 @@ EXPORT void iaxc_send_text(const char * text); /*! + Sends \a text to call \a callNo +*/ +EXPORT void iaxc_send_text_call(int callNo, const char * text); + +/*! Sends a URL across the currently selected call \param url The URL to send across. \param link If non-zero the URL is a link @@ -1135,9 +1140,14 @@ EXPORT int iaxc_set_audio_prefs(unsigned int prefs); /*! - Get video capture device information: + Get video capture device information. + WARNING: the array pointed to by parameter 'devs' below is owned + by iaxclient, and may be freed on subsequent calls to + this function. \param devs Returns an array of iaxc_video_device structures. - The array will will be valid as long as iaxc is initialized. + The array will only be valid until this function is + called again (if the device list changes), or until + iaxc is shutdown. \param nDevs Returns the number of devices in the devs array \param devId Returns the id of the currently selected video capture device Modified: branches/team/mihai/echocan/lib/iaxclient_lib.c =================================================================== --- branches/team/mihai/echocan/lib/iaxclient_lib.c 2007-11-05 15:09:32 UTC (rev 1265) +++ branches/team/mihai/echocan/lib/iaxclient_lib.c 2007-11-05 15:29:12 UTC (rev 1266) @@ -1512,6 +1512,17 @@ } } +EXPORT void iaxc_send_text_call(int callNo, const char * text) +{ + if ( callNo < 0 || !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) ) + return; + + get_iaxc_lock(); + if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE ) + iax_send_text(calls[callNo].session, text); + put_iaxc_lock(); +} + EXPORT void iaxc_send_url(const char * url, int link) { if ( selected_call >= 0 ) Modified: branches/team/mihai/echocan/lib/video.c =================================================================== --- branches/team/mihai/echocan/lib/video.c 2007-11-05 15:09:32 UTC (rev 1265) +++ branches/team/mihai/echocan/lib/video.c 2007-11-05 15:29:12 UTC (rev 1266) @@ -557,6 +557,15 @@ cap_info->error_status); vinfo.capturing = 0; + /* NOTE: + * We want to release now, but we're in the capture callback thread. + * vidcap_src_release() fails during capture. + * + * We'll defer the release until the end-application's main thread + * requires the release - if either iaxc_set_video_prefs(), + * iaxc_video_device_set() or video_destroy() are called. + */ + evt.type = IAXC_EVENT_VIDCAP_ERROR; iaxci_post_event(evt); return -1; @@ -967,20 +976,19 @@ !(prefs & IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED)) ) { MUTEXLOCK(&vinfo.camera_lock); - if ( vinfo.capturing ) + if ( vinfo.capturing && vinfo.src && + vidcap_src_capture_stop(vinfo.src) ) { - if ( vidcap_src_capture_stop(vinfo.src) ) - fprintf(stderr, "failed vidcap_src_capture_stop\n"); + fprintf(stderr, "failed vidcap_src_capture_stop\n"); + } - vinfo.capturing = 0; + if ( vinfo.src && vidcap_src_release(vinfo.src) ) + { + fprintf(stderr, "failed to release a video source\n"); + } - if ( vinfo.src && vidcap_src_release(vinfo.src) ) - { - fprintf(stderr, "failed to release a video source\n"); - } - - vinfo.src = 0; - } + vinfo.src = 0; + vinfo.capturing = 0; MUTEXUNLOCK(&vinfo.camera_lock); } else @@ -1371,19 +1379,17 @@ new_iaxc_dev_list[n].name = strdup(new_src_list[n].description); new_iaxc_dev_list[n].id_string = strdup(new_src_list[n].identifier); - /* this device may have been here all along - * Check if it has, and re-assign that device id + /* This device may have been here all along. + * If it has, re-assign that device id * else assign a new id */ for ( i = 0; i < vinfo.device_count; i++ ) { - if ( !strcmp(new_iaxc_dev_list[n].name, vinfo.devices[i].name) ) + /* check both the device name and its unique identifier */ + if ( !strcmp(new_iaxc_dev_list[n].name, vinfo.devices[i].name) && + !strcmp(new_iaxc_dev_list[n].id_string, + vinfo.devices[i].id_string) ) { - /*fprintf(stderr, "EXISTING DEVICE: %s - (id=%d) '%s'\n", - new_iaxc_dev_list[n].name, - vinfo.devices[i].id, - new_iaxc_dev_list[n].id_string); - */ new_iaxc_dev_list[n].id = vinfo.devices[i].id; if ( vinfo.selected_device_id == new_iaxc_dev_list[n].id ) @@ -1394,10 +1400,6 @@ if ( i == vinfo.device_count ) { new_iaxc_dev_list[n].id = vinfo.next_id++; - fprintf(stderr, "NEW DEVICE: %s - (id=%d) '%s'\n", - new_iaxc_dev_list[n].name, - new_iaxc_dev_list[n].id, - new_iaxc_dev_list[n].id_string); list_changed = 1; } @@ -1440,9 +1442,16 @@ free(old_iaxc_dev_list); } + /* If we can't find the selected device, defer releasing it. + * It'll happen when we set a new device, or shutdown + */ + + if ( !found_selected_device ) + vinfo.selected_device_id = -1; + *devs = vinfo.devices; *num_devs = vinfo.device_count; - *id_selected = found_selected_device ? vinfo.selected_device_id : -1; + *id_selected = vinfo.selected_device_id; return list_changed; } @@ -1486,6 +1495,12 @@ vinfo.selected_device_id = capture_dev_id; + if ( vinfo.capturing && vinfo.src && + vidcap_src_capture_stop(vinfo.src) ) + { + fprintf(stderr, "failed to stop video capture\n"); + } + if ( vinfo.src && vidcap_src_release(vinfo.src) ) { fprintf(stderr, "failed to release video source\n"); @@ -1530,12 +1545,14 @@ memset(&vinfo, 0, sizeof(vinfo)); + vinfo.width = vfinfo.width; + vinfo.height = vfinfo.height; + vinfo.selected_device_id = -1; + vinfo.next_id = starting_id; + MUTEXINIT(&vinfo.camera_lock); MUTEXINIT(&vinfo.dev_list_lock); - vinfo.width = vfinfo.width; - vinfo.height = vfinfo.height; - if ( !(vinfo.vc = vidcap_initialize()) ) { fprintf(stderr, "ERROR: failed vidcap_initialize\n"); @@ -1558,8 +1575,6 @@ vinfo.sapi_info.description, vinfo.sapi_info.identifier); - vinfo.selected_device_id = -1; - vinfo.device_count = vidcap_src_list_update(vinfo.sapi); if ( vinfo.device_count < 0 ) { @@ -1604,13 +1619,12 @@ * these ids may diverge as devices are added * and removed. */ - vinfo.devices[i].id = i + starting_id; + vinfo.devices[i].id = vinfo.next_id++; } - vinfo.next_id = vinfo.devices[vinfo.device_count - 1].id + 1; - /* set default source - the first device */ if ( vinfo.device_count ) { + /* set default source - the first device */ iaxc_video_device_set(vinfo.devices[0].id); } @@ -1649,9 +1663,25 @@ int video_destroy(void) { + int i; + if ( !vinfo.vc ) return -1; + free(vinfo.vc_src_info); + for ( i = 0; i < vinfo.device_count; i++ ) + { + free((void *)vinfo.devices[i].name); + free((void *)vinfo.devices[i].id_string); + } + free(vinfo.devices); + + if ( vinfo.capturing && vinfo.src ) + vidcap_src_capture_stop(vinfo.src); + + if ( vinfo.src ) + vidcap_src_release(vinfo.src); + vidcap_destroy(vinfo.vc); vinfo.vc = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |