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