aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhark <hark@puscii.nl>2016-03-25 03:33:09 +0000
committerhark <hark@puscii.nl>2016-03-25 03:33:09 +0000
commit2f5ca7693694fe917b9e322f6dc1692a5cbaacbf (patch)
tree46dc0cceb783ba5fac5fd30e9a631d6578abf233
parent22d081dc59a8e94b41879606a6927c658cc76d29 (diff)
downloadgnunet-2f5ca7693694fe917b9e322f6dc1692a5cbaacbf.tar.gz
gnunet-2f5ca7693694fe917b9e322f6dc1692a5cbaacbf.zip
experimental gstreamer audiobackend (not working)
-rw-r--r--src/conversation/Makefile.am34
-rw-r--r--src/conversation/build_gst_test.sh9
-rw-r--r--src/conversation/displaydot.sh5
-rw-r--r--src/conversation/gnunet_gst.c1079
-rw-r--r--src/conversation/gnunet_gst.h37
-rw-r--r--src/conversation/gnunet_gst_def.h190
-rw-r--r--src/conversation/gnunet_gst_test.c120
-rw-r--r--src/conversation/mediahelper.conf7
-rw-r--r--src/conversation/test.sh4
9 files changed, 1483 insertions, 2 deletions
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am
index 53ff1afc4..f61173a66 100644
--- a/src/conversation/Makefile.am
+++ b/src/conversation/Makefile.am
@@ -88,6 +88,12 @@ if BUILD_GST_HELPERS
88AUDIO_HELPER_RECD=gnunet-helper-audio-record 88AUDIO_HELPER_RECD=gnunet-helper-audio-record
89AUDIO_HELPER_PLAY=gnunet-helper-audio-playback 89AUDIO_HELPER_PLAY=gnunet-helper-audio-playback
90AUDIO_TESTS=$(check_PROGRAMS) 90AUDIO_TESTS=$(check_PROGRAMS)
91else
92if BUILD_EXPERIMENTAL_HELPERS
93AUDIO_HELPER_RECD=gnunet-helper-audio-record
94AUDIO_HELPER_PLAY=gnunet-helper-audio-playback
95AUDIO_TESTS=$(check_PROGRAMS)
96endif
91endif 97endif
92endif 98endif
93 99
@@ -132,7 +138,7 @@ gnunet_helper_audio_record_CFLAGS = \
132 $(GST_CFLAGS) 138 $(GST_CFLAGS)
133 139
134gnunet_helper_audio_playback_SOURCES = \ 140gnunet_helper_audio_playback_SOURCES = \
135 gnunet-helper-audio-playback-gst.c 141 gnunet_gst_test.c gnunet_gst.c
136gnunet_helper_audio_playback_LDADD = \ 142gnunet_helper_audio_playback_LDADD = \
137 $(top_builddir)/src/util/libgnunetutil.la \ 143 $(top_builddir)/src/util/libgnunetutil.la \
138 $(GST_LIBS) \ 144 $(GST_LIBS) \
@@ -140,7 +146,31 @@ gnunet_helper_audio_playback_LDADD = \
140gnunet_helper_audio_playback_LDFLAGS = \ 146gnunet_helper_audio_playback_LDFLAGS = \
141 $(WINFLAGS) $(GST_LDFLAGS) 147 $(WINFLAGS) $(GST_LDFLAGS)
142gnunet_helper_audio_playback_CFLAGS = \ 148gnunet_helper_audio_playback_CFLAGS = \
143 $(GST_CFLAGS) 149 $(GST_CFLAGS) -DIS_SPEAKER
150else
151if BUILD_EXPERIMENTAL_HELPERS
152gnunet_helper_audio_record_SOURCES = \
153 gnunet_gst_test.c gnunet_gst.c
154gnunet_helper_audio_record_LDADD = \
155 $(top_builddir)/src/util/libgnunetutil.la \
156 $(GST_LIBS) \
157 $(INTLLIBS)
158gnunet_helper_audio_record_LDFLAGS = \
159 $(WINFLAGS) $(GST_LDFLAGS)
160gnunet_helper_audio_record_CFLAGS = \
161 $(GST_CFLAGS) -DIS_MIC
162
163gnunet_helper_audio_playback_SOURCES = \
164 gnunet_gst_test.c gnunet_gst.c
165gnunet_helper_audio_playback_LDADD = \
166 $(top_builddir)/src/util/libgnunetutil.la \
167 $(GST_LIBS) \
168 $(INTLLIBS)
169gnunet_helper_audio_playback_LDFLAGS = \
170 $(WINFLAGS) $(GST_LDFLAGS)
171gnunet_helper_audio_playback_CFLAGS = \
172 $(GST_CFLAGS) -DIS_SPEAKER
173endif
144endif 174endif
145endif 175endif
146 176
diff --git a/src/conversation/build_gst_test.sh b/src/conversation/build_gst_test.sh
new file mode 100644
index 000000000..1feb9e1c4
--- /dev/null
+++ b/src/conversation/build_gst_test.sh
@@ -0,0 +1,9 @@
1#!/bin/bash
2
3colorgcc -DIS_MIC -g gnunet_gst_test.c gnunet_gst.c -o gnunet-helper-audio-record-experimental `pkg-config --cflags --libs gstreamer-app-1.0 gnunetutil gnunetconversation gnunetenv gstreamer-app-1.0 gstreamer-1.0 gstreamer-audio-1.0 gstreamer-pbutils-1.0 gstreamer-video-1.0` -O0 -march=native -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-conversion -Wformat -Wformat-security -fstack-protector -D_FORTIFY_SOURCE=2 -std=c99 -D_GNU_SOURCE
4
5colorgcc -DIS_SPEAKER -g gnunet_gst_test.c gnunet_gst.c -o gnunet-helper-audio-playback-experimental `pkg-config --cflags --libs gstreamer-app-1.0 gnunetutil gnunetconversation gnunetenv gstreamer-app-1.0 gstreamer-1.0 gstreamer-audio-1.0 gstreamer-pbutils-1.0 gstreamer-video-1.0` -O0 -march=native -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-conversion -Wformat -Wformat-security -fstack-protector -D_FORTIFY_SOURCE=2 -std=c99 -D_GNU_SOURCE
6
7
8
9#colorgcc -g gnunet_gst_test.c gnunet_gst.c -o gnunet_gst_test `pkg-config --cflags --libs gstreamer-app-1.0 gstreamer-1.0 gstreamer-audio-1.0 gstreamer-pbutils-1.0 gstreamer-video-1.0` -O0 -march=native -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-conversion -Wpedantic -Wformat -Wformat-security -fstack-protector -D_FORTIFY_SOURCE=2 -std=c99 -D_GNU_SOURCE
diff --git a/src/conversation/displaydot.sh b/src/conversation/displaydot.sh
new file mode 100644
index 000000000..e20d41c16
--- /dev/null
+++ b/src/conversation/displaydot.sh
@@ -0,0 +1,5 @@
1#!/bin/bash
2dot -Tpng `ls -tr1 /tmp/*rec*.dot | tail -1` | display /dev/stdin &
3
4dot -Tpng `ls -tr1 /tmp/*play*.dot | tail -1` | display /dev/stdin &
5
diff --git a/src/conversation/gnunet_gst.c b/src/conversation/gnunet_gst.c
new file mode 100644
index 000000000..657bb8e8a
--- /dev/null
+++ b/src/conversation/gnunet_gst.c
@@ -0,0 +1,1079 @@
1#include "gnunet_gst_def.h"
2
3/**
4 * Our configuration.
5 */
6static struct GNUNET_CONFIGURATION_Handle *cfg;
7
8 void
9dump_buffer(unsigned n, const unsigned char* buf)
10{
11 const unsigned char *p, *end;
12 unsigned i, j;
13
14 end = buf + n;
15
16 for (i = 0; ; i += 16) {
17 p = buf + i;
18 for (j = 0; j < 16; j++) {
19 fprintf(stderr, "%02X ", p[j]);
20 if (p + j >= end)
21 goto BREAKOUT;
22 }
23 fprintf(stderr, " ");
24 p = buf + i;
25 for (j = 0; j < 16; j++) {
26 fprintf(stderr, "%c", isprint(p[j]) ? p[j] :
27 '.');
28 if (p + j >= end)
29 goto BREAKOUT;
30 }
31 fprintf(stderr, "\n");
32 }
33BREAKOUT:
34 return;
35}
36
37/***
38 * load gnunet configuration
39 */
40 void
41gg_load_configuration(GNUNET_gstData * d)
42{
43 char *audiobackend_string;
44 cfg = GNUNET_CONFIGURATION_create();
45 GNUNET_CONFIGURATION_load(cfg, "mediahelper.conf");
46
47 char *section = "MEDIAHELPER";
48
49 GNUNET_CONFIGURATION_get_value_string(cfg, "MEDIAHELPER", "JACK_PP_IN", &d->jack_pp_in);
50 GNUNET_CONFIGURATION_get_value_string(cfg, "MEDIAHELPER", "JACK_PP_OUT", &d->jack_pp_out);
51
52 GNUNET_CONFIGURATION_get_value_string(cfg, "MEDIAHELPER", "AUDIOBACKEND", &audiobackend_string);
53
54 // printf("abstring: %s \n", audiobackend_string);
55
56 if ( audiobackend_string == "AUTO" )
57 {
58 d->audiobackend = AUTO;
59 } else if ( audiobackend_string = "JACK" )
60 {
61 d->audiobackend = JACK;
62 } else if ( audiobackend_string = "ALSA" )
63 {
64 d->audiobackend = ALSA;
65 } else if ( audiobackend_string = "FAKE" )
66 {
67 d->audiobackend = FAKE;
68 } else if ( audiobackend_string = "TEST" )
69 {
70 d->audiobackend = TEST;
71 } else
72 {
73 d->audiobackend = AUTO;
74 }
75
76 if (GNUNET_CONFIGURATION_get_value_yesno(cfg, "MEDIAHELPER", "REMOVESILENCE") == GNUNET_YES)
77 {
78 d->dropsilence = TRUE;
79 } else {
80 d->dropsilence = FALSE;
81 }
82
83 if (GNUNET_CONFIGURATION_get_value_yesno(cfg, "MEDIAHELPER", "NO_GN_HEADERS") == GNUNET_YES)
84 {
85 d->pure_ogg = TRUE;
86 } else {
87 d->pure_ogg = FALSE;
88 }
89
90
91 if (GNUNET_CONFIGURATION_get_value_yesno(cfg, "MEDIAHELPER", "USERTP") == GNUNET_YES)
92 {
93 d->usertp = TRUE;
94 } else {
95 d->usertp = FALSE;
96 }
97
98// GNUNET_CONFIGURATION_write(cfg, "mediahelper.conf");
99
100}
101
102static void
103write_data (const char *ptr, size_t msg_size)
104{
105 ssize_t ret;
106 size_t off;
107 off = 0;
108 while (off < msg_size)
109 {
110 ret = write (1, &ptr[off], msg_size - off);
111 if (0 >= ret)
112 {
113 if (-1 == ret)
114 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "write");
115// quit (2);
116 }
117 off += ret;
118 }
119}
120
121
122
123extern GstFlowReturn
124on_appsink_new_sample (GstElement * element, GNUNET_gstData * d)
125{
126 static unsigned long long toff;
127
128 //size of message including gnunet header
129 size_t msg_size;
130
131 GstSample *s;
132 GstBuffer *b;
133 GstMapInfo map;
134/*
135 const GstStructure *si;
136 char *si_str;
137 GstCaps *s_caps;
138 char *caps_str;
139*/
140 (d->audio_message)->header.size = htons ((uint16_t) msg_size);
141
142 if (gst_app_sink_is_eos(GST_APP_SINK(element)))
143 return GST_FLOW_OK;
144
145 //pull sample from appsink
146 s = gst_app_sink_pull_sample (GST_APP_SINK(element));
147
148 if (s == NULL)
149 return GST_FLOW_OK;
150
151 if (!GST_IS_SAMPLE (s))
152 return GST_FLOW_OK;
153
154 b = gst_sample_get_buffer(s);
155
156 GST_WARNING ("caps are %" GST_PTR_FORMAT, gst_sample_get_caps(s));
157
158
159
160 gst_buffer_map (b, &map, GST_MAP_READ);
161
162 size_t len;
163 len = map.size;
164 if (len > UINT16_MAX - sizeof (struct AudioMessage))
165 {
166 // this should never happen?
167 printf("GSTREAMER sample too big! \n");
168 exit(20);
169 len = UINT16_MAX - sizeof (struct AudioMessage);
170 }
171
172 msg_size = sizeof (struct AudioMessage) + len;
173
174 // copy the data into audio_message
175 memcpy (((char *) &(d->audio_message)[1]), map.data, len);
176/*
177 toff += msg_size;
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
179 "Sending %u bytes of audio data (total: %llu)\n",
180 (unsigned int) msg_size,
181 toff);
182*/
183 if (d->pure_ogg)
184 // write the audio_message without the gnunet headers
185 write_data ((const char *) &(d->audio_message)[1], len);
186 else
187 write_data ((const char *) d->audio_message, msg_size);
188
189 gst_sample_unref(s);
190 return GST_FLOW_OK;
191}
192
193/***
194 * Dump a pipeline graph
195 */
196 extern void
197pl_graph(GstElement * pipeline)
198{
199
200#ifdef IS_SPEAKER
201 gst_debug_bin_to_dot_file_with_ts(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "playback_helper.dot");
202
203#endif
204#ifdef IS_MIC
205 gst_debug_bin_to_dot_file_with_ts(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "record_helper.dot");
206
207#endif
208
209
210 // load_configuration();
211}
212
213
214
215extern gboolean
216gnunet_gst_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
217{
218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
219 "Bus message\n");
220 switch (GST_MESSAGE_TYPE (msg))
221 {
222 case GST_MESSAGE_EOS:
223 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
224 "End of stream\n");
225 exit (10);
226 break;
227
228 case GST_MESSAGE_ERROR:
229 {
230 gchar *debug;
231 GError *error;
232
233 gst_message_parse_error (msg, &error, &debug);
234 g_free (debug);
235
236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
237 "Error: %s\n",
238 error->message);
239 g_error_free (error);
240
241 exit (10);
242 break;
243 }
244 default:
245 break;
246 }
247
248 return TRUE;
249}
250
251/* called when pipeline changes state */
252 extern void
253state_changed_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * d)
254{
255 GstState old_state, new_state, pending_state;
256
257 gst_message_parse_state_changed (msg, &old_state, &new_state,
258 &pending_state);
259 switch (new_state)
260 {
261
262 case GST_STATE_READY:
263// printf("ready.... \n");
264 //pl_graph(GST_ELEMENT(d->pipeline));
265 break;
266 case GST_STATE_PLAYING:
267
268 //GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
269
270 // printf("Playing.... \n");
271 pl_graph(GST_ELEMENT(d->pipeline));
272 break;
273 case GST_STATE_VOID_PENDING:
274 // printf("void_pending.... \n");
275 //pl_graph(GST_ELEMENT(d->pipeline));
276 break;
277 case GST_STATE_NULL:
278 // printf("null.... \n");
279 //pl_graph(GST_ELEMENT(d->pipeline));
280 break;
281
282 case GST_STATE_PAUSED:
283 // printf("paused.... \n");
284 //pl_graph(GST_ELEMENT(d->pipeline));
285 break;
286 }
287}
288
289 static void
290 application_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * data)
291{
292 // printf("application cb");
293 return;
294}
295
296 static void
297 error_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * data)
298{
299 // printf("error cb");
300 return;
301}
302
303 static void
304 eos_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * data)
305{
306 // printf("eos cb");
307 return;
308}
309
310extern void
311gg_setup_gst_bus (GNUNET_gstData * d)
312{
313 GstBus *bus;
314 bus = gst_element_get_bus (GST_ELEMENT(d->pipeline));
315 gst_bus_add_signal_watch (bus);
316 g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
317 d);
318 g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback) eos_cb,
319 d);
320 g_signal_connect (G_OBJECT (bus), "message::state-changed",
321 (GCallback) state_changed_cb, d);
322 g_signal_connect (G_OBJECT (bus), "message::application",
323 (GCallback) application_cb, d);
324 g_signal_connect (G_OBJECT (bus), "message::about-to-finish",
325 (GCallback) application_cb, d);
326 gst_object_unref (bus);
327
328}
329
330/*
331 * take buffer from gstreamer and feed it to gnunet
332 */
333/*
334 extern int
335feed_buffer_to_gnunet (GNUNET_gstData * d)
336{
337 GstSample *s;
338 GstBuffer *b;
339 GstMapInfo m;
340 size_t len, msg_size;
341 const char *ptr;
342 int phase;
343
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pulling...\n");
345 s = gst_app_sink_pull_sample (GST_APP_SINK(d->appsink));
346 if (NULL == s)
347 {
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pulled NULL\n");
349 return OK;
350 }
351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "...pulled!\n");
352
353 const GstStructure *si;
354 char *si_str;
355 GstCaps *s_caps;
356 char *caps_str;
357 si = gst_sample_get_info (s);
358 if (si)
359 {
360 si_str = gst_structure_to_string (si);
361 if (si_str)
362 {
363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample %s\n", si_str);
364 g_free (si_str);
365 }
366 }
367 else
368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with no info\n");
369 s_caps = gst_sample_get_caps (s);
370 if (s_caps)
371 {
372 caps_str = gst_caps_to_string (s_caps);
373 if (caps_str)
374 {
375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with caps %s\n", caps_str);
376 g_free (caps_str);
377 }
378 }
379 else
380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with no caps\n");
381
382 b = gst_sample_get_buffer (s);
383 if (NULL == b || !gst_buffer_map (b, &m, GST_MAP_READ))
384 {
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got NULL buffer %p or failed to map the buffer\n", b);
386 gst_sample_unref (s);
387 return FAIL;
388 }
389
390 len = m.size;
391 if (len > UINT16_MAX - sizeof (struct AudioMessage))
392 {
393 GNUNET_break (0);
394 len = UINT16_MAX - sizeof (struct AudioMessage);
395 }
396 msg_size = sizeof (struct AudioMessage) + len;
397 audio_message.header.size = htons ((uint16_t) msg_size);
398
399
400 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
401 "Sending %u bytes of audio data\n", (unsigned int) msg_size);
402 for (phase = 0; phase < 2; phase++)
403 {
404 size_t offset;
405 size_t to_send;
406 ssize_t ret;
407 if (0 == phase && !d->pure_ogg)
408 {
409//#ifdef DEBUG_RECORD_PURE_OGG
410
411// if (d->pure_ogg)
412// break;
413
414//#endif
415 ptr = (const char *) &audio_message;
416 to_send = sizeof (audio_message);
417 }
418 else
419 {
420 ptr = (const char *) m.data;
421 to_send = len;
422 }
423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
424 "Sending %u bytes on phase %d\n", (unsigned int) to_send, phase);
425 for (offset = 0; offset < to_send; offset += ret)
426 {
427 ret = write (1, &ptr[offset], to_send - offset);
428 if (0 >= ret)
429 {
430 if (-1 == ret)
431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
432 "Failed to write %u bytes at offset %u (total %u) in phase %d: %s\n",
433 (unsigned int) to_send - offset, (unsigned int) offset,
434 (unsigned int) (to_send + offset), phase, strerror (errno));
435 // abort_send = 1;
436 return FAIL;
437 }
438 }
439
440 // if (abort_send)
441 // break;
442
443 }
444 gst_buffer_unmap (b, &m);
445 gst_sample_unref (s);
446}
447*/
448
449
450 extern int
451feed_buffer_to_gst (const char *audio, size_t b_len, GNUNET_gstData * d)
452{
453 GstBuffer *b;
454 gchar *bufspace;
455 GstFlowReturn flow;
456
457 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
458 "Feeding %u bytes to GStreamer\n",
459 (unsigned int) b_len);
460
461 bufspace = g_memdup (audio, b_len);
462 b = gst_buffer_new_wrapped (bufspace, b_len);
463 if (NULL == b)
464 {
465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
466 "Failed to wrap a buffer\n");
467 g_free (bufspace);
468 return GNUNET_SYSERR;
469 }
470 if (GST_APP_SRC(d->appsrc) == NULL)
471 exit(10);
472 flow = gst_app_src_push_buffer (GST_APP_SRC(d->appsrc), b);
473 /* They all return GNUNET_OK, because currently player stops when
474 * data stops coming. This might need to be changed for the player
475 * to also stop when pipeline breaks.
476 */
477 switch (flow)
478 {
479 case GST_FLOW_OK:
480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
481 "Fed %u bytes to the pipeline\n",
482 (unsigned int) b_len);
483 break;
484 case GST_FLOW_FLUSHING:
485 /* buffer was dropped, because pipeline state is not PAUSED or PLAYING */
486 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
487 "Dropped a buffer\n");
488 break;
489 case GST_FLOW_EOS:
490 /* end of stream */
491 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
492 "EOS\n");
493 break;
494 default:
495 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
496 "Unexpected push result\n");
497 break;
498 }
499 return GNUNET_OK;
500}
501
502
503
504/**
505 * debug making elements
506 */
507 extern GstElement *
508gst_element_factory_make_debug( gchar *factoryname, gchar *name)
509{
510 GstElement *element;
511
512 element = gst_element_factory_make(factoryname,name);
513
514 if (element == NULL) {
515
516 printf ("\n Failed to create element - type: %s name: %s \n", factoryname, name);
517 exit(10);
518 return element;
519 } else {
520 return element;
521 }
522}
523
524/*
525 static gboolean
526gst_element_link_many_debug(...)
527{
528 va_list arguments;
529 gst_element_link_many(argptr);
530}
531
532#define gst_element_link_many(...) \
533 gst_element_link_many_debug(__VA_ARGS__)
534*/
535 extern void
536lf(char * msg)
537{
538 printf("linking elements failed: %s", msg);
539 exit(10);
540}
541
542/***
543 * used to set properties on autoaudiosink's chosen sink
544 */
545static void
546autoaudiosink_child_added (GstChildProxy *child_proxy,
547 GObject *object,
548 gchar *name,
549 gpointer user_data)
550{
551 if (GST_IS_AUDIO_BASE_SRC (object))
552 g_object_set (object,
553 "buffer-time", (gint64) BUFFER_TIME,
554 "latency-time", (gint64) LATENCY_TIME,
555 NULL);
556}
557
558/***
559 * used to set properties on autoaudiosource's chosen sink
560 */
561static void
562autoaudiosource_child_added (GstChildProxy *child_proxy, GObject *object, gchar *name, gpointer user_data)
563{
564 if (GST_IS_AUDIO_BASE_SRC (object))
565 g_object_set (object, "buffer-time", (gint64) BUFFER_TIME, "latency-time", (gint64) LATENCY_TIME, NULL);
566}
567
568GstElement *
569get_pipeline(GstElement *element)
570{
571 GstPipeline *p;
572
573 p = gst_object_get_parent(element);
574
575 return p;
576}
577
578 static void
579decoder_ogg_pad_added (GstElement *element,
580 GstPad *pad,
581 gpointer data)
582{
583 GstPad *sinkpad;
584 GstElement *decoder = (GstElement *) data;
585
586 printf("==== ogg pad added callback \n");
587 /* We can now link this pad with the opus-decoder sink pad */
588// pl_graph(get_pipeline(element));
589 sinkpad = gst_element_get_static_pad (decoder, "sink");
590
591 gst_pad_link (pad, sinkpad);
592 gst_element_link_many(element, decoder, NULL);
593 gst_object_unref (sinkpad);
594}
595
596int
597gnunet_read (GNUNET_gstData * d)
598{
599 char readbuf[MAXLINE];
600 int ret;
601 printf("read \n");
602 ret = read (0, readbuf, sizeof (readbuf));
603 if (0 > ret)
604 {
605 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
606 _("Read error from STDIN: %d %s\n"),
607 ret, strerror (errno));
608 return FAIL;
609 }
610 //toff += ret;
611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
612 "Received %d bytes of audio data\n",
613 (int) ret);
614 if (0 == ret)
615 return FAIL;
616 //#ifdef DEBUG_READ_PURE_OGG
617
618 if (d->pure_ogg)
619 {
620 feed_buffer_to_gst (readbuf, ret, d);
621 }
622 else
623 {
624 //#endif
625 GNUNET_SERVER_mst_receive (d->stdin_mst, NULL,
626 readbuf, ret,
627 GNUNET_NO, GNUNET_NO);
628 }
629}
630
631/**
632 * Message callback
633 */
634static int
635stdin_receiver (void *cls,
636 void *client,
637 const struct GNUNET_MessageHeader *msg)
638{
639 struct AudioMessage *audio;
640 size_t b_len;
641 printf("stdin receiver \n ");
642 dump_buffer(sizeof(msg), msg);
643
644 switch (ntohs (msg->type))
645 {
646 case GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO:
647 audio = (struct AudioMessage *) msg;
648
649 b_len = ntohs (audio->header.size) - sizeof (struct AudioMessage);
650 printf("feeding buffer to gst \n ");
651 feed_buffer_to_gst ((const char *) &audio[1], b_len, cls);
652 break;
653 default:
654 printf("No audio message: %u \n ", ntohs(msg->type));
655 break;
656 }
657 return GNUNET_OK;
658}
659
660
661GstBin *
662get_app(GNUNET_gstData *d, int type)
663{
664 GstBin *bin;
665 GstPad *pad, *ghostpad;
666
667 if ( type == SOURCE )
668 {
669 bin = GST_BIN(gst_bin_new("Gnunet appsrc"));
670
671
672 GNUNET_assert (GNUNET_OK ==
673 GNUNET_log_setup ("gnunet-helper-audio-playback",
674 "WARNING",
675 NULL));
676
677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
678 "Audio playback starts\n");
679 printf(" creating appsrc \n ");
680 //d->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
681
682// d->audio_message = GNUNET_malloc (UINT16_MAX);
683 // d->audio_message = (AudioMessage*)malloc(sizeof(struct AudioMessage));
684// d->audio_message = GNUNET_malloc(sizeof(struct AudioMessage));
685
686
687 //d->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
688
689
690 d->stdin_mst = GNUNET_SERVER_mst_create (&stdin_receiver, d);
691
692 if ( d->stdin_mst == NULL)
693 printf("stdin_mst = NULL");
694
695 d->appsrc = gst_element_factory_make ("appsrc", "appsrc");
696
697 gst_bin_add_many( bin, d->appsrc, NULL);
698// gst_element_link_many ( encoder, muxer, NULL);
699
700 pad = gst_element_get_static_pad (d->appsrc, "src");
701 ghostpad = gst_ghost_pad_new ("src", pad);
702 }
703 if ( type == SINK )
704 {
705 bin = GST_BIN(gst_bin_new("Gnunet appsink"));
706
707
708 GNUNET_assert (GNUNET_OK ==
709 GNUNET_log_setup ("gnunet-helper-audio-record",
710 "WARNING",
711 NULL));
712
713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
714 "Audio source starts\n");
715
716 d->appsink = gst_element_factory_make ("appsink", "appsink");
717
718 // Move this out of here!
719 d->audio_message = GNUNET_malloc (UINT16_MAX);
720 (d->audio_message)->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
721 g_object_set (G_OBJECT (d->appsink), "emit-signals", TRUE, "sync", TRUE, NULL);
722
723 g_signal_connect (d->appsink, "new-sample",
724 G_CALLBACK (on_appsink_new_sample), &d);
725
726 gst_bin_add_many( bin, d->appsink, NULL);
727// gst_element_link_many ( encoder, muxer, NULL);
728
729 pad = gst_element_get_static_pad (d->appsink, "sink");
730 ghostpad = gst_ghost_pad_new ("sink", pad);
731 }
732
733 /* set the bin pads */
734 gst_pad_set_active (ghostpad, TRUE);
735 gst_element_add_pad (GST_ELEMENT(bin), ghostpad);
736
737 gst_object_unref (pad);
738
739 return bin;
740}
741
742 extern GstBin *
743get_coder(GNUNET_gstData *d , int type)
744{
745 GstBin *bin;
746 GstPad *srcpad, *sinkpad, *srcghostpad, *sinkghostpad;
747 GstCaps *caps, *rtpcaps;
748 GstElement *encoder, *muxer, *decoder, *demuxer, *jitterbuffer, *rtpcapsfilter;
749
750 if ( d->usertp == TRUE )
751 {
752 /*
753 * application/x-rtp, media=(string)audio, clock-rate=(int)48000, encoding-name=(string)OPUS, sprop-maxcapturerate=(string)48000, sprop-stereo=(string)0, payload=(int)96, encoding-params=(string)2, ssrc=(uint)630297634, timestamp-offset=(uint)678334141, seqnum-offset=(uint)16938 */
754/*
755 rtpcaps = gst_caps_new_simple ("application/x-rtp",
756 "media", G_TYPE_STRING, "audio",
757 "clock-rate", G_TYPE_INT, SAMPLING_RATE,
758 "encoding-name", G_TYPE_STRING, "OPUS",
759 "payload", G_TYPE_INT, 96,
760 "sprop-stereo", G_TYPE_STRING, "0",
761 "encoding-params", G_TYPE_STRING, "2",
762 NULL);
763*/
764 rtpcaps = gst_caps_new_simple ("application/x-rtp",
765 "media", G_TYPE_STRING, "audio",
766 "clock-rate", G_TYPE_INT, SAMPLING_RATE,
767 "encoding-name", G_TYPE_STRING, "OPUS",
768 "payload", G_TYPE_INT, 96,
769 "sprop-stereo", G_TYPE_STRING, "0",
770 "encoding-params", G_TYPE_STRING, "2",
771 NULL);
772
773
774 rtpcapsfilter = gst_element_factory_make ("capsfilter", "rtpcapsfilter");
775
776 g_object_set (G_OBJECT (rtpcapsfilter),
777 "caps", rtpcaps,
778 NULL);
779 gst_caps_unref (rtpcaps);
780
781 }
782
783
784 if ( type == ENCODER )
785 {
786 bin = GST_BIN(gst_bin_new("Gnunet audioencoder"));
787
788 encoder = gst_element_factory_make ("opusenc", "opus-encoder");
789 if ( d->usertp == TRUE )
790 {
791 muxer = gst_element_factory_make ("rtpopuspay", "rtp-payloader");
792 } else {
793 muxer = gst_element_factory_make ("oggmux", "ogg-muxer");
794 }
795 g_object_set (G_OBJECT (encoder),
796 /* "bitrate", 64000, */
797 /* "bandwidth", OPUS_BANDWIDTH_FULLBAND, */
798 "inband-fec", INBAND_FEC_MODE,
799 "packet-loss-percentage", PACKET_LOSS_PERCENTAGE,
800 "max-payload-size", MAX_PAYLOAD_SIZE,
801 "audio", TRUE, /* VoIP, not audio */
802 "frame-size", OPUS_FRAME_SIZE,
803 NULL);
804
805 if ( d->usertp != TRUE)
806 {
807 g_object_set (G_OBJECT (muxer),
808 "max-delay", OGG_MAX_DELAY,
809 "max-page-delay", OGG_MAX_PAGE_DELAY,
810 NULL);
811 }
812
813 gst_bin_add_many( bin, encoder, muxer, NULL);
814 gst_element_link_many ( encoder, muxer, NULL);
815 sinkpad = gst_element_get_static_pad(encoder, "sink");
816 sinkghostpad = gst_ghost_pad_new ("sink", sinkpad);
817
818 srcpad = gst_element_get_static_pad(muxer, "src");
819 srcghostpad = gst_ghost_pad_new ("src", srcpad);
820
821 }
822 if ( type == DECODER )
823 {
824 bin = GST_BIN(gst_bin_new("Gnunet audiodecoder"));
825
826 // decoder
827 if ( d->usertp == TRUE )
828 {
829
830 demuxer = gst_element_factory_make ("rtpopusdepay", "ogg-demuxer");
831 jitterbuffer = gst_element_factory_make ("rtpjitterbuffer", "rtpjitterbuffer");
832 } else {
833 demuxer = gst_element_factory_make ("oggdemux", "ogg-demuxer");
834 }
835 decoder = gst_element_factory_make ("opusdec", "opus-decoder");
836
837 if ( d->usertp == TRUE )
838 {
839 gst_bin_add_many( bin, rtpcapsfilter, jitterbuffer, demuxer, decoder, NULL);
840 gst_element_link_many ( rtpcapsfilter, jitterbuffer, demuxer, decoder, NULL);
841 sinkpad = gst_element_get_static_pad(rtpcapsfilter, "sink");
842
843
844 } else {
845 gst_bin_add_many( bin, demuxer, decoder, NULL);
846
847 g_signal_connect (demuxer,
848 "pad-added",
849 G_CALLBACK (decoder_ogg_pad_added),
850 decoder);
851
852 sinkpad = gst_element_get_static_pad(demuxer, "sink");
853 }
854 sinkghostpad = gst_ghost_pad_new ("sink", sinkpad);
855
856 srcpad = gst_element_get_static_pad(decoder, "src");
857 srcghostpad = gst_ghost_pad_new ("src", srcpad);
858
859 }
860
861 // add pads to the bin
862 gst_pad_set_active (sinkghostpad, TRUE);
863 gst_element_add_pad (GST_ELEMENT(bin), sinkghostpad);
864
865 gst_pad_set_active (srcghostpad, TRUE);
866 gst_element_add_pad (GST_ELEMENT(bin), srcghostpad);
867
868
869 return bin;
870}
871 extern GstBin *
872get_audiobin(GNUNET_gstData *d , int type)
873{
874 GstBin *bin;
875 GstElement *sink, *source, *queue, *conv, *resampler, *removesilence, *filter;
876 GstPad *pad, *ghostpad;
877 GstCaps *caps;
878 if ( type == SINK ) {
879
880 bin = GST_BIN(gst_bin_new("Gnunet audiosink"));
881
882 /* Create all the elements */
883 if ( d->dropsilence == TRUE )
884 {
885 queue = gst_element_factory_make ("queue", "queue");
886 removesilence = gst_element_factory_make ("removesilence", "removesilence");
887 }
888
889 conv = gst_element_factory_make ("audioconvert", "converter");
890 resampler= gst_element_factory_make ("audioresample", "resampler");
891
892 if ( d->audiobackend == AUTO )
893 {
894 sink = gst_element_factory_make ("autoaudiosink", "audiosink");
895 g_signal_connect (sink, "child-added", G_CALLBACK (autoaudiosink_child_added), NULL);
896
897 }
898
899 if ( d->audiobackend == ALSA )
900 {
901 sink = gst_element_factory_make ("alsaaudiosink", "audiosink");
902 }
903
904 if ( d->audiobackend == JACK )
905 {
906 sink = gst_element_factory_make ("jackaudiosink", "audiosink");
907
908 g_object_set (G_OBJECT (sink), "client-name", "gnunet", NULL);
909
910 if (g_object_class_find_property
911 (G_OBJECT_GET_CLASS (sink), "port-pattern"))
912 {
913
914// char *portpattern = "system";
915
916 g_object_set (G_OBJECT (sink), "port-pattern", d->jack_pp_out,
917 NULL);
918 }
919
920 }
921
922 if ( d->audiobackend == FAKE )
923 {
924 sink = gst_element_factory_make ("fakesink", "audiosink");
925 }
926
927 g_object_set (sink,
928 "buffer-time", (gint64) BUFFER_TIME,
929 "latency-time", (gint64) LATENCY_TIME,
930 NULL);
931
932 if ( d->dropsilence == TRUE )
933 {
934 // Do not remove silence by default
935 g_object_set( removesilence, "remove", FALSE, NULL);
936 g_object_set( queue, "max-size-buffers", 12, NULL);
937 /*
938 g_signal_connect (source,
939 "need-data",
940 G_CALLBACK(appsrc_need_data),
941 NULL);
942
943 g_signal_connect (source,
944 "enough-data",
945 G_CALLBACK(appsrc_enough_data),
946 NULL);
947 */
948/*
949 g_signal_connect (queue,
950 "notify::current-level-bytes",
951 G_CALLBACK(queue_current_level),
952 NULL);
953
954 g_signal_connect (queue,
955 "underrun",
956 G_CALLBACK(queue_underrun),
957 NULL);
958
959 g_signal_connect (queue,
960 "running",
961 G_CALLBACK(queue_running),
962 NULL);
963
964 g_signal_connect (queue,
965 "overrun",
966 G_CALLBACK(queue_overrun),
967 NULL);
968
969 g_signal_connect (queue,
970 "pushing",
971 G_CALLBACK(queue_pushing),
972 NULL);
973 */
974
975 }
976
977
978
979
980
981 gst_bin_add_many (bin , conv, resampler, sink, NULL);
982 gst_element_link_many ( conv, resampler, sink, NULL);
983
984 if ( d->dropsilence == TRUE )
985 {
986 gst_bin_add_many (bin , queue ,removesilence , NULL);
987
988 if ( !gst_element_link_many ( queue, removesilence, conv, NULL) )
989 lf ("queue, removesilence, conv ");
990
991 pad = gst_element_get_static_pad (queue, "sink");
992
993 } else {
994
995 pad = gst_element_get_static_pad(conv, "sink");
996
997 }
998
999 ghostpad = gst_ghost_pad_new ("sink", pad);
1000
1001 } else {
1002 // SOURCE
1003
1004 bin = GST_BIN(gst_bin_new("Gnunet audiosource"));
1005
1006 // source = gst_element_factory_make("audiotestsrc", "audiotestsrcbla");
1007
1008 if (d->audiobackend == AUTO )
1009 {
1010 source = gst_element_factory_make ("autoaudiosrc", "audiosource");
1011 }
1012 if (d->audiobackend == ALSA )
1013 {
1014 source = gst_element_factory_make ("alsasrc", "audiosource");
1015 }
1016 if (d->audiobackend == JACK )
1017 {
1018 source = gst_element_factory_make ("jackaudiosrc", "audiosource");
1019 }
1020 if (d->audiobackend == TEST )
1021 {
1022 source = gst_element_factory_make ("audiotestsrc", "audiosource");
1023 }
1024
1025 filter = gst_element_factory_make ("capsfilter", "filter");
1026 conv = gst_element_factory_make ("audioconvert", "converter");
1027 resampler= gst_element_factory_make ("audioresample", "resampler");
1028
1029 if (d->audiobackend == AUTO ) {
1030 g_signal_connect (source, "child-added", G_CALLBACK (autoaudiosource_child_added), NULL);
1031
1032 } else {
1033 if (GST_IS_AUDIO_BASE_SRC (source))
1034 g_object_set (source, "buffer-time", (gint64) BUFFER_TIME, "latency-time", (gint64) LATENCY_TIME, NULL);
1035 if ( d->audiobackend == JACK ) {
1036 g_object_set (G_OBJECT (source), "client-name", "gnunet", NULL);
1037 if (g_object_class_find_property
1038 (G_OBJECT_GET_CLASS (source), "port-pattern"))
1039 {
1040
1041 char *portpattern = "moc";
1042
1043 g_object_set (G_OBJECT (source), "port-pattern", portpattern,
1044 NULL);
1045 }
1046 }
1047 }
1048
1049 caps = gst_caps_new_simple ("audio/x-raw",
1050 /* "format", G_TYPE_STRING, "S16LE", */
1051 /* "rate", G_TYPE_INT, SAMPLING_RATE,*/
1052 "channels", G_TYPE_INT, OPUS_CHANNELS,
1053 /* "layout", G_TYPE_STRING, "interleaved",*/
1054 NULL);
1055
1056 g_object_set (G_OBJECT (filter),
1057 "caps", caps,
1058 NULL);
1059 gst_caps_unref (caps);
1060
1061 gst_bin_add_many (bin , source, filter, conv, resampler, NULL);
1062 gst_element_link_many ( source, filter, conv, resampler, NULL);
1063
1064 pad = gst_element_get_static_pad (resampler, "src");
1065
1066
1067 /* pads */
1068 ghostpad = gst_ghost_pad_new ("src", pad);
1069
1070 }
1071
1072 /* set the bin pads */
1073 gst_pad_set_active (ghostpad, TRUE);
1074 gst_element_add_pad (GST_ELEMENT(bin), ghostpad);
1075
1076 gst_object_unref (pad);
1077
1078 return bin;
1079}
diff --git a/src/conversation/gnunet_gst.h b/src/conversation/gnunet_gst.h
new file mode 100644
index 000000000..5a7213f48
--- /dev/null
+++ b/src/conversation/gnunet_gst.h
@@ -0,0 +1,37 @@
1// which audiobackend we use
2//
3
4/*
5int audiobackend = JACK;
6int dropsilence = TRUE;
7int enough = 0;
8int usertp = TRUE;
9*/
10
11#define gst_element_factory_make(element, name) gst_element_factory_make_debug (element, name);
12
13extern void pl_graph();
14
15
16extern GstElement *
17 gst_element_factory_make_debug( gchar *, gchar *);
18
19extern GstBin *
20 get_audiobin(GNUNET_gstData *, int);
21
22extern GstBin *
23 get_coder(GNUNET_gstData *, int);
24
25
26extern gboolean
27gnunet_gst_bus_call (GstBus *bus, GstMessage *msg, gpointer data);
28
29extern void
30gg_setup_gst_bus (GNUNET_gstData * d);
31
32extern void
33gg_load_configuration (GNUNET_gstData * d);
34
35extern GstFlowReturn
36on_appsink_new_sample (GstElement *, GNUNET_gstData *);
37
diff --git a/src/conversation/gnunet_gst_def.h b/src/conversation/gnunet_gst_def.h
new file mode 100644
index 000000000..2e6903db4
--- /dev/null
+++ b/src/conversation/gnunet_gst_def.h
@@ -0,0 +1,190 @@
1#include <getopt.h>
2#include <string.h>
3#include <stdio.h>
4#include <ctype.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <time.h>
8#include <regex.h>
9
10
11#include "gnunet/platform.h"
12#include "gnunet/gnunet_util_lib.h"
13#include "gnunet/gnunet_protocols.h"
14//#include "gnunet/conversation.h" doesn't get installed
15#include "conversation.h"
16#include "gnunet/gnunet_constants.h"
17#include "gnunet/gnunet_core_service.h"
18#include "gnunet/gnunet_common.h"
19
20/*
21#include <gst/gst.h>
22#include <gst/audio/gstaudiobasesrc.h>
23#include <gst/app/gstappsrc.h>
24*/
25
26/* huh
27#include <glib-2.0/glib.h>
28
29#include <gstreamer-1.0/gst/gst.h>
30#include <gstreamer-1.0/gst/pbutils/pbutils.h>
31#include <gstreamer-1.0/gst/video/videooverlay.h>
32#include <gstreamer-1.0/gst/audio/gstaudiobasesrc.h>
33#include <gstreamer-1.0/gst/app/gstappsrc.h>
34*/
35
36#include <gst/gst.h>
37#include <gst/audio/gstaudiobasesrc.h>
38#include <gst/app/gstappsrc.h>
39#include <glib.h>
40#include <gst/app/gstappsink.h>
41
42// sockets
43#include <netinet/in.h>
44#include <sys/socket.h>
45#include <fcntl.h>
46#include <arpa/inet.h>
47
48#include <sys/types.h>
49#include <sys/socket.h>
50#include <netdb.h>
51
52
53//glib stuff
54//#include <glib.h>
55#include <glib-2.0/glib/gprintf.h>
56#include <glib-unix.h>
57
58// static struct AudioMessage *audio_message;
59
60
61
62typedef struct GNUNET_gstData GNUNET_gstData;
63struct GNUNET_gstData {
64 //general
65 GstPipeline *pipeline;
66
67 // things
68 struct AudioMessage *audio_message;
69 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
70 GstElement *appsrc;
71 GstElement *appsink;
72 //settings
73 int audiobackend;
74 int dropsilence;
75 int usertp;
76 int pure_ogg;
77 char *jack_pp_in;
78 char *jack_pp_out;
79};
80
81
82
83
84#define DEBUG_READ_PURE_OGG 1
85#define DEBUG_RECORD_PURE_OGG 1
86
87
88/**
89 * How much data to read in one go
90 */
91#define MAXLINE 4096
92
93/**
94 * Max number of microseconds to buffer in audiosink.
95 * Default is 1000
96 */
97#define BUFFER_TIME 1000
98
99/**
100 * Min number of microseconds to buffer in audiosink.
101 * Default is 1000
102 */
103#define LATENCY_TIME 1000
104
105
106/**
107 * Number of channels.
108 * Must be one of the following (from libopusenc documentation):
109 * 1, 2
110 */
111#define OPUS_CHANNELS 1
112
113/**
114 * Maximal size of a single opus packet.
115 */
116#define MAX_PAYLOAD_SIZE (1024 / OPUS_CHANNELS)
117
118/**
119 * Size of a single frame fed to the encoder, in ms.
120 * Must be one of the following (from libopus documentation):
121 * 2.5, 5, 10, 20, 40 or 60
122 */
123#define OPUS_FRAME_SIZE 40
124
125/**
126 * Expected packet loss to prepare for, in percents.
127 */
128#define PACKET_LOSS_PERCENTAGE 1
129
130/**
131 * Set to 1 to enable forward error correction.
132 * Set to 0 to disable.
133 */
134#define INBAND_FEC_MODE 1
135
136/**
137 * Max number of microseconds to buffer in audiosource.
138 * Default is 200000
139 */
140#define BUFFER_TIME 1000 /* 1ms */
141
142/**
143 * Min number of microseconds to buffer in audiosource.
144 * Default is 10000
145 */
146#define LATENCY_TIME 1000 /* 1ms */
147
148/**
149 * Maximum delay in multiplexing streams, in ns.
150 * Setting this to 0 forces page flushing, which
151 * decreases delay, but increases overhead.
152 */
153#define OGG_MAX_DELAY 0
154
155/**
156 * Maximum delay for sending out a page, in ns.
157 * Setting this to 0 forces page flushing, which
158 * decreases delay, but increases overhead.
159 */
160#define OGG_MAX_PAGE_DELAY 0
161
162#define SAMPLING_RATE 48000
163
164enum {
165 AUTO,
166 JACK,
167 ALSA,
168 FAKE,
169 TEST
170};
171
172enum {
173 SOURCE,
174 SINK
175};
176
177enum {
178 ENCODER,
179 DECODER
180};
181
182enum {
183 FAIL,
184 OK
185};
186
187enum {
188 SPEAKER,
189 MICROPHONE
190};
diff --git a/src/conversation/gnunet_gst_test.c b/src/conversation/gnunet_gst_test.c
new file mode 100644
index 000000000..3e1454c5b
--- /dev/null
+++ b/src/conversation/gnunet_gst_test.c
@@ -0,0 +1,120 @@
1#include "gnunet_gst_def.h"
2#include "gnunet_gst.h"
3
4int
5main (int argc, char *argv[])
6{
7 struct GNUNET_gstData *gst;
8 GstBus *bus;
9 GstMessage *msg;
10 GstElement *gnunetsrc, *gnunetsink, *source, *sink, *encoder, *decoder;
11
12
13
14 // audio_message = GNUNET_malloc (UINT16_MAX);
15 //audio_message->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
16
17
18 //GstPipeline *pipeline;
19
20 gst = (GNUNET_gstData*)malloc(sizeof(struct GNUNET_gstData));
21
22 //gst->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
23
24
25 gg_load_configuration(gst);
26/*
27 gst->audiobackend = JACK;
28 gst->dropsilence = TRUE;
29 gst->usertp = FALSE;
30 */
31 /* Initialize GStreamer */
32 gst_init (&argc, &argv);
33
34 gst->pipeline = GST_PIPELINE(gst_pipeline_new ("gnunet-media-helper"));
35
36#ifdef IS_SPEAKER
37 int type = SPEAKER;
38 printf("this is the speaker \n");
39#endif
40#ifdef IS_MIC
41 int type = MICROPHONE;
42 printf("this is the microphone \n");
43
44#endif
45 if ( type == SPEAKER)
46 {
47
48 gnunetsrc = GST_ELEMENT(get_app(gst, SOURCE));
49
50 sink = GST_ELEMENT(get_audiobin(gst, SINK));
51 decoder = GST_ELEMENT(get_coder(gst, DECODER));
52 gst_bin_add_many( GST_BIN(gst->pipeline), gnunetsrc, decoder, sink, NULL);
53 gst_element_link_many( gnunetsrc, decoder, sink , NULL);
54
55 }
56 if ( type == MICROPHONE ) {
57
58 source = GST_ELEMENT(get_audiobin(gst, SOURCE));
59
60 encoder = GST_ELEMENT(get_coder(gst, ENCODER));
61
62 gnunetsink = GST_ELEMENT(get_app(gst, SINK));
63
64 gst_bin_add_many( GST_BIN(gst->pipeline), source, encoder, gnunetsink, NULL);
65 gst_element_link_many( source, encoder, gnunetsink , NULL);
66
67
68 }
69 /*
70 gst_bin_add_many( GST_BIN(gst->pipeline), appsource, appsink, source, encoder, decoder, sink, NULL);
71 gst_element_link_many( source, encoder, decoder, sink , NULL);
72*/
73 pl_graph(gst->pipeline);
74 /* Start playing */
75 gst_element_set_state (GST_ELEMENT(gst->pipeline), GST_STATE_PLAYING);
76
77 //pl_graph(gst->pipeline);
78
79 /* Wait until error or EOS */
80 //bus = gst_element_get_bus (GST_ELEMENT(gst->pipeline));
81 //bus_watch_id = gst_bus_add_watch (bus, gnunet_gst_bus_call, pipeline);
82
83 gg_setup_gst_bus(gst);
84// g_print ("Running...\n");
85
86
87 // start pushing buffers
88 if ( type == MICROPHONE )
89 {
90
91
92 GMainLoop *loop;
93 loop = g_main_loop_new (NULL, FALSE);
94
95 g_main_loop_run (loop);
96
97/*
98 while ( 1 )
99 {
100 GstFlowReturn flow;
101 flow = on_appsink_new_sample (gst->appsink, gst);
102 }
103*/
104 }
105 if ( type == SPEAKER )
106 {
107 while ( 1 )
108 {
109// printf("read.. \n");
110 gnunet_read(gst);
111 }
112 }
113 g_print ("Returned, stopping playback\n");
114
115 gst_object_unref (bus);
116 gst_element_set_state (GST_ELEMENT(gst->pipeline), GST_STATE_NULL);
117 gst_object_unref (gst->pipeline);
118
119 return 0;
120}
diff --git a/src/conversation/mediahelper.conf b/src/conversation/mediahelper.conf
new file mode 100644
index 000000000..85c051107
--- /dev/null
+++ b/src/conversation/mediahelper.conf
@@ -0,0 +1,7 @@
1[MEDIAHELPER]
2AUDIOBACKEND = JACK
3REMOVESILENCE = NO
4USERTP = NO
5NO_GN_HEADERS = NO
6JACK_PP_IN = mocp
7JACK_PP_OUT = system
diff --git a/src/conversation/test.sh b/src/conversation/test.sh
new file mode 100644
index 000000000..ca4d15ac1
--- /dev/null
+++ b/src/conversation/test.sh
@@ -0,0 +1,4 @@
1#!/bin/bash
2
3export GST_DEBUG_DUMP_DOT_DIR=/tmp/
4GST_DEBUG_DUMP_DOT_DIR=/tmp/ ./gnunet-helper-audio-record |GST_DEBUG_DUMP_DOT_DIR=/tmp/ ./gnunet-helper-audio-playback