gst-plugins-good  1.20.3
About: GStreamer (Good Plugins) is a library for constructing of graphs of media-handling components. A set of good-quality plug-ins (under LGPL license).
  Fossies Dox: gst-plugins-good-1.20.3.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

audioamplify.c
Go to the documentation of this file.
1/*
2 * GStreamer
3 * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
4 * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22/**
23 * SECTION:element-audioamplify
24 * @title: audioamplify
25 *
26 * Amplifies an audio stream by a given factor and allows the selection of different clipping modes.
27 * The difference between the clipping modes is best evaluated by testing.
28 *
29 * ## Example launch line
30 * |[
31 * gst-launch-1.0 audiotestsrc wave=saw ! audioamplify amplification=1.5 ! alsasink
32 * gst-launch-1.0 filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audioamplify amplification=1.5 clipping-method=wrap-negative ! alsasink
33 * gst-launch-1.0 audiotestsrc wave=saw ! audioconvert ! audioamplify amplification=1.5 clipping-method=wrap-positive ! audioconvert ! alsasink
34 * ]|
35 *
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#endif
41
42#include <gst/gst.h>
43#include <gst/base/gstbasetransform.h>
44#include <gst/audio/audio.h>
45#include <gst/audio/gstaudiofilter.h>
46
47#include "audioamplify.h"
48
49#define GST_CAT_DEFAULT gst_audio_amplify_debug
51
52/* Filter signals and args */
53enum
54{
55 /* FILL ME */
57};
58
59enum
60{
64};
65
66enum
67{
73};
74
75#define GST_TYPE_AUDIO_AMPLIFY_CLIPPING_METHOD (gst_audio_amplify_clipping_method_get_type ())
76static GType
78{
79 static GType gtype = 0;
80
81 if (gtype == 0) {
82 static const GEnumValue values[] = {
83 {METHOD_CLIP, "Normal clipping (default)", "clip"},
85 "Push overdriven values back from the opposite side",
86 "wrap-negative"},
87 {METHOD_WRAP_POSITIVE, "Push overdriven values back from the same side",
88 "wrap-positive"},
89 {METHOD_NOCLIP, "No clipping", "none"},
90 {0, NULL, NULL}
91 };
92 gtype = g_enum_register_static ("GstAudioAmplifyClippingMethod", values);
93 }
94 return gtype;
95}
96
97#define ALLOWED_CAPS \
98 "audio/x-raw," \
99 " format=(string) {S8,"GST_AUDIO_NE(S16)","GST_AUDIO_NE(S32)"," \
100 GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}," \
101 " rate=(int)[1,MAX]," \
102 " channels=(int)[1,MAX], " \
103 " layout=(string) {interleaved, non-interleaved}"
104
105G_DEFINE_TYPE (GstAudioAmplify, gst_audio_amplify, GST_TYPE_AUDIO_FILTER);
106GST_ELEMENT_REGISTER_DEFINE (audioamplify, "audioamplify",
107 GST_RANK_NONE, GST_TYPE_AUDIO_AMPLIFY);
108
110 filter, gint clipping, GstAudioFormat format);
111static void gst_audio_amplify_set_property (GObject * object, guint prop_id,
112 const GValue * value, GParamSpec * pspec);
113static void gst_audio_amplify_get_property (GObject * object, guint prop_id,
114 GValue * value, GParamSpec * pspec);
115
116static gboolean gst_audio_amplify_setup (GstAudioFilter * filter,
117 const GstAudioInfo * info);
118static GstFlowReturn gst_audio_amplify_transform_ip (GstBaseTransform * base,
119 GstBuffer * buf);
120
121#define MIN_gint8 G_MININT8
122#define MAX_gint8 G_MAXINT8
123#define MIN_gint16 G_MININT16
124#define MAX_gint16 G_MAXINT16
125#define MIN_gint32 G_MININT32
126#define MAX_gint32 G_MAXINT32
127
128#define MAKE_INT_FUNCS(type,largetype) \
129static void \
130gst_audio_amplify_transform_##type##_clip (GstAudioAmplify * filter, \
131 void * data, guint num_samples) \
132{ \
133 type *d = data; \
134 \
135 while (num_samples--) { \
136 largetype val = *d * filter->amplification; \
137 *d++ = CLAMP (val, MIN_##type, MAX_##type); \
138 } \
139} \
140static void \
141gst_audio_amplify_transform_##type##_wrap_negative (GstAudioAmplify * filter, \
142 void * data, guint num_samples) \
143{ \
144 type *d = data; \
145 \
146 while (num_samples--) { \
147 largetype val = *d * filter->amplification; \
148 if (val > MAX_##type) \
149 val = MIN_##type + (val - MIN_##type) % ((largetype) MAX_##type + 1 - \
150 MIN_##type); \
151 else if (val < MIN_##type) \
152 val = MAX_##type - (MAX_##type - val) % ((largetype) MAX_##type + 1 - \
153 MIN_##type); \
154 *d++ = val; \
155 } \
156} \
157static void \
158gst_audio_amplify_transform_##type##_wrap_positive (GstAudioAmplify * filter, \
159 void * data, guint num_samples) \
160{ \
161 type *d = data; \
162 \
163 while (num_samples--) { \
164 largetype val = *d * filter->amplification; \
165 do { \
166 if (val > MAX_##type) \
167 val = MAX_##type - (val - MAX_##type); \
168 else if (val < MIN_##type) \
169 val = MIN_##type + (MIN_##type - val); \
170 else \
171 break; \
172 } while (1); \
173 *d++ = val; \
174 } \
175} \
176static void \
177gst_audio_amplify_transform_##type##_noclip (GstAudioAmplify * filter, \
178 void * data, guint num_samples) \
179{ \
180 type *d = data; \
181 \
182 while (num_samples--) \
183 *d++ *= filter->amplification; \
184}
185
186#define MAKE_FLOAT_FUNCS(type) \
187static void \
188gst_audio_amplify_transform_##type##_clip (GstAudioAmplify * filter, \
189 void * data, guint num_samples) \
190{ \
191 type *d = data; \
192 \
193 while (num_samples--) { \
194 type val = *d* filter->amplification; \
195 *d++ = CLAMP (val, -1.0, +1.0); \
196 } \
197} \
198static void \
199gst_audio_amplify_transform_##type##_wrap_negative (GstAudioAmplify * \
200 filter, void * data, guint num_samples) \
201{ \
202 type *d = data; \
203 \
204 while (num_samples--) { \
205 type val = *d * filter->amplification; \
206 do { \
207 if (val > 1.0) \
208 val = -1.0 + (val - 1.0); \
209 else if (val < -1.0) \
210 val = 1.0 - (1.0 - val); \
211 else \
212 break; \
213 } while (1); \
214 *d++ = val; \
215 } \
216} \
217static void \
218gst_audio_amplify_transform_##type##_wrap_positive (GstAudioAmplify * filter, \
219 void * data, guint num_samples) \
220{ \
221 type *d = data; \
222 \
223 while (num_samples--) { \
224 type val = *d* filter->amplification; \
225 do { \
226 if (val > 1.0) \
227 val = 1.0 - (val - 1.0); \
228 else if (val < -1.0) \
229 val = -1.0 + (-1.0 - val); \
230 else \
231 break; \
232 } while (1); \
233 *d++ = val; \
234 } \
235} \
236static void \
237gst_audio_amplify_transform_##type##_noclip (GstAudioAmplify * filter, \
238 void * data, guint num_samples) \
239{ \
240 type *d = data; \
241 \
242 while (num_samples--) \
243 *d++ *= filter->amplification; \
244}
245
246/* *INDENT-OFF* */
247MAKE_INT_FUNCS (gint8,gint)
248MAKE_INT_FUNCS (gint16,gint)
249MAKE_INT_FUNCS (gint32,gint64)
252/* *INDENT-ON* */
253
254/* GObject vmethod implementations */
255
256static void
258{
259 GObjectClass *gobject_class;
260 GstElementClass *gstelement_class;
261 GstCaps *caps;
262
263 GST_DEBUG_CATEGORY_INIT (gst_audio_amplify_debug, "audioamplify", 0,
264 "audioamplify element");
265
266 gobject_class = (GObjectClass *) klass;
267 gstelement_class = (GstElementClass *) klass;
268
269 gobject_class->set_property = gst_audio_amplify_set_property;
270 gobject_class->get_property = gst_audio_amplify_get_property;
271
272 g_object_class_install_property (gobject_class, PROP_AMPLIFICATION,
273 g_param_spec_float ("amplification", "Amplification",
274 "Factor of amplification", -G_MAXFLOAT, G_MAXFLOAT,
275 1.0,
276 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
277
278 /**
279 * GstAudioAmplify:clipping-method
280 *
281 * Clipping method: clip mode set values higher than the maximum to the
282 * maximum. The wrap-negative mode pushes those values back from the
283 * opposite side, wrap-positive pushes them back from the same side.
284 *
285 **/
286 g_object_class_install_property (gobject_class, PROP_CLIPPING_METHOD,
287 g_param_spec_enum ("clipping-method", "Clipping method",
288 "Selects how to handle values higher than the maximum",
290 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
291
292 gst_element_class_set_static_metadata (gstelement_class, "Audio amplifier",
293 "Filter/Effect/Audio",
294 "Amplifies an audio stream by a given factor",
295 "Sebastian Dröge <slomo@circular-chaos.org>");
296
297 caps = gst_caps_from_string (ALLOWED_CAPS);
298 gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
299 caps);
300 gst_caps_unref (caps);
301
302 GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
303 GST_DEBUG_FUNCPTR (gst_audio_amplify_transform_ip);
304 GST_BASE_TRANSFORM_CLASS (klass)->transform_ip_on_passthrough = FALSE;
305
306 GST_AUDIO_FILTER_CLASS (klass)->setup =
307 GST_DEBUG_FUNCPTR (gst_audio_amplify_setup);
308
309 gst_type_mark_as_plugin_api (GST_TYPE_AUDIO_AMPLIFY_CLIPPING_METHOD, 0);
310}
311
312static void
314{
315 filter->amplification = 1.0;
317 GST_AUDIO_FORMAT_S16);
318 gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
319 gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
320}
321
323gst_audio_amplify_process_function (gint clipping, GstAudioFormat format)
324{
325 static const struct process
326 {
327 GstAudioFormat format;
328 gint clipping;
330 } process[] = {
331 {
333 GST_AUDIO_FORMAT_F32, METHOD_WRAP_NEGATIVE,
335 GST_AUDIO_FORMAT_F32, METHOD_WRAP_POSITIVE,
337 GST_AUDIO_FORMAT_F32, METHOD_NOCLIP,
339 GST_AUDIO_FORMAT_F64, METHOD_CLIP,
341 GST_AUDIO_FORMAT_F64, METHOD_WRAP_NEGATIVE,
343 GST_AUDIO_FORMAT_F64, METHOD_WRAP_POSITIVE,
345 GST_AUDIO_FORMAT_F64, METHOD_NOCLIP,
348 GST_AUDIO_FORMAT_S8, METHOD_WRAP_NEGATIVE,
350 GST_AUDIO_FORMAT_S8, METHOD_WRAP_POSITIVE,
352 GST_AUDIO_FORMAT_S8, METHOD_NOCLIP,
355 GST_AUDIO_FORMAT_S16, METHOD_WRAP_NEGATIVE,
357 GST_AUDIO_FORMAT_S16, METHOD_WRAP_POSITIVE,
359 GST_AUDIO_FORMAT_S16, METHOD_NOCLIP,
362 GST_AUDIO_FORMAT_S32, METHOD_WRAP_NEGATIVE,
364 GST_AUDIO_FORMAT_S32, METHOD_WRAP_POSITIVE,
366 GST_AUDIO_FORMAT_S32, METHOD_NOCLIP,
368 0, 0, NULL}
369 };
370 const struct process *p;
371
372 for (p = process; p->func; p++)
373 if (p->format == format && p->clipping == clipping)
374 return p->func;
375 return NULL;
376}
377
378static gboolean
380 clipping_method, GstAudioFormat format)
381{
383
384 /* set processing function */
385
387 if (!process) {
388 GST_DEBUG ("wrong format");
389 return FALSE;
390 }
391
392 filter->process = process;
393 filter->clipping_method = clipping_method;
394 filter->format = format;
395
396 return TRUE;
397}
398
399static void
400gst_audio_amplify_set_property (GObject * object, guint prop_id,
401 const GValue * value, GParamSpec * pspec)
402{
403 GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (object);
404
405 switch (prop_id) {
407 filter->amplification = g_value_get_float (value);
408 gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter),
409 filter->amplification == 1.0);
410 break;
412 gst_audio_amplify_set_process_function (filter, g_value_get_enum (value),
413 filter->format);
414 break;
415 default:
416 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
417 break;
418 }
419}
420
421static void
422gst_audio_amplify_get_property (GObject * object, guint prop_id,
423 GValue * value, GParamSpec * pspec)
424{
425 GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (object);
426
427 switch (prop_id) {
429 g_value_set_float (value, filter->amplification);
430 break;
432 g_value_set_enum (value, filter->clipping_method);
433 break;
434 default:
435 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
436 break;
437 }
438}
439
440/* GstAudioFilter vmethod implementations */
441static gboolean
442gst_audio_amplify_setup (GstAudioFilter * base, const GstAudioInfo * info)
443{
444 GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (base);
445
447 filter->clipping_method, GST_AUDIO_INFO_FORMAT (info));
448}
449
450/* GstBaseTransform vmethod implementations */
451static GstFlowReturn
452gst_audio_amplify_transform_ip (GstBaseTransform * base, GstBuffer * buf)
453{
454 GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (base);
455 guint num_samples;
456 GstClockTime timestamp, stream_time;
457 GstMapInfo map;
458
459 timestamp = GST_BUFFER_TIMESTAMP (buf);
460 stream_time =
461 gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
462
463 GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
464 GST_TIME_ARGS (timestamp));
465
466 if (GST_CLOCK_TIME_IS_VALID (stream_time))
467 gst_object_sync_values (GST_OBJECT (filter), stream_time);
468
469 if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))
470 return GST_FLOW_OK;
471
472 gst_buffer_map (buf, &map, GST_MAP_READWRITE);
473 num_samples = map.size / GST_AUDIO_FILTER_BPS (filter);
474
475 filter->process (filter, map.data, num_samples);
476
477 gst_buffer_unmap (buf, &map);
478
479 return GST_FLOW_OK;
480}
char * format
Definition: RaspiStill.c:190
#define MAKE_FLOAT_FUNCS(type)
Definition: audioamplify.c:186
static void gst_audio_amplify_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Definition: audioamplify.c:422
static void gst_audio_amplify_transform_gint16_wrap_negative(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:248
static void gst_audio_amplify_transform_gint32_wrap_positive(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:249
static void gst_audio_amplify_transform_gint32_clip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:249
G_DEFINE_TYPE(GstAudioAmplify, gst_audio_amplify, GST_TYPE_AUDIO_FILTER)
static void gst_audio_amplify_init(GstAudioAmplify *filter)
Definition: audioamplify.c:313
static void gst_audio_amplify_transform_gint32_wrap_negative(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:249
static gboolean gst_audio_amplify_setup(GstAudioFilter *filter, const GstAudioInfo *info)
Definition: audioamplify.c:442
static GstAudioAmplifyProcessFunc gst_audio_amplify_process_function(gint clipping, GstAudioFormat format)
Definition: audioamplify.c:323
static void gst_audio_amplify_transform_gint8_clip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:247
static void gst_audio_amplify_transform_gfloat_clip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:250
GST_DEBUG_CATEGORY_STATIC(gst_audio_amplify_debug)
#define MAKE_INT_FUNCS(type, largetype)
Definition: audioamplify.c:128
#define GST_TYPE_AUDIO_AMPLIFY_CLIPPING_METHOD
Definition: audioamplify.c:75
static void gst_audio_amplify_transform_gint16_clip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:248
static void gst_audio_amplify_transform_gdouble_wrap_negative(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:251
static void gst_audio_amplify_transform_gint16_noclip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:248
static void gst_audio_amplify_transform_gdouble_wrap_positive(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:251
static GstFlowReturn gst_audio_amplify_transform_ip(GstBaseTransform *base, GstBuffer *buf)
Definition: audioamplify.c:452
static void gst_audio_amplify_transform_gfloat_wrap_negative(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:250
@ LAST_SIGNAL
Definition: audioamplify.c:56
static void gst_audio_amplify_transform_gfloat_wrap_positive(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:250
GST_ELEMENT_REGISTER_DEFINE(audioamplify, "audioamplify", GST_RANK_NONE,(gst_audio_amplify_get_type()))
#define ALLOWED_CAPS
Definition: audioamplify.c:97
@ PROP_AMPLIFICATION
Definition: audioamplify.c:62
@ PROP_0
Definition: audioamplify.c:61
@ PROP_CLIPPING_METHOD
Definition: audioamplify.c:63
static GType gst_audio_amplify_clipping_method_get_type(void)
Definition: audioamplify.c:77
static void gst_audio_amplify_transform_gint32_noclip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:249
static void gst_audio_amplify_transform_gfloat_noclip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:250
static void gst_audio_amplify_class_init(GstAudioAmplifyClass *klass)
Definition: audioamplify.c:257
static void gst_audio_amplify_transform_gdouble_noclip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:251
@ METHOD_NOCLIP
Definition: audioamplify.c:71
@ METHOD_WRAP_POSITIVE
Definition: audioamplify.c:70
@ NUM_METHODS
Definition: audioamplify.c:72
@ METHOD_WRAP_NEGATIVE
Definition: audioamplify.c:69
@ METHOD_CLIP
Definition: audioamplify.c:68
#define GST_CAT_DEFAULT
Definition: audioamplify.c:49
static void gst_audio_amplify_transform_gint8_noclip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:247
static void gst_audio_amplify_transform_gint8_wrap_positive(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:247
static void gst_audio_amplify_transform_gint8_wrap_negative(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:247
static void gst_audio_amplify_transform_gint16_wrap_positive(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:248
static void gst_audio_amplify_transform_gdouble_clip(GstAudioAmplify *filter, void *data, guint num_samples)
Definition: audioamplify.c:251
static gboolean gst_audio_amplify_set_process_function(GstAudioAmplify *filter, gint clipping, GstAudioFormat format)
Definition: audioamplify.c:379
static void gst_audio_amplify_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Definition: audioamplify.c:400
#define GST_AUDIO_AMPLIFY(obj)
Definition: audioamplify.h:32
void(* GstAudioAmplifyProcessFunc)(GstAudioAmplify *, void *, guint)
Definition: audioamplify.h:40
#define GST_TYPE_AUDIO_AMPLIFY
Definition: audioamplify.h:31
static gdouble process(GstAudioFXBaseIIRFilter *filter, GstAudioFXBaseIIRFilterChannelCtx *ctx, gdouble x0)
const GstQTDemuxAddTagFunc func
Definition: qtdemux_tags.c:823
gfloat amplification
Definition: audioamplify.h:46
GstAudioAmplifyProcessFunc process
Definition: audioamplify.h:49
GstAudioFormat format
Definition: audioamplify.h:51