~ubuntu-branches/ubuntu/raring/gnomeradio/raring

« back to all changes in this revision

Viewing changes to src/rec_tech.c

  • Committer: Package Import Robot
  • Author(s): POJAR GEORGE
  • Date: 2012-07-02 20:54:09 UTC
  • Revision ID: package-import@ubuntu.com-20120702205409-0imetkxstcihst9e
Tags: 1.8-2ubuntu3
* debian/patches/gnomeradio-g_thread_init_deprecation.patch: Fix obsolete
  g_thread_init(). (LP: #1013383)
* debian/patches/gnomeradio-gtk_grid.patch: Port to GtkGrid from deprecated
  GtkTable. (LP: #1018398)
* gnomeradio-record_information.patch: Redesigned
  'Gnomeradio recording status' window to show more recording information.
  (LP: #1019981)

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <sys/stat.h>
24
24
#include <unistd.h>
25
25
#include <fcntl.h>
26
 
 
27
 
static void error_cb(GstBus *bus, GstMessage *message, gpointer user_data)
 
26
#include <math.h>
 
27
 
 
28
GtkWidget *level;
 
29
 
 
30
static void
 
31
show_error_dialog (GtkWindow *win, const gchar *dbg, const gchar * format, ...)
 
32
{
 
33
        GtkWidget *dialog;
 
34
        va_list args;
 
35
        gchar *s;
 
36
 
 
37
        va_start (args, format);
 
38
        s = g_strdup_vprintf (format, args);
 
39
        va_end (args);
 
40
 
 
41
        dialog = gtk_message_dialog_new (win,
 
42
                                         GTK_DIALOG_DESTROY_WITH_PARENT,
 
43
                                         GTK_MESSAGE_ERROR,
 
44
                                         GTK_BUTTONS_CLOSE,
 
45
                                         "%s",
 
46
                                         s);
 
47
 
 
48
        if (dbg != NULL) {
 
49
                g_printerr ("ERROR: %s\nDEBUG MESSAGE: %s\n", s, dbg);
 
50
        }
 
51
 
 
52
        gtk_dialog_run (GTK_DIALOG (dialog));
 
53
        gtk_widget_destroy (dialog);
 
54
        g_free (s);
 
55
}
 
56
 
 
57
static void
 
58
show_missing_known_element_error (GtkWindow *win, gchar *description,
 
59
        gchar *element, gchar *plugin, gchar *module)
 
60
{
 
61
        show_error_dialog (win, NULL,
 
62
                                                _("Could not create the GStreamer %s element.\n"
 
63
                                "Please install the '%s' plugin from the '%s' module.\n"
 
64
                                "Verify that the installation is correct by running\n"
 
65
                                                        "               gst-inspect-0.10 %s\n"
 
66
                                "and then restart gnome-sound-recorder."),
 
67
                                                description, plugin, module, element);
 
68
}
 
69
 
 
70
static void
 
71
show_profile_error (GtkWindow *win, gchar *debug, gchar *description,
 
72
        const char *profile)
 
73
{
 
74
        gchar *first;
 
75
 
 
76
        first = g_strdup_printf (description, profile);
 
77
        show_error_dialog (win, debug, "%s%s", first,
 
78
                        _("Please verify its settings.\n"
 
79
                                "You may be missing the necessary plugins."));
 
80
        g_free (first);
 
81
}
 
82
 
 
83
static void pipeline_error_cb(GstBus *bus, GstMessage *message, gpointer user_data)
28
84
{
29
85
        GError *error = NULL;
30
86
        GstElement *pipeline = user_data;
38
94
        g_error_free(error);
39
95
}
40
96
 
 
97
static gboolean
 
98
level_message_handler_cb (GstBus *bus, GstMessage *message, gpointer user_data)
 
99
{
 
100
        if (message->type == GST_MESSAGE_ELEMENT) {
 
101
                const GstStructure *s = gst_message_get_structure (message);
 
102
                const gchar *name = gst_structure_get_name (s);
 
103
 
 
104
                if (g_str_equal (name, "level")) {
 
105
                        gint channels;
 
106
                        gdouble peak_dB;
 
107
                        gdouble myind;
 
108
                        const GValue *list;
 
109
                        const GValue *value;
 
110
 
 
111
                        gint i;
 
112
                        /* we can get the number of channels as the length of any of the value
 
113
                         * lists */
 
114
 
 
115
                        list = gst_structure_get_value (s, "rms");
 
116
                        channels = gst_value_list_get_size (list);
 
117
 
 
118
                        for (i = 0; i < channels; ++i) {
 
119
        list = gst_structure_get_value (s, "peak");
 
120
                                value = gst_value_list_get_value (list, i);
 
121
                                peak_dB = g_value_get_double (value);
 
122
        myind = exp (peak_dB / 20);
 
123
        if (myind > 1.0)
 
124
                myind = 1.0;
 
125
        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (level), myind);
 
126
                        }
 
127
                }
 
128
        }
 
129
        /* we handled the message we want, and ignored the ones we didn't want.
 
130
         * so the core can unref the message for us */
 
131
        return TRUE;
 
132
}
 
133
 
41
134
Recording*
42
135
recording_start(const char* filename)
43
136
{
44
137
        GMAudioProfile *profile;
45
 
        GstElement *pipeline, *source, *encoder, *filesink;
46
 
        pipeline = source = encoder = filesink = NULL;
47
 
        
 
138
        const gchar *profile_pipeline_desc;
 
139
        GstElement *pipeline, *source, *encoder, *filesink, *level;
 
140
        pipeline = source = encoder = filesink = level = NULL;
 
141
        GError *err = NULL;
 
142
        gchar *pipeline_desc;
 
143
        const char *name;
 
144
 
 
145
        source = gst_element_factory_make ("gconfaudiosrc", "gconfaudiosource");
 
146
        if (source == NULL) {
 
147
                show_missing_known_element_error (NULL,
 
148
                                _("GConf audio recording"), "gconfaudiosrc",
 
149
                                "gconfelements", "gst-plugins-good");
 
150
                return FALSE;
 
151
        }
 
152
 
 
153
                                if (!gst_element_set_state (source, GST_STATE_READY)) {
 
154
                show_error_dialog (NULL, NULL,
 
155
                        _("Your audio capture settings are invalid. "
 
156
                                "Please correct them with the \"Sound Preferences\" "
 
157
                                "under the System Preferences menu."));
 
158
                return FALSE;
 
159
        }
 
160
 
 
161
        filesink = gst_element_factory_make ("filesink", "sink");
 
162
        if (filesink == NULL)
 
163
        {
 
164
                show_missing_known_element_error (NULL,
 
165
                                _("file output"), "filesink", "coreelements",
 
166
                                "gstreamer");
 
167
                gst_object_unref (source);
 
168
                return NULL;
 
169
        }
 
170
 
 
171
        pipeline = gst_pipeline_new("gnomeradio-record-pipeline");
 
172
 
 
173
        gst_bin_add (GST_BIN (pipeline), source);
 
174
 
 
175
        level = gst_element_factory_make ("level", "level");
 
176
        if (level == NULL)
 
177
        {
 
178
                show_missing_known_element_error (NULL,
 
179
                                _("level"), "level", "level",
 
180
                                "gstreamer");
 
181
                gst_object_unref (source);
 
182
                return NULL;
 
183
        }
 
184
        gst_element_set_name (level, "level");
 
185
 
48
186
        profile = gm_audio_profile_lookup(rec_settings.profile);
49
187
        g_assert(profile);
50
 
        
51
 
        pipeline = gst_pipeline_new("gnomeradio-record-pipeline");
52
 
        if (!pipeline) {
53
 
                g_warning(_("Could not create GStreamer pipeline. Check your Gstreamer installation!\n"));
54
 
                goto error;
55
 
        }               
56
 
        
57
 
        source = gst_element_factory_make("autoaudiosrc", "audio_source");
58
 
        if (!source) {
59
 
                g_warning(_("Could not open Gstreamer AUDIO Source. Verify your Gstreamer AUDIO subsystem installation!\n"));
60
 
                goto error;
61
 
        }
62
 
        
 
188
        if (profile == NULL)
 
189
                return NULL;
 
190
        profile_pipeline_desc = gm_audio_profile_get_pipeline (profile);
 
191
        name = gm_audio_profile_get_name (profile);
 
192
 
 
193
        GST_DEBUG ("encoder profile pipeline: '%s'",
 
194
                GST_STR_NULL (profile_pipeline_desc));
 
195
 
 
196
        pipeline_desc = g_strdup_printf ("audioconvert ! %s", profile_pipeline_desc);
 
197
        GST_DEBUG ("making encoder bin from description '%s'", pipeline_desc);
 
198
        encoder = gst_parse_bin_from_description (pipeline_desc, TRUE, &err);
 
199
        g_free (pipeline_desc);
 
200
        pipeline_desc = NULL;
 
201
 
 
202
        if (err) {
 
203
                show_profile_error (NULL, err->message,
 
204
                        _("Could not parse the '%s' audio profile. "), name);
 
205
                g_printerr ("Failed to create GStreamer encoder plugins [%s]: %s\n",
 
206
                                                         profile_pipeline_desc, err->message);
 
207
                g_error_free (err);
 
208
                gst_object_unref (pipeline);
 
209
                gst_object_unref (filesink);
 
210
                g_free (pipeline);
 
211
                return NULL;
 
212
        }
 
213
 
 
214
        gst_bin_add (GST_BIN (pipeline), level);
 
215
        gst_bin_add (GST_BIN (pipeline), encoder);
 
216
        gst_bin_add (GST_BIN (pipeline), filesink);
 
217
 
 
218
        if (!(gst_element_link_many (source, level, encoder, NULL))) {
 
219
                show_profile_error (NULL, NULL,
 
220
                        _("Could not capture using the '%s' audio profile. "),
 
221
                        name);
 
222
                gst_object_unref (pipeline);
 
223
                g_free (pipeline);
 
224
                return NULL;
 
225
        }
 
226
 
 
227
        if (!gst_element_link (encoder, filesink)) {
 
228
                show_profile_error (NULL, NULL,
 
229
                        _("Could not write to a file using the '%s' audio profile. "),
 
230
                        name);
 
231
                gst_object_unref (pipeline);
 
232
                g_free (pipeline);
 
233
                return NULL;
 
234
        }
 
235
 
63
236
        GstBus *bus = gst_element_get_bus(pipeline);
64
237
        gst_bus_add_signal_watch(bus);
65
 
        g_signal_connect(G_OBJECT(bus), "message::error", G_CALLBACK(error_cb), pipeline);
66
 
 
67
 
        char* pipeline_str = g_strdup_printf("audioconvert ! %s", gm_audio_profile_get_pipeline(profile));
68
 
        encoder = gst_parse_bin_from_description(pipeline_str, TRUE, NULL);
69
 
        g_free(pipeline_str);
70
 
        if (!encoder) {
71
 
                char *caption = g_strdup_printf(_("Could not create encoder \"%s\"."), gm_audio_profile_get_name (profile));
72
 
                g_warning(_("%s Verify your Gstreamer plugins installation!\n"), caption);
73
 
                g_free(caption);
74
 
                goto error;
75
 
        }
76
 
        
77
 
        /* Write to disk */
78
 
        filesink = gst_element_factory_make("filesink", "file-sink");
79
 
        if (!filesink) {        
80
 
                g_warning(_("Could not create Gstreamer filesink. Check your Gstreamer installation!"));
81
 
                goto error;
82
 
        }
83
 
        
84
 
        /* Add the elements to the pipeline */
85
 
        gst_bin_add_many(GST_BIN(pipeline), source, encoder, filesink, NULL);
86
 
        
87
 
        /* Link it all together */
88
 
        if (!gst_element_link_many(source, encoder, filesink, NULL)) {
89
 
                g_warning("Could not link elements. This is bad!\n");
90
 
                goto error;
91
 
        }
 
238
 
 
239
        g_signal_connect(G_OBJECT(bus), "message::error",
 
240
                          G_CALLBACK(pipeline_error_cb),
 
241
                          pipeline);
 
242
 
 
243
        g_signal_connect (G_OBJECT(bus), "message::element",
 
244
                          G_CALLBACK (level_message_handler_cb),
 
245
                          pipeline);
 
246
 
92
247
        char* path = g_strdup_printf("%s.%s", filename, gm_audio_profile_get_extension(profile));       
93
248
        g_object_set(G_OBJECT(filesink), "location", path, NULL);
94
249
        
99
254
        recording->pipeline = pipeline;
100
255
        
101
256
        return recording;
102
 
        
103
 
error:
104
 
        if (pipeline)
105
 
                gst_object_unref(GST_OBJECT(pipeline));
106
 
        if (source)
107
 
                gst_object_unref(GST_OBJECT(source));
108
 
        if (encoder)
109
 
                gst_object_unref(GST_OBJECT(encoder));
110
 
        if (filesink)
111
 
                gst_object_unref(GST_OBJECT(filesink));
112
 
        
113
 
        return NULL;
114
257
}               
115
258
 
116
259
void
121
264
        GstState state;
122
265
        gst_element_get_state(recording->pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
123
266
        if (state != GST_STATE_PLAYING) {
124
 
        g_print("Ups!\n");
 
267
                GST_DEBUG ("pipeline in wrong state: %s",
 
268
                        gst_element_state_get_name (state));
125
269
        } else {
126
270
                gst_element_set_state(recording->pipeline, GST_STATE_NULL);
127
271
        }