Commit 769e7d10 authored by smorlat's avatar smorlat

equalizer mostly works.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@538 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 23305782
......@@ -54,6 +54,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <mediastreamer2/mscommon.h>
typedef int32_t ms_int32_t;
#ifdef MS_FIXED_POINT
typedef short ms_word16_t;
......@@ -61,13 +63,13 @@ typedef int ms_word32_t;
typedef int ms_mem_t;
typedef short ms_coef_t;
#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST16(x,bits) ((ms_word16_t)(.5+(x)*(((ms_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((ms_word32_t)(.5+(x)*(((ms_word32_t)1)<<(bits))))
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define EXTRACT16(x) ((spx_word16_t)(x))
#define EXTEND32(x) ((spx_word32_t)(x))
#define EXTRACT16(x) ((ms_word16_t)(x))
#define EXTEND32(x) ((ms_word32_t)(x))
#define SHR16(a,shift) ((a) >> (shift))
#define SHL16(a,shift) ((a) << (shift))
#define SHR32(a,shift) ((a) >> (shift))
......@@ -79,22 +81,22 @@ typedef short ms_coef_t;
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
#define SHR(a,shift) ((a) >> (shift))
#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
#define SHL(a,shift) ((ms_word32_t)(a) << (shift))
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))
#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))
#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))
#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))
#define ADD16(a,b) ((ms_word16_t)((ms_word16_t)(a)+(ms_word16_t)(b)))
#define SUB16(a,b) ((ms_word16_t)(a)-(ms_word16_t)(b))
#define ADD32(a,b) ((ms_word32_t)(a)+(ms_word32_t)(b))
#define SUB32(a,b) ((ms_word32_t)(a)-(ms_word32_t)(b))
/* result fits in 16 bits */
#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b))))
#define MULT16_16_16(a,b) ((((ms_word16_t)(a))*((ms_word16_t)(b))))
/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
/* (ms_word32_t)(ms_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
#define MULT16_16(a,b) (((ms_word32_t)(ms_word16_t)(a))*((ms_word32_t)(ms_word16_t)(b)))
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
......@@ -124,10 +126,10 @@ typedef short ms_coef_t;
#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))
#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))
#define DIV32_16(a,b) ((ms_word16_t)(((ms_word32_t)(a))/((ms_word16_t)(b))))
#define PDIV32_16(a,b) ((ms_word16_t)(((ms_word32_t)(a)+((ms_word16_t)(b)>>1))/((ms_word16_t)(b))))
#define DIV32(a,b) (((ms_word32_t)(a))/((ms_word32_t)(b)))
#define PDIV32(a,b) (((ms_word32_t)(a)+((ms_word16_t)(b)>>1))/((ms_word32_t)(b)))
#ifdef ARM5E_ASM
#error "Fix me"
......@@ -356,6 +358,8 @@ typedef float ms_word32_t;
#endif
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#ifdef __cplusplus
extern "C"{
#endif
......
......@@ -49,12 +49,14 @@ struct _AudioStream
MSFilter *ec;/*echo canceler*/
MSFilter *volsend,*volrecv; /*MSVolumes*/
MSFilter *resampler;
MSFilter *equalizer;
uint64_t last_packet_count;
time_t last_packet_time;
EchoLimiterType el_type; /*use echo limiter: two MSVolume, measured input level controlling local output level*/
bool_t play_dtmfs;
bool_t use_gc;
bool_t use_agc;
bool_t eq_active;
};
#ifdef __cplusplus
......@@ -112,6 +114,11 @@ void audio_stream_enable_automatic_gain_control(AudioStream *stream, bool_t val)
void audio_stream_set_mic_gain(AudioStream *stream, float gain);
/*enable parametric equalizer in the stream that goes to the speaker*/
void audio_stream_enable_equalizer(AudioStream *stream, bool_t enabled);
void audio_stream_equalizer_set_gain(AudioStream *stream, int frequency, float gain);
/* stop the audio streaming thread and free everything*/
void audio_stream_stop (AudioStream * stream);
......
......@@ -29,6 +29,13 @@ typedef struct _MSEqualizerGain{
#define MS_EQUALIZER_SET_GAIN MS_FILTER_METHOD(MS_EQUALIZER_ID,0,MSEqualizerGain)
#define MS_EQUALIZER_GET_GAIN MS_FILTER_METHOD(MS_EQUALIZER_ID,1,MSEqualizerGain)
#define MS_EQUALIZER_SET_ACTIVE MS_FILTER_METHOD(MS_EQUALIZER_ID,2,int)
/**
* Sets the coeficient for computing how large is the frequency band around a gain setting.
* For example, setting this value to 0.4 will result in a frequency range of 800-1200 when setting
* a gain for frequency 1000 Hz.
**/
#define MS_EQUALIZER_SET_FREQ_WIDTH_COEF MS_FILTER_METHOD(MS_EQUALIZER_ID,3,float)
#endif
......@@ -49,7 +49,7 @@ struct kiss_fft_state{
* */
#ifdef MS_FIXED_POINT
# define FRACBITS 15
# define SAMPPROD spx_int32_t
# define SAMPPROD ms_int32_t
#define SAMP_MAX 32767
#define SAMP_MIN -SAMP_MAX
......@@ -158,15 +158,15 @@ struct kiss_fft_state{
#define L3 8277
#define L4 -626
static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
static inline ms_word16_t _ms_cos_pi_2(ms_word16_t x)
{
spx_word16_t x2;
ms_word16_t x2;
x2 = MULT16_16_P15(x,x);
return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
}
static inline spx_word16_t spx_cos_norm(spx_word32_t x)
static inline ms_word16_t ms_cos_norm(ms_word32_t x)
{
x = x&0x0001ffff;
if (x>SHL32(EXTEND32(1), 16))
......@@ -175,9 +175,9 @@ static inline spx_word16_t spx_cos_norm(spx_word32_t x)
{
if (x<SHL32(EXTEND32(1), 15))
{
return _spx_cos_pi_2(EXTRACT16(x));
return _ms_cos_pi_2(EXTRACT16(x));
} else {
return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
return NEG32(_ms_cos_pi_2(EXTRACT16(65536-x)));
}
} else {
if (x&0x0000ffff)
......@@ -190,13 +190,13 @@ static inline spx_word16_t spx_cos_norm(spx_word32_t x)
}
#else
#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
#define ms_cos_norm(x) (cos((.5f*M_PI)*(x)))
#endif
#define kf_cexp2(x,phase) \
do{ \
(x)->r = spx_cos_norm((phase));\
(x)->i = spx_cos_norm((phase)-32768);\
(x)->r = ms_cos_norm((phase));\
(x)->i = ms_cos_norm((phase)-32768);\
}while(0)
......
......@@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfileplayer.h"
#include "mediastreamer2/msfilerec.h"
#include "mediastreamer2/msvolume.h"
#include "mediastreamer2/msequalizer.h"
#ifdef INET6
#include <sys/types.h>
......@@ -283,6 +284,11 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
if (pt->send_fmtp!=NULL) ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP, (void*)pt->send_fmtp);
if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);
/*create the equalizer*/
stream->equalizer=ms_filter_new(MS_EQUALIZER_ID);
tmp=stream->eq_active;
ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp);
/* and then connect all */
/* tip: draw yourself the picture if you don't understand */
......@@ -303,6 +309,8 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
ms_connection_helper_link(&h,stream->rtprecv,-1,0);
ms_connection_helper_link(&h,stream->decoder,0,0);
ms_connection_helper_link(&h,stream->dtmfgen,0,0);
if (stream->equalizer)
ms_connection_helper_link(&h,stream->equalizer,0,0);
if (stream->volrecv)
ms_connection_helper_link(&h,stream->volrecv,0,0);
if (stream->ec)
......@@ -435,6 +443,23 @@ void audio_stream_set_mic_gain(AudioStream *stream, float gain){
"Use audio_stream_enable_gain_control() before starting the stream.");
}
void audio_stream_enable_equalizer(AudioStream *stream, bool_t enabled){
stream->eq_active=enabled;
if (stream->equalizer){
int tmp=enabled;
ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp);
}
}
void audio_stream_equalizer_set_gain(AudioStream *stream, int frequency, float gain){
if (stream->equalizer){
MSEqualizerGain d;
d.frequency=frequency;
d.gain=gain;
ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_GAIN,&d);
}
}
void audio_stream_stop(AudioStream * stream)
{
if (stream->ticker){
......@@ -461,6 +486,8 @@ void audio_stream_stop(AudioStream * stream)
ms_connection_helper_unlink(&h,stream->rtprecv,-1,0);
ms_connection_helper_unlink(&h,stream->decoder,0,0);
ms_connection_helper_unlink(&h,stream->dtmfgen,0,0);
if (stream->equalizer)
ms_connection_helper_unlink(&h,stream->equalizer,0,0);
if (stream->volrecv!=NULL)
ms_connection_helper_unlink(&h,stream->volrecv,0,0);
if (stream->ec!=NULL)
......
......@@ -62,7 +62,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ALLOC(var,size,type) var = alloca(sizeof(type)*(size))
#ifdef ARCH_BFIN
#if 0
//#ifdef ARCH_BFIN
static void filter_mem16(const ms_word16_t *_x, const ms_coef_t *num, const ms_coef_t *den, ms_word16_t *_y, int N, int ord, ms_mem_t *mem)
{
......@@ -220,7 +221,8 @@ void ms_fir_mem16(const ms_word16_t *x, const ms_coef_t *num, ms_word16_t *y, in
#else
#if 0
/* this one comes from speex but unfortunately does not make the expected result, maybe it is mis-used.*/
void ms_fir_mem16(const ms_word16_t *x, const ms_coef_t *num, ms_word16_t *y, int N, int ord, ms_mem_t *mem)
{
int i,j;
......@@ -238,8 +240,89 @@ void ms_fir_mem16(const ms_word16_t *x, const ms_coef_t *num, ms_word16_t *y, in
y[i] = yi;
}
}
#else
#ifndef MS_FIXED_POINT
void ms_fir_mem16(const ms_word16_t *x, const ms_coef_t *num, ms_word16_t *y, int N, int ord, ms_mem_t *mem){
int i,j;
ms_word16_t xi;
ms_word32_t acc;
for(i=0;i<N;++i){
xi=x[i];
mem[0]=xi;
/* accumulate and shift within the same loop*/
acc=mem[ord-1]*num[ord-1];
for(j=ord-2;j>=0;--j){
acc+=num[j]*mem[j];
mem[j+1]=mem[j];
}
y[i]=acc;
}
}
#else
void ms_fir_mem16(const ms_word16_t *x, const ms_coef_t *num, ms_word16_t *y, int N, int ord, ms_mem_t *mem){
int i,j;
ms_word16_t xi;
ms_word32_t acc;
int shift=0; /* REVISIT: empiric value...*/
for(i=0;i<N;++i){
xi=x[i];
mem[0]=xi;
/* accumulate and shift memories within the same loop*/
acc=(mem[ord-1]*(ms_word32_t)num[ord-1])>>shift;
for(j=ord-2;j>=0;--j){
acc+=(((ms_word32_t)num[j])*mem[j])>>shift;
mem[j+1]=mem[j];
}
y[i]=(ms_word16_t)SATURATE16(acc>>14,32767);
}
}
#endif
#endif
#endif
#ifdef MS_FIXED_POINT
static int maximize_range(ms_word16_t *in, ms_word16_t *out, ms_word16_t bound, int len)
{
int i, shift;
ms_word16_t max_val = 0;
for (i=0;i<len;i++)
{
if (in[i]>max_val)
max_val = in[i];
if (-in[i]>max_val)
max_val = -in[i];
}
shift=0;
while (max_val <= (bound>>1) && max_val != 0)
{
max_val <<= 1;
shift++;
}
for (i=0;i<len;i++)
{
out[i] = SHL16(in[i], shift);
}
return shift;
}
static void renorm_range(ms_word16_t *in, ms_word16_t *out, int shift, int len)
{
int i;
for (i=0;i<len;i++)
{
out[i] = PSHR16(in[i], shift);
}
}
#endif
#include "kiss_fftr.h"
#include "kiss_fft.h"
......
......@@ -22,7 +22,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h>
#define GAIN_ZERODB 22000
#define ABS_GAIN_ZERODB 22000
#ifdef MS_FIXED_POINT
#define GAIN_ZERODB ABS_GAIN_ZERODB
#else
#define GAIN_ZERODB (((float)ABS_GAIN_ZERODB)/32767.0)
#endif
typedef struct _EqualizerState{
......@@ -32,13 +40,17 @@ typedef struct _EqualizerState{
int fir_len;
ms_word16_t *fir;
ms_mem_t *mem; /*memories for filtering computations*/
float width_coef;
bool_t needs_update;
bool_t active;
} EqualizerState;
static void equalizer_state_flatten(EqualizerState *s){
int i;
for(i=0;i<s->nfft;i+=2)
s->fft_cpx[i]=GAIN_ZERODB;
ms_word16_t val=GAIN_ZERODB/s->nfft;
s->fft_cpx[0]=val;
for(i=1;i<s->nfft;i+=2)
s->fft_cpx[i]=val;
}
static EqualizerState * equalizer_state_new(int nfft){
......@@ -50,7 +62,9 @@ static EqualizerState * equalizer_state_new(int nfft){
s->fir_len=s->nfft;
s->fir=ms_new(ms_word16_t,s->fir_len);
s->mem=ms_new0(ms_mem_t,s->fir_len);
s->width_coef=0.4; /* when setting a gain at 1000hz, we will affect 800-1200 frequency band*/
s->needs_update=TRUE;
s->active=TRUE;
return s;
}
......@@ -70,30 +84,31 @@ static int equalizer_state_hz_to_index(EqualizerState *s, int hz){
if (hz>(s->rate/2)){
hz=(s->rate/2);
}
ret=hz*s->nfft/s->rate;
if (ret==s->nfft/2) ret--;
/*round to nearest integer*/
ret=((hz*s->nfft)+(hz/2))/s->rate;
if (ret==s->nfft/2) ret=(s->nfft/2)-1;
return ret;
}
static float gain_float(ms_word16_t val){
return (float)val/22000.0;
return (float)val/GAIN_ZERODB;
}
static ms_word16_t gain_int16(float val){
int ret=(int)(val*22000.0);
ms_word16_t ret=(val*GAIN_ZERODB);
if (ret>=32767) ret=32767;
return (ms_word16_t)ret;
}
static float equalizer_state_get(EqualizerState *s, int freqhz){
int idx=equalizer_state_hz_to_index(s,freqhz);
if (idx>=0) return gain_float(s->fft_cpx[idx*2]);
if (idx>=0) return gain_float(s->fft_cpx[idx*2])*s->nfft;
return 0;
}
/* return the frequency band width we want to control around hz*/
static void equalizer_state_get_band(EqualizerState *s, int hz, int *low_index, int *high_index){
int half_band=(int)((float)hz*0.1);
int half_band=(int)((float)hz*s->width_coef*0.5);
*low_index=equalizer_state_hz_to_index(s,hz-half_band);
*high_index=equalizer_state_hz_to_index(s,hz+half_band);
}
......@@ -104,7 +119,7 @@ static void equalizer_state_set(EqualizerState *s, int freqhz, float gain){
equalizer_state_get_band(s,freqhz,&low,&high);
for(i=low;i<=high;++i){
ms_message("Setting gain %f for freq_index %i (freqhz=%i)",gain,i,freqhz);
s->fft_cpx[i*2]=gain_int16(gain);
s->fft_cpx[1+(i*2)]=gain_int16(gain)/s->nfft;
}
s->needs_update=TRUE;
}
......@@ -119,6 +134,17 @@ static void dump_table(ms_word16_t *t, int len){
#endif
}
static void time_shift(ms_word16_t *s, int len){
int i;
int half=len/2;
ms_word16_t tmp;
for (i=0;i<half;++i){
tmp=s[i];
s[i]=s[i+half];
s[i+half]=tmp;
}
}
/*
*hamming:
* 0.54 - 0.46*cos(2*M_PI*t/T)
......@@ -127,7 +153,7 @@ static void dump_table(ms_word16_t *t, int len){
* 0.42 - 0.5*cos(2*M_PI*t/T) + 0.08*cos(4*M_PI*t/T)
*/
static void apodize(ms_word16_t *s, int len){
static void norm_and_apodize(ms_word16_t *s, int len){
int i;
float x;
float w;
......@@ -140,10 +166,16 @@ static void apodize(ms_word16_t *s, int len){
static void equalizer_state_compute_impulse_response(EqualizerState *s){
void *fft_handle=ms_fft_init(s->nfft);
ms_message("Spectral domain:");
dump_table(s->fft_cpx,s->nfft);
ms_ifft(fft_handle,s->fft_cpx,s->fir);
ms_fft_destroy(fft_handle);
ms_message("Inverse fft result:");
dump_table(s->fir,s->fir_len);
apodize(s->fir,s->fir_len);
time_shift(s->fir,s->fir_len);
ms_message("Time shifted:");
dump_table(s->fir,s->fir_len);
norm_and_apodize(s->fir,s->fir_len);
ms_message("Apodized impulse response:");
dump_table(s->fir,s->fir_len);
s->needs_update=FALSE;
......@@ -195,7 +227,9 @@ void equalizer_process(MSFilter *f){
mblk_t *m;
EqualizerState *s=(EqualizerState*)f->data;
while((m=ms_queue_get(f->inputs[0]))!=NULL){
equalizer_state_run(s,(int16_t*)m->b_rptr,(m->b_wptr-m->b_rptr)/2);
if (s->active){
equalizer_state_run(s,(int16_t*)m->b_rptr,(m->b_wptr-m->b_rptr)/2);
}
ms_queue_put(f->outputs[0],m);
}
}
......@@ -220,10 +254,24 @@ int equalizer_set_rate(MSFilter *f, void *data){
return 0;
}
int equalizer_set_active(MSFilter *f, void *data){
EqualizerState *s=(EqualizerState*)f->data;
s->active=*(int*)data;
return 0;
}
int equalizer_set_freq_width_coef(MSFilter *f, void *data){
EqualizerState *s=(EqualizerState*)f->data;
s->width_coef=*(float*)data;
return 0;
}
static MSFilterMethod equalizer_methods[]={
{ MS_EQUALIZER_SET_GAIN , equalizer_set_gain },
{ MS_EQUALIZER_GET_GAIN , equalizer_get_gain },
{ MS_EQUALIZER_SET_ACTIVE , equalizer_set_active },
{ MS_FILTER_SET_SAMPLE_RATE , equalizer_set_rate },
{ MS_EQUALIZER_SET_FREQ_WIDTH_COEF, equalizer_set_freq_width_coef},
{ 0 , NULL }
};
......
......@@ -125,7 +125,7 @@ const char *usage="mediastream --local <port> --remote <ip:port> --payload <payl
"[ --bitrate <bits per seconds>]\n"
"[ --ec (enable echo canceller)]\n"
"[ --agc (enable automatic gain control)]\n";
static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc);
static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc, bool_t eq);
int main(int argc, char * argv[])
......@@ -139,6 +139,7 @@ int main(int argc, char * argv[])
MSVideoSize vs;
bool_t ec=FALSE;
bool_t agc=FALSE;
bool_t eq=FALSE;
/*create the rtp session */
ortp_init();
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
......@@ -193,14 +194,16 @@ int main(int argc, char * argv[])
ec=TRUE;
}else if (strcmp(argv[i],"--agc")==0){
agc=TRUE;
}else if (strcmp(argv[i],"--eq")==0){
eq=TRUE;
}
}
run_media_streams(localport,ip,remoteport,payload,fmtp,jitter,ec,bitrate,vs, agc);
run_media_streams(localport,ip,remoteport,payload,fmtp,jitter,ec,bitrate,vs, agc,eq);
return 0;
}
void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc)
void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc, bool_t eq)
{
AudioStream *audio=NULL;
#ifdef VIDEO_ENABLED
......@@ -233,6 +236,10 @@ void run_media_streams(int localport, const char *remote_ip, int remoteport, in
if (audio) session=audio->session;
}else{
#ifdef VIDEO_ENABLED
if (eq){
ms_fatal("Cannot put an audio equalizer in a video stream !");
exit(-1);
}
printf("Starting video stream.\n");
video=video_stream_new(localport, ms_is_ipv6(remote_ip));
video_stream_set_sent_video_size(video,vs);
......@@ -247,34 +254,53 @@ void run_media_streams(int localport, const char *remote_ip, int remoteport, in
printf("Error: video support not compiled.\n");
#endif
}
rtp_session_register_event_queue(session,q);
while(cond)
{
int n;
for(n=0;n<100;++n){
#ifdef WIN32
MSG msg;
Sleep(10);
while (PeekMessage(&msg, NULL, 0, 0,1)){
TranslateMessage(&msg);
DispatchMessage(&msg);
if (!eq){
rtp_session_register_event_queue(session,q);
while(cond)
{
int n;
for(n=0;n<100;++n){
#ifdef WIN32
MSG msg;
Sleep(10);
while (PeekMessage(&msg, NULL, 0, 0,1)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#else
struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000;
nanosleep(&ts,NULL);
#endif
#if defined(VIDEO_ENABLED)
if (video) video_stream_iterate(video);
#endif
}
ortp_global_stats_display();
if (session){
printf("Bandwidth usage: download=%f kbits/sec, upload=%f kbits/sec\n",
rtp_session_compute_recv_bandwidth(session)*1e-3,
rtp_session_compute_send_bandwidth(session)*1e-3);
parse_events(q);
}
#else
struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000;
nanosleep(&ts,NULL);
#endif
#if defined(VIDEO_ENABLED)
if (video) video_stream_iterate(video);
#endif
}
ortp_global_stats_display();
if (session){
printf("Bandwidth usage: download=%f kbits/sec, upload=%f kbits/sec\n",
rtp_session_compute_recv_bandwidth(session)*1e-3,
rtp_session_compute_send_bandwidth(session)*1e-3);
parse_events(q);
}else{/*read from stdin equalizer commands */
char commands[128];
commands[127]='\0';
printf("Please enter equalizer requests, such as 'eq active 1', 'eq active 0', 'eq 1200 0.1'\n");
while(fgets(commands,sizeof(commands)-1,stdin)!=NULL){
int active,freq;
float gain;
if (sscanf(commands,"eq active %i",&active)==1){
audio_stream_enable_equalizer(audio,active);
printf("OK\n");
}else if (sscanf(commands,"eq %i %f",&freq,&gain)==2){
audio_stream_equalizer_set_gain(audio,freq,gain);
printf("OK\n");
}else if (strstr(commands,"quit")){
break;
}else printf("Cannot understand this.\n");
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment