]> err.no Git - mapper/blobdiff - src/audio-note.c
Fixes to gstreamer element and caps handlings.
[mapper] / src / audio-note.c
index 1ff76aa46382fe6a1c853ba2a0aa52bbc3700712..46370529cce284a00868755d6ee3319fe89d8fbb 100644 (file)
  */
 
 #include "config.h"
+#include <glib.h>
 #include <gst/gst.h>
+#include <gtk/gtk.h>
 
+#include "ui-common.h"
+#include "audio.h"
 #include "audio-note.h"
 
+static note_pipeline note_play;
+static note_pipeline note_record;
+static GstBus *bus;
+static gchar *cfile=NULL;
+
+static gboolean
+audio_note_record_cb(GtkWidget *widget, gpointer data)
+{
+const gchar *basedir;
+gchar buffer[128];
+audio_note_ui *ui=(audio_note_ui *)data;
+GDate *gd;
+time_t t;
+struct tm *tmp;
+
+/* XXX: Make this a configuration option */
 #ifdef WITH_DEVICE_770
-#define AUDIO_SRC "dsppcmsrc"
-#define AUDIO_SINK "dsppcmsink"
+basedir="/media/mmc1/MapperAudioNotes";
+if (g_mkdir_with_parents(basedir, 0775)==-1) {
+       MACRO_BANNER_SHOW_INFO(_window, _("Failed to create directory for sound files!"));
+       return TRUE;
+}
 #else
-#define AUDIO_SRC "alsasrc"
-#define AUDIO_SINK "autoaudiosink"
+basedir=g_get_home_dir();
 #endif
 
-typedef struct _note_pipeline note_pipeline;
-struct _note_pipeline {
-       GstElement *pipeline;
-       GstElement *src;
-       GstElement *sink;
-       GstElement *filter;
-       gboolean rec;
-};
-static note_pipeline note_play;
-static note_pipeline note_record;
+t=time(NULL);
+tmp=localtime(&t);
+if (tmp == NULL) {
+       MACRO_BANNER_SHOW_INFO(_window, _("Failed to get timestamp for file!"));
+       return TRUE;
+}
+strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H:%M:%S", tmp);
 
-static GstBus *bus;
+if (cfile)
+       g_free(cfile);
+
+cfile=g_strdup_printf("%s/an-%s.wav", basedir, buffer);
+
+audio_note_record(cfile);
+
+MACRO_BANNER_SHOW_INFO(_window, _("Recording..."));
+
+return TRUE;
+}
+
+static gboolean
+audio_note_play_cb(GtkWidget *widget, gpointer data)
+{
+audio_note_ui *ui=(audio_note_ui *)data;
+
+audio_note_play(cfile);
+MACRO_BANNER_SHOW_INFO(_window, _("Playing..."));
+return TRUE;
+}
+
+static gboolean
+audio_note_stop_cb(GtkWidget *widget, gpointer data)
+{
+if (audio_note_stop()==TRUE)
+       MACRO_BANNER_SHOW_INFO(_window, _("Stopped..."));
+return TRUE;
+}
+
+audio_note_ui *
+audio_note_new(void)
+{
+audio_note_ui *ui;
+ui=g_slice_new(audio_note_ui);
+ui->vbox=gtk_vbox_new(FALSE, 0);
+ui->lbl_time=gtk_label_new("");
+ui->btn_record=gtk_button_new_from_stock(GTK_STOCK_MEDIA_RECORD);
+ui->btn_play=gtk_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
+ui->btn_stop=gtk_button_new_from_stock(GTK_STOCK_MEDIA_STOP);
+
+gtk_box_pack_start(GTK_BOX(ui->vbox), ui->lbl_time, TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(ui->vbox), ui->btn_record, TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(ui->vbox), ui->btn_play, TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(ui->vbox), ui->btn_stop, TRUE, TRUE, 0);
+
+ui->note_play=&note_play;
+ui->note_record=&note_record;
+
+g_signal_connect(G_OBJECT(ui->btn_record), "clicked", G_CALLBACK(audio_note_record_cb), ui);
+g_signal_connect(G_OBJECT(ui->btn_play), "clicked", G_CALLBACK(audio_note_play_cb), ui);
+g_signal_connect(G_OBJECT(ui->btn_stop), "clicked", G_CALLBACK(audio_note_stop_cb), ui);
+
+return ui;
+}
 
 static gboolean
 audio_note_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
 {
 gchar *debug;
 GError *err;
+note_pipeline *np=(note_pipeline *)data;
 
 switch (GST_MESSAGE_TYPE (msg)) {
        case GST_MESSAGE_EOS:
-       g_print ("EOS\n");
+               np->active=FALSE;
+       g_debug("EOS\n");
        break;
        case GST_MESSAGE_ERROR:
                gst_message_parse_error (msg, &err, &debug);
+               g_debug("Error: %s", err->message);
                g_free(debug);
-
-               g_printf("Error: %s\n", err->message);
                g_error_free(err);
+               np->active=FALSE;
        break;
        case GST_MESSAGE_STATE_CHANGED:
-               g_printf("State changed\n");
+               g_debug("GST: %s", gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
        break;
     default:
-               g_printf("GST: %s\n", gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
+               g_debug("GST: %s", gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
        break;
        }
 return TRUE;
@@ -79,20 +154,47 @@ static gboolean
 audio_create_pipeline(note_pipeline *np, gboolean rec)
 {
 np->pipeline=gst_pipeline_new("pipeline");
-g_assert(np->pipeline);
+bus=gst_pipeline_get_bus(GST_PIPELINE(np->pipeline));
+gst_bus_add_watch(bus, audio_note_bus_cb, np);
+
 if (rec==TRUE) {
+       g_debug("GST: Creating record pipeline");
        np->src=gst_element_factory_make(AUDIO_SRC, "source");
        np->filter=gst_element_factory_make("wavenc", "filter");
        np->sink=gst_element_factory_make("filesink", "sink");
+
+       gst_bin_add_many(GST_BIN(np->pipeline), np->src, np->filter, np->sink, NULL);
+
+#ifndef WITH_DEVICE_770
+       /* Don't waste space with some hifi format */
+       np->srccaps=gst_caps_new_simple ("audio/x-raw-int",
+                       "depth", G_TYPE_INT, 16,
+                       "signed", G_TYPE_BOOLEAN, TRUE, 
+                       "width", G_TYPE_INT, 16,
+                       "rate", G_TYPE_INT, 11025,
+                       "channels", G_TYPE_INT, 1,
+                       NULL);
+       if (!gst_element_link_filtered(np->src, np->filter, np->srccaps))
+               g_printerr("Failed to set caps for source\n");
+       else
+               gst_element_link(np->src, np->filter);
+       gst_caps_unref(np->srccaps);
+#else
+       gst_element_link(np->src, np->filter);  
+#endif
+       gst_element_link(np->filter, np->sink);
+
 } else {
+       g_debug("GST: Creating playback pipeline");
        np->src=gst_element_factory_make("filesrc", "source");
-       np->filter=gst_element_factory_make("wavenc", "filter");
+       np->filter=gst_element_factory_make("wavparse", "filter");
        np->sink=gst_element_factory_make(AUDIO_SINK, "sink");
+       gst_bin_add_many(GST_BIN(np->pipeline), np->src, np->filter, np->sink, NULL);
+       if (!gst_element_link_many(np->src, np->filter, np->sink, NULL))
+               g_printerr("Failed to link play pipeline\n");
 }
 np->rec=rec;
-g_assert(np->src);
-g_assert(np->sink);
-g_assert(np->filter);
+np->active=FALSE;
 return TRUE;
 }
 
@@ -111,11 +213,16 @@ g_object_set(G_OBJECT(e), "location", file, NULL);
 gboolean
 audio_note_play(gchar *file)
 {
+if (note_play.active==TRUE)
+       return TRUE;
 audio_set_filename(note_play.src, file);
-if (gst_element_set_state (note_play.pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
-       g_printf("Failed to play file %s\n", file);
+if (gst_element_set_state(note_play.pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+       g_printerr("Failed to play file %s\n", file);
+       note_play.active=FALSE;
        return FALSE;
 }
+g_debug("Playing");
+note_play.active=TRUE;
 return TRUE;
 }
 
@@ -125,14 +232,42 @@ return TRUE;
 gboolean
 audio_note_record(gchar *file)
 {
+if (note_record.active==TRUE)
+       return TRUE;
 audio_set_filename(note_record.sink, file);
-if (gst_element_set_state (note_record.pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
-       g_printf("Failed to record to file %s\n", file);
+if (gst_element_set_state(note_record.pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+       g_printerr("Failed to record to file %s\n", file);
+       note_record.active=FALSE;
        return FALSE;
 }
+g_debug("Recording");
+note_record.active=TRUE;
 return TRUE;
 }
 
+gboolean
+audio_note_stop()
+{
+GstState current;
+GstState pending;
+
+gst_element_get_state(note_record.pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
+if (current==GST_STATE_PLAYING) {
+       gst_element_set_state(note_record.pipeline, GST_STATE_PAUSED);
+       note_record.active=FALSE;
+       return TRUE;
+}
+
+gst_element_get_state(note_play.pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
+if (current==GST_STATE_PLAYING) {
+       gst_element_set_state(note_play.pipeline, GST_STATE_PAUSED);
+       note_play.active=FALSE;
+       return TRUE;
+}
+
+return FALSE;
+}
+
 /**
  * Init gst pipelines for note play and record
  */
@@ -141,15 +276,6 @@ audio_note_init(void)
 {
 audio_create_pipeline(&note_play, FALSE);
 audio_create_pipeline(&note_record, TRUE);
-
-bus=gst_pipeline_get_bus(GST_PIPELINE(note_play.pipeline));
-g_assert(bus);
-gst_bus_add_watch(bus, audio_note_bus_cb, NULL);
-
-bus=gst_pipeline_get_bus(GST_PIPELINE(note_record.pipeline));
-g_assert(bus);
-gst_bus_add_watch(bus, audio_note_bus_cb, NULL);
-
 return TRUE;
 }
 
@@ -162,3 +288,4 @@ gst_object_unref(note_play.pipeline);
 gst_element_set_state(note_record.pipeline, GST_STATE_NULL);
 gst_object_unref(note_record.pipeline);
 }
+