OSDN Git Service

clear btn, about btn, dicts info ...
[eb123/eb123.git] / src / audio.c
1
2 #include "defs.h"
3
4 #include "eb123.h"
5 #include "ebgstsrc.h"
6 #include "history.h"
7 #include "mainwnd.h"
8 #include "render.h"
9 #include "audio.h"
10
11 G_DEFINE_TYPE(Audio, audio, GTK_TYPE_FRAME);
12
13 EB_Error_Code audio_save_wave(RESULT *res, gchar *file)
14 {
15     char binary_data[EB_SIZE_PAGE];
16     EB_Error_Code error_code;
17     EB_Position end_position;
18     ssize_t read_len;
19     size_t write_len;
20     FILE *fp;
21
22     end_position.page = res->pos.page + (res->size / EB_SIZE_PAGE);
23     end_position.offset = res->pos.offset + (res->size % EB_SIZE_PAGE);
24     if (EB_SIZE_PAGE <= end_position.offset)
25     {
26         end_position.offset -= EB_SIZE_PAGE;
27         end_position.page++;
28     }
29     error_code = eb_set_binary_wave(res->binfo->book, &res->pos, &end_position);
30     if (error_code != EB_SUCCESS)
31     {
32         LOG(LOG_CRITICAL, "Failed to set binary wave: %s", eb_error_message(error_code));
33         return error_code;
34     }
35
36     fp = fopen(file, "wb");
37     if(!fp)
38     {
39         LOG(LOG_CRITICAL, "Failed to open file : %s", file);
40         return EB_ERR_BAD_FILE_NAME;
41     }
42
43     for(;;)
44     {
45         error_code = eb_read_binary(res->binfo->book, EB_SIZE_PAGE, binary_data, &read_len);
46         if(error_code != EB_SUCCESS || read_len == 0)
47         {
48             fclose(fp);
49             return error_code;
50         }
51
52         // If there are extra data (32 bytes) before fmt chunk,remove them.
53         if((strncmp("fmt ", &binary_data[44], 4) == 0) && (strncmp("fmt ", &binary_data[12], 4) != 0))
54         {
55             LOG(LOG_CRITICAL, "Warning: extra header found in WAVE data.");
56             write_len = fwrite(binary_data, 12, 1, fp);
57             write_len = fwrite(&binary_data[44], read_len - 44, 1, fp);
58         }
59         else
60             write_len = fwrite(binary_data, read_len, 1, fp);
61     }
62     return EB_SUCCESS;
63 }
64
65 void audio_save_as(GtkWidget *w, gpointer data)
66 {       
67     static gchar *path = NULL;
68     path = app_browse_disk(_("Save Audio As"), mainwnd_get_wnd(), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_SAVE_AS, path);
69     if(path)
70     {
71         RESULT *res = (RESULT*)data;
72         if(audio_save_wave(res, path) != EB_SUCCESS)
73             LOG(LOG_WARNING, _("Failed to save audio"));
74     }
75
76 }
77
78 #if 0
79 gboolean audio_context_menu(GtkWidget *w, GdkEventButton *event, gpointer user_data)
80 {
81     if(event->button != 3) return FALSE;
82     GtkWidget *menu = gtk_menu_new(), *item;
83     item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE_AS, NULL);
84     g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(audio_save_as), user_data);
85     gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
86     gtk_widget_show_all(menu);
87     gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
88     return TRUE;
89 }
90 #endif
91
92 #ifdef ENABLE_GSTREAMER
93
94 gboolean audio_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
95 {
96     GstElement *pipeline = GST_ELEMENT(data);
97     switch (GST_MESSAGE_TYPE (msg))
98     {
99         case GST_MESSAGE_EOS:
100         {
101             gst_element_set_state(pipeline, GST_STATE_NULL);
102             gst_object_unref(GST_OBJECT (pipeline));
103             break;
104         }
105
106         case GST_MESSAGE_ERROR:
107         {
108             gchar  *debug;
109             GError *error;
110
111             gst_message_parse_error(msg, &error, &debug);
112             g_free(debug);
113
114             LOG(LOG_INFO, "%s\n", error->message);
115             g_error_free(error);
116
117             break;
118         }
119          default:
120             break;
121     }
122
123     return TRUE;
124 }
125
126 static void audio_pad_added_cb(GstElement *dec, GstPad *pad, gpointer data)
127 {
128     GstElement *sink = (GstElement*)data;
129     GstPad *sinkpad = gst_element_get_pad(sink, "sink");
130
131     gst_pad_link(pad, sinkpad);
132     gst_object_unref(sinkpad);
133 }
134
135 void audio_play(GtkWidget *w, gpointer data)
136 {
137     GstElement *src, *dec, *sink, *pipeline = gst_pipeline_new ("pipeline");
138     GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline));
139     RESULT *res = (RESULT*)data;
140
141     gst_bus_add_watch(bus, audio_bus_cb, (gpointer)pipeline);
142     gst_object_unref(bus);
143
144     src = g_object_new(GST_TYPE_SRC, NULL);
145     GST_SRC(src)->res = res;
146     dec = gst_element_factory_make("wavparse", "decoder");
147     sink = gst_element_factory_make("alsasink", "sink");
148
149     gst_bin_add_many(GST_BIN(pipeline), src, dec, sink, NULL);
150     gst_element_link(src, dec);
151     g_signal_connect(dec, "pad-added", G_CALLBACK(audio_pad_added_cb), sink);
152
153     gst_element_set_state(pipeline, GST_STATE_PLAYING);
154 }
155
156 #endif
157
158 static void audio_class_init(AudioClass *klass)
159 {
160 }
161
162 static void audio_init(Audio *self)
163 {
164     GtkWidget *btn, *img;
165     GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
166     gtk_container_add(GTK_CONTAINER(self), hbox);
167 #ifdef ENABLE_GSTREAMER
168     btn = gtk_button_new();
169     img = gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_SMALL_TOOLBAR);
170     gtk_button_set_image(GTK_BUTTON(btn), img);
171     g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(audio_play), render.link);
172     gtk_box_pack_start(GTK_BOX(hbox), btn, FALSE, TRUE, 0);
173 #else
174     GtkWidget *label = gtk_label_new(_("Audio"));
175     gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
176 #endif
177     btn = gtk_button_new();
178     img = gtk_image_new_from_stock(GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_SMALL_TOOLBAR);
179     gtk_container_add(GTK_CONTAINER(btn), img);
180     //g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(audio_save_as), render.link);
181     gtk_box_pack_start(GTK_BOX(hbox), btn, FALSE, TRUE, 0);
182 }
183
184 void audio_render(Audio *self)
185 {
186     GtkTextIter iter1, iter2;
187 #if 0
188     if(render_get_last_mark("wave", &iter1, &iter2))
189     {
190         gtk_text_buffer_delete(render.buf, &iter1, &iter2);
191         gtk_text_buffer_get_end_iter(render.buf, &iter1);
192         gtk_text_buffer_insert(render.buf, &iter1, "\n", -1);
193         gtk_text_buffer_get_end_iter(render.buf, &iter1);
194         GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(render.buf, &iter1);
195         gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(render.view), GTK_WIDGET(self), anchor);
196         gtk_text_buffer_insert(render.buf, &iter1, "\n", -1);
197         g_object_set_data_full(G_OBJECT(self), "audio", render.link, result_free);
198         gtk_widget_show_all(GTK_WIDGET(self));
199         gtk_widget_realize(GTK_WIDGET(self));
200     }
201 #endif
202 }
203