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
This commit is contained in:
uau 2007-11-01 06:52:01 +00:00
parent c6824f577e
commit 7deec05ea0
24 changed files with 54 additions and 99 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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