• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  *
3  * volume.c: sample application to change the volume of a pipeline
4  *
5  * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <math.h>
28 
29 #include <gst/gst.h>
30 #include <gtk/gtk.h>
31 
32 /* global pointer for the scale widget */
33 static GtkWidget *elapsed;
34 static GtkWidget *scale;
35 
36 #ifndef M_LN10
37 #define M_LN10 (log(10.0))
38 #endif
39 
40 static void
value_changed_callback(GtkWidget * widget,GstElement * volume)41 value_changed_callback (GtkWidget * widget, GstElement * volume)
42 {
43   gdouble value;
44   gdouble level;
45 
46   value = gtk_range_get_value (GTK_RANGE (widget));
47   level = exp (value / 20.0 * M_LN10);
48   g_print ("Value: %f dB, level: %f\n", value, level);
49   g_object_set (volume, "volume", level, NULL);
50 }
51 
52 static void
setup_gui(GstElement * volume)53 setup_gui (GstElement * volume)
54 {
55   GtkWidget *window;
56   GtkWidget *vbox;
57   GtkWidget *label, *hbox;
58 
59   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
60   g_signal_connect (window, "destroy", gtk_main_quit, NULL);
61 
62   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
63   gtk_container_add (GTK_CONTAINER (window), vbox);
64 
65   /* elapsed widget */
66   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
67   label = gtk_label_new ("Elapsed: ");
68   elapsed = gtk_label_new ("0.0");
69   gtk_container_add (GTK_CONTAINER (hbox), label);
70   gtk_container_add (GTK_CONTAINER (hbox), elapsed);
71   gtk_container_add (GTK_CONTAINER (vbox), hbox);
72 
73   /* volume */
74   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
75   label = gtk_label_new ("volume");
76   gtk_container_add (GTK_CONTAINER (hbox), label);
77   scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -90.0, 10.0,
78       0.2);
79   gtk_range_set_value (GTK_RANGE (scale), 0.0);
80   gtk_widget_set_size_request (scale, 100, -1);
81   gtk_container_add (GTK_CONTAINER (hbox), scale);
82   gtk_container_add (GTK_CONTAINER (vbox), hbox);
83   g_signal_connect (scale, "value-changed",
84       G_CALLBACK (value_changed_callback), volume);
85 
86   gtk_widget_show_all (GTK_WIDGET (window));
87 }
88 
89 static gboolean
progress_update(gpointer data)90 progress_update (gpointer data)
91 {
92   GstElement *pipeline = (GstElement *) data;
93   gint64 position;
94   gchar *position_str;
95 
96   if (gst_element_query_position (pipeline, GST_FORMAT_TIME, &position))
97     position_str = g_strdup_printf ("%.1f", (gfloat) position / GST_SECOND);
98   else
99     position_str = g_strdup_printf ("n/a");
100   gtk_label_set_text (GTK_LABEL (elapsed), position_str);
101 
102   g_free (position_str);
103 
104   return TRUE;
105 }
106 
107 static void
message_received(GstBus * bus,GstMessage * message,GstPipeline * pipeline)108 message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
109 {
110   const GstStructure *s;
111 
112   s = gst_message_get_structure (message);
113   g_print ("message from \"%s\" (%s): ",
114       GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))),
115       gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
116   if (s) {
117     gchar *sstr;
118 
119     sstr = gst_structure_to_string (s);
120     g_print ("%s\n", sstr);
121     g_free (sstr);
122   } else {
123     g_print ("no message details\n");
124   }
125 }
126 
127 static void
eos_message_received(GstBus * bus,GstMessage * message,GstPipeline * pipeline)128 eos_message_received (GstBus * bus, GstMessage * message,
129     GstPipeline * pipeline)
130 {
131   message_received (bus, message, pipeline);
132   gtk_main_quit ();
133 }
134 
135 int
main(int argc,char * argv[])136 main (int argc, char *argv[])
137 {
138 
139   GstElement *pipeline = NULL;
140 
141 #ifndef GST_DISABLE_PARSE
142   GError *error = NULL;
143 #endif
144   GstElement *volume;
145   GstBus *bus;
146 
147 #ifdef GST_DISABLE_PARSE
148   g_print ("GStreamer was built without pipeline parsing capabilities.\n");
149   g_print
150       ("Please rebuild GStreamer with pipeline parsing capabilities activated to use this example.\n");
151   return 1;
152 #else
153   gst_init (&argc, &argv);
154   gtk_init (&argc, &argv);
155 
156   pipeline = gst_parse_launchv ((const gchar **) &argv[1], &error);
157   if (error) {
158     g_print ("pipeline could not be constructed: %s\n", error->message);
159     g_print ("Please give a complete pipeline  with a 'volume' element.\n");
160     g_print ("Example: audiotestsrc ! volume ! %s\n", DEFAULT_AUDIOSINK);
161     g_error_free (error);
162     return 1;
163   }
164 #endif
165   volume = gst_bin_get_by_name (GST_BIN (pipeline), "volume0");
166   if (volume == NULL) {
167     g_print ("Please give a pipeline with a 'volume' element in it\n");
168     return 1;
169   }
170 
171   /* setup message handling */
172   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
173   gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
174   g_signal_connect (bus, "message::error", (GCallback) message_received,
175       pipeline);
176   g_signal_connect (bus, "message::warning", (GCallback) message_received,
177       pipeline);
178   g_signal_connect (bus, "message::eos", (GCallback) eos_message_received,
179       pipeline);
180 
181   /* setup GUI */
182   setup_gui (volume);
183 
184   /* go to main loop */
185   gst_element_set_state (pipeline, GST_STATE_PLAYING);
186   g_timeout_add (100, progress_update, pipeline);
187   gtk_main ();
188   gst_element_set_state (pipeline, GST_STATE_NULL);
189   gst_object_unref (volume);
190   gst_object_unref (pipeline);
191   gst_object_unref (bus);
192 
193   return 0;
194 }
195