aboutsummaryrefslogtreecommitdiff
path: root/src/conversation/gnunet-helper-audio-record-gst.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conversation/gnunet-helper-audio-record-gst.c')
-rwxr-xr-xsrc/conversation/gnunet-helper-audio-record-gst.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/src/conversation/gnunet-helper-audio-record-gst.c b/src/conversation/gnunet-helper-audio-record-gst.c
index 8d7a88fab..808ad2034 100755
--- a/src/conversation/gnunet-helper-audio-record-gst.c
+++ b/src/conversation/gnunet-helper-audio-record-gst.c
@@ -34,6 +34,8 @@
34#include <gst/audio/gstaudiobasesrc.h> 34#include <gst/audio/gstaudiobasesrc.h>
35#include <glib.h> 35#include <glib.h>
36 36
37#define DEBUG_RECORD_PURE_OGG 1
38
37/** 39/**
38 * Number of channels. 40 * Number of channels.
39 * Must be one of the following (from libopusenc documentation): 41 * Must be one of the following (from libopusenc documentation):
@@ -51,7 +53,7 @@
51 * Must be one of the following (from libopus documentation): 53 * Must be one of the following (from libopus documentation):
52 * 2.5, 5, 10, 20, 40 or 60 54 * 2.5, 5, 10, 20, 40 or 60
53 */ 55 */
54#define OPUS_FRAME_SIZE 20 56#define OPUS_FRAME_SIZE 40
55 57
56/** 58/**
57 * Expected packet loss to prepare for, in percents. 59 * Expected packet loss to prepare for, in percents.
@@ -68,19 +70,37 @@
68 * Max number of microseconds to buffer in audiosource. 70 * Max number of microseconds to buffer in audiosource.
69 * Default is 200000 71 * Default is 200000
70 */ 72 */
71#define BUFFER_TIME 1000 73#define BUFFER_TIME 1000 /* 1ms */
72 74
73/** 75/**
74 * Min number of microseconds to buffer in audiosource. 76 * Min number of microseconds to buffer in audiosource.
75 * Default is 10000 77 * Default is 10000
76 */ 78 */
77#define LATENCY_TIME 1000 79#define LATENCY_TIME 1000 /* 1ms */
80
81/**
82 * Maximum delay in multiplexing streams, in ns.
83 * Setting this to 0 forces page flushing, which
84 * decreases delay, but increases overhead.
85 */
86#define OGG_MAX_DELAY 0
87
88/**
89 * Maximum delay for sending out a page, in ns.
90 * Setting this to 0 forces page flushing, which
91 * decreases delay, but increases overhead.
92 */
93#define OGG_MAX_PAGE_DELAY 0
78 94
79/** 95/**
80 * Main pipeline. 96 * Main pipeline.
81 */ 97 */
82static GstElement *pipeline; 98static GstElement *pipeline;
83 99
100#ifdef DEBUG_RECORD_PURE_OGG
101static int dump_pure_ogg;
102#endif
103
84static void 104static void
85quit () 105quit ()
86{ 106{
@@ -103,13 +123,13 @@ bus_call (GstBus *bus, GstMessage *msg, gpointer data)
103 { 123 {
104 gchar *debug; 124 gchar *debug;
105 GError *error; 125 GError *error;
106 126
107 gst_message_parse_error (msg, &error, &debug); 127 gst_message_parse_error (msg, &error, &debug);
108 g_free (debug); 128 g_free (debug);
109 129
110 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error: %s\n", error->message); 130 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error: %s\n", error->message);
111 g_error_free (error); 131 g_error_free (error);
112 132
113 quit (); 133 quit ();
114 break; 134 break;
115 } 135 }
@@ -137,18 +157,23 @@ signalhandler (int s)
137int 157int
138main (int argc, char **argv) 158main (int argc, char **argv)
139{ 159{
140 GstElement *source, *encoder, *conv, *resampler, *sink; 160 GstElement *source, *filter, *encoder, *conv, *resampler, *sink, *oggmux;
161 GstCaps *caps;
141 GstBus *bus; 162 GstBus *bus;
142 guint bus_watch_id; 163 guint bus_watch_id;
143 struct AudioMessage audio_message; 164 struct AudioMessage audio_message;
144 int abort_send = 0; 165 int abort_send = 0;
145 166
146 typedef void (*SignalHandlerPointer) (int); 167 typedef void (*SignalHandlerPointer) (int);
147 168
148 SignalHandlerPointer inthandler, termhandler; 169 SignalHandlerPointer inthandler, termhandler;
149 inthandler = signal (SIGINT, signalhandler); 170 inthandler = signal (SIGINT, signalhandler);
150 termhandler = signal (SIGTERM, signalhandler); 171 termhandler = signal (SIGTERM, signalhandler);
151 172
173#ifdef DEBUG_RECORD_PURE_OGG
174 dump_pure_ogg = getenv ("GNUNET_RECORD_PURE_OGG") ? 1 : 0;
175#endif
176
152#ifdef WINDOWS 177#ifdef WINDOWS
153 setmode (1, _O_BINARY); 178 setmode (1, _O_BINARY);
154#endif 179#endif
@@ -169,12 +194,14 @@ main (int argc, char **argv)
169 /* Create gstreamer elements */ 194 /* Create gstreamer elements */
170 pipeline = gst_pipeline_new ("audio-recorder"); 195 pipeline = gst_pipeline_new ("audio-recorder");
171 source = gst_element_factory_make ("autoaudiosrc", "audiosource"); 196 source = gst_element_factory_make ("autoaudiosrc", "audiosource");
197 filter = gst_element_factory_make ("capsfilter", "filter");
172 conv = gst_element_factory_make ("audioconvert", "converter"); 198 conv = gst_element_factory_make ("audioconvert", "converter");
173 resampler= gst_element_factory_make ("audioresample", "resampler"); 199 resampler= gst_element_factory_make ("audioresample", "resampler");
174 encoder = gst_element_factory_make ("opusenc", "opus-encoder"); 200 encoder = gst_element_factory_make ("opusenc", "opus-encoder");
201 oggmux = gst_element_factory_make ("oggmux", "ogg-muxer");
175 sink = gst_element_factory_make ("appsink", "audio-output"); 202 sink = gst_element_factory_make ("appsink", "audio-output");
176 203
177 if (!pipeline || !source || !conv || !resampler || !encoder || !sink) 204 if (!pipeline || !filter || !source || !conv || !resampler || !encoder || !oggmux || !sink)
178 { 205 {
179 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 206 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
180 "One element could not be created. Exiting.\n"); 207 "One element could not be created. Exiting.\n");
@@ -185,6 +212,17 @@ main (int argc, char **argv)
185 212
186 /* Set up the pipeline */ 213 /* Set up the pipeline */
187 214
215 caps = gst_caps_new_simple ("audio/x-raw",
216 "format", G_TYPE_STRING, "S16LE",
217/* "rate", G_TYPE_INT, SAMPLING_RATE,*/
218 "channels", G_TYPE_INT, OPUS_CHANNELS,
219/* "layout", G_TYPE_STRING, "interleaved",*/
220 NULL);
221 g_object_set (G_OBJECT (filter),
222 "caps", caps,
223 NULL);
224 gst_caps_unref (caps);
225
188 g_object_set (G_OBJECT (encoder), 226 g_object_set (G_OBJECT (encoder),
189/* "bitrate", 64000, */ 227/* "bitrate", 64000, */
190/* "bandwidth", OPUS_BANDWIDTH_FULLBAND, */ 228/* "bandwidth", OPUS_BANDWIDTH_FULLBAND, */
@@ -194,7 +232,12 @@ main (int argc, char **argv)
194 "audio", FALSE, /* VoIP, not audio */ 232 "audio", FALSE, /* VoIP, not audio */
195 "frame-size", OPUS_FRAME_SIZE, 233 "frame-size", OPUS_FRAME_SIZE,
196 NULL); 234 NULL);
197 235
236 g_object_set (G_OBJECT (oggmux),
237 "max-delay", OGG_MAX_DELAY,
238 "max-page-delay", OGG_MAX_PAGE_DELAY,
239 NULL);
240
198 /* we add a message handler */ 241 /* we add a message handler */
199 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 242 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
200 bus_watch_id = gst_bus_add_watch (bus, bus_call, pipeline); 243 bus_watch_id = gst_bus_add_watch (bus, bus_call, pipeline);
@@ -202,11 +245,11 @@ main (int argc, char **argv)
202 245
203 /* we add all elements into the pipeline */ 246 /* we add all elements into the pipeline */
204 /* audiosource | converter | resampler | opus-encoder | audio-output */ 247 /* audiosource | converter | resampler | opus-encoder | audio-output */
205 gst_bin_add_many (GST_BIN (pipeline), source, conv, resampler, encoder, 248 gst_bin_add_many (GST_BIN (pipeline), source, filter, conv, resampler, encoder,
206 sink, NULL); 249 oggmux, sink, NULL);
207 250
208 /* we link the elements together */ 251 /* we link the elements together */
209 gst_element_link_many (source, conv, resampler, encoder, sink, NULL); 252 gst_element_link_many (source, filter, conv, resampler, encoder, oggmux, sink, NULL);
210 253
211 /* Set the pipeline to "playing" state*/ 254 /* Set the pipeline to "playing" state*/
212 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Now playing\n"); 255 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Now playing\n");
@@ -288,6 +331,10 @@ main (int argc, char **argv)
288 ssize_t ret; 331 ssize_t ret;
289 if (0 == phase) 332 if (0 == phase)
290 { 333 {
334#ifdef DEBUG_RECORD_PURE_OGG
335 if (dump_pure_ogg)
336 continue;
337#endif
291 ptr = (const char *) &audio_message; 338 ptr = (const char *) &audio_message;
292 to_send = sizeof (audio_message); 339 to_send = sizeof (audio_message);
293 } 340 }
@@ -308,7 +355,7 @@ main (int argc, char **argv)
308 "Failed to write %u bytes at offset %u (total %u) in phase %d: %s\n", 355 "Failed to write %u bytes at offset %u (total %u) in phase %d: %s\n",
309 (unsigned int) to_send - offset, (unsigned int) offset, 356 (unsigned int) to_send - offset, (unsigned int) offset,
310 (unsigned int) (to_send + offset), phase, strerror (errno)); 357 (unsigned int) (to_send + offset), phase, strerror (errno));
311 abort_send = 1; 358 abort_send = 1;
312 break; 359 break;
313 } 360 }
314 } 361 }