~audio-recorder/audio-recorder/trunk

« back to all changes in this revision

Viewing changes to src/gst-recorder.c

  • Committer: Osmo Antero
  • Date: 2012-09-29 18:12:44 UTC
  • Revision ID: osmoma@gmail.com-20120929181244-gmrxd5xww9pua60a
Support new systems; Ubuntu 12.10, Fedora 18. Improved timer and VAD-modules. Better gst-pipeline.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
*/
19
19
#include <math.h>
20
20
#include "gst-recorder.h"
 
21
//#include "gst-recorder-ext.h"
21
22
#include "rec-manager.h"
22
23
#include "media-profiles.h"
23
24
#include "log.h"
41
42
 
42
43
static gboolean rec_level_message_cb(GstBus *bus, GstMessage *message, void *user_data);
43
44
 
44
 
GstElement *rec_create_pipeline(gchar *audio_source, GList *dev_list, gchar *enc_pipeline,
45
 
                                gchar *output_filename, gboolean append_to_file, GError **error);
 
45
GstElement *rec_create_pipeline(PipelineParms *parms, GError **error);
46
46
 
47
47
void rec_set_state_to_null();
48
48
 
186
186
 
187
187
    // Variables
188
188
    gboolean ret = FALSE;
189
 
    gchar *filename = NULL;
190
 
 
191
 
    // Audio source, eg "pulsesrc", "
192
 
    gchar *audio_source = NULL;
193
 
 
194
 
    // Device list
195
 
    GList *dev_list = NULL;
196
 
 
197
 
    gchar *encoder_pipeline = NULL;
 
189
 
 
190
    // Parms to construct a pipeline
 
191
    PipelineParms *parms = g_malloc0(sizeof(PipelineParms));
198
192
 
199
193
    gchar *track_name = NULL;
 
194
    gchar *artist_name = NULL;
 
195
    gchar *album_name = NULL;
200
196
    gint track_pos = 0;
201
197
    gint track_len = 0;
202
 
    gchar *artist_name = NULL;
203
 
    gchar *album_name = NULL;
204
198
 
205
199
    // Get data from GConf registry.
206
200
    // Track name
229
223
    str_trim(last_track_name);
230
224
 
231
225
    // Append to file?
232
 
    gboolean append_to_file = FALSE;
233
 
    conf_get_boolean_value("append-to-file", &append_to_file);
 
226
    conf_get_boolean_value("append-to-file", &parms->append);
234
227
 
235
 
    if (append_to_file && g_file_test(last_track_name, G_FILE_TEST_IS_REGULAR)) {
 
228
    if (parms->append && g_file_test(last_track_name, G_FILE_TEST_IS_REGULAR)) {
236
229
        // Record to an existing filename
237
 
        filename = g_strdup(last_track_name);
 
230
        parms->filename = g_strdup(last_track_name);
238
231
    }
239
232
    // Did we get a track name (output filename) from a Media Player, Skype?
240
233
    else if (str_length(track_name, 2048) > 0) {
241
234
        // We have track, album and artist names. Create filename from these.
242
 
        filename = rec_create_filename(track_name, artist_name, album_name);
 
235
        parms->filename = rec_create_filename(track_name, artist_name, album_name);
243
236
 
244
237
    } else  {
245
238
        // Simply generate a new, unique filename from date+time pattern
246
 
        filename = rec_generate_unique_filename();
 
239
        parms->filename = rec_generate_unique_filename();
247
240
    }
248
241
 
249
242
    // Purify the final filename, remove illegal characters. Edit in place.
250
 
    purify_filename(filename, FALSE);
 
243
    purify_filename(parms->filename, FALSE);
251
244
 
252
245
    // Can we write to path/filename?
253
 
    if (!is_file_writable(filename)) {
254
 
        gchar *msg = g_strdup_printf(_("Cannot write to file \"%s\".\n"), filename);
 
246
    if (!is_file_writable(parms->filename)) {
 
247
        gchar *msg = g_strdup_printf(_("Cannot write to file \"%s\".\n"), parms->filename);
255
248
 
256
249
        // Show error text
257
 
        LOG_DEBUG("Cannot write to file \"%s\".\n", filename);
 
250
        LOG_DEBUG("Cannot write to file \"%s\".\n", parms->filename);
258
251
 
259
252
        rec_manager_set_error_text(msg);
260
253
        g_free(msg);
263
256
    }
264
257
 
265
258
    // Save the last file name
266
 
    conf_save_string_value("track/last-track-name", filename);
 
259
    conf_save_string_value("track/last-track-name", parms->filename);
267
260
 
268
261
    // Get the saved media profile id (aac, mp3, cdlossless, cdlossy, etc).
269
262
    gchar *media_profile_id = rec_get_media_profile_id();
270
263
 
271
264
    // Get partial pipline from GConf for this media_profile_id
272
 
    encoder_pipeline = media_profiles_get_pipeline(media_profile_id);
 
265
    parms->profile_str = media_profiles_get_pipeline(media_profile_id);
 
266
    parms->file_ext = media_profiles_get_extension(media_profile_id);
273
267
    g_free(media_profile_id);
274
268
 
 
269
 
 
270
 
275
271
#if 0
276
272
    // Debugging:
277
273
    gchar *device_id = NULL;
292
288
#endif
293
289
 
294
290
    // Set/show current filename
295
 
    rec_manager_set_filename_label(filename);
 
291
    rec_manager_set_filename_label(parms->filename);
296
292
 
297
293
    // Get audio source and device list
298
 
    dev_list = audio_sources_get_device_NEW(&audio_source);
 
294
    gchar *audio_source = NULL;
 
295
    parms->dev_list = audio_sources_get_device_NEW(&audio_source);
 
296
    parms->source = audio_source; 
299
297
 
300
298
    // Now build a GStreamer pipeline with these values
301
299
    GError *error = NULL;
302
 
    g_pipeline = rec_create_pipeline(audio_source, dev_list, encoder_pipeline, filename, append_to_file, &error);
 
300
    g_pipeline = rec_create_pipeline(parms, &error);
303
301
 
304
302
    ret = TRUE;
305
303
 
317
315
 
318
316
        ret = FALSE;
319
317
    } else {
320
 
        // Alles Ok.
321
 
        // Clear error messages.
 
318
        // Alles Ok. Clear error messages.
322
319
        rec_manager_set_error_text(NULL);
323
320
    }
324
321
 
326
323
 
327
324
LBL_1:
328
325
 
329
 
    g_free(filename);
330
 
 
331
326
    g_free(track_name);
332
327
    g_free(artist_name);
333
328
    g_free(album_name);
334
329
 
335
 
    g_free(encoder_pipeline);
336
 
    g_free(audio_source);
337
 
 
338
 
    // Free dev_list
339
 
    str_list_free(dev_list);
340
 
    dev_list = NULL;
 
330
    pipeline_free_parms(parms);
 
331
    parms = NULL;
341
332
 
342
333
    return ret;
343
334
}
568
559
    if (!GST_IS_MESSAGE(msg)) return;
569
560
 
570
561
    // We are only interested in the top-level pipeline.
571
 
    if (msg->src != GST_OBJECT(g_pipeline)) return;
 
562
    if (GST_MESSAGE_SRC(msg) != GST_OBJECT(g_pipeline)) return;
572
563
 
573
564
    GstState old_state, new_state;
574
565
    gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
575
566
 
576
 
 
577
567
    GstState state, pending;
578
568
    gst_element_get_state(g_pipeline, &state, &pending, 0);
579
 
    LOG_DEBUG("Pipeline state changed from %s to: %s  (stat=%s pending=%s).\n", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state),
 
569
    LOG_DEBUG("Pipeline state changed from %s to: %s  (stat=%s pending=%s).\n", 
 
570
              gst_element_state_get_name(old_state), gst_element_state_get_name(new_state), 
580
571
              gst_element_state_get_name(state), gst_element_state_get_name(pending));
581
572
 
582
573
    // Pipeline state changed from PAUSED to: READY  (stat=READY pending=VOID_PENDING).
645
636
    g_got_EOS_message = TRUE;
646
637
}
647
638
 
648
 
GstElement *rec_create_pipeline(gchar *audio_source, GList *dev_list, gchar *enc_pipeline, gchar *output_filename, gboolean append_to_file, GError **error) {
 
639
GstElement *rec_create_pipeline(PipelineParms *parms, GError **error) {
649
640
    // Create a GStreamer pipeline for audio recording.
650
641
    gchar *err_msg = NULL;
651
642
 
652
643
    // Print debug info
653
644
    LOG_DEBUG("----------------------------\n");
654
645
    LOG_DEBUG("rec_create_pipeline, The parameters are:\n");
655
 
    LOG_DEBUG("audio_source=%s\n", audio_source);
656
 
    LOG_DEBUG("Device list is:\n");
 
646
    LOG_DEBUG("audio source=%s\n", parms->source);
 
647
    LOG_DEBUG("device list is:\n");
657
648
 
658
 
    GList *n = g_list_first(dev_list);
 
649
    GList *n = g_list_first(parms->dev_list);
659
650
    while (n) {
660
651
        gchar *device = (gchar*)n->data;
661
652
        (void)device; // Avoid unused var message
664
655
        n = g_list_next(n);
665
656
    }
666
657
 
667
 
    LOG_DEBUG("encoder_pipeline (from GConf)=%s\n",enc_pipeline);
668
 
    LOG_DEBUG("filename=%s\n", output_filename);
669
 
    LOG_DEBUG("append_to_file=%s\n", (append_to_file ? "TRUE" : "FALSE"));
 
658
    LOG_DEBUG("profile from GConf=%s\n",parms->profile_str);
 
659
    LOG_DEBUG("filename=%s\n", parms->filename);
 
660
    LOG_DEBUG("append to file=%s\n", (parms->append ? "TRUE" : "FALSE"));
670
661
 
671
 
    // Create pipeline
672
 
    GstElement *pipeline = pipeline_create(audio_source, dev_list, enc_pipeline, "filesink", &err_msg);
 
662
    // Create pipeline from the parms
 
663
    GstElement *pipeline = pipeline_create(parms, &err_msg);
673
664
 
674
665
    // Errors?
675
666
    if (!GST_IS_PIPELINE(pipeline) || err_msg) {
676
667
        goto LBL_1;
677
668
    }
678
669
 
679
 
    // Get "output-sink" element
680
 
    GstElement *filesink = gst_bin_get_by_name(GST_BIN(pipeline), "output-sink");
 
670
    // Get "filesink" and set location (file name) and append mode
 
671
    GstElement *filesink = gst_bin_get_by_name(GST_BIN(pipeline), "filesink");
681
672
 
682
673
    if (!GST_IS_ELEMENT(filesink)) {
683
674
        err_msg = g_strdup_printf(_("Cannot find audio element %s.\n"), "filesink");
684
675
        goto LBL_1;
685
676
    }
686
677
 
687
 
    // And set location (filename) and append mode
688
 
    g_object_set(G_OBJECT(filesink), "location", output_filename, NULL);
689
 
    g_object_set(G_OBJECT(filesink), "append", append_to_file, NULL);
690
 
 
 
678
    g_object_set(G_OBJECT(filesink), "location", parms->filename, NULL);
 
679
    g_object_set(G_OBJECT(filesink), "append", parms->append, NULL);
691
680
    g_object_unref(filesink);
692
681
 
693
682
    // Add a message handler
718
707
        err_msg = g_strdup(_("Cannot start reading from the stream/pipeline.\n"));
719
708
        ret = FALSE;
720
709
    } else {
721
 
        LOG_DEBUG("Pipeline is OK. Starting recording to %s.\n", output_filename);
 
710
        LOG_DEBUG("Pipeline is OK. Starting recording to %s.\n", parms->filename);
722
711
    }
723
712
 
 
713
    // gst_element_get_state(pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
 
714
 
 
715
 
724
716
    // Are we finally ok?
725
717
    if (ret) {
726
718
        return pipeline;
758
750
    // Valid pipeline?
759
751
    if (!GST_IS_ELEMENT(g_pipeline)) return NULL;
760
752
 
761
 
    // Get the "output-sink" element (by name)
762
 
    GstElement *filesink = gst_bin_get_by_name(GST_BIN(g_pipeline), "output-sink");
 
753
    // Get the "filesink" element (by name)
 
754
    GstElement *filesink = gst_bin_get_by_name(GST_BIN(g_pipeline), "filesink");
763
755
 
764
756
    // Got filesink?
765
757
    if (!GST_IS_ELEMENT(filesink)) return NULL;
964
956
    return filename;
965
957
}
966
958
 
 
959
/*
 
960
void rec_treshold_message(GstClockTime timestamp, gboolean above, gdouble threshold) {
 
961
    // Listener module calls this function to notify the recorder about level change.
 
962
    // The signal level is below/above the threshold.
 
963
 
 
964
    g_print("Timestamp=%" GST_TIME_FORMAT "  above=%s  threshold=%3.3f\n", 
 
965
                GST_TIME_ARGS(timestamp), (above ? "TRUE" : "FALSE") , threshold);
 
966
 
 
967
}
 
968
*/
 
969