1 /* GStreamer
2 * Copyright (C) 2009 Sebastian Droege <sebastian.droege@collabora.co.uk>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /* This small sample application creates a lowpass IIR filter
21 * and applies it to white noise.
22 * See http://www.dspguide.com/ch19/2.htm for a description
23 * of the IIR filter that is used.
24 */
25
26 /* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
27 * with newer GLib versions (>= 2.31.0) */
28 #define GLIB_DISABLE_DEPRECATION_WARNINGS
29
30 #include <string.h>
31 #include <math.h>
32
33 #include <gst/gst.h>
34
35 /* Cutoff of 4000 Hz */
36 #define CUTOFF (4000.0)
37
38 static gboolean
on_message(GstBus * bus,GstMessage * message,gpointer user_data)39 on_message (GstBus * bus, GstMessage * message, gpointer user_data)
40 {
41 GMainLoop *loop = (GMainLoop *) user_data;
42
43 switch (GST_MESSAGE_TYPE (message)) {
44 case GST_MESSAGE_ERROR:
45 g_error ("Got ERROR");
46 g_main_loop_quit (loop);
47 break;
48 case GST_MESSAGE_WARNING:
49 g_warning ("Got WARNING");
50 g_main_loop_quit (loop);
51 break;
52 case GST_MESSAGE_EOS:
53 g_main_loop_quit (loop);
54 break;
55 default:
56 break;
57 }
58
59 return TRUE;
60 }
61
62 static void
on_rate_changed(GstElement * element,gint rate,gpointer user_data)63 on_rate_changed (GstElement * element, gint rate, gpointer user_data)
64 {
65 GValueArray *va;
66 GValue v = { 0, };
67 gdouble x;
68
69 if (rate / 2.0 > CUTOFF)
70 x = exp (-2.0 * G_PI * (CUTOFF / rate));
71 else
72 x = 0.0;
73
74 va = g_value_array_new (1);
75
76 g_value_init (&v, G_TYPE_DOUBLE);
77 g_value_set_double (&v, 1.0 - x);
78 g_value_array_append (va, &v);
79 g_value_reset (&v);
80 g_object_set (G_OBJECT (element), "a", va, NULL);
81 g_value_array_free (va);
82
83 va = g_value_array_new (1);
84 g_value_set_double (&v, x);
85 g_value_array_append (va, &v);
86 g_value_reset (&v);
87 g_object_set (G_OBJECT (element), "b", va, NULL);
88 g_value_array_free (va);
89 }
90
91 gint
main(gint argc,gchar * argv[])92 main (gint argc, gchar * argv[])
93 {
94 GstElement *pipeline, *src, *filter, *conv, *sink;
95 GstBus *bus;
96 GMainLoop *loop;
97
98 gst_init (NULL, NULL);
99
100 pipeline = gst_element_factory_make ("pipeline", NULL);
101
102 src = gst_element_factory_make ("audiotestsrc", NULL);
103 g_object_set (G_OBJECT (src), "wave", 5, NULL);
104
105 filter = gst_element_factory_make ("audioiirfilter", NULL);
106 g_signal_connect (G_OBJECT (filter), "rate-changed",
107 G_CALLBACK (on_rate_changed), NULL);
108
109 conv = gst_element_factory_make ("audioconvert", NULL);
110
111 sink = gst_element_factory_make ("autoaudiosink", NULL);
112 g_return_val_if_fail (sink != NULL, -1);
113
114 gst_bin_add_many (GST_BIN (pipeline), src, filter, conv, sink, NULL);
115 if (!gst_element_link_many (src, filter, conv, sink, NULL)) {
116 g_error ("Failed to link elements");
117 return -2;
118 }
119
120 loop = g_main_loop_new (NULL, FALSE);
121
122 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
123 gst_bus_add_signal_watch (bus);
124 g_signal_connect (G_OBJECT (bus), "message", G_CALLBACK (on_message), loop);
125 gst_object_unref (GST_OBJECT (bus));
126
127 if (gst_element_set_state (pipeline,
128 GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
129 g_error ("Failed to go into PLAYING state");
130 return -3;
131 }
132
133 g_main_loop_run (loop);
134
135 gst_element_set_state (pipeline, GST_STATE_NULL);
136
137 g_main_loop_unref (loop);
138 gst_object_unref (pipeline);
139
140 return 0;
141 }
142