aboutsummaryrefslogtreecommitdiff
path: root/src/conversation/gnunet-helper-audio-playback.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-03 00:05:47 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-03 00:05:47 +0000
commitf3c7f9aa97c759ff56dc65c887b87be09da877c7 (patch)
tree917584c5dcf0c78a7c41f32d9a02b558f5f7e91f /src/conversation/gnunet-helper-audio-playback.c
parent17ee77576112312de11efa52eda7fa960fb908e2 (diff)
downloadgnunet-f3c7f9aa97c759ff56dc65c887b87be09da877c7.tar.gz
gnunet-f3c7f9aa97c759ff56dc65c887b87be09da877c7.zip
-much better latency
Diffstat (limited to 'src/conversation/gnunet-helper-audio-playback.c')
-rw-r--r--src/conversation/gnunet-helper-audio-playback.c95
1 files changed, 29 insertions, 66 deletions
diff --git a/src/conversation/gnunet-helper-audio-playback.c b/src/conversation/gnunet-helper-audio-playback.c
index 74571e538..6b2a3df6d 100644
--- a/src/conversation/gnunet-helper-audio-playback.c
+++ b/src/conversation/gnunet-helper-audio-playback.c
@@ -74,11 +74,6 @@ static pa_context *context;
74static pa_stream *stream_out; 74static pa_stream *stream_out;
75 75
76/** 76/**
77 * Pulseaudio io events
78 */
79static pa_io_event *stdio_event;
80
81/**
82 * OPUS decoder 77 * OPUS decoder
83 */ 78 */
84static OpusDecoder *dec; 79static OpusDecoder *dec;
@@ -99,20 +94,9 @@ static int pcm_length;
99static int frame_size; 94static int frame_size;
100 95
101/** 96/**
102 * Audio buffer 97 * Pipe we use to signal the main loop that we are ready to receive.
103 */
104static void *buffer;
105
106/**
107 * Length of audio buffer
108 */ 98 */
109static size_t buffer_length; 99static int ready_pipe[2];
110
111/**
112 * Read index for transmit buffer
113 */
114static size_t buffer_index;
115
116 100
117/** 101/**
118 * Message callback 102 * Message callback
@@ -143,9 +127,10 @@ stdin_receiver (void *cls,
143 return GNUNET_OK; 127 return GNUNET_OK;
144 } 128 }
145 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
146 "Decoded frame\n"); 130 "Decoded frame with %u bytes\n",
131 ntohs (audio->header.size));
147 if (pa_stream_write 132 if (pa_stream_write
148 (stream_out, (uint8_t *) pcm_buffer, pcm_length, NULL, 0, 133 (stream_out, pcm_buffer, pcm_length, NULL, 0,
149 PA_SEEK_RELATIVE) < 0) 134 PA_SEEK_RELATIVE) < 0)
150 { 135 {
151 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 136 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -173,44 +158,6 @@ quit (int ret)
173 158
174 159
175/** 160/**
176 * Write some data to the stream
177 */
178static void
179do_stream_write (size_t length)
180{
181 size_t l;
182
183 GNUNET_assert (0 != length);
184 if ( (! buffer) || (! buffer_length) )
185 return;
186
187 l = length;
188 if (l > buffer_length)
189 l = buffer_length;
190 if (0 > pa_stream_write (stream_out,
191 (uint8_t *) buffer + buffer_index,
192 l,
193 NULL, 0,
194 PA_SEEK_RELATIVE))
195 {
196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
197 _("pa_stream_write() failed: %s\n"),
198 pa_strerror (pa_context_errno (context)));
199 quit (1);
200 return;
201 }
202 buffer_length -= l;
203 buffer_index += l;
204 if (! buffer_length)
205 {
206 pa_xfree (buffer);
207 buffer = NULL;
208 buffer_index = buffer_length = 0;
209 }
210}
211
212
213/**
214 * Callback when data is there for playback 161 * Callback when data is there for playback
215 */ 162 */
216static void 163static void
@@ -218,11 +165,13 @@ stream_write_callback (pa_stream * s,
218 size_t length, 165 size_t length,
219 void *userdata) 166 void *userdata)
220{ 167{
221 if (stdio_event) 168 /* unblock 'main' */
222 mainloop_api->io_enable (stdio_event, PA_IO_EVENT_INPUT); 169 if (-1 != ready_pipe[1])
223 if (!buffer) 170 {
224 return; 171 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
225 do_stream_write (length); 172 "Unblocking main loop!\n");
173 write (ready_pipe[1], "r", 1);
174 }
226} 175}
227 176
228 177
@@ -269,7 +218,7 @@ context_state_callback (pa_context * c,
269 goto fail; 218 goto fail;
270 } 219 }
271 pa_stream_set_write_callback (stream_out, 220 pa_stream_set_write_callback (stream_out,
272 stream_write_callback, 221 &stream_write_callback,
273 NULL); 222 NULL);
274 if ((p = 223 if ((p =
275 pa_stream_connect_playback (stream_out, NULL, NULL, 0, NULL, 224 pa_stream_connect_playback (stream_out, NULL, NULL, 0, NULL,
@@ -279,7 +228,7 @@ context_state_callback (pa_context * c,
279 _("pa_stream_connect_playback() failed: %s\n"), 228 _("pa_stream_connect_playback() failed: %s\n"),
280 pa_strerror (pa_context_errno (c))); 229 pa_strerror (pa_context_errno (c)));
281 goto fail; 230 goto fail;
282 } 231 }
283 break; 232 break;
284 } 233 }
285 case PA_CONTEXT_TERMINATED: 234 case PA_CONTEXT_TERMINATED:
@@ -379,17 +328,31 @@ main (int argc, char *argv[])
379 328
380 char readbuf[MAXLINE]; 329 char readbuf[MAXLINE];
381 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; 330 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
331 char c;
332 ssize_t ret;
382 333
383 GNUNET_assert (GNUNET_OK == 334 GNUNET_assert (GNUNET_OK ==
384 GNUNET_log_setup ("gnunet-helper-audio-playback", 335 GNUNET_log_setup ("gnunet-helper-audio-playback",
385 "DEBUG", 336 "DEBUG",
386 "/tmp/helper-audio-playback")); 337 "/tmp/helper-audio-playback"));
338 if (0 != pipe (ready_pipe))
339 {
340 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
341 return 1;
342 }
387 stdin_mst = GNUNET_SERVER_mst_create (&stdin_receiver, NULL); 343 stdin_mst = GNUNET_SERVER_mst_create (&stdin_receiver, NULL);
388 opus_init (); 344 opus_init ();
389 pa_init (); 345 pa_init ();
346 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
347 "Waiting for PulseAudio to be ready.\n");
348 GNUNET_assert (1 == read (ready_pipe[0], &c, 1));
349 close (ready_pipe[0]);
350 close (ready_pipe[1]);
351 ready_pipe[0] = -1;
352 ready_pipe[1] = -1;
390 while (1) 353 while (1)
391 { 354 {
392 ssize_t ret = read (0, readbuf, sizeof (readbuf)); 355 ret = read (0, readbuf, sizeof (readbuf));
393 toff += ret; 356 toff += ret;
394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
395 "Received %d bytes of audio data (total: %llu)\n", 358 "Received %d bytes of audio data (total: %llu)\n",