gst/filter/gstlpwsinc.c: Fix processing if the input has more than one channel.

Original commit message from CVS:
* gst/filter/gstlpwsinc.c: (process_32), (process_64),
(lpwsinc_build_kernel):
Fix processing if the input has more than one channel.
This commit is contained in:
Sebastian Dröge 2007-08-10 04:06:53 +00:00
parent 88313e142a
commit 3dffa0f9e6
2 changed files with 42 additions and 18 deletions

View file

@ -1,3 +1,9 @@
2007-08-10 Sebastian Dröge <slomo@circular-chaos.org>
* gst/filter/gstlpwsinc.c: (process_32), (process_64),
(lpwsinc_build_kernel):
Fix processing if the input has more than one channel.
2007-08-09 Sebastian Dröge <slomo@circular-chaos.org>
* gst/filter/gstbpwsinc.c: (gst_bpwsinc_dispose),

View file

@ -31,7 +31,8 @@
* is probably the bottleneck.
* - Implement a highpass mode (spectral inversion)
* - Allow choosing between different windows (blackman, hanning, ...)
* FIXME: - Doesn't work at all with >1 channels
* - Maybe allow cascading the filter to get a better stopband attenuation.
* Can be done by convolving a filter kernel with itself.
*/
#ifdef HAVE_CONFIG_H
@ -173,21 +174,26 @@ static void
process_32 (GstLPWSinc * self, gfloat * src, gfloat * dst, guint input_samples)
{
gint kernel_length = self->wing_size * 2 + 1;;
gint i, j;
gint i, j, k, l;
gint channels = GST_AUDIO_FILTER (self)->format.channels;
/* convolution */
for (i = 0; i < input_samples; ++i) {
for (i = 0; i < input_samples; i++) {
dst[i] = 0.0;
for (j = 0; j < kernel_length; ++j)
if (i < j)
dst[i] += self->residue[kernel_length + i - j] * self->kernel[j];
k = i % channels;
l = i / channels;
for (j = 0; j < kernel_length; j++)
if (l < j)
dst[i] +=
self->residue[(kernel_length + l - j) * channels +
k] * self->kernel[j];
else
dst[i] += src[i - j] * self->kernel[j];
dst[i] += src[(l - j) * channels + k] * self->kernel[j];
}
/* copy the tail of the current input buffer to the residue */
for (i = 0; i < kernel_length; i++)
self->residue[i] = src[input_samples - kernel_length + i];
for (i = 0; i < kernel_length * channels; i++)
self->residue[i] = src[input_samples - kernel_length * channels + i];
}
static void
@ -195,21 +201,26 @@ process_64 (GstLPWSinc * self, gdouble * src, gdouble * dst,
guint input_samples)
{
gint kernel_length = self->wing_size * 2 + 1;;
gint i, j;
gint i, j, k, l;
gint channels = GST_AUDIO_FILTER (self)->format.channels;
/* convolution */
for (i = 0; i < input_samples; ++i) {
for (i = 0; i < input_samples; i++) {
dst[i] = 0.0;
for (j = 0; j < kernel_length; ++j)
if (i < j)
dst[i] += self->residue[kernel_length + i - j] * self->kernel[j];
k = i % channels;
l = i / channels;
for (j = 0; j < kernel_length; j++)
if (l < j)
dst[i] +=
self->residue[(kernel_length + l - j) * channels +
k] * self->kernel[j];
else
dst[i] += src[i - j] * self->kernel[j];
dst[i] += src[(l - j) * channels + k] * self->kernel[j];
}
/* copy the tail of the current input buffer to the residue */
for (i = 0; i < kernel_length; i++)
self->residue[i] = src[input_samples - kernel_length + i];
for (i = 0; i < kernel_length * channels; i++)
self->residue[i] = src[input_samples - kernel_length * channels + i];
}
static void
@ -229,6 +240,11 @@ lpwsinc_build_kernel (GstLPWSinc * self)
return;
}
if (GST_AUDIO_FILTER (self)->format.channels == 0) {
GST_DEBUG ("channels not set yet");
return;
}
/* Clamp cutoff frequency between 0 and the nyquist frequency */
self->frequency =
CLAMP (self->frequency, 0.0, GST_AUDIO_FILTER (self)->format.rate / 2);
@ -257,7 +273,9 @@ lpwsinc_build_kernel (GstLPWSinc * self)
/* set up the residue memory space */
if (self->residue)
g_free (self->residue);
self->residue = g_new0 (gdouble, len * 2 + 1);
self->residue =
g_new0 (gdouble,
(len * 2 + 1) * GST_AUDIO_FILTER (self)->format.channels);
self->have_kernel = TRUE;
}