static void gst_audio_fir_filter_update_kernel (GstAudioFIRFilter * self, GValueArray * va) { gdouble *kernel; guint i; if (va) { if (self->kernel) g_value_array_free (self->kernel); self->kernel = va; } kernel = g_new (gdouble, self->kernel->n_values); for (i = 0; i < self->kernel->n_values; i++) { GValue *v = g_value_array_get_nth (self->kernel, i); kernel[i] = g_value_get_double (v); } gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self), kernel, self->kernel->n_values, self->latency); }
static void gst_audio_wsinclimit_build_kernel (GstAudioWSincLimit * self, const GstAudioInfo * info) { gint i = 0; gdouble sum = 0.0; gint len = 0; gdouble w; gdouble *kernel = NULL; gint rate, channels; len = self->kernel_length; if (info) { rate = GST_AUDIO_INFO_RATE (info); channels = GST_AUDIO_INFO_CHANNELS (info); } else { rate = GST_AUDIO_FILTER_RATE (self); channels = GST_AUDIO_FILTER_CHANNELS (self); } if (rate == 0) { GST_DEBUG ("rate not set yet"); return; } if (channels == 0) { GST_DEBUG ("channels not set yet"); return; } /* Clamp cutoff frequency between 0 and the nyquist frequency */ self->cutoff = CLAMP (self->cutoff, 0.0, rate / 2); GST_DEBUG ("gst_audio_wsinclimit_: initializing filter kernel of length %d " "with cutoff %.2lf Hz " "for mode %s", len, self->cutoff, (self->mode == MODE_LOW_PASS) ? "low-pass" : "high-pass"); /* fill the kernel */ w = 2 * G_PI * (self->cutoff / rate); kernel = g_new (gdouble, len); for (i = 0; i < len; ++i) { if (i == (len - 1) / 2.0) kernel[i] = w; else kernel[i] = sin (w * (i - (len - 1) / 2)) / (i - (len - 1) / 2.0); /* windowing */ switch (self->window) { case WINDOW_HAMMING: kernel[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / (len - 1))); break; case WINDOW_BLACKMAN: kernel[i] *= (0.42 - 0.5 * cos (2 * G_PI * i / (len - 1)) + 0.08 * cos (4 * G_PI * i / (len - 1))); break; case WINDOW_GAUSSIAN: kernel[i] *= exp (-0.5 * POW2 (3.0 / len * (2 * i - (len - 1)))); break; case WINDOW_COSINE: kernel[i] *= cos (G_PI * i / (len - 1) - G_PI / 2); break; case WINDOW_HANN: kernel[i] *= 0.5 * (1 - cos (2 * G_PI * i / (len - 1))); break; } } /* normalize for unity gain at DC */ for (i = 0; i < len; ++i) sum += kernel[i]; for (i = 0; i < len; ++i) kernel[i] /= sum; /* convert to highpass if specified */ if (self->mode == MODE_HIGH_PASS) { for (i = 0; i < len; ++i) kernel[i] = -kernel[i]; if (len % 2 == 1) { kernel[(len - 1) / 2] += 1.0; } else { kernel[len / 2 - 1] += 0.5; kernel[len / 2] += 0.5; } } gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self), kernel, self->kernel_length, (len - 1) / 2, info); }
static void gst_audio_wsincband_build_kernel (GstAudioWSincBand * self) { gint i = 0; gdouble sum = 0.0; gint len = 0; gdouble *kernel_lp, *kernel_hp; gdouble w; gdouble *kernel; len = self->kernel_length; if (GST_AUDIO_FILTER (self)->format.rate == 0) { GST_DEBUG ("rate not set yet"); return; } if (GST_AUDIO_FILTER (self)->format.channels == 0) { GST_DEBUG ("channels not set yet"); return; } /* Clamp frequencies */ self->lower_frequency = CLAMP (self->lower_frequency, 0.0, GST_AUDIO_FILTER (self)->format.rate / 2); self->upper_frequency = CLAMP (self->upper_frequency, 0.0, GST_AUDIO_FILTER (self)->format.rate / 2); if (self->lower_frequency > self->upper_frequency) { gint tmp = self->lower_frequency; self->lower_frequency = self->upper_frequency; self->upper_frequency = tmp; } GST_DEBUG ("gst_audio_wsincband: initializing filter kernel of length %d " "with lower frequency %.2lf Hz " ", upper frequency %.2lf Hz for mode %s", len, self->lower_frequency, self->upper_frequency, (self->mode == MODE_BAND_PASS) ? "band-pass" : "band-reject"); /* fill the lp kernel */ w = 2 * M_PI * (self->lower_frequency / GST_AUDIO_FILTER (self)->format.rate); kernel_lp = g_new (gdouble, len); for (i = 0; i < len; ++i) { if (i == len / 2) kernel_lp[i] = w; else kernel_lp[i] = sin (w * (i - len / 2)) / (i - len / 2); /* Windowing */ if (self->window == WINDOW_HAMMING) kernel_lp[i] *= (0.54 - 0.46 * cos (2 * M_PI * i / len)); else kernel_lp[i] *= (0.42 - 0.5 * cos (2 * M_PI * i / len) + 0.08 * cos (4 * M_PI * i / len)); } /* normalize for unity gain at DC */ sum = 0.0; for (i = 0; i < len; ++i) sum += kernel_lp[i]; for (i = 0; i < len; ++i) kernel_lp[i] /= sum; /* fill the hp kernel */ w = 2 * M_PI * (self->upper_frequency / GST_AUDIO_FILTER (self)->format.rate); kernel_hp = g_new (gdouble, len); for (i = 0; i < len; ++i) { if (i == len / 2) kernel_hp[i] = w; else kernel_hp[i] = sin (w * (i - len / 2)) / (i - len / 2); /* Windowing */ if (self->window == WINDOW_HAMMING) kernel_hp[i] *= (0.54 - 0.46 * cos (2 * M_PI * i / len)); else kernel_hp[i] *= (0.42 - 0.5 * cos (2 * M_PI * i / len) + 0.08 * cos (4 * M_PI * i / len)); } /* normalize for unity gain at DC */ sum = 0.0; for (i = 0; i < len; ++i) sum += kernel_hp[i]; for (i = 0; i < len; ++i) kernel_hp[i] /= sum; /* do spectral inversion to go from lowpass to highpass */ for (i = 0; i < len; ++i) kernel_hp[i] = -kernel_hp[i]; kernel_hp[len / 2] += 1; /* combine the two kernels */ kernel = g_new (gdouble, len); for (i = 0; i < len; ++i) kernel[i] = kernel_lp[i] + kernel_hp[i]; /* free the helper kernels */ g_free (kernel_lp); g_free (kernel_hp); /* do spectral inversion to go from bandreject to bandpass * if specified */ if (self->mode == MODE_BAND_PASS) { for (i = 0; i < len; ++i) kernel[i] = -kernel[i]; kernel[len / 2] += 1; } gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self), kernel, self->kernel_length, (len - 1) / 2); }
static void gst_audio_wsincband_build_kernel (GstAudioWSincBand * self, const GstAudioInfo * info) { gint i = 0; gdouble sum = 0.0; gint len = 0; gdouble *kernel_lp, *kernel_hp; gdouble w; gdouble *kernel; gint rate, channels; len = self->kernel_length; if (info) { rate = GST_AUDIO_INFO_RATE (info); channels = GST_AUDIO_INFO_CHANNELS (info); } else { rate = GST_AUDIO_FILTER_RATE (self); channels = GST_AUDIO_FILTER_CHANNELS (self); } if (rate == 0) { GST_DEBUG ("rate not set yet"); return; } if (channels == 0) { GST_DEBUG ("channels not set yet"); return; } /* Clamp frequencies */ self->lower_frequency = CLAMP (self->lower_frequency, 0.0, rate / 2); self->upper_frequency = CLAMP (self->upper_frequency, 0.0, rate / 2); if (self->lower_frequency > self->upper_frequency) { gint tmp = self->lower_frequency; self->lower_frequency = self->upper_frequency; self->upper_frequency = tmp; } GST_DEBUG ("gst_audio_wsincband: initializing filter kernel of length %d " "with lower frequency %.2lf Hz " ", upper frequency %.2lf Hz for mode %s", len, self->lower_frequency, self->upper_frequency, (self->mode == MODE_BAND_PASS) ? "band-pass" : "band-reject"); /* fill the lp kernel */ w = 2 * G_PI * (self->lower_frequency / rate); kernel_lp = g_new (gdouble, len); for (i = 0; i < len; ++i) { if (i == (len - 1) / 2.0) kernel_lp[i] = w; else kernel_lp[i] = sin (w * (i - (len - 1) / 2.0)) / (i - (len - 1) / 2.0); /* windowing */ switch (self->window) { case WINDOW_HAMMING: kernel_lp[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / (len - 1))); break; case WINDOW_BLACKMAN: kernel_lp[i] *= (0.42 - 0.5 * cos (2 * G_PI * i / (len - 1)) + 0.08 * cos (4 * G_PI * i / (len - 1))); break; case WINDOW_GAUSSIAN: kernel_lp[i] *= exp (-0.5 * POW2 (3.0 / len * (2 * i - (len - 1)))); break; case WINDOW_COSINE: kernel_lp[i] *= cos (G_PI * i / (len - 1) - G_PI / 2); break; case WINDOW_HANN: kernel_lp[i] *= 0.5 * (1 - cos (2 * G_PI * i / (len - 1))); break; } } /* normalize for unity gain at DC */ sum = 0.0; for (i = 0; i < len; ++i) sum += kernel_lp[i]; for (i = 0; i < len; ++i) kernel_lp[i] /= sum; /* fill the hp kernel */ w = 2 * G_PI * (self->upper_frequency / rate); kernel_hp = g_new (gdouble, len); for (i = 0; i < len; ++i) { if (i == (len - 1) / 2.0) kernel_hp[i] = w; else kernel_hp[i] = sin (w * (i - (len - 1) / 2.0)) / (i - (len - 1) / 2.0); /* Windowing */ switch (self->window) { case WINDOW_HAMMING: kernel_hp[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / (len - 1))); break; case WINDOW_BLACKMAN: kernel_hp[i] *= (0.42 - 0.5 * cos (2 * G_PI * i / (len - 1)) + 0.08 * cos (4 * G_PI * i / (len - 1))); break; case WINDOW_GAUSSIAN: kernel_hp[i] *= exp (-0.5 * POW2 (3.0 / len * (2 * i - (len - 1)))); break; case WINDOW_COSINE: kernel_hp[i] *= cos (G_PI * i / (len - 1) - G_PI / 2); break; case WINDOW_HANN: kernel_hp[i] *= 0.5 * (1 - cos (2 * G_PI * i / (len - 1))); break; } } /* normalize for unity gain at DC */ sum = 0.0; for (i = 0; i < len; ++i) sum += kernel_hp[i]; for (i = 0; i < len; ++i) kernel_hp[i] /= sum; /* do spectral inversion to go from lowpass to highpass */ for (i = 0; i < len; ++i) kernel_hp[i] = -kernel_hp[i]; if (len % 2 == 1) { kernel_hp[(len - 1) / 2] += 1.0; } else { kernel_hp[len / 2 - 1] += 0.5; kernel_hp[len / 2] += 0.5; } /* combine the two kernels */ kernel = g_new (gdouble, len); for (i = 0; i < len; ++i) kernel[i] = kernel_lp[i] + kernel_hp[i]; /* free the helper kernels */ g_free (kernel_lp); g_free (kernel_hp); /* do spectral inversion to go from bandreject to bandpass * if specified */ if (self->mode == MODE_BAND_PASS) { for (i = 0; i < len; ++i) kernel[i] = -kernel[i]; kernel[len / 2] += 1; } gst_audio_fx_base_fir_filter_set_kernel (GST_AUDIO_FX_BASE_FIR_FILTER (self), kernel, self->kernel_length, (len - 1) / 2, info); }