diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2007-08-10 04:06:53 +0000 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2007-08-10 04:06:53 +0000 |
commit | 3dffa0f9e68d6401cd38937ca562f84ab33b93b1 (patch) | |
tree | 318a507f1c61674a6a1047a99289bd7e683987c1 /gst | |
parent | 88313e142a0f886973ffa1ea5c0816d2c0da5ff7 (diff) | |
download | gst-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')
-rw-r--r-- | gst/filter/gstlpwsinc.c | 54 |
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; } |