[MPlayer-dev-eng] [PATCH] Proof of concept extrasurround plugin

Kis Gergely kisg at lme.linux.hu
Thu Apr 4 15:55:45 CEST 2002


Hi,
I promise this is the last patch from me today. I hope Arpi won't ban me for
this.

I added a sochans option for the pl_surround plugin.
Usage:
mplayer -aop list=surround:sochans=6 filename

4 channel output is the default. The nice thing is, that in 4 channel mode
every file plays well. In 6 channel mode the previous problems apply.

Could somebody try it out, and tell me what am I missing?

The patch is attached, and uploaded to mplayerhq/incoming/extrasurround

You can also get it from http://www.inf.bme.hu/~kisg/mplayer

Thanks,
kisg

-------------- next part --------------
? cfg-mplayer.h.kisg4
? extrasurround_kisg4.patch
? libao2/audio_plugin.h.kisg4
? libao2/pl_surround.c.kisg1
? libao2/pl_surround.c.kisg2
Index: cfg-mplayer.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-mplayer.h,v
retrieving revision 1.143
diff -u -r1.143 cfg-mplayer.h
--- cfg-mplayer.h	4 Apr 2002 00:00:41 -0000	1.143
+++ cfg-mplayer.h	4 Apr 2002 13:58:14 -0000
@@ -112,6 +112,7 @@
 	{"volume", &ao_plugin_cfg.pl_volume_volume, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
 	{"mul", &ao_plugin_cfg.pl_extrastereo_mul, CONF_TYPE_FLOAT, CONF_RANGE, -10.0, 10.0, NULL},
 	{"softclip", &ao_plugin_cfg.pl_volume_softclip, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"sochans", &ao_plugin_cfg.pl_surround_sochans, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL},
 	{NULL, NULL, 0, 0, 0, 0, NULL}
 };
 
Index: libao2/audio_plugin.h
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/audio_plugin.h,v
retrieving revision 1.10
diff -u -r1.10 audio_plugin.h
--- libao2/audio_plugin.h	13 Mar 2002 12:32:42 -0000	1.10
+++ libao2/audio_plugin.h	4 Apr 2002 13:58:16 -0000
@@ -38,6 +38,7 @@
   int pl_volume_volume; // Initial volume setting
   float pl_extrastereo_mul; // Stereo enhancer multiplier
   int pl_volume_softclip;   // Enable soft clipping
+  int pl_surround_sochans; // Output channels for surround plugin 
 } ao_plugin_cfg_t;
 
 extern ao_plugin_cfg_t ao_plugin_cfg;
@@ -50,7 +51,8 @@
  48000, \
  101, \
  2.5, \
- 0 \
+ 0, \
+ 4 \
 };
 
 // This block should not be available in the pl_xxxx files
Index: libao2/pl_surround.c
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/pl_surround.c,v
retrieving revision 1.9
diff -u -r1.9 pl_surround.c
--- libao2/pl_surround.c	24 Dec 2001 18:54:58 -0000	1.9
+++ libao2/pl_surround.c	4 Apr 2002 13:58:17 -0000
@@ -64,6 +64,7 @@
   int passthrough;      // Just be a "NO-OP"
   int msecs;            // Rear channel delay in milliseconds
   int16_t* databuf;     // Output audio buffer
+  int databuf_len;	// Output audio buffer length in samples
   int16_t* Ls_delaybuf; // circular buffer to be used for delaying Ls audio
   int16_t* Rs_delaybuf; // circular buffer to be used for delaying Rs audio
   int delaybuf_len;     // delaybuf buffer length in samples
@@ -72,10 +73,14 @@
   int rate;             // input data rate
   int format;           // input format
   int input_channels;   // input channels
+  int output_channels;  // output channels
+  float lowp_cutoff;    // cutoff freq for the lowpass filter
+  double lowp_A, lowp_B; // parameters for lowpass filter
+  double lowp_outm1;		// output for lowpass filter (??)
 
 } pl_surround_t;
 
-static pl_surround_t pl_surround={0,20,NULL,NULL,NULL,0,0,NULL,0,0,0};
+static pl_surround_t pl_surround={0,20,NULL,0,NULL,NULL,0,0,NULL,0,0,0,0,0,0,0,0};
 
 // to set/get/query special features/parameters
 static int control(int cmd,int arg){
@@ -89,9 +94,10 @@
       free(pl_surround.databuf);  pl_surround.databuf = NULL;
     }
     // Allocate output buffer
-    pl_surround.databuf = calloc(ao_plugin_data.len, 1);
+    pl_surround.databuf_len = ao_plugin_data.len / sizeof(int16_t) / pl_surround.input_channels;
+    pl_surround.databuf = calloc(pl_surround.databuf_len, sizeof(int16_t)*pl_surround.output_channels);
     // Return back smaller len so we don't get overflowed...
-    ao_plugin_data.len /= 2;
+    // ao_plugin_data.len /= 2;
     return CONTROL_OK;
   }
   return -1;
@@ -113,6 +119,12 @@
     return 1;
   }
 
+  if (ao_plugin_cfg.pl_surround_sochans != 4 && ao_plugin_cfg.pl_surround_sochans != 6) {
+    fprintf(stderr, "pl_surround: I'm dumb and can only output 4 or 6 channel sound. Entering passtrough mode.\n");
+    pl_surround.passthrough = 1;
+    return 1;    
+  }
+
   pl_surround.passthrough = 0;
 
   /* Store info on input format to expect */
@@ -120,9 +132,16 @@
   pl_surround.format=ao_plugin_data.format;
   pl_surround.input_channels=ao_plugin_data.channels;
 
+  /* Store info on output channel number */
+  pl_surround.output_channels = ao_plugin_cfg.pl_surround_sochans;
+
+
   // Input 2 channels, output will be 4 - tell ao_plugin
-  ao_plugin_data.channels    = 4;
-  ao_plugin_data.sz_mult    /= 2;
+//  ao_plugin_data.channels    = 4;
+//  ao_plugin_data.sz_mult    /= 2;
+
+  ao_plugin_data.channels    = pl_surround.output_channels;
+  ao_plugin_data.sz_mult    /= pl_surround.output_channels / pl_surround.input_channels;
 
   // Figure out buffer space (in int16_ts) needed for the 15msec delay
   // Extra 31 samples allow for lowpass filter delay (taps-1)
@@ -137,6 +156,16 @@
   pl_surround.filter_coefs_surround = calc_coefficients_7kHz_lowpass(pl_surround.rate);
   //dump_filter_coefficients(pl_surround.filter_coefs_surround);
   //testfilter(pl_surround.filter_coefs_surround, 32, pl_surround.rate);
+  
+  pl_surround.lowp_cutoff = 7000;
+  if (pl_surround.lowp_cutoff > pl_surround.rate / 2) {
+    // Cutoff rate must be < sample rate / 2 (Nyquist rate)
+    pl_surround.lowp_cutoff = pl_surround.rate / 2 - 1;
+  } 
+  pl_surround.lowp_B = exp ((-2.0 * M_PI * (pl_surround.lowp_cutoff / pl_surround.rate)));
+  pl_surround.lowp_A = 1 - pl_surround.lowp_B;
+  pl_surround.lowp_outm1 = 0.0;
+  
   return 1;
 }
 
@@ -161,6 +190,7 @@
   pl_surround.delaybuf_pos = 0;
   memset(pl_surround.Ls_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
   memset(pl_surround.Rs_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
+  pl_surround.lowp_outm1 = 0;
 }
 
 // The beginnings of an active matrix...
@@ -222,6 +252,26 @@
 #else
     out[3] = -out[2];
 #endif
+    if (pl_surround.output_channels == 6) {
+    
+	int32_t avg;
+	double d;
+	avg = (out[0] + out[1]) / 2;
+	
+	d = pl_surround.lowp_A * avg + pl_surround.lowp_B * pl_surround.lowp_outm1;
+
+	if (d > 32767L) {
+	    d = 32767L;
+	}
+	if (d < -32768L) {
+	    d = -32768L;
+	}
+	pl_surround.lowp_outm1 = d;
+	out[5] = d;
+	// Only 4.1 output, center speaker remains silent
+	out[4] = 0;
+    }
+    
     // calculate and save surround for 20msecs time
 #ifdef SPLITREAR
     pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos] =
@@ -235,7 +285,7 @@
     pl_surround.delaybuf_pos %= pl_surround.delaybuf_len;
 
     // next samples...
-    in = &in[pl_surround.input_channels];  out = &out[4];
+    in = &in[pl_surround.input_channels];  out = &out[pl_surround.output_channels];
   }
 
   // Show some state
@@ -243,6 +293,6 @@
   
   // Set output block/len
   ao_plugin_data.data=pl_surround.databuf;
-  ao_plugin_data.len=samples*sizeof(int16_t)*4;
+  ao_plugin_data.len=samples*sizeof(int16_t)*pl_surround.output_channels;
   return 1;
 }
? libavcodec/.depend
? libavcodec/README.MPlayer


More information about the MPlayer-dev-eng mailing list