changeset 8867:558f0b1f45ee

New auto config for volume and resample and added support for float flag in configuration
author anders
date Fri, 10 Jan 2003 01:01:38 +0000
parents f84a5237f914
children 398e3fb7c103
files libaf/af.h libaf/af_resample.c libaf/af_volume.c
diffstat 3 files changed, 100 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af.h	Thu Jan 09 21:23:54 2003 +0000
+++ b/libaf/af.h	Fri Jan 10 01:01:38 2003 +0000
@@ -69,6 +69,10 @@
 #define AF_INIT_FORCE	  	0x00000003
 #define AF_INIT_TYPE_MASK 	0x00000003
 
+#define AF_INIT_INT		0x00000000
+#define AF_INIT_FLOAT		0x00000010
+#define AF_INIT_FORMAT_MASK	0x00000010
+
 // Default init type 
 #ifndef AF_INIT_TYPE
 #if defined(HAVE_SSE) || defined(HAVE_3DNOW)
--- a/libaf/af_resample.c	Thu Jan 09 21:23:54 2003 +0000
+++ b/libaf/af_resample.c	Fri Jan 10 01:01:38 2003 +0000
@@ -34,9 +34,15 @@
 #include "af_resample.h"
 
 // Filtering types
-#define TYPE_LIN   0	// Linear interpolation
-#define TYPE_INT   1   	// 16 bit integer 
-#define TYPE_FLOAT 2	// 32 bit floating point
+#define RSMP_LIN   	(0<<0)	// Linear interpolation
+#define RSMP_INT   	(1<<0)  // 16 bit integer 
+#define RSMP_FLOAT	(2<<0)	// 32 bit floating point
+#define RSMP_MASK	(3<<0)
+
+// Defines for sloppy or exact resampling
+#define FREQ_SLOPPY 	(0<<2)
+#define FREQ_EXACT  	(1<<2)
+#define FREQ_MASK	(1<<2)
 
 // Accuracy for linear interpolation
 #define STEPACCURACY 32
@@ -53,8 +59,7 @@
   uint32_t	up;	// Up sampling factor 
   uint64_t	step;	// Step size for linear interpolation
   uint64_t	pt;	// Pointer remainder for linear interpolation
-  int		sloppy;	// Enable sloppy resampling to reduce memory usage
-  int		type;	// Filter type 
+  int		setup;	// Setup parameters cmdline or through postcreate
 } af_resample_t;
 
 // Euclids algorithm for calculating Greatest Common Divisor GCD(a,b)
@@ -120,6 +125,55 @@
   return len;
 }
 
+/* Determine resampling type and format */
+static int set_types(struct af_instance_s* af, af_data_t* data)
+{
+  af_resample_t* s = af->setup;
+  int rv = AF_OK;
+  float rd = 0;
+
+  // Make sure this filter isn't redundant 
+  if((af->data->rate == data->rate) || (af->data->rate == 0))
+    return AF_DETACH;
+
+  /* If sloppy and small resampling difference (2%) */
+  rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate;
+  if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) && 
+      (data->format != (AF_FORMAT_NE | AF_FORMAT_F))) || 
+     ((s->setup & RSMP_MASK) == RSMP_LIN)){
+    s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN;
+    af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
+    af->data->bps    = 2;
+    af_msg(AF_MSG_VERBOSE,"[resample] Using linear interpolation. \n");
+  }
+  else{
+    /* If the input format is float or if float is explicitly selected
+       use float, otherwise use int */
+    if((data->format == (AF_FORMAT_NE | AF_FORMAT_F)) || 
+       ((s->setup & RSMP_MASK) == RSMP_FLOAT)){
+      s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT;
+      af->data->format = AF_FORMAT_NE | AF_FORMAT_F;
+      af->data->bps    = 4;
+    }
+    else{
+      s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT;
+      af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
+      af->data->bps    = 2;
+    }
+    af_msg(AF_MSG_VERBOSE,"[resample] Using %s processing and %s frequecy"
+	   " conversion.\n",
+	   ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer",
+	   ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact");
+  }
+
+  if(af->data->format != data->format || af->data->bps != data->bps)
+    rv = AF_FALSE;
+  data->format = af->data->format;
+  data->bps = af->data->bps;
+  af->data->nch = data->nch;
+  return rv;
+}
+
 // Initialization and runtime control
 static int control(struct af_instance_s* af, int cmd, void* arg)
 {
@@ -129,62 +183,34 @@
     af_data_t* 	   n   = (af_data_t*)arg; // New configureation
     int            i,d = 0;
     int 	   rv  = AF_OK;
-    size_t 	   tsz = (s->type==TYPE_INT) ? sizeof(int16_t) : sizeof(float);
 
-    // Make sure this filter isn't redundant 
-    if((af->data->rate == n->rate) || (af->data->rate == 0))
+    // Free space for circular bufers
+    if(s->xq){
+      for(i=1;i<af->data->nch;i++)
+	if(s->xq[i])
+	  free(s->xq[i]);
+      free(s->xq);
+    }
+
+    if(AF_DETACH == (rv = set_types(af,n)))
       return AF_DETACH;
-
+    
     // If linear interpolation 
-    if(s->type == TYPE_LIN){
+    if((s->setup & RSMP_MASK) == RSMP_LIN){
       s->pt=0LL;
       s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL;
-      af_msg(AF_MSG_VERBOSE,"[resample] Linear interpolation step: 0x%016X.\n",
+      af_msg(AF_MSG_DEBUG0,"[resample] Linear interpolation step: 0x%016X.\n",
 	     s->step);
       af->mul.n = af->data->rate;
       af->mul.d = n->rate;
-    }
-
-    // Create space for circular bufers (if nesessary)
-    if((af->data->nch != n->nch) && (s->type != TYPE_LIN)){
-      // First free the old ones
-      if(s->xq){
-	for(i=1;i<af->data->nch;i++)
-	  if(s->xq[i])
-	    free(s->xq[i]);
-	free(s->xq);
-      }
-      // ... then create new
-      s->xq = malloc(n->nch*sizeof(void*));
-      for(i=0;i<n->nch;i++)
-	s->xq[i] = malloc(2*L*tsz);
-      s->xi = 0;
+      return AF_OK;
     }
 
-    // Set parameters
-    af->data->nch    = n->nch;
-    if(s->type == TYPE_INT || s->type == TYPE_LIN){
-      af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
-      af->data->bps    = 2;
-    }
-    else{
-      af->data->format = AF_FORMAT_NE | AF_FORMAT_F;
-      af->data->bps    = 4;
-    }
-    if(af->data->format != n->format || af->data->bps != n->bps)
-      rv = AF_FALSE;
-    n->format = af->data->format;
-    n->bps = af->data->bps;
-
-    // If linear interpolation is used the setup is done.
-    if(s->type == TYPE_LIN)
-      return rv;
-
     // Calculate up and down sampling factors
     d=gcd(af->data->rate,n->rate);
 
     // If sloppy resampling is enabled limit the upsampling factor
-    if(s->sloppy && (af->data->rate/d > 5000)){
+    if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){
       int up=af->data->rate/2;
       int dn=n->rate/2;
       int m=2;
@@ -195,6 +221,12 @@
       d*=m;
     }
 
+    // Create space for circular bufers
+    s->xq = malloc(n->nch*sizeof(void*));
+    for(i=0;i<n->nch;i++)
+      s->xq[i] = malloc(2*L*af->data->bps);
+    s->xi = 0;
+
     // Check if the the design needs to be redone
     if(s->up != af->data->rate/d || s->dn != n->rate/d){
       float* w;
@@ -210,7 +242,7 @@
       w = malloc(sizeof(float) * s->up *L);
       if(NULL != s->w)
 	free(s->w);
-      s->w = malloc(L*s->up*tsz);
+      s->w = malloc(L*s->up*af->data->bps);
 
       // Design prototype filter type using Kaiser window with beta = 10
       if(NULL == w || NULL == s->w || 
@@ -222,7 +254,7 @@
       wt=w;
       for(j=0;j<L;j++){//Columns
 	for(i=0;i<s->up;i++){//Rows
-	  if(s->type == TYPE_INT){
+	  if((s->setup & RSMP_MASK) == RSMP_INT){
 	    float t=(float)s->up*32767.0*(*wt);
 	    ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5));
 	  }
@@ -245,15 +277,16 @@
   case AF_CONTROL_COMMAND_LINE:{
     af_resample_t* s   = (af_resample_t*)af->setup; 
     int rate=0;
-    int lin=0;
-    sscanf((char*)arg,"%i:%i:%i", &rate, &(s->sloppy), &lin);
-    if(lin)
-      s->type = TYPE_LIN;
+    int type=RSMP_INT;
+    int sloppy=1;
+    sscanf((char*)arg,"%i:%i:%i", &rate, &type, &sloppy);
+    s->setup = (sloppy?FREQ_SLOPPY:FREQ_EXACT) | 
+      (clamp(type,RSMP_LIN,RSMP_FLOAT));
     return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate);
   }
   case AF_CONTROL_POST_CREATE:	
-    ((af_resample_t*)af->setup)->type = 
-      ((af_cfg_t*)arg)->force  == AF_INIT_SLOW ? TYPE_INT : TYPE_FLOAT;
+    if((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == AF_INIT_FLOAT)
+      ((af_resample_t*)af->setup)->setup |= RSMP_FLOAT;
     return AF_OK;
   case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: 
     // Reinit must be called after this function has been called
@@ -293,8 +326,8 @@
     return NULL;
 
   // Run resampling
-  switch(s->type){
-  case(TYPE_INT):
+  switch(s->setup & RSMP_MASK){
+  case(RSMP_INT):
 # define FORMAT_I 1
     if(s->up>s->dn){
 #     define UP
@@ -307,7 +340,7 @@
 #     undef DN
     }
     break;
-  case(TYPE_FLOAT):
+  case(RSMP_FLOAT):
 # undef FORMAT_I
 # define FORMAT_F 1
     if(s->up>s->dn){
@@ -321,7 +354,7 @@
 #     undef DN
     }
     break;
-  case(TYPE_LIN):
+  case(RSMP_LIN):
     len = linint(c, l, s);
     break;
   }
@@ -345,6 +378,7 @@
   af->setup=calloc(1,sizeof(af_resample_t));
   if(af->data == NULL || af->setup == NULL)
     return AF_ERROR;
+  ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
   return AF_OK;
 }
 
--- a/libaf/af_volume.c	Thu Jan 09 21:23:54 2003 +0000
+++ b/libaf/af_volume.c	Fri Jan 10 01:01:38 2003 +0000
@@ -60,7 +60,7 @@
     af->data->rate   = ((af_data_t*)arg)->rate;
     af->data->nch    = ((af_data_t*)arg)->nch;
     
-    if(s->fast){
+    if(s->fast && (((af_data_t*)arg)->format != (AF_FORMAT_F | AF_FORMAT_NE))){
       af->data->format = AF_FORMAT_SI | AF_FORMAT_NE;
       af->data->bps    = 2;
     }
@@ -83,7 +83,8 @@
     return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol);
   }
   case AF_CONTROL_POST_CREATE:	
-    s->fast = ((af_cfg_t*)arg)->force  == AF_INIT_SLOW ? 1 : 0;
+    s->fast = (((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == 
+      AF_INIT_FLOAT ? 1 : 0;
     return AF_OK;
   case AF_CONTROL_VOLUME_ON_OFF | AF_CONTROL_SET:
     memcpy(s->enable,(int*)arg,AF_NCH*sizeof(int));