gst_plugins_good/gst/audiofx/audiofxbaseiirfilter.c
changeset 26 69c7080681bf
parent 24 bc39b352897e
child 28 4ed5253bb6ba
--- a/gst_plugins_good/gst/audiofx/audiofxbaseiirfilter.c	Fri Jul 09 16:26:45 2010 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-/* 
- * GStreamer
- * Copyright (C) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/audio/audio.h>
-#include <gst/audio/gstaudiofilter.h>
-#include <gst/controller/gstcontroller.h>
-
-#include <math.h>
-
-#include "audiofxbaseiirfilter.h"
-
-#define GST_CAT_DEFAULT gst_audio_fx_base_iir_filter_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-#define ALLOWED_CAPS \
-    "audio/x-raw-float,"                                              \
-    " width = (int) { 32, 64 }, "                                     \
-    " endianness = (int) BYTE_ORDER,"                                 \
-    " rate = (int) [ 1, MAX ],"                                       \
-    " channels = (int) [ 1, MAX ]"
-
-#define DEBUG_INIT(bla) \
-  GST_DEBUG_CATEGORY_INIT (gst_audio_fx_base_iir_filter_debug, "audiofxbaseiirfilter", 0, "Audio IIR Filter Base Class");
-
-GST_BOILERPLATE_FULL (GstAudioFXBaseIIRFilter,
-    gst_audio_fx_base_iir_filter, GstAudioFilter, GST_TYPE_AUDIO_FILTER,
-    DEBUG_INIT);
-
-static gboolean gst_audio_fx_base_iir_filter_setup (GstAudioFilter * filter,
-    GstRingBufferSpec * format);
-static GstFlowReturn
-gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base,
-    GstBuffer * buf);
-static gboolean gst_audio_fx_base_iir_filter_stop (GstBaseTransform * base);
-
-static void process_64 (GstAudioFXBaseIIRFilter * filter,
-    gdouble * data, guint num_samples);
-static void process_32 (GstAudioFXBaseIIRFilter * filter,
-    gfloat * data, guint num_samples);
-
-/* GObject vmethod implementations */
-
-static void
-gst_audio_fx_base_iir_filter_base_init (gpointer klass)
-{
-  GstCaps *caps;
-
-  caps = gst_caps_from_string (ALLOWED_CAPS);
-  gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
-      caps);
-  gst_caps_unref (caps);
-}
-
-static void
-gst_audio_fx_base_iir_filter_dispose (GObject * object)
-{
-  GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (object);
-
-  if (filter->a) {
-    g_free (filter->a);
-    filter->a = NULL;
-  }
-
-  if (filter->b) {
-    g_free (filter->b);
-    filter->b = NULL;
-  }
-
-  if (filter->channels) {
-    GstAudioFXBaseIIRFilterChannelCtx *ctx;
-    guint i;
-
-    for (i = 0; i < filter->nchannels; i++) {
-      ctx = &filter->channels[i];
-      g_free (ctx->x);
-      g_free (ctx->y);
-    }
-
-    g_free (filter->channels);
-    filter->channels = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_audio_fx_base_iir_filter_class_init (GstAudioFXBaseIIRFilterClass * klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-  GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
-  GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
-
-  gobject_class->dispose = gst_audio_fx_base_iir_filter_dispose;
-
-  filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_fx_base_iir_filter_setup);
-
-  trans_class->transform_ip =
-      GST_DEBUG_FUNCPTR (gst_audio_fx_base_iir_filter_transform_ip);
-  trans_class->stop = GST_DEBUG_FUNCPTR (gst_audio_fx_base_iir_filter_stop);
-}
-
-static void
-gst_audio_fx_base_iir_filter_init (GstAudioFXBaseIIRFilter * filter,
-    GstAudioFXBaseIIRFilterClass * klass)
-{
-  gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
-
-  filter->a = NULL;
-  filter->na = 0;
-  filter->b = NULL;
-  filter->nb = 0;
-  filter->channels = NULL;
-  filter->nchannels = 0;
-}
-
-/* Evaluate the transfer function that corresponds to the IIR
- * coefficients at zr + zi*I and return the magnitude */
-gdouble
-gst_audio_fx_base_iir_filter_calculate_gain (gdouble * a, guint na, gdouble * b,
-    guint nb, gdouble zr, gdouble zi)
-{
-  gdouble sum_ar, sum_ai;
-  gdouble sum_br, sum_bi;
-  gdouble gain_r, gain_i;
-
-  gdouble sum_r_old;
-  gdouble sum_i_old;
-
-  gint i;
-
-  sum_ar = 0.0;
-  sum_ai = 0.0;
-  for (i = na - 1; i >= 0; i--) {
-    sum_r_old = sum_ar;
-    sum_i_old = sum_ai;
-
-    sum_ar = (sum_r_old * zr - sum_i_old * zi) + a[i];
-    sum_ai = (sum_r_old * zi + sum_i_old * zr) + 0.0;
-  }
-
-  sum_br = 0.0;
-  sum_bi = 0.0;
-  for (i = nb - 1; i >= 0; i--) {
-    sum_r_old = sum_br;
-    sum_i_old = sum_bi;
-
-    sum_br = (sum_r_old * zr - sum_i_old * zi) - b[i];
-    sum_bi = (sum_r_old * zi + sum_i_old * zr) - 0.0;
-  }
-  sum_br += 1.0;
-  sum_bi += 0.0;
-
-  gain_r =
-      (sum_ar * sum_br + sum_ai * sum_bi) / (sum_br * sum_br + sum_bi * sum_bi);
-  gain_i =
-      (sum_ai * sum_br - sum_ar * sum_bi) / (sum_br * sum_br + sum_bi * sum_bi);
-
-  return (sqrt (gain_r * gain_r + gain_i * gain_i));
-}
-
-void
-gst_audio_fx_base_iir_filter_set_coefficients (GstAudioFXBaseIIRFilter * filter,
-    gdouble * a, guint na, gdouble * b, guint nb)
-{
-  guint i;
-
-  g_return_if_fail (GST_IS_AUDIO_FX_BASE_IIR_FILTER (filter));
-
-  GST_BASE_TRANSFORM_LOCK (filter);
-
-  g_free (filter->a);
-  g_free (filter->b);
-
-  filter->a = filter->b = NULL;
-
-  if (filter->channels) {
-    GstAudioFXBaseIIRFilterChannelCtx *ctx;
-    gboolean free = (na != filter->na || nb != filter->nb);
-
-    for (i = 0; i < filter->nchannels; i++) {
-      ctx = &filter->channels[i];
-
-      if (free)
-        g_free (ctx->x);
-      else
-        memset (ctx->x, 0, filter->na * sizeof (gdouble));
-
-      if (free)
-        g_free (ctx->y);
-      else
-        memset (ctx->y, 0, filter->nb * sizeof (gdouble));
-    }
-
-    g_free (filter->channels);
-    filter->channels = NULL;
-  }
-
-  filter->na = na;
-  filter->nb = nb;
-
-  filter->a = a;
-  filter->b = b;
-
-  if (filter->nchannels && !filter->channels) {
-    GstAudioFXBaseIIRFilterChannelCtx *ctx;
-
-    filter->channels =
-        g_new0 (GstAudioFXBaseIIRFilterChannelCtx, filter->nchannels);
-    for (i = 0; i < filter->nchannels; i++) {
-      ctx = &filter->channels[i];
-
-      ctx->x = g_new0 (gdouble, filter->na);
-      ctx->y = g_new0 (gdouble, filter->nb);
-    }
-  }
-
-  GST_BASE_TRANSFORM_UNLOCK (filter);
-}
-
-/* GstAudioFilter vmethod implementations */
-
-static gboolean
-gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base,
-    GstRingBufferSpec * format)
-{
-  GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
-  gboolean ret = TRUE;
-
-  if (format->width == 32)
-    filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
-        process_32;
-  else if (format->width == 64)
-    filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
-        process_64;
-  else
-    ret = FALSE;
-
-  if (format->channels != filter->nchannels) {
-    guint i;
-    GstAudioFXBaseIIRFilterChannelCtx *ctx;
-
-    if (filter->channels) {
-
-      for (i = 0; i < filter->nchannels; i++) {
-        ctx = &filter->channels[i];
-
-        g_free (ctx->x);
-        g_free (ctx->y);
-      }
-
-      g_free (filter->channels);
-      filter->channels = NULL;
-    }
-
-    filter->nchannels = format->channels;
-
-    filter->channels =
-        g_new0 (GstAudioFXBaseIIRFilterChannelCtx, filter->nchannels);
-    for (i = 0; i < filter->nchannels; i++) {
-      ctx = &filter->channels[i];
-
-      ctx->x = g_new0 (gdouble, filter->na);
-      ctx->y = g_new0 (gdouble, filter->nb);
-    }
-  }
-
-  return ret;
-}
-
-static inline gdouble
-process (GstAudioFXBaseIIRFilter * filter,
-    GstAudioFXBaseIIRFilterChannelCtx * ctx, gdouble x0)
-{
-  gdouble val = filter->a[0] * x0;
-  gint i, j;
-
-  for (i = 1, j = ctx->x_pos; i < filter->na; i++) {
-    val += filter->a[i] * ctx->x[j];
-    j--;
-    if (j < 0)
-      j = filter->na - 1;
-  }
-
-  for (i = 1, j = ctx->y_pos; i < filter->nb; i++) {
-    val += filter->b[i] * ctx->y[j];
-    j--;
-    if (j < 0)
-      j = filter->nb - 1;
-  }
-
-  if (ctx->x) {
-    ctx->x_pos++;
-    if (ctx->x_pos >= filter->na)
-      ctx->x_pos = 0;
-    ctx->x[ctx->x_pos] = x0;
-  }
-  if (ctx->y) {
-    ctx->y_pos++;
-    if (ctx->y_pos >= filter->nb)
-      ctx->y_pos = 0;
-
-    ctx->y[ctx->y_pos] = val;
-  }
-
-  return val;
-}
-
-#define DEFINE_PROCESS_FUNC(width,ctype) \
-static void \
-process_##width (GstAudioFXBaseIIRFilter * filter, \
-    g##ctype * data, guint num_samples) \
-{ \
-  gint i, j, channels = GST_AUDIO_FILTER (filter)->format.channels; \
-  gdouble val; \
-  \
-  for (i = 0; i < num_samples / channels; i++) { \
-    for (j = 0; j < channels; j++) { \
-      val = process (filter, &filter->channels[j], *data); \
-      *data++ = val; \
-    } \
-  } \
-}
-
-DEFINE_PROCESS_FUNC (32, float);
-DEFINE_PROCESS_FUNC (64, double);
-
-#undef DEFINE_PROCESS_FUNC
-
-/* GstBaseTransform vmethod implementations */
-static GstFlowReturn
-gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base,
-    GstBuffer * buf)
-{
-  GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
-  guint num_samples =
-      GST_BUFFER_SIZE (buf) / (GST_AUDIO_FILTER (filter)->format.width / 8);
-
-  if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
-    gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (buf));
-
-  if (gst_base_transform_is_passthrough (base))
-    return GST_FLOW_OK;
-
-  g_return_val_if_fail (filter->a != NULL, GST_FLOW_ERROR);
-
-  filter->process (filter, GST_BUFFER_DATA (buf), num_samples);
-
-  return GST_FLOW_OK;
-}
-
-
-static gboolean
-gst_audio_fx_base_iir_filter_stop (GstBaseTransform * base)
-{
-  GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
-  guint channels = GST_AUDIO_FILTER (filter)->format.channels;
-  GstAudioFXBaseIIRFilterChannelCtx *ctx;
-  guint i;
-
-  /* Reset the history of input and output values if
-   * already existing */
-  if (channels && filter->channels) {
-    for (i = 0; i < channels; i++) {
-      ctx = &filter->channels[i];
-      g_free (ctx->x);
-      g_free (ctx->y);
-    }
-    g_free (filter->channels);
-  }
-  filter->channels = NULL;
-
-  return TRUE;
-}