From 7bba98f69d787568e077a1e5249359ee70e3ccb0 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Thu, 28 Feb 2008 16:04:28 +0200 Subject: [PATCH] Implement more of the audio note taking system. Build the gst pipelines properly. --- src/audio-note.c | 141 ++++++++++++++++++++++++++++++++++++----------- src/audio-note.h | 26 +++++++++ 2 files changed, 136 insertions(+), 31 deletions(-) diff --git a/src/audio-note.c b/src/audio-note.c index 2c7e100..b0c1830 100644 --- a/src/audio-note.c +++ b/src/audio-note.c @@ -24,45 +24,86 @@ #include "config.h" #include +#include #include "audio.h" #include "audio-note.h" -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; - static GstBus *bus; +static gboolean +audio_note_record_cb(GtkWidget *widget, gpointer data) +{ +audio_note_record("/tmp/testing.wav"); +return TRUE; +} + +static gboolean +audio_note_play_cb(GtkWidget *widget, gpointer data) +{ +audio_note_play("/tmp/testing.wav"); +return TRUE; +} + +static gboolean +audio_note_stop_cb(GtkWidget *widget, gpointer data) +{ +audio_note_stop(); +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=¬e_play; +ui->note_record=¬e_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; @@ -72,20 +113,39 @@ 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"); +#if 0 + /* No idea wasting space with some hifi format */ + np->caps=gst_element_factory_make("capsfilter", "caps"); + 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, 8000, + "channels", G_TYPE_INT, 1, + NULL); +#endif + 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 record pipeline\n"); } 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; } @@ -104,11 +164,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); + g_printerr("Failed to play file %s\n", file); + note_play.active=FALSE; return FALSE; } +g_debug("Playing"); +note_play.active=TRUE; return TRUE; } @@ -118,18 +183,40 @@ 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); + 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() { -return TRUE; +GstState current; +GstState pending; + +gst_element_get_state(note_record.pipeline, ¤t, &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, ¤t, &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; } /** @@ -140,15 +227,6 @@ audio_note_init(void) { audio_create_pipeline(¬e_play, FALSE); audio_create_pipeline(¬e_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; } @@ -161,3 +239,4 @@ gst_object_unref(note_play.pipeline); gst_element_set_state(note_record.pipeline, GST_STATE_NULL); gst_object_unref(note_record.pipeline); } + diff --git a/src/audio-note.h b/src/audio-note.h index 1d0fda9..0f64ac8 100644 --- a/src/audio-note.h +++ b/src/audio-note.h @@ -21,6 +21,32 @@ #ifndef _AUDIO_NOTE_H #define _AUDIO_NOTE_H +#include +#include + +typedef struct _note_pipeline note_pipeline; +struct _note_pipeline { + GstElement *pipeline; + GstElement *src; + GstElement *sink; + GstElement *filter; + gboolean active; + gboolean rec; +}; + +typedef struct _audio_note_ui audio_note_ui; +struct _audio_note_ui { + GtkWidget *vbox; + GtkWidget *lbl_time; + GtkWidget *btn_record; + GtkWidget *btn_play; + GtkWidget *btn_stop; + note_pipeline *note_play; + note_pipeline *note_record; +}; + +audio_note_ui *audio_note_new(void); + gboolean audio_note_init(void); void audio_note_deinit(void); -- 2.39.5