mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
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:
parent
ccb73e617b
commit
0e4fc6653a
1 changed files with 36 additions and 18 deletions
|
@ -31,7 +31,8 @@
|
||||||
* is probably the bottleneck.
|
* is probably the bottleneck.
|
||||||
* - Implement a highpass mode (spectral inversion)
|
* - Implement a highpass mode (spectral inversion)
|
||||||
* - Allow choosing between different windows (blackman, hanning, ...)
|
* - 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
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -173,21 +174,26 @@ static void
|
||||||
process_32 (GstLPWSinc * self, gfloat * src, gfloat * dst, guint input_samples)
|
process_32 (GstLPWSinc * self, gfloat * src, gfloat * dst, guint input_samples)
|
||||||
{
|
{
|
||||||
gint kernel_length = self->wing_size * 2 + 1;;
|
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 */
|
/* convolution */
|
||||||
for (i = 0; i < input_samples; ++i) {
|
for (i = 0; i < input_samples; i++) {
|
||||||
dst[i] = 0.0;
|
dst[i] = 0.0;
|
||||||
for (j = 0; j < kernel_length; ++j)
|
k = i % channels;
|
||||||
if (i < j)
|
l = i / channels;
|
||||||
dst[i] += self->residue[kernel_length + i - j] * self->kernel[j];
|
for (j = 0; j < kernel_length; j++)
|
||||||
|
if (l < j)
|
||||||
|
dst[i] +=
|
||||||
|
self->residue[(kernel_length + l - j) * channels +
|
||||||
|
k] * self->kernel[j];
|
||||||
else
|
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 */
|
/* copy the tail of the current input buffer to the residue */
|
||||||
for (i = 0; i < kernel_length; i++)
|
for (i = 0; i < kernel_length * channels; i++)
|
||||||
self->residue[i] = src[input_samples - kernel_length + i];
|
self->residue[i] = src[input_samples - kernel_length * channels + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -195,21 +201,26 @@ process_64 (GstLPWSinc * self, gdouble * src, gdouble * dst,
|
||||||
guint input_samples)
|
guint input_samples)
|
||||||
{
|
{
|
||||||
gint kernel_length = self->wing_size * 2 + 1;;
|
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 */
|
/* convolution */
|
||||||
for (i = 0; i < input_samples; ++i) {
|
for (i = 0; i < input_samples; i++) {
|
||||||
dst[i] = 0.0;
|
dst[i] = 0.0;
|
||||||
for (j = 0; j < kernel_length; ++j)
|
k = i % channels;
|
||||||
if (i < j)
|
l = i / channels;
|
||||||
dst[i] += self->residue[kernel_length + i - j] * self->kernel[j];
|
for (j = 0; j < kernel_length; j++)
|
||||||
|
if (l < j)
|
||||||
|
dst[i] +=
|
||||||
|
self->residue[(kernel_length + l - j) * channels +
|
||||||
|
k] * self->kernel[j];
|
||||||
else
|
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 */
|
/* copy the tail of the current input buffer to the residue */
|
||||||
for (i = 0; i < kernel_length; i++)
|
for (i = 0; i < kernel_length * channels; i++)
|
||||||
self->residue[i] = src[input_samples - kernel_length + i];
|
self->residue[i] = src[input_samples - kernel_length * channels + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -229,6 +240,11 @@ lpwsinc_build_kernel (GstLPWSinc * self)
|
||||||
return;
|
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 */
|
/* Clamp cutoff frequency between 0 and the nyquist frequency */
|
||||||
self->frequency =
|
self->frequency =
|
||||||
CLAMP (self->frequency, 0.0, GST_AUDIO_FILTER (self)->format.rate / 2);
|
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 */
|
/* set up the residue memory space */
|
||||||
if (self->residue)
|
if (self->residue)
|
||||||
g_free (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;
|
self->have_kernel = TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue