[MPlayer-dev-eng] [PATCH] Proof of concept extrasurround plugin
Kis Gergely
kisg at lme.linux.hu
Thu Apr 4 14:50:55 CEST 2002
Hi,
I found some more bugs in the plugin...
I attached the new version and uploaded sample media to
MPlayerHQ/incoming/extrasurround
You can download the sample media from http://www.inf.bme.hu/~kisg/mplayer too.
WHAT'S NEW:
-> More bugs discovered.
-> More parametrized code, one step closer to finish the first TODO item.
TODO:
-> Make it an option of the plugin
-> Use the same lowpass filter as in the original surround part of the plugin.
I couldn't figure the firfilter thingie out, so I stole^H^H^H^H^H reused
the simple RC lowpass filter from sox.
-> Fix the bugs
KNOWN BUGS:
-> Many files don't play well. This includes many avi, every mp3, wav and mpeg1
files I tried.
I couldn't figure out what the problem could be. The problem should be
somewhere in the buffer handling part, because the sound got f*cked up
even when I set the out[4] and out[5] to 0.
Somebody please help me! Sample media included in the upload.
-> I couldn't play any files with 48000 Hz sample rate. But it worked with
some 44100 Hz sample rate files. I don't exactly know why, but now the resample
workaround works with fout=44100. Nice, eh? :-)
The workaround for 48kHz files is:
mplayer -aop list=resample,surround:fout=44100 filename
Included sample media:
216-DA-ExtraSurround-Works.avi -> this file works for me.
AP-Resample-Needed.avi -> works with resample workaround.
Edda-Alom-ExtraSurround-Fails.mp3 -> this file works with original
surround plugin, but not with the
modified version.
Thanks for your time,
kisg
-------------- next part --------------
--- pl_surround.c.orig Tue Dec 25 10:52:21 2001
+++ pl_surround.c Thu Apr 4 14:09:33 2002
@@ -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;
@@ -120,9 +126,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 = 6;
+
+
// 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 +150,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 +184,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 +246,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 +279,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 +287,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;
}
More information about the MPlayer-dev-eng
mailing list