2 This file is part of GNUnet.
3 Copyright (C) 2016 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file conversation/gnunet_gst.c
25 #include "gnunet_gst_def.h"
30 static struct GNUNET_CONFIGURATION_Handle *cfg;
34 dump_buffer(unsigned n, const unsigned char* buf)
36 const unsigned char *p, *end;
41 for (i = 0; ; i += 16) {
43 for (j = 0; j < 16; j++) {
44 fprintf(stderr, "%02X ", p[j]);
50 for (j = 0; j < 16; j++) {
51 fprintf(stderr, "%c", isprint(p[j]) ? p[j] :
56 fprintf(stderr, "\n");
63 * load gnunet configuration
66 gg_load_configuration(GNUNET_gstData * d)
68 char *audiobackend_string;
69 cfg = GNUNET_CONFIGURATION_create();
70 GNUNET_CONFIGURATION_load(cfg, "mediahelper.conf");
72 GNUNET_CONFIGURATION_get_value_string(cfg, "MEDIAHELPER", "JACK_PP_IN", &d->jack_pp_in);
73 GNUNET_CONFIGURATION_get_value_string(cfg, "MEDIAHELPER", "JACK_PP_OUT", &d->jack_pp_out);
75 GNUNET_CONFIGURATION_get_value_string(cfg, "MEDIAHELPER", "AUDIOBACKEND", &audiobackend_string);
77 // printf("abstring: %s \n", audiobackend_string);
79 if (0 == strcasecmp (audiobackend_string, "AUTO"))
81 d->audiobackend = AUTO;
82 } else if (0 == strcasecmp (audiobackend_string, "JACK"))
84 d->audiobackend = JACK;
85 } else if (0 == strcasecmp (audiobackend_string, "ALSA"))
87 d->audiobackend = ALSA;
88 } else if (0 == strcasecmp (audiobackend_string, "FAKE"))
90 d->audiobackend = FAKE;
91 } else if (0 == strcasecmp (audiobackend_string, "TEST"))
93 d->audiobackend = TEST;
96 d->audiobackend = AUTO;
99 if (GNUNET_CONFIGURATION_get_value_yesno(cfg, "MEDIAHELPER", "REMOVESILENCE") == GNUNET_YES)
101 d->dropsilence = TRUE;
103 d->dropsilence = FALSE;
106 if (GNUNET_CONFIGURATION_get_value_yesno(cfg, "MEDIAHELPER", "NO_GN_HEADERS") == GNUNET_YES)
114 if (GNUNET_CONFIGURATION_get_value_yesno(cfg, "MEDIAHELPER", "USERTP") == GNUNET_YES)
121 // GNUNET_CONFIGURATION_write(cfg, "mediahelper.conf");
126 write_data (const char *ptr, size_t msg_size)
131 while (off < msg_size)
133 ret = write (1, &ptr[off], msg_size - off);
137 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "write");
147 on_appsink_new_sample (GstElement * element, GNUNET_gstData * d)
149 //size of message including gnunet header
156 const GstStructure *si;
162 if (gst_app_sink_is_eos(GST_APP_SINK(element)))
165 //pull sample from appsink
166 s = gst_app_sink_pull_sample (GST_APP_SINK(element));
171 if (!GST_IS_SAMPLE (s))
174 b = gst_sample_get_buffer(s);
176 GST_WARNING ("caps are %" GST_PTR_FORMAT, gst_sample_get_caps(s));
180 gst_buffer_map (b, &map, GST_MAP_READ);
184 if (len > UINT16_MAX - sizeof (struct AudioMessage))
186 // this should never happen?
187 printf("GSTREAMER sample too big! \n");
189 len = UINT16_MAX - sizeof (struct AudioMessage);
192 msg_size = sizeof (struct AudioMessage) + len;
194 // copy the data into audio_message
195 GNUNET_memcpy (((char *) &(d->audio_message)[1]), map.data, len);
196 (d->audio_message)->header.size = htons ((uint16_t) msg_size);
198 // write the audio_message without the gnunet headers
199 write_data ((const char *) &(d->audio_message)[1], len);
201 write_data ((const char *) d->audio_message, msg_size);
208 * Dump a pipeline graph
211 pl_graph(GstElement * pipeline)
215 gst_debug_bin_to_dot_file_with_ts(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "playback_helper.dot");
219 gst_debug_bin_to_dot_file_with_ts(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "record_helper.dot");
224 // load_configuration();
230 gnunet_gst_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
234 switch (GST_MESSAGE_TYPE (msg))
236 case GST_MESSAGE_EOS:
237 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
242 case GST_MESSAGE_ERROR:
247 gst_message_parse_error (msg, &error, &debug);
250 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
253 g_error_free (error);
265 /* called when pipeline changes state */
267 state_changed_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * d)
269 GstState old_state, new_state, pending_state;
271 gst_message_parse_state_changed (msg, &old_state, &new_state,
276 case GST_STATE_READY:
277 // printf("ready.... \n");
278 //pl_graph(GST_ELEMENT(d->pipeline));
280 case GST_STATE_PLAYING:
282 //GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
284 // printf("Playing.... \n");
285 pl_graph(GST_ELEMENT(d->pipeline));
287 case GST_STATE_VOID_PENDING:
288 // printf("void_pending.... \n");
289 //pl_graph(GST_ELEMENT(d->pipeline));
292 // printf("null.... \n");
293 //pl_graph(GST_ELEMENT(d->pipeline));
296 case GST_STATE_PAUSED:
297 // printf("paused.... \n");
298 //pl_graph(GST_ELEMENT(d->pipeline));
304 application_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * data)
306 // printf("application cb");
311 error_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * data)
313 // printf("error cb");
318 eos_cb (GstBus * bus, GstMessage * msg, GNUNET_gstData * data)
325 gg_setup_gst_bus (GNUNET_gstData * d)
328 bus = gst_element_get_bus (GST_ELEMENT(d->pipeline));
329 gst_bus_add_signal_watch (bus);
330 g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
332 g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback) eos_cb,
334 g_signal_connect (G_OBJECT (bus), "message::state-changed",
335 (GCallback) state_changed_cb, d);
336 g_signal_connect (G_OBJECT (bus), "message::application",
337 (GCallback) application_cb, d);
338 g_signal_connect (G_OBJECT (bus), "message::about-to-finish",
339 (GCallback) application_cb, d);
340 gst_object_unref (bus);
345 * take buffer from gstreamer and feed it to gnunet
349 feed_buffer_to_gnunet (GNUNET_gstData * d)
354 size_t len, msg_size;
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pulling...\n");
359 s = gst_app_sink_pull_sample (GST_APP_SINK(d->appsink));
362 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pulled NULL\n");
365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "...pulled!\n");
367 const GstStructure *si;
371 si = gst_sample_get_info (s);
374 si_str = gst_structure_to_string (si);
377 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample %s\n", si_str);
382 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with no info\n");
383 s_caps = gst_sample_get_caps (s);
386 caps_str = gst_caps_to_string (s_caps);
389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with caps %s\n", caps_str);
394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with no caps\n");
396 b = gst_sample_get_buffer (s);
397 if (NULL == b || !gst_buffer_map (b, &m, GST_MAP_READ))
399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got NULL buffer %p or failed to map the buffer\n", b);
400 gst_sample_unref (s);
405 if (len > UINT16_MAX - sizeof (struct AudioMessage))
408 len = UINT16_MAX - sizeof (struct AudioMessage);
410 msg_size = sizeof (struct AudioMessage) + len;
411 audio_message.header.size = htons ((uint16_t) msg_size);
414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
415 "Sending %u bytes of audio data\n", (unsigned int) msg_size);
416 for (phase = 0; phase < 2; phase++)
421 if (0 == phase && !d->pure_ogg)
423 //#ifdef DEBUG_RECORD_PURE_OGG
429 ptr = (const char *) &audio_message;
430 to_send = sizeof (audio_message);
434 ptr = (const char *) m.data;
437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
438 "Sending %u bytes on phase %d\n", (unsigned int) to_send, phase);
439 for (offset = 0; offset < to_send; offset += ret)
441 ret = write (1, &ptr[offset], to_send - offset);
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
446 "Failed to write %u bytes at offset %u (total %u) in phase %d: %s\n",
447 (unsigned int) to_send - offset, (unsigned int) offset,
448 (unsigned int) (to_send + offset), phase, strerror (errno));
458 gst_buffer_unmap (b, &m);
459 gst_sample_unref (s);
465 feed_buffer_to_gst (const char *audio, size_t b_len, GNUNET_gstData * d)
471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
472 "Feeding %u bytes to GStreamer\n",
473 (unsigned int) b_len);
475 bufspace = g_memdup (audio, b_len);
476 b = gst_buffer_new_wrapped (bufspace, b_len);
479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
480 "Failed to wrap a buffer\n");
482 return GNUNET_SYSERR;
484 if (GST_APP_SRC(d->appsrc) == NULL)
486 flow = gst_app_src_push_buffer (GST_APP_SRC(d->appsrc), b);
487 /* They all return GNUNET_OK, because currently player stops when
488 * data stops coming. This might need to be changed for the player
489 * to also stop when pipeline breaks.
494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
495 "Fed %u bytes to the pipeline\n",
496 (unsigned int) b_len);
498 case GST_FLOW_FLUSHING:
499 /* buffer was dropped, because pipeline state is not PAUSED or PLAYING */
500 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
501 "Dropped a buffer\n");
505 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
509 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
510 "Unexpected push result\n");
519 * debug making elements
522 gst_element_factory_make_debug( gchar *factoryname, gchar *name)
526 element = gst_element_factory_make(factoryname,name);
528 if (element == NULL) {
530 printf ("\n Failed to create element - type: %s name: %s \n", factoryname, name);
540 gst_element_link_many_debug(...)
543 gst_element_link_many(argptr);
546 #define gst_element_link_many(...) \
547 gst_element_link_many_debug(__VA_ARGS__)
552 printf("linking elements failed: %s", msg);
557 * used to set properties on autoaudiosink's chosen sink
560 autoaudiosink_child_added (GstChildProxy *child_proxy,
565 if (GST_IS_AUDIO_BASE_SRC (object))
566 g_object_set (object,
567 "buffer-time", (gint64) BUFFER_TIME,
568 "latency-time", (gint64) LATENCY_TIME,
573 * used to set properties on autoaudiosource's chosen sink
576 autoaudiosource_child_added (GstChildProxy *child_proxy, GObject *object, gchar *name, gpointer user_data)
578 if (GST_IS_AUDIO_BASE_SRC (object))
579 g_object_set (object, "buffer-time", (gint64) BUFFER_TIME, "latency-time", (gint64) LATENCY_TIME, NULL);
584 get_pipeline(GstElement *element)
588 p = GST_PIPELINE (gst_object_get_parent(GST_OBJECT (element)));
590 return GST_ELEMENT (p);
594 decoder_ogg_pad_added (GstElement *element,
599 GstElement *decoder = (GstElement *) data;
601 printf("==== ogg pad added callback \n");
602 /* We can now link this pad with the opus-decoder sink pad */
603 // pl_graph(get_pipeline(element));
604 sinkpad = gst_element_get_static_pad (decoder, "sink");
606 gst_pad_link (pad, sinkpad);
607 gst_element_link_many(element, decoder, NULL);
608 gst_object_unref (sinkpad);
613 gnunet_read (GNUNET_gstData * d)
615 char readbuf[MAXLINE];
618 ret = read (0, readbuf, sizeof (readbuf));
621 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
622 _("Read error from STDIN: %d %s\n"),
623 ret, strerror (errno));
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
628 "Received %d bytes of audio data\n",
632 //#ifdef DEBUG_READ_PURE_OGG
636 feed_buffer_to_gst (readbuf, ret, d);
641 GNUNET_MST_from_buffer (d->stdin_mst,
653 * @param msg message we received.
654 * @return #GNUNET_OK on success,
655 * #GNUNET_NO to stop further processing due to disconnect (no error)
656 * #GNUNET_SYSERR to stop further processing due to error
659 stdin_receiver (void *cls,
660 const struct GNUNET_MessageHeader *msg)
662 struct AudioMessage *audio;
665 printf("stdin receiver \n ");
666 dump_buffer (sizeof(msg),
667 (const unsigned char *) msg);
669 switch (ntohs (msg->type))
671 case GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO:
672 audio = (struct AudioMessage *) msg;
674 b_len = ntohs (audio->header.size) - sizeof (struct AudioMessage);
675 printf("feeding buffer to gst \n ");
676 feed_buffer_to_gst ((const char *) &audio[1], b_len, cls);
679 printf("No audio message: %u \n ", ntohs(msg->type));
687 get_app(GNUNET_gstData *d, int type)
690 GstPad *pad, *ghostpad;
692 if ( type == SOURCE )
694 bin = GST_BIN(gst_bin_new("Gnunet appsrc"));
697 GNUNET_assert (GNUNET_OK ==
698 GNUNET_log_setup ("gnunet-helper-audio-playback",
702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
703 "Audio playback starts\n");
704 printf(" creating appsrc \n ");
705 //d->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
707 // d->audio_message = GNUNET_malloc (UINT16_MAX);
708 // d->audio_message = (AudioMessage*)malloc(sizeof(struct AudioMessage));
709 // d->audio_message = GNUNET_malloc(sizeof(struct AudioMessage));
712 //d->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
715 d->stdin_mst = GNUNET_MST_create (&stdin_receiver, d);
717 if ( d->stdin_mst == NULL)
718 printf("stdin_mst = NULL");
720 d->appsrc = gst_element_factory_make ("appsrc", "appsrc");
722 gst_bin_add_many( bin, d->appsrc, NULL);
723 // gst_element_link_many ( encoder, muxer, NULL);
725 pad = gst_element_get_static_pad (d->appsrc, "src");
726 ghostpad = gst_ghost_pad_new ("src", pad);
730 bin = GST_BIN(gst_bin_new("Gnunet appsink"));
733 GNUNET_assert (GNUNET_OK ==
734 GNUNET_log_setup ("gnunet-helper-audio-record",
738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
739 "Audio source starts\n");
741 d->appsink = gst_element_factory_make ("appsink", "appsink");
743 // Move this out of here!
744 d->audio_message = GNUNET_malloc (UINT16_MAX);
745 (d->audio_message)->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
746 g_object_set (G_OBJECT (d->appsink), "emit-signals", TRUE, "sync", TRUE, NULL);
748 g_signal_connect (d->appsink, "new-sample",
749 G_CALLBACK (on_appsink_new_sample), &d);
751 gst_bin_add_many( bin, d->appsink, NULL);
752 // gst_element_link_many ( encoder, muxer, NULL);
754 pad = gst_element_get_static_pad (d->appsink, "sink");
755 ghostpad = gst_ghost_pad_new ("sink", pad);
758 /* set the bin pads */
759 gst_pad_set_active (ghostpad, TRUE);
760 gst_element_add_pad (GST_ELEMENT(bin), ghostpad);
762 gst_object_unref (pad);
768 get_coder(GNUNET_gstData *d , int type)
771 GstPad *srcpad, *sinkpad, *srcghostpad, *sinkghostpad;
773 GstElement *encoder, *muxer, *decoder, *demuxer, *jitterbuffer, *rtpcapsfilter;
775 if ( d->usertp == TRUE )
778 * 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 */
780 rtpcaps = gst_caps_new_simple ("application/x-rtp",
781 "media", G_TYPE_STRING, "audio",
782 "clock-rate", G_TYPE_INT, SAMPLING_RATE,
783 "encoding-name", G_TYPE_STRING, "OPUS",
784 "payload", G_TYPE_INT, 96,
785 "sprop-stereo", G_TYPE_STRING, "0",
786 "encoding-params", G_TYPE_STRING, "2",
789 rtpcaps = gst_caps_new_simple ("application/x-rtp",
790 "media", G_TYPE_STRING, "audio",
791 "clock-rate", G_TYPE_INT, SAMPLING_RATE,
792 "encoding-name", G_TYPE_STRING, "OPUS",
793 "payload", G_TYPE_INT, 96,
794 "sprop-stereo", G_TYPE_STRING, "0",
795 "encoding-params", G_TYPE_STRING, "2",
799 rtpcapsfilter = gst_element_factory_make ("capsfilter", "rtpcapsfilter");
801 g_object_set (G_OBJECT (rtpcapsfilter),
804 gst_caps_unref (rtpcaps);
809 if ( type == ENCODER )
811 bin = GST_BIN(gst_bin_new("Gnunet audioencoder"));
813 encoder = gst_element_factory_make ("opusenc", "opus-encoder");
814 if ( d->usertp == TRUE )
816 muxer = gst_element_factory_make ("rtpopuspay", "rtp-payloader");
818 muxer = gst_element_factory_make ("oggmux", "ogg-muxer");
820 g_object_set (G_OBJECT (encoder),
821 /* "bitrate", 64000, */
822 /* "bandwidth", OPUS_BANDWIDTH_FULLBAND, */
823 "inband-fec", INBAND_FEC_MODE,
824 "packet-loss-percentage", PACKET_LOSS_PERCENTAGE,
825 "max-payload-size", MAX_PAYLOAD_SIZE,
826 "audio", TRUE, /* VoIP, not audio */
827 "frame-size", OPUS_FRAME_SIZE,
830 if ( d->usertp != TRUE)
832 g_object_set (G_OBJECT (muxer),
833 "max-delay", OGG_MAX_DELAY,
834 "max-page-delay", OGG_MAX_PAGE_DELAY,
838 gst_bin_add_many( bin, encoder, muxer, NULL);
839 gst_element_link_many ( encoder, muxer, NULL);
840 sinkpad = gst_element_get_static_pad(encoder, "sink");
841 sinkghostpad = gst_ghost_pad_new ("sink", sinkpad);
843 srcpad = gst_element_get_static_pad(muxer, "src");
844 srcghostpad = gst_ghost_pad_new ("src", srcpad);
847 if ( type == DECODER )
849 bin = GST_BIN(gst_bin_new("Gnunet audiodecoder"));
852 if ( d->usertp == TRUE )
855 demuxer = gst_element_factory_make ("rtpopusdepay", "ogg-demuxer");
856 jitterbuffer = gst_element_factory_make ("rtpjitterbuffer", "rtpjitterbuffer");
858 demuxer = gst_element_factory_make ("oggdemux", "ogg-demuxer");
860 decoder = gst_element_factory_make ("opusdec", "opus-decoder");
862 if ( d->usertp == TRUE )
864 gst_bin_add_many( bin, rtpcapsfilter, jitterbuffer, demuxer, decoder, NULL);
865 gst_element_link_many ( rtpcapsfilter, jitterbuffer, demuxer, decoder, NULL);
866 sinkpad = gst_element_get_static_pad(rtpcapsfilter, "sink");
870 gst_bin_add_many( bin, demuxer, decoder, NULL);
872 g_signal_connect (demuxer,
874 G_CALLBACK (decoder_ogg_pad_added),
877 sinkpad = gst_element_get_static_pad(demuxer, "sink");
879 sinkghostpad = gst_ghost_pad_new ("sink", sinkpad);
881 srcpad = gst_element_get_static_pad(decoder, "src");
882 srcghostpad = gst_ghost_pad_new ("src", srcpad);
886 // add pads to the bin
887 gst_pad_set_active (sinkghostpad, TRUE);
888 gst_element_add_pad (GST_ELEMENT(bin), sinkghostpad);
890 gst_pad_set_active (srcghostpad, TRUE);
891 gst_element_add_pad (GST_ELEMENT(bin), srcghostpad);
899 get_audiobin(GNUNET_gstData *d , int type)
902 GstElement *sink, *source, *queue, *conv, *resampler, *removesilence, *filter;
903 GstPad *pad, *ghostpad;
905 if ( type == SINK ) {
907 bin = GST_BIN(gst_bin_new("Gnunet audiosink"));
909 /* Create all the elements */
910 if ( d->dropsilence == TRUE )
912 queue = gst_element_factory_make ("queue", "queue");
913 removesilence = gst_element_factory_make ("removesilence", "removesilence");
916 conv = gst_element_factory_make ("audioconvert", "converter");
917 resampler= gst_element_factory_make ("audioresample", "resampler");
919 if ( d->audiobackend == AUTO )
921 sink = gst_element_factory_make ("autoaudiosink", "audiosink");
922 g_signal_connect (sink, "child-added", G_CALLBACK (autoaudiosink_child_added), NULL);
926 if ( d->audiobackend == ALSA )
928 sink = gst_element_factory_make ("alsaaudiosink", "audiosink");
931 if ( d->audiobackend == JACK )
933 sink = gst_element_factory_make ("jackaudiosink", "audiosink");
935 g_object_set (G_OBJECT (sink), "client-name", "gnunet", NULL);
937 if (g_object_class_find_property
938 (G_OBJECT_GET_CLASS (sink), "port-pattern"))
941 // char *portpattern = "system";
943 g_object_set (G_OBJECT (sink), "port-pattern", d->jack_pp_out,
949 if ( d->audiobackend == FAKE )
951 sink = gst_element_factory_make ("fakesink", "audiosink");
955 "buffer-time", (gint64) BUFFER_TIME,
956 "latency-time", (gint64) LATENCY_TIME,
959 if ( d->dropsilence == TRUE )
961 // Do not remove silence by default
962 g_object_set( removesilence, "remove", FALSE, NULL);
963 g_object_set( queue, "max-size-buffers", 12, NULL);
965 g_signal_connect (source,
967 G_CALLBACK(appsrc_need_data),
970 g_signal_connect (source,
972 G_CALLBACK(appsrc_enough_data),
976 g_signal_connect (queue,
977 "notify::current-level-bytes",
978 G_CALLBACK(queue_current_level),
981 g_signal_connect (queue,
983 G_CALLBACK(queue_underrun),
986 g_signal_connect (queue,
988 G_CALLBACK(queue_running),
991 g_signal_connect (queue,
993 G_CALLBACK(queue_overrun),
996 g_signal_connect (queue,
998 G_CALLBACK(queue_pushing),
1008 gst_bin_add_many (bin , conv, resampler, sink, NULL);
1009 gst_element_link_many ( conv, resampler, sink, NULL);
1011 if ( d->dropsilence == TRUE )
1013 gst_bin_add_many (bin , queue ,removesilence , NULL);
1015 if ( !gst_element_link_many ( queue, removesilence, conv, NULL) )
1016 lf ("queue, removesilence, conv ");
1018 pad = gst_element_get_static_pad (queue, "sink");
1022 pad = gst_element_get_static_pad(conv, "sink");
1026 ghostpad = gst_ghost_pad_new ("sink", pad);
1031 bin = GST_BIN(gst_bin_new("Gnunet audiosource"));
1033 // source = gst_element_factory_make("audiotestsrc", "audiotestsrcbla");
1035 if (d->audiobackend == AUTO )
1037 source = gst_element_factory_make ("autoaudiosrc", "audiosource");
1039 if (d->audiobackend == ALSA )
1041 source = gst_element_factory_make ("alsasrc", "audiosource");
1043 if (d->audiobackend == JACK )
1045 source = gst_element_factory_make ("jackaudiosrc", "audiosource");
1047 if (d->audiobackend == TEST )
1049 source = gst_element_factory_make ("audiotestsrc", "audiosource");
1052 filter = gst_element_factory_make ("capsfilter", "filter");
1053 conv = gst_element_factory_make ("audioconvert", "converter");
1054 resampler= gst_element_factory_make ("audioresample", "resampler");
1056 if (d->audiobackend == AUTO ) {
1057 g_signal_connect (source, "child-added", G_CALLBACK (autoaudiosource_child_added), NULL);
1060 if (GST_IS_AUDIO_BASE_SRC (source))
1061 g_object_set (source, "buffer-time", (gint64) BUFFER_TIME, "latency-time", (gint64) LATENCY_TIME, NULL);
1062 if ( d->audiobackend == JACK ) {
1063 g_object_set (G_OBJECT (source), "client-name", "gnunet", NULL);
1064 if (g_object_class_find_property
1065 (G_OBJECT_GET_CLASS (source), "port-pattern"))
1068 char *portpattern = "moc";
1070 g_object_set (G_OBJECT (source), "port-pattern", portpattern,
1076 caps = gst_caps_new_simple ("audio/x-raw",
1077 /* "format", G_TYPE_STRING, "S16LE", */
1078 /* "rate", G_TYPE_INT, SAMPLING_RATE,*/
1079 "channels", G_TYPE_INT, OPUS_CHANNELS,
1080 /* "layout", G_TYPE_STRING, "interleaved",*/
1083 g_object_set (G_OBJECT (filter),
1086 gst_caps_unref (caps);
1088 gst_bin_add_many (bin , source, filter, conv, resampler, NULL);
1089 gst_element_link_many ( source, filter, conv, resampler, NULL);
1091 pad = gst_element_get_static_pad (resampler, "src");
1095 ghostpad = gst_ghost_pad_new ("src", pad);
1099 /* set the bin pads */
1100 gst_pad_set_active (ghostpad, TRUE);
1101 gst_element_add_pad (GST_ELEMENT(bin), ghostpad);
1103 gst_object_unref (pad);