gststereo.c 6.36 KB
Newer Older
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
1
/* GStreamer
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * 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.
 */

Benjamin Otte's avatar
Benjamin Otte committed
20 21 22 23 24
/* This effect is borrowed from xmms-0.6.1, though I mangled it so badly in
 * the process of copying it over that the xmms people probably won't want
 * any credit for it ;-)
 */

25 26 27
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
28 29
#include <gststereo.h>

30
/* elementfactory information */
Benjamin Otte's avatar
Benjamin Otte committed
31
static GstElementDetails stereo_details = GST_ELEMENT_DETAILS (
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
32
  "Stereo effect",
33 34
  "Filter/Effect/Audio",
  "Muck with the stereo signal to enhance its 'stereo-ness'",
Benjamin Otte's avatar
Benjamin Otte committed
35 36
  "Erik Walthinsen <omega@cse.ogi.edu>"
);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51


/* Stereo signals and args */
enum {
  /* FILL ME */
  LAST_SIGNAL
};

enum {
  ARG_0,
  ARG_ACTIVE,
  ARG_STEREO
};


Benjamin Otte's avatar
Benjamin Otte committed
52
static void	gst_stereo_base_init		(gpointer g_class);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
53 54 55 56 57 58
static void	gst_stereo_class_init		(GstStereoClass *klass);
static void	gst_stereo_init			(GstStereo *stereo);

static void	gst_stereo_set_property		(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void	gst_stereo_get_property		(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);

59
static void	gst_stereo_chain		(GstPad *pad, GstData *_data);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
60 61

static GstElementClass *parent_class = NULL;
62
/*static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
63 64 65 66 67 68 69

GType
gst_stereo_get_type(void) {
  static GType stereo_type = 0;

  if (!stereo_type) {
    static const GTypeInfo stereo_info = {
Benjamin Otte's avatar
Benjamin Otte committed
70 71
      sizeof(GstStereoClass),
      gst_stereo_base_init,
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
72 73 74 75 76 77 78 79 80 81 82 83 84
      NULL,
      (GClassInitFunc)gst_stereo_class_init,
      NULL,
      NULL,
      sizeof(GstStereo),
      0,
      (GInstanceInitFunc)gst_stereo_init,
    };
    stereo_type = g_type_register_static(GST_TYPE_ELEMENT, "GstStereo", &stereo_info, 0);
  }
  return stereo_type;
}

Benjamin Otte's avatar
Benjamin Otte committed
85 86 87 88 89 90
static void
gst_stereo_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  gst_element_class_set_details (element_class, &stereo_details);
}
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
91 92 93 94 95 96 97 98 99 100 101 102 103
static void
gst_stereo_class_init (GstStereoClass *klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass*)klass;
  gstelement_class = (GstElementClass*)klass;

  parent_class = g_type_class_ref(GST_TYPE_ELEMENT);

  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ACTIVE,
    g_param_spec_int("active","active","active",
104
                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
105 106
  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_STEREO,
    g_param_spec_float("stereo","stereo","stereo",
107
                       0.0,1.0,0.0,G_PARAM_READWRITE)); /* CHECKME */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

  gobject_class->set_property = gst_stereo_set_property;
  gobject_class->get_property = gst_stereo_get_property;
}

static void
gst_stereo_init (GstStereo *stereo)
{
  stereo->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
  gst_element_add_pad(GST_ELEMENT(stereo),stereo->sinkpad);
  gst_pad_set_chain_function(stereo->sinkpad,gst_stereo_chain);
  stereo->srcpad = gst_pad_new("src",GST_PAD_SRC);
  gst_element_add_pad(GST_ELEMENT(stereo),stereo->srcpad);

  stereo->active = FALSE;
  stereo->stereo = 2.5;
}

static void
127
gst_stereo_chain (GstPad *pad,GstData *_data)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
128
{
129
  GstBuffer *buf = GST_BUFFER (_data);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143
  GstStereo *stereo;
  gint16 *data;
  gint samples;
  gint i;
  gdouble avg,ldiff,rdiff,tmp,mul;

  g_return_if_fail(pad != NULL);
  g_return_if_fail(GST_IS_PAD(pad));
  g_return_if_fail(buf != NULL);

  stereo = GST_STEREO(GST_OBJECT_PARENT (pad));
  g_return_if_fail(stereo != NULL);
  g_return_if_fail(GST_IS_STEREO(stereo));

144 145 146
/*  FIXME */
/*  if (buf->meta) */
/*    memcpy(&stereo->meta,buf->meta,sizeof(stereo->meta)); */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
147 148 149

  if (stereo->active) {

150
    /*if (stereo->meta.channels == 2 && stereo->meta.format == AFMT_S16_LE) { */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
      data = (gint16 *)GST_BUFFER_DATA(buf);
      samples = GST_BUFFER_SIZE(buf) / 2;
      mul = stereo->stereo;
      for (i = 0; i < samples / 2; i += 2) {
        avg = (data[i] + data[i + 1]) / 2;
        ldiff = data[i] - avg;
        rdiff = data[i + 1] - avg;

        tmp = avg + ldiff * mul;
        if (tmp < -32768)
          tmp = -32768;
        if (tmp > 32767)
          tmp = 32767;
        data[i] = tmp;

        tmp = avg + rdiff * mul;
        if (tmp < -32768)
          tmp = -32768;
        if (tmp > 32767)
          tmp = 32767;
        data[i + 1] = tmp;
      }
173
    /*} */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
174 175
  }

176
  gst_pad_push(stereo->srcpad,GST_DATA (buf));
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
}

static void
gst_stereo_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
  GstStereo *stereo;

  /* it's not null if we got it, but it might not be ours */
  g_return_if_fail(GST_IS_STEREO(object));
  stereo = GST_STEREO(object);

  switch (prop_id) {
    case ARG_ACTIVE:
      stereo->active = g_value_get_int (value);
      break;
    case ARG_STEREO:
      stereo->stereo = g_value_get_float (value) * 10.0;
      break;
    default:
      break;
  }
}

static void
gst_stereo_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
  GstStereo *stereo;

  /* it's not null if we got it, but it might not be ours */
  g_return_if_fail(GST_IS_STEREO(object));
  stereo = GST_STEREO(object);

  switch (prop_id) {
    case ARG_ACTIVE:
      g_value_set_int (value, stereo->active);
      break;
    case ARG_STEREO:
      g_value_set_float (value, stereo->stereo / 10.0);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
Benjamin Otte's avatar
Benjamin Otte committed
223
plugin_init (GstPlugin *plugin)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
224
{
Benjamin Otte's avatar
Benjamin Otte committed
225
  return gst_element_register (plugin, "stereo", GST_RANK_NONE, GST_TYPE_STEREO);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
226 227
}

Benjamin Otte's avatar
Benjamin Otte committed
228
GST_PLUGIN_DEFINE (
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
229 230 231
  GST_VERSION_MAJOR,
  GST_VERSION_MINOR,
  "stereo",
Benjamin Otte's avatar
Benjamin Otte committed
232 233 234 235 236 237 238 239
  "Muck with the stereo signal, enhance it's 'stereo-ness'",
  plugin_init,
  VERSION,
  GST_LICENSE,
  GST_COPYRIGHT,
  GST_PACKAGE,
  GST_ORIGIN
)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
240