summaryrefslogtreecommitdiffstats
path: root/gst/filter
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2007-08-10 04:06:53 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2007-08-10 04:06:53 +0000
commit3dffa0f9e68d6401cd38937ca562f84ab33b93b1 (patch)
tree318a507f1c61674a6a1047a99289bd7e683987c1 /gst/filter
parent88313e142a0f886973ffa1ea5c0816d2c0da5ff7 (diff)
downloadgst-plugins-bad-3dffa0f9e68d6401cd38937ca562f84ab33b93b1.tar.gz
gst-plugins-bad-3dffa0f9e68d6401cd38937ca562f84ab33b93b1.tar.bz2
gst-plugins-bad-3dffa0f9e68d6401cd38937ca562f84ab33b93b1.zip
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.
Diffstat (limited to 'gst/filter')
-rw-r--r--gst/filter/gstlpwsinc.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/gst/filter/gstlpwsinc.c b/gst/filter/gstlpwsinc.c
index 5707f524..1ba193a9 100644
--- a/gst/filter/gstlpwsinc.c
+++ b/gst/filter/gstlpwsinc.c
@@ -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;
}