diff options
author | uau <uau@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2007-11-01 06:52:01 +0000 |
---|---|---|
committer | uau <uau@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2007-11-01 06:52:01 +0000 |
commit | 7deec05ea0d14dd950715f232b9e7cb7183dd333 (patch) | |
tree | a669500520b58be3ba988f7a3e7e0b7d802e0313 /libaf | |
parent | c6824f577ee5da01a7bb0b787d0253da925c2c0f (diff) | |
download | mpv-7deec05ea0d14dd950715f232b9e7cb7183dd333.tar.bz2 mpv-7deec05ea0d14dd950715f232b9e7cb7183dd333.tar.xz |
libaf: change filter input/output ratio calculations
Change the audio filters to use a double instead of rationals for the
ratio of output to input size. The rationals could overflow when
calculating the overall ratio of a filter chain and gave no real
advantage compared to doubles.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@24916 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libaf')
-rw-r--r-- | libaf/af.c | 43 | ||||
-rw-r--r-- | libaf/af.h | 4 | ||||
-rw-r--r-- | libaf/af_center.c | 3 | ||||
-rw-r--r-- | libaf/af_channels.c | 11 | ||||
-rw-r--r-- | libaf/af_comp.c | 3 | ||||
-rw-r--r-- | libaf/af_delay.c | 3 | ||||
-rw-r--r-- | libaf/af_dummy.c | 3 | ||||
-rw-r--r-- | libaf/af_equalizer.c | 3 | ||||
-rw-r--r-- | libaf/af_export.c | 3 | ||||
-rw-r--r-- | libaf/af_extrastereo.c | 3 | ||||
-rw-r--r-- | libaf/af_format.c | 7 | ||||
-rw-r--r-- | libaf/af_gate.c | 3 | ||||
-rw-r--r-- | libaf/af_hrtf.c | 8 | ||||
-rw-r--r-- | libaf/af_karaoke.c | 3 | ||||
-rw-r--r-- | libaf/af_ladspa.c | 3 | ||||
-rw-r--r-- | libaf/af_lavcresample.c | 11 | ||||
-rw-r--r-- | libaf/af_pan.c | 9 | ||||
-rw-r--r-- | libaf/af_resample.c | 10 | ||||
-rw-r--r-- | libaf/af_sinesuppress.c | 3 | ||||
-rw-r--r-- | libaf/af_sub.c | 3 | ||||
-rw-r--r-- | libaf/af_surround.c | 5 | ||||
-rw-r--r-- | libaf/af_sweep.c | 3 | ||||
-rw-r--r-- | libaf/af_volnorm.c | 3 | ||||
-rw-r--r-- | libaf/af_volume.c | 3 |
24 files changed, 54 insertions, 99 deletions
diff --git a/libaf/af.c b/libaf/af.c index 5b1b36cdbf..5c529875ee 100644 --- a/libaf/af.c +++ b/libaf/af.c @@ -516,12 +516,14 @@ af_data_t* af_play(af_stream_t* s, af_data_t* data) return data; } -/* Helper function used to calculate the exact buffer length needed - when buffers are resized. The returned length is >= than what is - needed */ -inline int af_lencalc(frac_t mul, af_data_t* d){ - register int t = d->bps*d->nch; - return t*(((d->len/t)*mul.n)/mul.d + 1); +/* Calculate the minimum output buffer size for given input data d + * when using the RESIZE_LOCAL_BUFFER macro. The +t+1 part ensures the + * value is >= len*mul rounded upwards to whole samples even if the + * double 'mul' is inexact. */ +int af_lencalc(double mul, af_data_t* d) +{ + int t = d->bps * d->nch; + return d->len * mul + t + 1; } /* Calculate how long the input IN to the filters should be to produce @@ -537,34 +539,21 @@ int af_calc_insize_constrained(af_stream_t* s, int len, { int t = s->input.bps*s->input.nch; int in = 0; - int out = 0; af_instance_t* af=s->first; - frac_t mul = {1,1}; + double mul = 1; // Iterate through all filters and calculate total multiplication factor do{ - af_frac_mul(&mul, &af->mul); - af=af->next; + mul *= af->mul; + af=af->next; }while(af); - // Sanity check - if(!mul.n || !mul.d) - return -1; - in = t * (((len/t) * mul.d - 1)/mul.n); - + if (len > max_outsize) + len = max_outsize; + + in = len / t / mul * t; + if(in>max_insize) in=t*(max_insize/t); - // Try to meet constraint nr 3. - while((out=t * (((in/t+1)*mul.n - 1)/mul.d)) <= max_outsize && in<=max_insize){ - if( (t * (((in/t)*mul.n))/mul.d) >= len) return in; - in+=t; - } - - // Could no meet constraint nr 3. - while(out > max_outsize || in > max_insize){ - in-=t; - if(in<t) return -1; // Input parameters are probably incorrect - out = t * (((in/t)*mul.n + 1)/mul.d); - } return in; } diff --git a/libaf/af.h b/libaf/af.h index d41f9964fb..8f9ab9183b 100644 --- a/libaf/af.h +++ b/libaf/af.h @@ -65,7 +65,7 @@ typedef struct af_instance_s struct af_instance_s* next; struct af_instance_s* prev; double delay; // Delay caused by the filter [ms] - frac_t mul; /* length multiplier: how much does this instance change + double mul; /* length multiplier: how much does this instance change the length of the buffer. */ }af_instance_t; @@ -238,7 +238,7 @@ int af_resize_local_buffer(af_instance_t* af, af_data_t* data); /* Helper function used to calculate the exact buffer length needed when buffers are resized. The returned length is >= than what is needed */ -int af_lencalc(frac_t mul, af_data_t* data); +int af_lencalc(double mul, af_data_t* data); /** * \brief convert dB to gain value diff --git a/libaf/af_center.c b/libaf/af_center.c index 484742f623..dd9f624ebe 100644 --- a/libaf/af_center.c +++ b/libaf/af_center.c @@ -95,8 +95,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=s=calloc(1,sizeof(af_center_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_channels.c b/libaf/af_channels.c index 3ebb894f56..772242038e 100644 --- a/libaf/af_channels.c +++ b/libaf/af_channels.c @@ -148,9 +148,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) af->data->rate = ((af_data_t*)arg)->rate; af->data->format = ((af_data_t*)arg)->format; af->data->bps = ((af_data_t*)arg)->bps; - af->mul.n = af->data->nch; - af->mul.d = ((af_data_t*)arg)->nch; - af_frac_cancel(&af->mul); + af->mul = (double)af->data->nch / ((af_data_t*)arg)->nch; return check_routes(s,((af_data_t*)arg)->nch,af->data->nch); case AF_CONTROL_COMMAND_LINE:{ int nch = 0; @@ -251,7 +249,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) return NULL; // Reset unused channels - memset(l->audio,0,(c->len*af->mul.n)/af->mul.d); + memset(l->audio,0,c->len / c->nch * l->nch); if(AF_OK == check_routes(s,c->nch,l->nch)) for(i=0;i<s->nr;i++) @@ -260,7 +258,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) // Set output data c->audio = l->audio; - c->len = (c->len*af->mul.n)/af->mul.d; + c->len = c->len / c->nch * l->nch; c->nch = l->nch; return c; @@ -271,8 +269,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_channels_t)); if((af->data == NULL) || (af->setup == NULL)) diff --git a/libaf/af_comp.c b/libaf/af_comp.c index 2d92413ba3..0b77c7a025 100644 --- a/libaf/af_comp.c +++ b/libaf/af_comp.c @@ -141,8 +141,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_comp_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_delay.c b/libaf/af_delay.c index b7532da98b..61bd77c24d 100644 --- a/libaf/af_delay.c +++ b/libaf/af_delay.c @@ -167,8 +167,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_delay_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_dummy.c b/libaf/af_dummy.c index 05d51ac191..3136dbb00f 100644 --- a/libaf/af_dummy.c +++ b/libaf/af_dummy.c @@ -40,8 +40,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.d=1; - af->mul.n=1; + af->mul=1; af->data=malloc(sizeof(af_data_t)); if(af->data == NULL) return AF_ERROR; diff --git a/libaf/af_equalizer.c b/libaf/af_equalizer.c index a86225269a..9eb09a8188 100644 --- a/libaf/af_equalizer.c +++ b/libaf/af_equalizer.c @@ -222,8 +222,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_equalizer_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_export.c b/libaf/af_export.c index ff8871fdee..571507019d 100644 --- a/libaf/af_export.c +++ b/libaf/af_export.c @@ -239,8 +239,7 @@ static int af_open( af_instance_t* af ) af->control = control; af->uninit = uninit; af->play = play; - af->mul.n = 1; - af->mul.d = 1; + af->mul=1; af->data = calloc(1, sizeof(af_data_t)); af->setup = calloc(1, sizeof(af_export_t)); if((af->data == NULL) || (af->setup == NULL)) diff --git a/libaf/af_extrastereo.c b/libaf/af_extrastereo.c index 2aaf941128..7159221d54 100644 --- a/libaf/af_extrastereo.c +++ b/libaf/af_extrastereo.c @@ -128,8 +128,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play_s16; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_extrastereo_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_format.c b/libaf/af_format.c index c042c6acce..58f70732f3 100644 --- a/libaf/af_format.c +++ b/libaf/af_format.c @@ -104,9 +104,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) af->data->rate = data->rate; af->data->nch = data->nch; - af->mul.n = af->data->bps; - af->mul.d = data->bps; - af_frac_cancel(&af->mul); + af->mul = (double)af->data->bps / data->bps; af->play = play; // set default @@ -309,8 +307,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); if(af->data == NULL) return AF_ERROR; diff --git a/libaf/af_gate.c b/libaf/af_gate.c index 8f5038fa51..f4d574a64e 100644 --- a/libaf/af_gate.c +++ b/libaf/af_gate.c @@ -137,8 +137,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_gate_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_hrtf.c b/libaf/af_hrtf.c index 3e973f62f2..e8d0b9cd14 100644 --- a/libaf/af_hrtf.c +++ b/libaf/af_hrtf.c @@ -293,8 +293,7 @@ static int control(struct af_instance_s *af, int cmd, void* arg) af->data->format = AF_FORMAT_S16_NE; af->data->bps = 2; test_output_res = af_test_output(af, (af_data_t*)arg); - af->mul.n = 2; - af->mul.d = af->data->nch; + af->mul = 2.0 / af->data->nch; // after testing input set the real output format af->data->nch = 2; s->print_flag = 1; @@ -560,7 +559,7 @@ static af_data_t* play(struct af_instance_s *af, af_data_t *data) /* Set output data */ data->audio = af->data->audio; - data->len = (data->len * af->mul.n) / af->mul.d; + data->len = data->len / data->nch * 2; data->nch = 2; return data; @@ -597,8 +596,7 @@ static int af_open(af_instance_t* af) af->control = control; af->uninit = uninit; af->play = play; - af->mul.n = 1; - af->mul.d = 1; + af->mul = 1; af->data = calloc(1, sizeof(af_data_t)); af->setup = calloc(1, sizeof(af_hrtf_t)); if((af->data == NULL) || (af->setup == NULL)) diff --git a/libaf/af_karaoke.c b/libaf/af_karaoke.c index a1426bb58f..6524f0edd0 100644 --- a/libaf/af_karaoke.c +++ b/libaf/af_karaoke.c @@ -65,8 +65,7 @@ static int af_open(af_instance_t* af){ af->control = control; af->uninit = uninit; af->play = play; - af->mul.n = 1; - af->mul.d = 1; + af->mul = 1; af->data = calloc(1,sizeof(af_data_t)); if(af->data == NULL) diff --git a/libaf/af_ladspa.c b/libaf/af_ladspa.c index 5fd03f367d..199faabfbb 100644 --- a/libaf/af_ladspa.c +++ b/libaf/af_ladspa.c @@ -940,8 +940,7 @@ static int af_open(af_instance_t *af) { af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data = calloc(1, sizeof(af_data_t)); if (af->data == NULL) diff --git a/libaf/af_lavcresample.c b/libaf/af_lavcresample.c index fd288bf4be..f44f26cabf 100644 --- a/libaf/af_lavcresample.c +++ b/libaf/af_lavcresample.c @@ -47,13 +47,11 @@ static int control(struct af_instance_s* af, int cmd, void* arg) if (af->data->nch > AF_NCH) af->data->nch = AF_NCH; af->data->format = AF_FORMAT_S16_NE; af->data->bps = 2; - af->mul.n = af->data->rate; - af->mul.d = data->rate; - af_frac_cancel(&af->mul); + af->mul = (double)af->data->rate / data->rate; af->delay = 500*s->filter_length/(double)min(af->data->rate, data->rate); if(s->avrctx) av_resample_close(s->avrctx); - s->avrctx= av_resample_init(af->mul.n, /*in_rate*/af->mul.d, s->filter_length, s->phase_shift, s->linear, s->cutoff); + s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff); // hack to make af_test_output ignore the samplerate change out_rate = af->data->rate; @@ -99,7 +97,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) int16_t *out; int chans = data->nch; int in_len = data->len/(2*chans); - int out_len = (in_len*af->mul.n) / af->mul.d + 10; + int out_len = in_len * af->mul + 10; int16_t tmp[AF_NCH][out_len]; if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) @@ -168,8 +166,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); s->filter_length= 16; s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80); diff --git a/libaf/af_pan.c b/libaf/af_pan.c index 7d25e1afde..67c58a22a2 100644 --- a/libaf/af_pan.c +++ b/libaf/af_pan.c @@ -40,9 +40,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) af->data->format = AF_FORMAT_FLOAT_NE; af->data->bps = 4; af->data->nch = s->nch ? s->nch: ((af_data_t*)arg)->nch; - af->mul.n = af->data->nch; - af->mul.d = ((af_data_t*)arg)->nch; - af_frac_cancel(&af->mul); + af->mul = (double)af->data->nch / ((af_data_t*)arg)->nch; if((af->data->format != ((af_data_t*)arg)->format) || (af->data->bps != ((af_data_t*)arg)->bps)){ @@ -175,7 +173,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) // Set output data c->audio = l->audio; - c->len = (c->len*af->mul.n)/af->mul.d; + c->len = c->len / c->nch * l->nch; c->nch = l->nch; return c; @@ -186,8 +184,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_pan_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_resample.c b/libaf/af_resample.c index 87fcef446b..e5332cb230 100644 --- a/libaf/af_resample.c +++ b/libaf/af_resample.c @@ -184,9 +184,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL; af_msg(AF_MSG_DEBUG0,"[resample] Linear interpolation step: 0x%016"PRIX64".\n", s->step); - af->mul.n = af->data->rate; - af->mul.d = n->rate; - af_frac_cancel(&af->mul); + af->mul = (double)af->data->rate / n->rate; return rv; } @@ -256,8 +254,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) // Set multiplier and delay af->delay = (double)(1000*L/2)/((double)n->rate); - af->mul.n = s->up; - af->mul.d = s->dn; + af->mul = (double)s->up / s->dn; return rv; } case AF_CONTROL_COMMAND_LINE:{ @@ -359,8 +356,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_resample_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_sinesuppress.c b/libaf/af_sinesuppress.c index 4e56413325..9928ebc17c 100644 --- a/libaf/af_sinesuppress.c +++ b/libaf/af_sinesuppress.c @@ -153,8 +153,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play_s16; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_sinesuppress_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_sub.c b/libaf/af_sub.c index bb6ff81095..3a48363e8e 100644 --- a/libaf/af_sub.c +++ b/libaf/af_sub.c @@ -158,8 +158,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=s=calloc(1,sizeof(af_sub_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_surround.c b/libaf/af_surround.c index 3c56279d03..5966e725fb 100644 --- a/libaf/af_surround.c +++ b/libaf/af_surround.c @@ -243,7 +243,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data){ // Set output data data->audio = af->data->audio; - data->len = (data->len*af->mul.n)/af->mul.d; + data->len *= 2; data->nch = af->data->nch; return data; @@ -253,8 +253,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=2; - af->mul.d=1; + af->mul=2; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_surround_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_sweep.c b/libaf/af_sweep.c index 6c44cada43..c75ce28f78 100644 --- a/libaf/af_sweep.c +++ b/libaf/af_sweep.c @@ -74,8 +74,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_sweept)); return AF_OK; diff --git a/libaf/af_volnorm.c b/libaf/af_volnorm.c index f4ef35fb5f..d067e78db7 100644 --- a/libaf/af_volnorm.c +++ b/libaf/af_volnorm.c @@ -315,8 +315,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_volnorm_t)); if(af->data == NULL || af->setup == NULL) diff --git a/libaf/af_volume.c b/libaf/af_volume.c index 664cf87427..c06b6710a6 100644 --- a/libaf/af_volume.c +++ b/libaf/af_volume.c @@ -195,8 +195,7 @@ static int af_open(af_instance_t* af){ af->control=control; af->uninit=uninit; af->play=play; - af->mul.n=1; - af->mul.d=1; + af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=calloc(1,sizeof(af_volume_t)); if(af->data == NULL || af->setup == NULL) |