changeset 24888:b2402b4f0afa

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.
author uau
date Thu, 01 Nov 2007 06:52:01 +0000
parents 484b8eaaf28f
children 4055d43fc406
files libaf/af.c libaf/af.h libaf/af_center.c libaf/af_channels.c libaf/af_comp.c libaf/af_delay.c libaf/af_dummy.c libaf/af_equalizer.c libaf/af_export.c libaf/af_extrastereo.c libaf/af_format.c libaf/af_gate.c libaf/af_hrtf.c libaf/af_karaoke.c libaf/af_ladspa.c libaf/af_lavcresample.c libaf/af_pan.c libaf/af_resample.c libaf/af_sinesuppress.c libaf/af_sub.c libaf/af_surround.c libaf/af_sweep.c libaf/af_volnorm.c libaf/af_volume.c
diffstat 24 files changed, 54 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af.c	Thu Nov 01 06:52:01 2007 +0000
@@ -516,12 +516,14 @@
   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 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;
 }
 
--- a/libaf/af.h	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af.h	Thu Nov 01 06:52:01 2007 +0000
@@ -65,7 +65,7 @@
   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 @@
 /* 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
--- a/libaf/af_center.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_center.c	Thu Nov 01 06:52:01 2007 +0000
@@ -95,8 +95,7 @@
   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)
--- a/libaf/af_channels.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_channels.c	Thu Nov 01 06:52:01 2007 +0000
@@ -148,9 +148,7 @@
     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 @@
     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 @@
   
   // 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 @@
   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))
--- a/libaf/af_comp.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_comp.c	Thu Nov 01 06:52:01 2007 +0000
@@ -141,8 +141,7 @@
   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)
--- a/libaf/af_delay.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_delay.c	Thu Nov 01 06:52:01 2007 +0000
@@ -167,8 +167,7 @@
   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)
--- a/libaf/af_dummy.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_dummy.c	Thu Nov 01 06:52:01 2007 +0000
@@ -40,8 +40,7 @@
   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;
--- a/libaf/af_equalizer.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_equalizer.c	Thu Nov 01 06:52:01 2007 +0000
@@ -222,8 +222,7 @@
   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)
--- a/libaf/af_export.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_export.c	Thu Nov 01 06:52:01 2007 +0000
@@ -239,8 +239,7 @@
   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))
--- a/libaf/af_extrastereo.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_extrastereo.c	Thu Nov 01 06:52:01 2007 +0000
@@ -128,8 +128,7 @@
   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)
--- a/libaf/af_format.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_format.c	Thu Nov 01 06:52:01 2007 +0000
@@ -104,9 +104,7 @@
 
     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 @@
   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;
--- a/libaf/af_gate.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_gate.c	Thu Nov 01 06:52:01 2007 +0000
@@ -137,8 +137,7 @@
   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)
--- a/libaf/af_hrtf.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_hrtf.c	Thu Nov 01 06:52:01 2007 +0000
@@ -293,8 +293,7 @@
 	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 @@
 
     /* 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 @@
     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))
--- a/libaf/af_karaoke.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_karaoke.c	Thu Nov 01 06:52:01 2007 +0000
@@ -65,8 +65,7 @@
 	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)
--- a/libaf/af_ladspa.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_ladspa.c	Thu Nov 01 06:52:01 2007 +0000
@@ -940,8 +940,7 @@
     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)
--- a/libaf/af_lavcresample.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_lavcresample.c	Thu Nov 01 06:52:01 2007 +0000
@@ -47,13 +47,11 @@
     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 @@
   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 @@
   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);
--- a/libaf/af_pan.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_pan.c	Thu Nov 01 06:52:01 2007 +0000
@@ -40,9 +40,7 @@
     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 @@
 
   // 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 @@
   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)
--- a/libaf/af_resample.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_resample.c	Thu Nov 01 06:52:01 2007 +0000
@@ -184,9 +184,7 @@
       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 @@
 
     // 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 @@
   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)
--- a/libaf/af_sinesuppress.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_sinesuppress.c	Thu Nov 01 06:52:01 2007 +0000
@@ -153,8 +153,7 @@
   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)
--- a/libaf/af_sub.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_sub.c	Thu Nov 01 06:52:01 2007 +0000
@@ -158,8 +158,7 @@
   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)
--- a/libaf/af_surround.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_surround.c	Thu Nov 01 06:52:01 2007 +0000
@@ -243,7 +243,7 @@
 
   // 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 @@
   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)
--- a/libaf/af_sweep.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_sweep.c	Thu Nov 01 06:52:01 2007 +0000
@@ -74,8 +74,7 @@
   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;
--- a/libaf/af_volnorm.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_volnorm.c	Thu Nov 01 06:52:01 2007 +0000
@@ -315,8 +315,7 @@
   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)
--- a/libaf/af_volume.c	Thu Nov 01 06:51:57 2007 +0000
+++ b/libaf/af_volume.c	Thu Nov 01 06:52:01 2007 +0000
@@ -195,8 +195,7 @@
   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)