aboutsummaryrefslogtreecommitdiff
path: root/src/conversation/gnunet-helper-audio-playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conversation/gnunet-helper-audio-playback.c')
-rw-r--r--src/conversation/gnunet-helper-audio-playback.c136
1 files changed, 73 insertions, 63 deletions
diff --git a/src/conversation/gnunet-helper-audio-playback.c b/src/conversation/gnunet-helper-audio-playback.c
index 91231a87e..97664d0f5 100644
--- a/src/conversation/gnunet-helper-audio-playback.c
+++ b/src/conversation/gnunet-helper-audio-playback.c
@@ -55,77 +55,77 @@ static pa_sample_spec sample_spec = {
55}; 55};
56 56
57/** 57/**
58* Pulseaudio mainloop api 58 * Pulseaudio mainloop api
59*/ 59 */
60static pa_mainloop_api *mainloop_api; 60static pa_mainloop_api *mainloop_api;
61 61
62/** 62/**
63* Pulseaudio threaded mainloop 63 * Pulseaudio threaded mainloop
64*/ 64 */
65static pa_threaded_mainloop *m; 65static pa_threaded_mainloop *m;
66 66
67/** 67/**
68* Pulseaudio context 68 * Pulseaudio context
69*/ 69 */
70static pa_context *context; 70static pa_context *context;
71 71
72/** 72/**
73* Pulseaudio output stream 73 * Pulseaudio output stream
74*/ 74 */
75static pa_stream *stream_out; 75static pa_stream *stream_out;
76 76
77/** 77/**
78* Pulseaudio io events 78 * Pulseaudio io events
79*/ 79 */
80static pa_io_event *stdio_event; 80static pa_io_event *stdio_event;
81 81
82/** 82/**
83* OPUS decoder 83 * OPUS decoder
84*/ 84 */
85static OpusDecoder *dec; 85static OpusDecoder *dec;
86 86
87/** 87/**
88* PCM data buffer 88 * PCM data buffer
89*/ 89 */
90static float *pcm_buffer; 90static float *pcm_buffer;
91 91
92/** 92/**
93* Length of PCM buffer 93 * Length of PCM buffer
94*/ 94 */
95static int pcm_length; 95static int pcm_length;
96 96
97/** 97/**
98* Number of samples for one frame 98 * Number of samples for one frame
99*/ 99 */
100static int frame_size; 100static int frame_size;
101 101
102/** 102/**
103* The sampling rate used in Pulseaudio specification 103 * The sampling rate used in Pulseaudio specification
104*/ 104 */
105static opus_int32 sampling_rate; 105static opus_int32 sampling_rate;
106 106
107/** 107/**
108* Audio buffer 108 * Audio buffer
109*/ 109 */
110static void *buffer; 110static void *buffer;
111 111
112/** 112/**
113* Length of audio buffer 113 * Length of audio buffer
114*/ 114 */
115static size_t buffer_length; 115static size_t buffer_length;
116 116
117/** 117/**
118* Read index for transmit buffer 118 * Read index for transmit buffer
119*/ 119 */
120static size_t buffer_index; 120static size_t buffer_index;
121 121
122 122
123
124/** 123/**
125* Message callback 124 * Message callback
126*/ 125 */
127static void 126static void
128stdin_receiver (void *cls, const struct GNUNET_MessageHeader *msg) 127stdin_receiver (void *cls,
128 const struct GNUNET_MessageHeader *msg)
129{ 129{
130 struct AudioMessage *audio; 130 struct AudioMessage *audio;
131 131
@@ -135,9 +135,12 @@ stdin_receiver (void *cls, const struct GNUNET_MessageHeader *msg)
135 audio = (struct AudioMessage *) msg; 135 audio = (struct AudioMessage *) msg;
136 136
137 int len = 137 int len =
138 opus_decode_float (dec, audio->audio, audio->length, pcm_buffer, 138 opus_decode_float (dec,
139 (const unsigned char *) &audio[1],
140 ntohs (audio->header.size) - sizeof (struct AudioMessage),
141 pcm_buffer,
139 frame_size, 0); 142 frame_size, 0);
140 143 // FIXME: pcm_length != len???
141 if (pa_stream_write 144 if (pa_stream_write
142 (stream_out, (uint8_t *) pcm_buffer, pcm_length, NULL, 0, 145 (stream_out, (uint8_t *) pcm_buffer, pcm_length, NULL, 0,
143 PA_SEEK_RELATIVE) < 0) 146 PA_SEEK_RELATIVE) < 0)
@@ -156,9 +159,10 @@ stdin_receiver (void *cls, const struct GNUNET_MessageHeader *msg)
156 } 159 }
157} 160}
158 161
162
159/** 163/**
160* Pulseaudio shutdown task 164 * Pulseaudio shutdown task
161*/ 165 */
162static void 166static void
163quit (int ret) 167quit (int ret)
164{ 168{
@@ -166,9 +170,10 @@ quit (int ret)
166 exit (ret); 170 exit (ret);
167} 171}
168 172
173
169/** 174/**
170* Write some data to the stream 175 * Write some data to the stream
171*/ 176 */
172static void 177static void
173do_stream_write (size_t length) 178do_stream_write (size_t length)
174{ 179{
@@ -210,9 +215,10 @@ do_stream_write (size_t length)
210 } 215 }
211} 216}
212 217
218
213/** 219/**
214* Callback when data is there for playback 220 * Callback when data is there for playback
215*/ 221 */
216static void 222static void
217stream_write_callback (pa_stream * s, size_t length, void *userdata) 223stream_write_callback (pa_stream * s, size_t length, void *userdata)
218{ 224{
@@ -232,9 +238,10 @@ stream_write_callback (pa_stream * s, size_t length, void *userdata)
232 do_stream_write (length); 238 do_stream_write (length);
233} 239}
234 240
241
235/** 242/**
236* Exit callback for SIGTERM and SIGINT 243 * Exit callback for SIGTERM and SIGINT
237*/ 244 */
238static void 245static void
239exit_signal_callback (pa_mainloop_api * m, pa_signal_event * e, int sig, 246exit_signal_callback (pa_mainloop_api * m, pa_signal_event * e, int sig,
240 void *userdata) 247 void *userdata)
@@ -244,9 +251,10 @@ exit_signal_callback (pa_mainloop_api * m, pa_signal_event * e, int sig,
244 quit (1); 251 quit (1);
245} 252}
246 253
254
247/** 255/**
248* Pulseaudio stream state callback 256 * Pulseaudio stream state callback
249*/ 257 */
250static void 258static void
251context_state_callback (pa_context * c, void *userdata) 259context_state_callback (pa_context * c, void *userdata)
252{ 260{
@@ -309,13 +317,13 @@ context_state_callback (pa_context * c, void *userdata)
309 317
310fail: 318fail:
311 quit (1); 319 quit (1);
312
313} 320}
314 321
322
315/** 323/**
316* Pulseaudio initialization 324 * Pulseaudio initialization
317*/ 325 */
318void 326static void
319pa_init () 327pa_init ()
320{ 328{
321 int r; 329 int r;
@@ -365,10 +373,11 @@ pa_init ()
365 } 373 }
366} 374}
367 375
376
368/** 377/**
369* OPUS initialization 378 * OPUS initialization
370*/ 379 */
371void 380static void
372opus_init () 381opus_init ()
373{ 382{
374 int err; 383 int err;
@@ -381,6 +390,7 @@ opus_init ()
381 pcm_buffer = (float *) pa_xmalloc (frame_size * channels * sizeof (float)); 390 pcm_buffer = (float *) pa_xmalloc (frame_size * channels * sizeof (float));
382} 391}
383 392
393
384/** 394/**
385 * The main function for the playback helper. 395 * The main function for the playback helper.
386 * 396 *
@@ -394,25 +404,25 @@ main (int argc, char *argv[])
394 char readbuf[MAXLINE]; 404 char readbuf[MAXLINE];
395 struct MessageStreamTokenizer *stdin_mst; 405 struct MessageStreamTokenizer *stdin_mst;
396 406
407 GNUNET_assert (GNUNET_OK ==
408 GNUNET_log_setup ("gnunet-helper-audio-playback",
409 "WARNING",
410 NULL));
397 stdin_mst = mst_create (&stdin_receiver, NULL); 411 stdin_mst = mst_create (&stdin_receiver, NULL);
398
399 opus_init (); 412 opus_init ();
400 pa_init (); 413 pa_init ();
401
402 while (1) 414 while (1)
415 {
416 ssize_t ret = read (0, readbuf, sizeof (readbuf));
417 if (0 > ret)
403 { 418 {
404 ssize_t ret = read (0, readbuf, sizeof (readbuf)); 419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
405 420 _("Read error from STDIN: %s\n"),
406 if (0 > ret) 421 strerror (errno));
407 { 422 break;
408 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 423 }
409 _("Read error from STDIN: %s\n"), strerror (errno)); 424 mst_receive (stdin_mst, readbuf, ret);
410 break; 425 }
411 }
412
413 mst_receive (stdin_mst, readbuf, ret);
414 }
415 mst_destroy (stdin_mst); 426 mst_destroy (stdin_mst);
416
417 return 0; 427 return 0;
418} 428}