[MPlayer-dev-eng] [PATCH] A new "balance" filter

Zuxy Meng zuxy.meng at gmail.com
Sun Jun 10 18:54:59 CEST 2007


Hi,

As discussed with Reimar, due to subtle semantic problems existing pan
filter cannot be used to implement the audio balance feature, so I've
simply added a new filter, mostly based on pan code.

Currently it's for internal use only and doesn't expose an
AF_CONTROL_COMMAND_LINE interface so no document update is included.

-- 
Zuxy
Beauty is truth,
While truth is beauty.
PGP KeyID: E8555ED6
-------------- next part --------------
Index: libaf/af_pan.c
===================================================================
--- libaf/af_pan.c	?????? 23533??
+++ libaf/af_pan.c	????????????
@@ -26,7 +26,7 @@
 }af_pan_t;
 
 // Initialization and runtime control
-static int control(struct af_instance_s* af, int cmd, void* arg)
+static int control(struct af_instance_s* af, int cmd, void* arg, int pan)
 {
   af_pan_t* s = af->setup; 
 
@@ -35,6 +35,8 @@
     // Sanity check
     if(!arg) return AF_ERROR;
 
+    if (!pan)
+      af->data->nch = ((af_data_t*)arg)->nch;
     af->data->rate   = ((af_data_t*)arg)->rate;
     af->data->format = AF_FORMAT_FLOAT_NE;
     af->data->bps    = 4;
@@ -48,15 +50,22 @@
       ((af_data_t*)arg)->bps = af->data->bps;
       return AF_FALSE;
     }
-    return control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &af->data->nch);
+    if (pan)
+      return control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET,
+	  &af->data->nch, pan);
+    else
+      return AF_OK;
   case AF_CONTROL_COMMAND_LINE:{
     int   nch = 0;
     int   n = 0;
     char* cp = NULL;
     int   j,k;
+
+    if (!pan)
+      return AF_UNKNOWN;
     // Read number of outputs
     sscanf((char*)arg,"%i%n", &nch,&n);
-    if(AF_OK != control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &nch))
+    if(AF_OK != control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &nch, pan))
       return AF_ERROR;
 
     // Read pan values
@@ -75,6 +84,7 @@
     }
     return AF_OK;
   }
+  case AF_CONTROL_BALANCE_LEVEL | AF_CONTROL_SET:
   case AF_CONTROL_PAN_LEVEL | AF_CONTROL_SET:{
     int    i;
     int    ch = ((af_control_ext_t*)arg)->ch;
@@ -85,6 +95,7 @@
       s->level[ch][i] = level[i];
     return AF_OK;
   }
+  case AF_CONTROL_BALANCE_LEVEL | AF_CONTROL_GET:
   case AF_CONTROL_PAN_LEVEL | AF_CONTROL_GET:{
     int    i;
     int ch = ((af_control_ext_t*)arg)->ch;
@@ -98,6 +109,8 @@
   case AF_CONTROL_PAN_NOUT | AF_CONTROL_SET:
     // Reinit must be called after this function has been called
 
+    if (!pan)
+      return AF_UNKNOWN;
     // Sanity check
     if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){
       af_msg(AF_MSG_ERROR,"[pan] The number of output channels must be" 
@@ -106,6 +119,7 @@
     }
     af->data->nch=((int*)arg)[0];
     return AF_OK;
+  case AF_CONTROL_BALANCE_NOUT | AF_CONTROL_GET:
   case AF_CONTROL_PAN_NOUT | AF_CONTROL_GET:
     *(int*)arg = af->data->nch;
     return AF_OK;
@@ -113,6 +127,16 @@
   return AF_UNKNOWN;
 }
 
+static int control_pan(struct af_instance_s* af, int cmd, void* arg)
+{
+  return control(af, cmd, arg, 1);
+}
+
+static int control_balance(struct af_instance_s* af, int cmd, void* arg)
+{
+  return control(af, cmd, arg, 0);
+}
+
 // Deallocate memory 
 static void uninit(struct af_instance_s* af)
 {
@@ -163,8 +187,8 @@
 }
 
 // Allocate memory and set function pointers
-static int af_open(af_instance_t* af){
-  af->control=control;
+static int af_open(af_instance_t* af, int pan){
+  af->control=pan?control_pan:control_balance;
   af->uninit=uninit;
   af->play=play;
   af->mul.n=1;
@@ -174,9 +198,23 @@
   if(af->data == NULL || af->setup == NULL)
     return AF_ERROR;
   // Set initial pan to pass-through.
+  if (!pan) {
+    int i;
+    af_pan_t* s = af->setup;
+    for (i = 0; i < AF_NCH; i++)
+      s->level[i][i] = 1.f;
+  }
   return AF_OK;
 }
 
+static int af_open_pan(af_instance_t* af){
+  return af_open(af, 1);
+}
+
+static int af_open_balance(af_instance_t* af){
+  return af_open(af, 0);
+}
+
 // Description of this filter
 af_info_t af_info_pan = {
     "Panning audio filter",
@@ -184,5 +222,16 @@
     "Anders",
     "",
     AF_FLAGS_NOT_REENTRANT,
-    af_open
+    af_open_pan
 };
+
+// Description of this filter
+af_info_t af_info_balance = {
+    "Balancing audio filter",
+    "balance",
+    "Zuxy",
+    "",
+    AF_FLAGS_NOT_REENTRANT,
+    af_open_balance
+};
+
Index: libaf/control.h
===================================================================
--- libaf/control.h	?????? 23533??
+++ libaf/control.h	????????????
@@ -229,4 +229,8 @@
 #define AF_CONTROL_SS_FREQ		0x00002300 | AF_CONTROL_FILTER_SPECIFIC
 #define AF_CONTROL_SS_DECAY		0x00002400 | AF_CONTROL_FILTER_SPECIFIC
 
+// Balance
+#define AF_CONTROL_BALANCE_LEVEL 	0x00002500 | AF_CONTROL_FILTER_SPECIFIC
+#define AF_CONTROL_BALANCE_NOUT 	0x00002600 | AF_CONTROL_FILTER_SPECIFIC
+
 #endif /*__af_control_h */
Index: libaf/af.c
===================================================================
--- libaf/af.c	?????? 23533??
+++ libaf/af.c	????????????
@@ -19,6 +19,7 @@
 extern af_info_t af_info_gate;
 extern af_info_t af_info_comp;
 extern af_info_t af_info_pan;
+extern af_info_t af_info_balance;
 extern af_info_t af_info_surround;
 extern af_info_t af_info_sub;
 extern af_info_t af_info_export;
@@ -43,6 +44,7 @@
    &af_info_gate,
    &af_info_comp,
    &af_info_pan,
+   &af_info_balance,
    &af_info_surround,
    &af_info_sub,
 #ifdef HAVE_SYS_MMAN_H


More information about the MPlayer-dev-eng mailing list