1 /*
2 buffer.c: output buffer
3
4 copyright 1997-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
6 initially written by Oliver Fromme
7
8 I (ThOr) am reviewing this file at about the same daytime as Oliver's timestamp here:
9 Mon Apr 14 03:53:18 MET DST 1997
10 - dammed night coders;-)
11
12 This has been heavily reworked to be barely recognizable for the creation of
13 libout123. There is more structure in the communication, as is necessary if
14 the libout123 functionality is offered via some API to unknown client
15 programs instead of being used from mpg123 alone. The basic idea is the same,
16 the xfermem part only sligthly modified for more synchronization, as I sensed
17 potential deadlocks. --ThOr
18 */
19
20 /*
21 Communication to the buffer is normally via xfermem_putcmd() and blocking
22 on a response, relying on the buffer process periodically checking for
23 pending commands.
24
25 For more immediate concerns, you can send SIGINT. The only result is that this
26 interrupts a current device writing operation and causes the buffer to wait
27 for a following command.
28 */
29
30 /* Needed for kill() from signal.h. */
31 #define _POSIX_SOURCE
32
33 #include "buffer.h"
34 #include "out123_int.h"
35 #include "xfermem.h"
36 #include <errno.h>
37 #include "debug.h"
38 #ifdef HAVE_SYS_WAIT_H
39 #include <sys/wait.h>
40 #endif
41 #ifdef HAVE_SIGNAL_H
42 #include <signal.h>
43 #else
44 #ifdef HAVE_SYS_SIGNAL_H
45 #include <sys/signal.h>
46 #endif
47 #endif
48
49
50 #define BUF_CMD_OPEN XF_CMD_CUSTOM1
51 #define BUF_CMD_CLOSE XF_CMD_CUSTOM2
52 #define BUF_CMD_START XF_CMD_CUSTOM3
53 #define BUF_CMD_STOP XF_CMD_CUSTOM4
54 #define BUF_CMD_AUDIOCAP XF_CMD_CUSTOM5
55 #define BUF_CMD_PARAM XF_CMD_CUSTOM6
56 #define BUF_CMD_NDRAIN XF_CMD_CUSTOM7
57 #define BUF_CMD_AUDIOFMT XF_CMD_CUSTOM8
58
59 /* TODO: Dynamically allocate that to allow multiple instances. */
60 int outburst = 32768;
61
62 /* This is static and global for the forked buffer process.
63 Another forked buffer process will have its on value. */
64 static int intflag = FALSE;
65
66 static void catch_interrupt (void)
67 {
68 intflag = TRUE;
69 }
70
71 static int read_record(out123_handle *ao
72 , int who, void **buf, byte *prebuf, int *preoff, int presize, size_t *recsize);
73 static int buffer_loop(out123_handle *ao);
74
75 static void catch_child(void)
76 {
77 /* Disabled for now. We do not really need that.
78 Rather get return status in a controlled way in buffer_exit(). */
79 /* while (waitpid(-1, NULL, WNOHANG) > 0); */
_rl_enable_paren_matching(on_or_off)80 }
81
82 /*
83 Functions called from the controlling process.
84 */
85
86 /* Start a buffer process. */
87 int buffer_init(out123_handle *ao, size_t bytes)
88 {
89 buffer_exit(ao);
90 if(bytes < outburst) bytes = 2*outburst;
91
92 #ifdef DONT_CATCH_SIGNALS
93 #error I really need to catch signals here!
94 #endif
95 xfermem_init(&ao->buffermem, bytes, 0, 0);
96 /* Is catch_child() really useful? buffer_exit() does waitpid().
97 And if buffer_exit() is not called, the main process might be
98 killed off and not be able to run a signal handler anyway. */
99 catchsignal(SIGCHLD, catch_child);
100 switch((ao->buffer_pid = fork()))
101 {
102 case -1: /* error */
103 if(!AOQUIET)
104 error("cannot fork!");
105 goto buffer_init_bad;
106 case 0: /* child */
107 {
108 int ret;
109 /*
110 Ensure the normal default value for buffer_pid to be able
111 to call normal out123 routines from the buffer proess.
112 One could keep it at zero and even use this for detecting the
113 buffer process and do special stuff for that. But the point
114 is that there shouldn't be special stuff.
115 */
116 ao->buffer_pid = -1;
117 /* Not preparing audio output anymore, that comes later. */
118 xfermem_init_reader(ao->buffermem);
119 ret = buffer_loop(ao); /* Here the work happens. */
120 xfermem_done_reader(ao->buffermem);
121 xfermem_done(ao->buffermem);
122 /* Proper cleanup of output handle, including out123_close(). */
123 out123_del(ao);
124 exit(ret);
125 }
126 default: /* parent */
127 {
128 int cmd;
129 xfermem_init_writer(ao->buffermem);
130 debug("waiting for inital pong from buffer process");
131 if( (cmd=xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE))
132 != XF_CMD_PONG )
133 {
134 if(!AOQUIET)
135 error2("Got %i instead of expected initial response %i. Killing rogue buffer process."
136 , cmd, XF_CMD_PONG);
137 kill(ao->buffer_pid, SIGKILL);
138 buffer_exit(ao);
139 return -1;
140 }
141 }
142 }
143
144 return 0;
145 buffer_init_bad:
146 if(ao->buffermem)
147 {
148 xfermem_done(ao->buffermem);
149 ao->buffermem = NULL;
150 }
151 return -1;
152 }
153
154 /* End a buffer process. */
155 void buffer_exit(out123_handle *ao)
156 {
157 int status = 0;
158 if(ao->buffer_pid == -1) return;
159
160 debug("ending buffer");
161 buffer_stop(ao); /* Puts buffer into waiting-for-command mode. */
162 buffer_end(ao); /* Gives command to end operation. */
163 xfermem_done_writer(ao->buffermem);
164 waitpid(ao->buffer_pid, &status, 0);
165 xfermem_done(ao->buffermem);
166 ao->buffermem = NULL;
167 ao->buffer_pid = -1;
168 if(WIFEXITED(status))
169 {
170 int ret = WEXITSTATUS(status);
171 if(ret && !AOQUIET)
172 error1("Buffer process isses arose, non-zero return value %i.", ret);
173 }
174 else if(!AOQUIET)
175 error("Buffer process did not exit normally.");
176 }
177
178 /*
179 Communication from writer to reader (buffer process).
180 Remember: The ao struct here is the writer's instance.
181 */
182
183 static int buffer_cmd_finish(out123_handle *ao)
184 {
185 /* Only if buffer returns XF_CMD_OK we got lucky. Otherwise, we expect
186 the buffer to deliver a reason right after XF_CMD_ERROR. */
187 switch(xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE))
188 {
189 case XF_CMD_OK: return 0;
190 case XF_CMD_ERROR:
191 if(!GOOD_READVAL(ao->buffermem->fd[XF_WRITER], ao->errcode))
192 ao->errcode = OUT123_BUFFER_ERROR;
193 return -1;
194 break;
195 default:
196 ao->errcode = OUT123_BUFFER_ERROR;
197 return -1;
198 }
199 }
200
201 int buffer_sync_param(out123_handle *ao)
202 {
203 int writerfd = ao->buffermem->fd[XF_WRITER];
204 if(xfermem_putcmd(writerfd, BUF_CMD_PARAM) != 1)
205 {
206 ao->errcode = OUT123_BUFFER_ERROR;
207 return -1;
208 }
209 /* Calling an external serialization routine to avoid forgetting
210 any fresh parameters here. */
211 if(write_parameters(ao, XF_WRITER))
212 {
213 ao->errcode = OUT123_BUFFER_ERROR;
214 return -1;
215 }
216 return buffer_cmd_finish(ao);
217 }
218
219 int buffer_open(out123_handle *ao, const char* driver, const char* device)
220 {
221 int writerfd = ao->buffermem->fd[XF_WRITER];
222
223 if(xfermem_putcmd(writerfd, BUF_CMD_OPEN) != 1)
224 {
225 ao->errcode = OUT123_BUFFER_ERROR;
226 return -1;
227 }
228 /* Passing over driver and device name. */
229 if( xfer_write_string(ao, XF_WRITER, driver)
230 || xfer_write_string(ao, XF_WRITER, device) )
231 {
232 ao->errcode = OUT123_BUFFER_ERROR;
233 return -1;
234 }
235
236 if(buffer_cmd_finish(ao) == 0)
237 /* Retrieve driver and device name. */
238 return ( xfer_read_string(ao, XF_WRITER, &ao->driver)
239 || xfer_read_string(ao, XF_WRITER, &ao->device)
240 || xfer_read_string(ao, XF_WRITER, &ao->realname) );
241 else
242 return -1;
243 }
244
245 int buffer_encodings(out123_handle *ao)
246 {
247 int writerfd = ao->buffermem->fd[XF_WRITER];
248
249 if(xfermem_putcmd(writerfd, BUF_CMD_AUDIOCAP) != 1)
250 {
251 ao->errcode = OUT123_BUFFER_ERROR;
252 return -1;
253 }
254 /* Now shoving over the parameters for opening the device. */
255 if(
256 !GOOD_WRITEVAL(writerfd, ao->channels)
257 || !GOOD_WRITEVAL(writerfd, ao->rate)
258 )
259 {
260 ao->errcode = OUT123_BUFFER_ERROR;
261 return -1;
262 }
263
264 if(buffer_cmd_finish(ao) == 0)
265 {
266 int encodings;
267 /* If all good, the answer can be read how. */
268 if(!GOOD_READVAL(writerfd, encodings))
269 {
270 ao->errcode = OUT123_BUFFER_ERROR;
271 return -1;
272 }
273 else return encodings;
274 }
275 else return -1;
276 }
277
278 int buffer_formats( out123_handle *ao, const long *rates, int ratecount
279 , int minchannels, int maxchannels
280 , struct mpg123_fmt **fmtlist )
281 {
282 int writerfd = ao->buffermem->fd[XF_WRITER];
283 size_t ratesize;
284
285 debug("buffer_formats");
286
287 if(xfermem_putcmd(writerfd, BUF_CMD_AUDIOFMT) != 1)
288 {
289 ao->errcode = OUT123_BUFFER_ERROR;
290 return -1;
291 }
292
293 ratesize = ratecount*sizeof(rates);
294
295 if(
296 !GOOD_WRITEVAL(writerfd, maxchannels)
297 || !GOOD_WRITEVAL(writerfd, minchannels)
298 || !GOOD_WRITEVAL(writerfd, ratesize)
299 || !GOOD_WRITEBUF(writerfd, rates, ratesize)
300 ){
301 ao->errcode = OUT123_BUFFER_ERROR;
302 return -1;
303 }
304 if(buffer_cmd_finish(ao) == 0)
305 {
306 int fmtcount;
307 size_t fmtsize;
308 if(
309 !GOOD_READVAL(writerfd, fmtcount)
310 || read_record(ao, XF_WRITER, (void**)fmtlist, NULL, NULL, 0, &fmtsize)
311 ){
312 ao->errcode = OUT123_BUFFER_ERROR;
313 return -1;
314 } else
315 return fmtsize/sizeof(struct mpg123_fmt);
316 }
317 else return -1;
318 }
319
320 int buffer_start(out123_handle *ao)
321 {
322 int writerfd = ao->buffermem->fd[XF_WRITER];
323 if(xfermem_putcmd(writerfd, BUF_CMD_START) != 1)
324 {
325 ao->errcode = OUT123_BUFFER_ERROR;
326 return -1;
327 }
328 /* Now shoving over the parameters for opening the device. */
329 if(
330 !GOOD_WRITEVAL(writerfd, ao->format)
331 || !GOOD_WRITEVAL(writerfd, ao->channels)
332 || !GOOD_WRITEVAL(writerfd, ao->rate)
333 )
334 {
335 ao->errcode = OUT123_BUFFER_ERROR;
336 return -1;
337 }
338
339 return buffer_cmd_finish(ao);
340 }
341
342 #define BUFFER_SIMPLE_CONTROL(name, cmd) \
343 void name(out123_handle *ao) \
344 { \
345 xfermem_putcmd(ao->buffermem->fd[XF_WRITER], cmd); \
346 xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE); \
347 }
348
349 BUFFER_SIMPLE_CONTROL(buffer_stop, BUF_CMD_STOP)
350 BUFFER_SIMPLE_CONTROL(buffer_continue, XF_CMD_CONTINUE)
351 BUFFER_SIMPLE_CONTROL(buffer_ignore_lowmem, XF_CMD_IGNLOW)
352 BUFFER_SIMPLE_CONTROL(buffer_drain, XF_CMD_DRAIN)
353 BUFFER_SIMPLE_CONTROL(buffer_end, XF_CMD_TERMINATE)
354 BUFFER_SIMPLE_CONTROL(buffer_close, BUF_CMD_CLOSE)
355
356 #define BUFFER_SIGNAL_CONTROL(name, cmd) \
357 void name(out123_handle *ao) \
358 { \
359 kill(ao->buffer_pid, SIGINT); \
360 xfermem_putcmd(ao->buffermem->fd[XF_WRITER], cmd); \
361 xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE); \
362 }
363
364 BUFFER_SIGNAL_CONTROL(buffer_pause, XF_CMD_PAUSE)
365 BUFFER_SIGNAL_CONTROL(buffer_drop, XF_CMD_DROP)
366
367 size_t buffer_fill(out123_handle *ao)
368 {
369 return xfermem_get_usedspace(ao->buffermem);
370 }
371
372 void buffer_ndrain(out123_handle *ao, size_t bytes)
373 {
374 size_t oldfill;
375 int writerfd = ao->buffermem->fd[XF_WRITER];
376
377 oldfill = buffer_fill(ao);
378 if(xfermem_putcmd(writerfd, BUF_CMD_NDRAIN) != 1)
379 {
380 ao->errcode = OUT123_BUFFER_ERROR;
381 return;
382 }
383 /* Now shoving over the parameters for opening the device. */
384 if( !GOOD_WRITEVAL(writerfd, bytes)
385 || !GOOD_WRITEVAL(writerfd, oldfill) )
386 {
387 ao->errcode = OUT123_BUFFER_ERROR;
388 return;
389 }
390
391 buffer_cmd_finish(ao);
392 }
393
394 /* The workhorse: Send data to the buffer with some synchronization and even
395 error checking. */
396 size_t buffer_write(out123_handle *ao, void *buffer, size_t bytes)
397 {
398 /*
399 Writing the whole buffer in one piece is no good as that means
400 waiting for the buffer being empty. That is called a buffer underrun.
401 We want to refill the buffer before that happens. So, what is sane?
402 */
403 size_t written = 0;
404 size_t max_piece = ao->buffermem->size / 2;
405 while(bytes)
406 {
407 size_t count_piece = bytes > max_piece
408 ? max_piece
409 : bytes;
410 int ret = xfermem_write(ao->buffermem
411 , (char*)buffer+written, count_piece);
412 if(ret)
413 {
414 if(!AOQUIET)
415 error1("writing to buffer memory failed (%i)", ret);
416 if(ret == XF_CMD_ERROR)
417 {
418 /* Buffer tells me that it has an error waiting. */
419 if(!GOOD_READVAL(ao->buffermem->fd[XF_WRITER], ao->errcode))
420 ao->errcode = OUT123_BUFFER_ERROR;
421 }
422 return 0;
423 }
424 bytes -= count_piece;
425 written += count_piece;
426 }
427 return written;
428 }
429
430
431 /*
432 Code for the buffer process itself.
433 */
434
435 /*
436
437 buffer loop:
438
439 {
440 1. normal operation: get data, feed to audio device
441 (if device open and alive, if data there, if no other command pending)
442 2. command response: pause/unpause, open module/device, query caps
443
444 One command at a time, synchronized ... writer process blocks, waiting for
445 response.
446 }
447
448 */
449
450 /*
451 Fill buffer to that value when starting playback from stopped state or after
452 experiencing a serious underrun.
453 One might also define intermediate preload to recover from underruns. Earlier
454 code used 1/8 of the buffer.
455 */
456 static size_t preload_size(out123_handle *ao)
457 {
458 size_t preload = 0;
459 txfermem *xf = ao->buffermem;
460 /* Fill configured part of buffer on first run before starting to play.
461 * Live mp3 streams constantly approach buffer underrun otherwise. [dk]
462 */
463 if(ao->preload > 0.) preload = (size_t)(ao->preload*xf->size);
464 if(preload > xf->size/2) preload = xf->size/2;
465
466 return preload;
467 }
468
469 /* Play one piece of audio from the buffer after settling preload etc.
470 On error, the device is closed and this naturally stops playback
471 as that depends on ao->state == play_live.
472 This plays _at_ _most_ the given amount of bytes, usually less. */
473 static void buffer_play(out123_handle *ao, size_t bytes)
474 {
475 size_t written;
476 txfermem *xf = ao->buffermem;
477 /* Settle amount of bytes accessible in one block. */
478 if (bytes > xf->size - xf->readindex)
479 bytes = xf->size - xf->readindex;
480 /* Not more than configured output block. */
481 if (bytes > outburst)
482 bytes = outburst;
483 /* The output can only take multiples of framesize. */
484 bytes -= bytes % ao->framesize;
485 /* Actual work by out123_play to ensure logic like automatic continue. */
486 written = out123_play(ao, (unsigned char*)xf->data+xf->readindex, bytes);
487 /* Advance read pointer by the amount of written bytes. */
488 xf->readindex = (xf->readindex + written) % xf->size;
489 /* Detect a fatal error by proxy. */
490 if(ao->errcode == OUT123_DEV_PLAY)
491 out123_close(ao);
492 }
493
494 /* Now I'm getting really paranoid: Helper to skip bytes from command
495 channel if we cannot allocate enough memory to hold the data. */
496 static void skip_bytes(int fd, size_t count)
497 {
498 while(count)
499 {
500 char buf[1024];
501 if(!unintr_read(fd, buf, (count < sizeof(buf) ? count : sizeof(buf))))
502 return;
503 }
504 }
505
506 /* Write a string to command channel.
507 Return 0 on success, set ao->errcode on issues. */
508 int xfer_write_string(out123_handle *ao, int who, const char *buf)
509 {
510 txfermem *xf = ao->buffermem;
511 int my_fd = xf->fd[who];
512 size_t len;
513
514 /* A NULL string is passed als zero bytes. */
515 len = buf ? (strlen(buf)+1) : 0;
516 if( !GOOD_WRITEVAL(my_fd, len)
517 || !GOOD_WRITEBUF(my_fd, buf, len) )
518 {
519 ao->errcode = OUT123_BUFFER_ERROR;
520 return -1;
521 }
522 return 0;
523 }
524
525
526 int xfer_read_string(out123_handle *ao, int who, char **buf)
527 {
528 /* ao->errcode set in read_record() */
529 return read_record(ao, who, (void**)buf, NULL, NULL, 0, NULL)
530 ? -1 /* read_record could return 2, normalize to -1 */
531 : 0;
532 }
533
534 /* Read a value from command channel with prebuffer.
535 This assumes responsible use and avoids needless checking of input.
536 And, yes, it modifies the preoff argument!
537 Returns 0 on success, modifies prebuffer fill. */
538 int read_buf(int fd, void *addr, size_t size, byte *prebuf, int *preoff, int presize)
539 {
540 size_t need = size;
541
542 if(prebuf)
543 {
544 int have = presize - *preoff;
545 if(have > need)
546 have = need;
547 memcpy(addr, prebuf+*preoff, have);
548 *preoff += have;
549 addr = (char*)addr+have;
550 need -= have;
551 }
552 if(need)
553 return !GOOD_READBUF(fd, addr, need);
554 else
555 return 0;
556 }
557
558
559 /* Read a record of unspecified type from command channel.
560 Return 0 on success, set ao->errcode on issues. */
561 static int read_record(out123_handle *ao
562 , int who, void **buf, byte *prebuf, int *preoff, int presize
563 , size_t *reclen)
564 {
565 txfermem *xf = ao->buffermem;
566 int my_fd = xf->fd[who];
567 size_t len;
568
569 if(*buf)
570 free(*buf);
571 *buf = NULL;
572
573 if(read_buf(my_fd, &len, sizeof(len), prebuf, preoff, presize))
574 {
575 ao->errcode = OUT123_BUFFER_ERROR;
576 return 2;
577 }
578 if(reclen)
579 *reclen = len;
580 /* If there is an insane length of given, that shall be handled. */
581 if(len && !(*buf = malloc(len)))
582 {
583 ao->errcode = OUT123_DOOM;
584 skip_bytes(my_fd, len);
585 return -1;
586 }
587 if(read_buf(my_fd, *buf, len, prebuf, preoff, presize))
588 {
589 ao->errcode = OUT123_BUFFER_ERROR;
590 free(*buf);
591 *buf = NULL;
592 return 2;
593 }
594 return 0;
595 }
596
597
598 /* The main loop, returns 0 when no issue occured. */
599 int buffer_loop(out123_handle *ao)
600 {
601 txfermem *xf = ao->buffermem;
602 int my_fd = xf->fd[XF_READER];
603 int preloading = FALSE;
604 int draining = FALSE;
605 /* The buffer loop maintains a playback state that can differ from
606 the underlying device's. During prebuffering, the device is paused,
607 but we are playing (as soon as enough data is there, the device is,
608 too). */
609 enum playstate mystate = ao->state;
610
611 ao->flags &= ~OUT123_KEEP_PLAYING; /* No need for that here. */
612 /* Be prepared to use SIGINT for communication. */
613 catchsignal (SIGINT, catch_interrupt);
614 /* sigprocmask (SIG_SETMASK, oldsigset, NULL); */
615 /* Say hello to the writer. */
616 xfermem_putcmd(my_fd, XF_CMD_PONG);
617
618 debug1("buffer with preload %g", ao->preload);
619 while(1)
620 {
621 /* If a device is opened and playing, it is our first duty to keep it playing. */
622 if(mystate == play_live)
623 {
624 size_t bytes = xfermem_get_usedspace(xf);
625 debug4( "Play or preload? Got %"SIZE_P" B / %"SIZE_P" B (%i,%i)."
626 , (size_p)bytes, (size_p)preload_size(ao), preloading, draining );
627 if(preloading)
628 preloading = (bytes < preload_size(ao));
629 if(!preloading)
630 {
631 if(!draining && bytes < outburst)
632 preloading = TRUE;
633 else
634 {
635 buffer_play(ao, bytes);
636 mystate = ao->state; /* Maybe changed, must be in sync now. */
637 }
638 }
639 /* Be nice and pause the device on preloading. */
640 if(preloading && ao->state == play_live)
641 out123_pause(ao);
642 }
643 /* Now always check for a pending command, in a blocking way if there is
644 no playback. */
645 debug2("Buffer cmd? (Interruped: %i) (mystate=%i)", intflag, (int)mystate);
646 /*
647 The writer only ever signals before sending a command and also waiting
648 for a response. So, the right place to reset the flag is any time
649 before giving the response. But let's ensure two things:
650 1. The flag really is only cleared when a command response is given.
651 2. Command parsing does not stop until a command demanding a response
652 was handled.
653 */
654 do
655 {
656 /* Getting a whole block of commands to efficiently process those
657 XF_CMD_DATA messages. */
658 byte cmd[100];
659 int cmdcount;
660 int i;
661
662 cmdcount = xfermem_getcmds( my_fd
663 , (preloading || intflag || (mystate != play_live))
664 , cmd
665 , sizeof(cmd) );
666 if(cmdcount < 0)
667 {
668 if(!AOQUIET)
669 error1("Reading a command set returned %i, my link is broken.", cmdcount);
670 return 1;
671 }
672 #ifdef DEBUG
673 for(i=0; i<cmdcount; ++i)
674 debug2("cmd[%i]=%u", i, cmd[i]);
675 #endif
676 /*
677 These actions should rely heavily on calling the normal out123
678 API functions, just with some parameter passing and error checking
679 wrapped around. If there is much code here, it is wrong.
680 */
681 for(i=0; i<cmdcount;) switch(cmd[i++])
682 {
683 #define GOOD_READVAL_BUF(fd, val) \
684 !read_buf(my_fd, &val, sizeof(val), cmd, &i, cmdcount)
685 case XF_CMD_DATA:
686 debug("got new data");
687 /* Other states should not happen. */
688 if(mystate == play_paused)
689 mystate = play_live;
690 /* When new data arrives, we are obviously not draining. */
691 draining = FALSE;
692 break;
693 case XF_CMD_PING:
694 intflag = FALSE;
695 /* Expecting ping-pong only while playing! Otherwise, the writer
696 could get stuck waiting for free space forever. */
697 if(mystate == play_live)
698 xfermem_putcmd(my_fd, XF_CMD_PONG);
699 else
700 {
701 xfermem_putcmd(my_fd, XF_CMD_ERROR);
702 if(ao->errcode == OUT123_OK)
703 ao->errcode = OUT123_NOT_LIVE;
704 if(!GOOD_WRITEVAL(my_fd, ao->errcode))
705 return 2;
706 }
707 break;
708 case BUF_CMD_PARAM:
709 intflag = FALSE;
710 /* If that does not work, communication is broken anyway and
711 writer will notice soon enough. */
712 read_parameters(ao, XF_READER, cmd, &i, cmdcount);
713 ao->flags &= ~OUT123_KEEP_PLAYING; /* No need for that here. */
714 xfermem_putcmd(my_fd, XF_CMD_OK);
715 break;
716 case BUF_CMD_OPEN:
717 {
718 char *driver = NULL;
719 char *device = NULL;
720 int success;
721
722 intflag = FALSE;
723 success = (
724 !read_record( ao, XF_READER, (void**)&driver
725 , cmd, &i, cmdcount, NULL )
726 && !read_record( ao, XF_READER, (void**)&device
727 , cmd, &i, cmdcount, NULL )
728 && !out123_open(ao, driver, device)
729 );
730 free(device);
731 free(driver);
732 draining = FALSE;
733 mystate = ao->state;
734 if(success)
735 {
736 xfermem_putcmd(my_fd, XF_CMD_OK);
737 if( xfer_write_string(ao, XF_READER, ao->driver)
738 || xfer_write_string(ao, XF_READER, ao->device)
739 || xfer_write_string(ao, XF_READER, ao->realname ) )
740 return 2;
741 }
742 else
743 {
744 xfermem_putcmd(my_fd, XF_CMD_ERROR);
745 /* Again, no sense to bitch around about communication errors,
746 just quit. */
747 if(!GOOD_WRITEVAL(my_fd, ao->errcode))
748 return 2;
749 }
750 }
751 break;
752 case BUF_CMD_CLOSE:
753 intflag = FALSE;
754 out123_close(ao);
755 draining = FALSE;
756 mystate = ao->state;
757 xfermem_putcmd(my_fd, XF_CMD_OK);
758 break;
759 case BUF_CMD_AUDIOCAP:
760 {
761 int encodings;
762
763 intflag = FALSE;
764 if(
765 !GOOD_READVAL_BUF(my_fd, ao->channels)
766 || !GOOD_READVAL_BUF(my_fd, ao->rate)
767 )
768 return 2;
769 encodings = out123_encodings(ao, ao->rate, ao->channels);
770 mystate = ao->state;
771 if(encodings >= 0)
772 {
773 xfermem_putcmd(my_fd, XF_CMD_OK);
774 if(!GOOD_WRITEVAL(my_fd, encodings))
775 return 2;
776 }
777 else
778 {
779 xfermem_putcmd(my_fd, XF_CMD_ERROR);
780 if(!GOOD_WRITEVAL(my_fd, ao->errcode))
781 return 2;
782 }
783 }
784 break;
785 case BUF_CMD_AUDIOFMT:
786 {
787 size_t blocksize;
788 long *rates = NULL;
789 int minchannels;
790 int maxchannels;
791 struct mpg123_fmt *fmtlist;
792 int fmtcount = -1;
793
794 if(
795 !GOOD_READVAL_BUF(my_fd, maxchannels)
796 || !GOOD_READVAL_BUF(my_fd, minchannels)
797 )
798 return 2;
799 if(
800 read_record( ao, XF_READER, (void**)&rates
801 , cmd, &i, cmdcount, &blocksize )
802 ){
803 xfermem_putcmd(my_fd, XF_CMD_ERROR);
804 if(!GOOD_WRITEVAL(my_fd, ao->errcode))
805 return 2;
806 }
807 fmtcount = out123_formats( ao, rates
808 , (int)(blocksize/sizeof(*rates))
809 , minchannels, maxchannels, &fmtlist );
810 mystate = ao->state;
811 free(rates);
812 if(fmtcount >= 0)
813 {
814 int success;
815
816 blocksize = sizeof(*fmtlist)*fmtcount;
817 debug2("responding with %i formats (block: %"SIZE_P")"
818 , fmtcount, (size_p)blocksize);
819 xfermem_putcmd(my_fd, XF_CMD_OK);
820 success =
821 GOOD_WRITEVAL(my_fd, fmtcount)
822 && GOOD_WRITEVAL(my_fd, blocksize)
823 && GOOD_WRITEBUF(my_fd, fmtlist, blocksize);
824 free(fmtlist);
825 if(!success)
826 return 2;
827 } else
828 {
829 xfermem_putcmd(my_fd, XF_CMD_ERROR);
830 if(!GOOD_WRITEVAL(my_fd, ao->errcode))
831 return 2;
832 }
833 }
834 break;
835 case BUF_CMD_START:
836 intflag = FALSE;
837 draining = FALSE;
838 if(
839 !GOOD_READVAL_BUF(my_fd, ao->format)
840 || !GOOD_READVAL_BUF(my_fd, ao->channels)
841 || !GOOD_READVAL_BUF(my_fd, ao->rate)
842 )
843 return 2;
844 if(!out123_start(ao, ao->rate, ao->channels, ao->format))
845 {
846 out123_pause(ao); /* Be nice, start only on buffer_play(). */
847 mystate = play_live;
848 preloading = TRUE;
849 xfermem_putcmd(my_fd, XF_CMD_OK);
850 }
851 else
852 {
853 mystate = ao->state;
854 xfermem_putcmd(my_fd, XF_CMD_ERROR);
855 if(!GOOD_WRITEVAL(my_fd, ao->errcode))
856 return 2;
857 }
858 break;
859 case BUF_CMD_STOP:
860 intflag = FALSE;
861 if(mystate == play_live)
862 { /* Drain is implied! */
863 size_t bytes;
864 while((bytes = xfermem_get_usedspace(xf)))
865 buffer_play(ao, bytes);
866 }
867 out123_stop(ao);
868 draining = FALSE;
869 mystate = ao->state;
870 xfermem_putcmd(my_fd, XF_CMD_OK);
871 break;
872 case XF_CMD_CONTINUE:
873 intflag = FALSE;
874 debug("continuing");
875 mystate = play_live; /* We'll get errors reported later if that is not right. */
876 preloading = FALSE; /* It should continue without delay. */
877 draining = FALSE; /* But outburst should be cared for. */
878 xfermem_putcmd(my_fd, XF_CMD_OK);
879 break;
880 case XF_CMD_IGNLOW:
881 intflag = FALSE;
882 preloading = FALSE;
883 xfermem_putcmd(my_fd, XF_CMD_OK);
884 break;
885 case XF_CMD_DRAIN:
886 debug("buffer drain");
887 intflag = FALSE;
888 if(mystate == play_live)
889 {
890 size_t bytes;
891 while(
892 (bytes = xfermem_get_usedspace(xf))
893 && bytes > ao->framesize
894 )
895 buffer_play(ao, bytes);
896 out123_drain(ao);
897 mystate = ao->state;
898 }
899 draining = FALSE;
900 xfermem_putcmd(my_fd, XF_CMD_OK);
901 break;
902 case BUF_CMD_NDRAIN:
903 {
904 size_t limit;
905 size_t oldfill;
906
907 debug("buffer ndrain");
908 intflag = FALSE;
909 /* Expect further calls to ndrain, avoid prebuffering. */
910 draining = TRUE;
911 preloading = FALSE;
912 if(
913 !GOOD_READVAL_BUF(my_fd, limit)
914 || !GOOD_READVAL_BUF(my_fd, oldfill)
915 )
916 return 2;
917 if(mystate == play_live)
918 {
919 size_t bytes;
920 while(
921 (bytes = xfermem_get_usedspace(xf))
922 && bytes > ao->framesize
923 && oldfill >= bytes /* paranoia, overflow would handle it anyway */
924 && (oldfill-bytes) < limit
925 )
926 buffer_play(ao, bytes > limit ? limit : bytes);
927 /* Only drain hardware if the end was reached. */
928 if(!xfermem_get_usedspace(xf))
929 {
930 out123_drain(ao);
931 mystate = ao->state;
932 draining = FALSE;
933 }
934 debug2( "buffer drained %"SIZE_P" / %"SIZE_P
935 , oldfill-bytes, limit );
936 }
937 else
938 debug("drain without playback ... not good");
939 xfermem_putcmd(my_fd, XF_CMD_OK);
940 }
941 break;
942 case XF_CMD_TERMINATE:
943 intflag = FALSE;
944 /* Will that response always reach the writer? Well, at worst,
945 it's an ignored error on xfermem_getcmd(). */
946 xfermem_putcmd(my_fd, XF_CMD_OK);
947 return 0;
948 case XF_CMD_PAUSE:
949 intflag = FALSE;
950 draining = FALSE;
951 out123_pause(ao);
952 mystate = ao->state;
953 xfermem_putcmd(my_fd, XF_CMD_OK);
954 break;
955 case XF_CMD_DROP:
956 intflag = FALSE;
957 draining = FALSE;
958 xf->readindex = xf->freeindex;
959 out123_drop(ao);
960 xfermem_putcmd(my_fd, XF_CMD_OK);
961 break;
962 default:
963 if(!AOQUIET)
964 error1("Unknown command %u encountered. Confused Suicide!", cmd[i]);
965 return 1;
966 #undef GOOD_READVAL_BUF
967 }
968 } /* Ensure that an interrupt-giving command has been received. */
969 while(intflag);
970 if(intflag && !AOQUIET)
971 error("buffer: The intflag should not be set anymore.");
972 intflag = FALSE; /* Any possible harm by _not_ ensuring that the flag is cleared here? */
973 }
974 }
975