mirror of
https://github.com/mpv-player/mpv
synced 2025-02-07 07:31:48 +00:00
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:
parent
c6824f577e
commit
7deec05ea0
43
libaf/af.c
43
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user