1 
2 /*
3  * alsa.c -- The Advanced Linux Sound System backend for Speech Dispatcher
4  *
5  * Copyright (C) 2005,2006 Brailcom, o.p.s.
6  * Copyright (C) 2019 Samuel Thibault <samuel.thibault@ens-lyon.org>
7  *
8  * This is free software; you can redistribute it and/or modify it under the
9  * terms of the GNU Lesser General Public License as published by the Free
10  * Software Foundation; either version 2.1, or (at your option) any later
11  * version.
12  *
13  * This software is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  *
21  * $Id: alsa.c,v 1.30 2008-10-15 17:27:32 hanke Exp $
22  */
23 
24 /* NOTE: This module uses the non-blocking write() / poll() approach to
25     alsa-lib functions.*/
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 
31 #include <stdio.h>
32 #include <sys/time.h>
33 #include <time.h>
34 #include <pthread.h>
35 #include <glib.h>
36 
37 #include <alsa/asoundlib.h>
38 #include <alsa/pcm.h>
39 
40 #define SPD_AUDIO_PLUGIN_ENTRY spd_alsa_LTX_spd_audio_plugin_get
41 #include <spd_audio_plugin.h>
42 
43 typedef struct {
44 	AudioID id;
45 	snd_pcm_t *alsa_pcm;	/* identifier of the ALSA device */
46 	snd_pcm_hw_params_t *alsa_hw_params;	/* parameters of sound */
47 	snd_pcm_sw_params_t *alsa_sw_params;	/* parameters of playback */
48 	snd_pcm_uframes_t alsa_buffer_size;
49 	pthread_mutex_t alsa_pcm_mutex;	/* mutex to guard the state of the device */
50 	pthread_mutex_t alsa_pipe_mutex;	/* mutex to guard the stop pipes */
51 	pthread_cond_t alsa_pipe_cond;	/* mutex to guard the stop pipes */
52 	int alsa_stop_pipe[2];	/* Pipe for communication about stop requests */
53 	int stop_requested;	/* Whether we want to stop */
54 	int alsa_fd_count;	/* Counter of descriptors to poll */
55 	struct pollfd *alsa_poll_fds;	/* Descriptors to poll */
56 	int alsa_opened;	/* 1 between snd_pcm_open and _close, 0 otherwise */
57 	char *alsa_device_name;	/* the name of the device to open */
58 } spd_alsa_id_t;
59 
60 static int _alsa_close(spd_alsa_id_t * id);
61 static int _alsa_open(spd_alsa_id_t * id);
62 
63 static int xrun(spd_alsa_id_t * id);
64 static int suspend(spd_alsa_id_t * id);
65 
66 static int wait_for_poll(spd_alsa_id_t * id, struct pollfd *alsa_poll_fds,
67 			 unsigned int count, int draining);
68 
69 #ifndef timersub
70 #define	timersub(a, b, result) \
71 	do { \
72 		(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
73 		(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
74 		if ((result)->tv_usec < 0) { \
75 			--(result)->tv_sec; \
76 			(result)->tv_usec += 1000000; \
77 		} \
78 	} while (0)
79 #endif
80 
81 /* Put a message into the logfile (stderr) */
82 #define MSG(level, arg...) \
83 	if(level <= alsa_log_level){ \
84 		time_t t; \
85 		struct timeval tv; \
86 		char *tstr; \
87 		t = time(NULL); \
88 		tstr = g_strdup(ctime(&t)); \
89 		tstr[strlen(tstr)-1] = 0; \
90 		gettimeofday(&tv,NULL); \
91 		fprintf(stderr," %s [%d.%06d]",tstr, (int)tv.tv_sec % 10, (int) tv.tv_usec); \
92 		fprintf(stderr," ALSA: "); \
93 		fprintf(stderr,arg); \
94 		fprintf(stderr,"\n"); \
95 		fflush(stderr); \
96 		g_free(tstr); \
97 	}
98 
99 #define ERR(arg...) \
100 	{ \
101 		time_t t; \
102 		struct timeval tv; \
103 		char *tstr; \
104 		t = time(NULL); \
105 		tstr = g_strdup(ctime(&t)); \
106 		tstr[strlen(tstr)-1] = 0; \
107 		gettimeofday(&tv,NULL); \
108 		fprintf(stderr," %s [%d]",tstr, (int) tv.tv_usec); \
109 		fprintf(stderr," ALSA ERROR: "); \
110 		fprintf(stderr,arg); \
111 		fprintf(stderr,"\n"); \
112 		fflush(stderr); \
113 		g_free(tstr); \
114 	}
115 
116 static int alsa_log_level;
117 static char const *alsa_play_cmd = "aplay";
118 
119 /* I/O error handler */
xrun(spd_alsa_id_t * id)120 static int xrun(spd_alsa_id_t * id)
121 {
122 	snd_pcm_status_t *status;
123 	int res;
124 
125 	if (id == NULL)
126 		return -1;
127 
128 	MSG(1, "WARNING: Entering XRUN handler");
129 
130 	snd_pcm_status_alloca(&status);
131 	if ((res = snd_pcm_status(id->alsa_pcm, status)) < 0) {
132 		ERR("status error: %s", snd_strerror(res));
133 
134 		return -1;
135 	}
136 	if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {
137 		struct timeval now, diff, tstamp;
138 		gettimeofday(&now, 0);
139 		snd_pcm_status_get_trigger_tstamp(status, &tstamp);
140 		timersub(&now, &tstamp, &diff);
141 		MSG(1, "underrun!!! (at least %.3f ms long)",
142 		    diff.tv_sec * 1000 + diff.tv_usec / 1000.0);
143 		if ((res = snd_pcm_prepare(id->alsa_pcm)) < 0) {
144 			ERR("xrun: prepare error: %s", snd_strerror(res));
145 
146 			return -1;
147 		}
148 
149 		return 0;	/* ok, data should be accepted again */
150 	}
151 	ERR("read/write error, state = %s",
152 	    snd_pcm_state_name(snd_pcm_status_get_state(status)));
153 
154 	return -1;
155 }
156 
157 /* I/O suspend handler */
suspend(spd_alsa_id_t * id)158 static int suspend(spd_alsa_id_t * id)
159 {
160 	int res;
161 
162 	MSG(1, "WARNING: Entering SUSPEND handler.");
163 
164 	if (id == NULL)
165 		return -1;
166 
167 	while ((res = snd_pcm_resume(id->alsa_pcm)) == -EAGAIN)
168 		sleep(1);	/* wait until suspend flag is released */
169 
170 	if (res < 0) {
171 		if ((res = snd_pcm_prepare(id->alsa_pcm)) < 0) {
172 			ERR("suspend: prepare error: %s", snd_strerror(res));
173 
174 			return -1;
175 		}
176 	}
177 
178 	return 0;
179 }
180 
181 /* Open the device so that it's ready for playing on the default
182    device. Internal function used by the public alsa_open. */
_alsa_open(spd_alsa_id_t * id)183 static int _alsa_open(spd_alsa_id_t * id)
184 {
185 	int err;
186 
187 	MSG(1, "Opening ALSA device");
188 	fflush(stderr);
189 
190 	/* Open the device */
191 	if ((err = snd_pcm_open(&id->alsa_pcm, id->alsa_device_name,
192 				SND_PCM_STREAM_PLAYBACK,
193 				SND_PCM_NONBLOCK)) < 0) {
194 		ERR("Cannot open audio device %s (%s)", id->alsa_device_name,
195 		    snd_strerror(err));
196 		return -1;
197 	}
198 
199 	/* Allocate space for hw_params (description of the sound parameters) */
200 	/* Allocate space for sw_params (description of the sound parameters) */
201 	MSG(2, "Allocating new sw_params structure");
202 	if ((err = snd_pcm_sw_params_malloc(&id->alsa_sw_params)) < 0) {
203 		ERR("Cannot allocate hardware parameter structure (%s)",
204 		    snd_strerror(err));
205 		return -1;
206 	}
207 
208 	MSG(1, "Opening ALSA device ... success");
209 
210 	return 0;
211 }
212 
213 /*
214    Close the device. Internal function used by public alsa_close.
215 */
216 
_alsa_close(spd_alsa_id_t * id)217 static int _alsa_close(spd_alsa_id_t * id)
218 {
219 	int err;
220 
221 	MSG(1, "Closing ALSA device");
222 
223 	pthread_mutex_lock(&id->alsa_pipe_mutex);
224 
225 	if (id->alsa_opened == 0) {
226 		pthread_mutex_unlock(&id->alsa_pipe_mutex);
227 		return 0;
228 	}
229 
230 	id->alsa_opened = 0;
231 
232 	if ((err = snd_pcm_close(id->alsa_pcm)) < 0) {
233 		MSG(2, "Cannot close ALSA device (%s)", snd_strerror(err));
234 		pthread_mutex_unlock(&id->alsa_pipe_mutex);
235 		return -1;
236 	}
237 
238 	snd_pcm_sw_params_free(id->alsa_sw_params);
239 
240 	g_free(id->alsa_poll_fds);
241 	pthread_mutex_unlock(&id->alsa_pipe_mutex);
242 
243 	MSG(1, "Closing ALSA device ... success");
244 
245 	return 0;
246 }
247 
248 /* Open ALSA for playback.
249 
250   These parameters are passed in pars:
251   (char*) pars[0] ... null-terminated string containing the name
252                       of the device to be used for sound output
253                       on ALSA
254   (void*) pars[1] ... =NULL
255 */
alsa_open(void ** pars)256 static AudioID *alsa_open(void **pars)
257 {
258 	spd_alsa_id_t *alsa_id;
259 	int ret;
260 
261 	if (pars[1] == NULL) {
262 		ERR("Can't open ALSA sound output, missing parameters in argument.");
263 		return NULL;
264 	}
265 
266 	alsa_id = (spd_alsa_id_t *) g_malloc(sizeof(spd_alsa_id_t));
267 
268 	pthread_mutex_init(&alsa_id->alsa_pipe_mutex, NULL);
269 	pthread_cond_init(&alsa_id->alsa_pipe_cond, NULL);
270 
271 	alsa_id->alsa_opened = 0;
272 
273 	MSG(1, "Opening ALSA sound output");
274 
275 	alsa_id->alsa_device_name = g_strdup(pars[1]);
276 
277 	ret = _alsa_open(alsa_id);
278 	if (ret) {
279 		ERR("Cannot initialize Alsa device '%s': Can't open.",
280 		    alsa_id->alsa_device_name);
281 		g_free(alsa_id);
282 		return NULL;
283 	}
284 
285 	MSG(1, "Device '%s' initialized successfully.",
286 	    alsa_id->alsa_device_name);
287 
288 	return (AudioID *) alsa_id;
289 }
290 
291 /* Close ALSA */
alsa_close(AudioID * id)292 static int alsa_close(AudioID * id)
293 {
294 	int err;
295 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
296 
297 	/* Close device */
298 	if ((err = _alsa_close(alsa_id)) < 0) {
299 		ERR("Cannot close audio device");
300 		return -1;
301 	}
302 	MSG(1, "ALSA closed.");
303 
304 	g_free(alsa_id->alsa_device_name);
305 	g_free(alsa_id);
306 	id = NULL;
307 
308 	return 0;
309 }
310 
311 /* Wait until ALSA is readdy for more samples or alsa_stop() was called.
312 
313 Returns 0 if ALSA is ready for more input, +1 if a request to stop
314 the sound output was received and a negative value on error.  */
315 
wait_for_poll(spd_alsa_id_t * id,struct pollfd * alsa_poll_fds,unsigned int count,int draining)316 int wait_for_poll(spd_alsa_id_t * id, struct pollfd *alsa_poll_fds,
317 		  unsigned int count, int draining)
318 {
319 	unsigned short revents;
320 	snd_pcm_state_t state;
321 	int ret;
322 
323 	//      MSG("Waiting for poll");
324 
325 	/* Wait for certain events */
326 	while (1) {
327 		ret = poll(id->alsa_poll_fds, count, -1);
328 		//      MSG("wait_for_poll: activity on %d descriptors", ret);
329 
330 		/* Check for stop request from alsa_stop on the last file
331 		   descriptors */
332 		revents = id->alsa_poll_fds[count - 1].revents;
333 		if (0 != revents) {
334 			if (revents & POLLIN) {
335 				MSG(4, "wait_for_poll: stop requested");
336 				return 1;
337 			}
338 		}
339 
340 		/* Check the first count-1 descriptors for ALSA events */
341 		snd_pcm_poll_descriptors_revents(id->alsa_pcm,
342 						 id->alsa_poll_fds, count - 1,
343 						 &revents);
344 
345 		/* Ensure we are in the right state */
346 		state = snd_pcm_state(id->alsa_pcm);
347 		//      MSG("State after poll returned is %s", snd_pcm_state_name(state));
348 
349 		if (SND_PCM_STATE_XRUN == state) {
350 			if (!draining) {
351 				MSG(1, "WARNING: Buffer underrun detected!");
352 				if (xrun(id) != 0)
353 					return -1;
354 				return 0;
355 			} else {
356 				MSG(4, "Poll: Playback terminated");
357 				return 0;
358 			}
359 		}
360 
361 		if (SND_PCM_STATE_SUSPENDED == state) {
362 			MSG(1, "WARNING: Suspend detected!");
363 			if (suspend(id) != 0)
364 				return -1;
365 			return 0;
366 		}
367 
368 		/* Check for errors */
369 		if (revents & POLLERR) {
370 			MSG(4, "wait_for_poll: poll revents says POLLERR");
371 			return -EIO;
372 		}
373 
374 		/* Is ALSA ready for more input? */
375 		if ((revents & POLLOUT)) {
376 			MSG(5, "Poll: Ready for more input");
377 			return 0;
378 		}
379 	}
380 }
381 
382 #define ERROR_EXIT() do {\
383 	g_free(track_volume.samples); \
384 	ERR("alsa_play() abnormal exit"); \
385 	_alsa_close(alsa_id); \
386 	return -1; \
387 } while (0)
388 
389 /* Configure ALSA playback for the given configuration of track
390    But do not play anything yet */
alsa_begin(AudioID * id,AudioTrack track)391 static int alsa_begin(AudioID * id, AudioTrack track)
392 {
393 	snd_pcm_format_t format;
394 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
395 
396 	int err;
397 
398 	snd_pcm_uframes_t period_size;
399 	unsigned int sr;
400 
401 	snd_pcm_state_t state;
402 
403 	struct pollfd alsa_stop_pipe_pfd;
404 
405 	if (alsa_id == NULL) {
406 		ERR("Invalid device passed to alsa_play()");
407 		return -1;
408 	}
409 
410 	pthread_mutex_lock(&alsa_id->alsa_pipe_mutex);
411 
412 	MSG(2, "Start of playback on ALSA");
413 
414 	/* Is it not an empty track? */
415 	/* Passing an empty track is not an error */
416 	if (track.samples == NULL) {
417 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
418 		return 0;
419 	}
420 	/* Allocate space for hw_params (description of the sound parameters) */
421 	MSG(2, "Allocating new hw_params structure");
422 	if ((err = snd_pcm_hw_params_malloc(&alsa_id->alsa_hw_params)) < 0) {
423 		ERR("Cannot allocate hardware parameter structure (%s)",
424 		    snd_strerror(err));
425 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
426 		return -1;
427 	}
428 
429 	/* Initialize hw_params on our pcm */
430 	if ((err =
431 	     snd_pcm_hw_params_any(alsa_id->alsa_pcm,
432 				   alsa_id->alsa_hw_params)) < 0) {
433 		ERR("Cannot initialize hardware parameter structure (%s)",
434 		    snd_strerror(err));
435 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
436 		return -1;
437 	}
438 
439 	/* Create the pipe for communication about stop requests */
440 	if (pipe(alsa_id->alsa_stop_pipe)) {
441 		ERR("Stop pipe creation failed (%s)", strerror(errno));
442 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
443 		return -1;
444 	}
445 	alsa_id->stop_requested = 0;
446 
447 	/* Find how many descriptors we will get for poll() */
448 	alsa_id->alsa_fd_count =
449 	    snd_pcm_poll_descriptors_count(alsa_id->alsa_pcm);
450 	if (alsa_id->alsa_fd_count <= 0) {
451 		ERR("Invalid poll descriptors count returned from ALSA.");
452 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
453 		return -1;
454 	}
455 
456 	/* Create and fill in struct pollfd *alsa_poll_fds with ALSA descriptors */
457 	alsa_id->alsa_poll_fds =
458 	    g_malloc((alsa_id->alsa_fd_count + 1) * sizeof(struct pollfd));
459 	assert(alsa_id->alsa_poll_fds);
460 	if ((err =
461 	     snd_pcm_poll_descriptors(alsa_id->alsa_pcm, alsa_id->alsa_poll_fds,
462 				      alsa_id->alsa_fd_count)) < 0) {
463 		ERR("Unable to obtain poll descriptors for playback: %s\n",
464 		    snd_strerror(err));
465 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
466 		return -1;
467 	}
468 
469 	/* Create a new pollfd structure for requests by alsa_stop() */
470 	alsa_stop_pipe_pfd.fd = alsa_id->alsa_stop_pipe[0];
471 	alsa_stop_pipe_pfd.events = POLLIN;
472 	alsa_stop_pipe_pfd.revents = 0;
473 
474 	/* Join this our own pollfd to the ALSAs ones */
475 	alsa_id->alsa_poll_fds[alsa_id->alsa_fd_count] = alsa_stop_pipe_pfd;
476 	alsa_id->alsa_fd_count++;
477 
478 	alsa_id->alsa_opened = 1;
479 	pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
480 
481 	/* Report current state */
482 	state = snd_pcm_state(alsa_id->alsa_pcm);
483 	MSG(4, "PCM state before setting audio parameters: %s",
484 	    snd_pcm_state_name(state));
485 
486 	/* Choose the correct format */
487 	if (track.bits == 16) {
488 		switch (alsa_id->id.format) {
489 		case SPD_AUDIO_LE:
490 			format = SND_PCM_FORMAT_S16_LE;
491 			break;
492 		case SPD_AUDIO_BE:
493 			format = SND_PCM_FORMAT_S16_BE;
494 			break;
495 		default:
496 			ERR("unknown audio format (%d)", alsa_id->id.format);
497 			return -1;
498 		}
499 	} else if (track.bits == 8) {
500 		format = SND_PCM_FORMAT_S8;
501 	} else {
502 		ERR("Unsupported sound data format, track.bits = %d",
503 		    track.bits);
504 		return -1;
505 	}
506 
507 	/* Set access mode, bitrate, sample rate and channels */
508 	MSG(4, "Setting access type to INTERLEAVED");
509 	if ((err = snd_pcm_hw_params_set_access(alsa_id->alsa_pcm,
510 						alsa_id->alsa_hw_params,
511 						SND_PCM_ACCESS_RW_INTERLEAVED)
512 	    ) < 0) {
513 		ERR("Cannot set access type (%s)", snd_strerror(err));
514 		return -1;
515 	}
516 
517 	MSG(4, "Setting sample format to %s", snd_pcm_format_name(format));
518 	if ((err =
519 	     snd_pcm_hw_params_set_format(alsa_id->alsa_pcm,
520 					  alsa_id->alsa_hw_params,
521 					  format)) < 0) {
522 		ERR("Cannot set sample format (%s)", snd_strerror(err));
523 		return -1;
524 	}
525 
526 	MSG(4, "Setting sample rate to %i", track.sample_rate);
527 	sr = track.sample_rate;
528 	if ((err =
529 	     snd_pcm_hw_params_set_rate_near(alsa_id->alsa_pcm,
530 					     alsa_id->alsa_hw_params, &sr,
531 					     0)) < 0) {
532 		ERR("Cannot set sample rate (%s)", snd_strerror(err));
533 
534 		return -1;
535 	}
536 
537 	MSG(4, "Setting channel count to %i", track.num_channels);
538 	if ((err =
539 	     snd_pcm_hw_params_set_channels(alsa_id->alsa_pcm,
540 					    alsa_id->alsa_hw_params,
541 					    track.num_channels)) < 0) {
542 		MSG(4, "cannot set channel count (%s)", snd_strerror(err));
543 		return -1;
544 	}
545 
546 	MSG(4, "Setting hardware parameters on the ALSA device");
547 	if ((err =
548 	     snd_pcm_hw_params(alsa_id->alsa_pcm,
549 			       alsa_id->alsa_hw_params)) < 0) {
550 		MSG(4, "cannot set parameters (%s) state=%s", snd_strerror(err),
551 		    snd_pcm_state_name(snd_pcm_state(alsa_id->alsa_pcm)));
552 		return -1;
553 	}
554 
555 	/* Get the current swparams */
556 	if ((err =
557 	     snd_pcm_sw_params_current(alsa_id->alsa_pcm,
558 				       alsa_id->alsa_sw_params)) < 0) {
559 		ERR("Unable to determine current swparams for playback: %s\n",
560 		    snd_strerror(err));
561 		return -1;
562 	}
563 	//    MSG("Checking buffer size");
564 	if ((err =
565 	     snd_pcm_hw_params_get_buffer_size(alsa_id->alsa_hw_params,
566 					       &(alsa_id->alsa_buffer_size))) <
567 	    0) {
568 		ERR("Unable to get buffer size for playback: %s\n",
569 		    snd_strerror(err));
570 		return -1;
571 	}
572 	MSG(4, "Buffer size on ALSA device is %d frames",
573 	    (int)alsa_id->alsa_buffer_size);
574 
575 	/* This is probably better left for the device driver to decide */
576 	/* allow the transfer when at least period_size samples can be processed */
577 	/*    err = snd_pcm_sw_params_set_avail_min(id->alsa_pcm, id->alsa_sw_params, id->alsa_buffer_size/4);
578 	   if (err < 0) {
579 	   ERR("Unable to set avail min for playback: %s\n", snd_strerror(err));
580 	   return err;
581 	   } */
582 
583 	/* Get period size. */
584 	snd_pcm_hw_params_get_period_size(alsa_id->alsa_hw_params, &period_size,
585 	                                  0);
586 	MSG(4, "Period size on ALSA device is %lu frames", (unsigned long) period_size);
587 
588 	MSG(4, "Preparing device for playback");
589 	if ((err = snd_pcm_prepare(alsa_id->alsa_pcm)) < 0) {
590 		ERR("Cannot prepare audio interface for playback (%s)",
591 		    snd_strerror(err));
592 
593 		return -1;
594 	}
595 
596 	return 0;
597 }
598 
599 /* Push audio track to ALSA playback */
alsa_feed(AudioID * id,AudioTrack track)600 static int alsa_feed(AudioID * id, AudioTrack track)
601 {
602 	int bytes_per_sample;
603 	int num_bytes;
604 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
605 
606 	AudioTrack track_volume;
607 	float real_volume;
608 	int i;
609 
610 	signed short *output_samples;
611 
612 	int err;
613 	int ret;
614 
615 	snd_pcm_state_t state;
616 
617 	snd_pcm_uframes_t framecount;
618 	size_t volume_size;
619 
620 	bytes_per_sample = track.bits / 8;
621 
622 	/* Calculate space needed to round up to nearest period size. */
623 	volume_size = bytes_per_sample * track.num_samples;
624 	MSG(4, "volume size = %i", (int)volume_size);
625 
626 	/* Create a copy of track with adjusted volume. */
627 	MSG(4, "Making copy of track and adjusting volume");
628 	track_volume = track;
629 	track_volume.samples = (short *)g_malloc(volume_size);
630 	real_volume = ((float)alsa_id->id.volume + 100) / (float)200;
631 	for (i = 0; i <= track.num_samples - 1; i++)
632 		track_volume.samples[i] = track.samples[i] * real_volume;
633 
634 	/* Loop until all samples are played on the device. */
635 	output_samples = track_volume.samples;
636 	num_bytes = volume_size;
637 	MSG(4, "%d bytes to be played", num_bytes);
638 	while (num_bytes > 0) {
639 
640 		/* Write as much samples as possible */
641 		framecount = num_bytes / bytes_per_sample / track.num_channels;
642 
643 		/* Report current state state */
644 		state = snd_pcm_state(alsa_id->alsa_pcm);
645 		//      MSG("PCM state before writei: %s",
646 		//          snd_pcm_state_name(state));
647 
648 		/* MSG("snd_pcm_writei() called") */
649 		ret =
650 		    snd_pcm_writei(alsa_id->alsa_pcm, output_samples,
651 				   framecount);
652 		if (ret >= 0)
653 			MSG(5, "Sent %d of %d remaining bytes", ret*bytes_per_sample*track.num_channels, num_bytes);
654 
655 		if (ret == -EAGAIN) {
656 			MSG(4, "Warning: Forced wait!");
657 			snd_pcm_wait(alsa_id->alsa_pcm, 100);
658 		} else if (ret == -EPIPE) {
659 			MSG(4, "Warning: returned EPIPE!");
660 			if (xrun(alsa_id) != 0)
661 				ERROR_EXIT();
662 #ifdef ESTRPIPE
663 		} else if (ret == -ESTRPIPE) {
664 			MSG(4, "Warning: returned ESTRPIPE!");
665 			if (suspend(alsa_id) != 0)
666 				ERROR_EXIT();
667 #endif
668 		} else if (ret == -EBUSY) {
669 			MSG(4, "WARNING: sleeping while PCM BUSY");
670 			usleep(100);
671 			continue;
672 		} else if (ret < 0) {
673 			ERR("Write to audio interface failed (%s)",
674 			    snd_strerror(ret));
675 			ERROR_EXIT();
676 		}
677 
678 		if (ret > 0) {
679 			/* Update counter of bytes left and move the data pointer */
680 			num_bytes -=
681 			    ret * bytes_per_sample * track.num_channels;
682 			output_samples +=
683 			    ret * bytes_per_sample * track.num_channels / 2;
684 		}
685 
686 		/* Report current state */
687 		state = snd_pcm_state(alsa_id->alsa_pcm);
688 		//      MSG("PCM state before polling: %s",
689 		//          snd_pcm_state_name(state));
690 
691 		err =
692 		    wait_for_poll(alsa_id, alsa_id->alsa_poll_fds,
693 				  alsa_id->alsa_fd_count, 0);
694 		if (err < 0) {
695 			ERR("Wait for poll() failed\n");
696 			ERROR_EXIT();
697 		} else if (err == 1) {
698 			MSG(4, "Playback stopped");
699 
700 			/* Drop the playback on the sound device (probably
701 			   still in progress up till now) */
702 			err = snd_pcm_drop(alsa_id->alsa_pcm);
703 			if (err < 0) {
704 				ERR("snd_pcm_drop() failed: %s",
705 				    snd_strerror(err));
706 				return -1;
707 			}
708 
709 			/* Terminating (successfully or after a stop) */
710 			goto terminate;
711 		}
712 
713 		if (num_bytes <= 0)
714 			break;
715 //      MSG("ALSA ready for more samples");
716 
717 		/* Stop requests can be issued again */
718 	}
719 
720 terminate:
721 	if (track_volume.samples != NULL)
722 		g_free(track_volume.samples);
723 
724 	return 0;
725 }
726 
727 /* Drain ALSA playback until only `left' samples are left in the buffer */
alsa_drain_left(AudioID * id,snd_pcm_uframes_t left)728 static int alsa_drain_left(AudioID * id, snd_pcm_uframes_t left)
729 {
730 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
731 
732 	int err;
733 
734 	MSG(4, "Draining until %lu frames left...", (unsigned long) left);
735 
736 	/* We want to get next "device ready" notification only after the buffer
737 	   is already empty */
738 	err =
739 	    snd_pcm_sw_params_set_avail_min(alsa_id->alsa_pcm,
740 					    alsa_id->alsa_sw_params,
741 					    alsa_id->alsa_buffer_size - left);
742 	if (err < 0) {
743 		ERR("Unable to set avail min for playback: %s\n",
744 		    snd_strerror(err));
745 		return err;
746 	}
747 	/* write the parameters to the playback device */
748 	err = snd_pcm_sw_params(alsa_id->alsa_pcm, alsa_id->alsa_sw_params);
749 	if (err < 0) {
750 		ERR("Unable to set sw params for playback: %s\n",
751 		    snd_strerror(err));
752 		return -1;
753 	}
754 
755 	err =
756 	    wait_for_poll(alsa_id, alsa_id->alsa_poll_fds,
757 			  alsa_id->alsa_fd_count, 1);
758 	if (err < 0) {
759 		ERR("Wait for poll() failed\n");
760 		return -1;
761 	} else if (err == 1) {
762 		MSG(4, "Playback stopped while draining");
763 
764 		/* Drop the playback on the sound device (probably
765 		   still in progress up till now) */
766 		err = snd_pcm_drop(alsa_id->alsa_pcm);
767 		if (err < 0) {
768 			ERR("snd_pcm_drop() failed: %s", snd_strerror(err));
769 			return -1;
770 		}
771 	}
772 
773 	/* When ALSA is going through Pulseaudio, wait_for_poll returns too
774 	   early because the file descriptor is always availble for writing
775 	   :/ */
776 	while (!alsa_id->stop_requested)
777 	{
778 		snd_pcm_sframes_t frames;
779 		snd_pcm_state_t state;
780 		struct timeval tv;
781 		struct timespec ts;
782 
783 		/* Poll server */
784 		frames = snd_pcm_avail(alsa_id->alsa_pcm);
785 		if (frames < 0) {
786 			MSG(4, "Drain: Buffer clear");
787 			break;
788 		}
789 
790 		MSG(5, "Drain: %lu frames left in buffer",
791 			(unsigned long) alsa_id->alsa_buffer_size - frames);
792 		if (alsa_id->alsa_buffer_size - frames <= left) {
793 			MSG(4, "Drain: Buffer clear enough");
794 			break;
795 		}
796 
797 		state = snd_pcm_state(alsa_id->alsa_pcm);
798 		if (err != 0) {
799 			MSG(4, "Drain: Status error %d", err);
800 			break;
801 		}
802 		if (state == SND_PCM_STATE_XRUN) {
803 			MSG(4, "Drain: Playback terminated");
804 			break;
805 		}
806 
807 		/* Poll every 10ms */
808 		gettimeofday(&tv, NULL);
809 		ts.tv_sec = tv.tv_sec;
810 		ts.tv_nsec = tv.tv_usec * 1000 + 10000000;
811 		if (ts.tv_nsec >= 1000000000) {
812 			ts.tv_sec += 1;
813 			ts.tv_nsec -= 1000000000;
814 		}
815 
816 		pthread_mutex_lock(&alsa_id->alsa_pipe_mutex);
817 		if (!alsa_id->stop_requested)
818 			pthread_cond_timedwait(&alsa_id->alsa_pipe_cond,
819 					       &alsa_id->alsa_pipe_mutex, &ts);
820 		pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
821 	}
822 
823 	MSG(4, "Draining terminated");
824 
825 	return 0;
826 }
827 
828 /* Drain until the amount of samples left in the buffer is big enough to make
829    sure we will have time to push the rest of the audio */
alsa_drain_overlap(AudioID * id,AudioTrack track)830 static int alsa_drain_overlap(AudioID * id, AudioTrack track)
831 {
832 	/* We typically want 20ms overlap: usually about a period size, and
833 	   small enough to be unnoticeable */
834 	unsigned min_ms = 20;
835 
836 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
837 	snd_pcm_uframes_t min;
838 	snd_pcm_uframes_t period_size;
839 	snd_pcm_uframes_t min2;
840 	snd_pcm_uframes_t left;
841 
842 	min = (min_ms * track.sample_rate) / 1000;
843 
844 	/* Get period size. */
845 	snd_pcm_hw_params_get_period_size(alsa_id->alsa_hw_params, &period_size,
846 	                                  0);
847 
848 	/* Round minimum to two period size */
849 	if (2*period_size >= min)
850 		min2 = 2*period_size;
851 	else
852 		min2 = (min + period_size - 1) / period_size;
853 
854 	/* Usually the buffer size will be far enough */
855 	if (alsa_id->alsa_buffer_size >= min2)
856 		left = min2;
857 	else
858 		/* That's very odd. Just wait for some room to be available */
859 		left = alsa_id->alsa_buffer_size - 1;
860 
861 	MSG(4, "Draining with at least %ums left, i.e. %lu frames, with period %lu frames, thus %lu frames, i.e. %lu left of %lu",
862 		min_ms, (unsigned long) min, (unsigned long) period_size,
863 		(unsigned long) min2, (unsigned long) left, (unsigned long)
864 		alsa_id->alsa_buffer_size);
865 
866 	return alsa_drain_left(id, left);
867 }
868 
alsa_drain(AudioID * id)869 static int alsa_drain(AudioID * id)
870 {
871 	return alsa_drain_left(id, 0);
872 }
873 
alsa_feed_sync(AudioID * id,AudioTrack track)874 static int alsa_feed_sync(AudioID * id, AudioTrack track)
875 {
876 	int ret;
877 
878 	ret = alsa_feed(id, track);
879 	if (ret)
880 		return ret;
881 
882 	return alsa_drain(id);
883 }
884 
alsa_feed_sync_overlap(AudioID * id,AudioTrack track)885 static int alsa_feed_sync_overlap(AudioID * id, AudioTrack track)
886 {
887 	int ret;
888 
889 	ret = alsa_feed(id, track);
890 	if (ret)
891 		return ret;
892 
893 	return alsa_drain_overlap(id, track);
894 }
895 
alsa_end(AudioID * id)896 static int alsa_end(AudioID * id)
897 {
898 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
899 	int err;
900 
901 	if (!alsa_id->stop_requested)
902 		alsa_drain(id);
903 
904 	err = snd_pcm_drop(alsa_id->alsa_pcm);
905 	if (err < 0) {
906 		ERR("snd_pcm_drop() failed: %s", snd_strerror(err));
907 		return -1;
908 	}
909 
910 	MSG(2, "Freeing HW parameters");
911 	snd_pcm_hw_params_free(alsa_id->alsa_hw_params);
912 
913 	pthread_mutex_lock(&alsa_id->alsa_pipe_mutex);
914 	alsa_id->alsa_opened = 0;
915 	close(alsa_id->alsa_stop_pipe[0]);
916 	close(alsa_id->alsa_stop_pipe[1]);
917 
918 	g_free(alsa_id->alsa_poll_fds);
919 	pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
920 
921 	MSG(1, "End of playback on ALSA");
922 
923 	return 0;
924 }
925 
926 /* Play the track _track_ (see spd_audio.h) using the id->alsa_pcm device and
927  id-hw_params parameters. This is a blocking function, however, it's possible
928  to interrupt playing from a different thread with alsa_stop(). alsa_play
929  returns after and immediatelly after the whole sound was played on the
930  speakers.
931 
932  The idea is that we get the ALSA file descriptors and we will poll() to see
933  when alsa is ready for more input while sleeping in the meantime. We will
934  additionally poll() for one more descriptor used by alsa_stop() to notify the
935  thread with alsa_play() that the stop of the playback is requested. The
936  variable can_be_stopped is used for very simple synchronization between the
937  two threads. */
alsa_play(AudioID * id,AudioTrack track)938 static int alsa_play(AudioID * id, AudioTrack track)
939 {
940 	int ret;
941 
942 	ret = alsa_begin(id, track);
943 	if (ret)
944 		return ret;
945 
946 	ret = alsa_feed_sync(id, track);
947 	if (ret)
948 		return ret;
949 
950 	return alsa_end(id);
951 }
952 
953 #undef ERROR_EXIT
954 
955 /*
956  Stop the playback on the device and interrupt alsa_play()
957 */
alsa_stop(AudioID * id)958 static int alsa_stop(AudioID * id)
959 {
960 	char buf;
961 	int ret;
962 	spd_alsa_id_t *alsa_id = (spd_alsa_id_t *) id;
963 
964 	MSG(1, "STOP!");
965 
966 	if (alsa_id == NULL)
967 		return 0;
968 
969 	pthread_mutex_lock(&alsa_id->alsa_pipe_mutex);
970 	if (alsa_id->alsa_opened) {
971 		alsa_id->stop_requested = 1;
972 
973 		/* This constant is arbitrary */
974 		buf = 42;
975 
976 		ret = write(alsa_id->alsa_stop_pipe[1], &buf, 1);
977 		if (ret <= 0) {
978 			ERR("Can't write stop request to pipe, err %d: %s",
979 			    errno, strerror(errno));
980 		}
981 		pthread_cond_broadcast(&alsa_id->alsa_pipe_cond);
982 	}
983 	pthread_mutex_unlock(&alsa_id->alsa_pipe_mutex);
984 
985 	return 0;
986 }
987 
988 /*
989   Set volume
990 
991   Comments: It's not possible to set individual track volume with Alsa, so we
992    handle volume in alsa_play() by multiplication of each sample.
993 */
alsa_set_volume(AudioID * id,int volume)994 static int alsa_set_volume(AudioID * id, int volume)
995 {
996 	return 0;
997 }
998 
alsa_set_loglevel(int level)999 static void alsa_set_loglevel(int level)
1000 {
1001 	if (level) {
1002 		alsa_log_level = level;
1003 	}
1004 }
1005 
alsa_get_playcmd(void)1006 static char const *alsa_get_playcmd(void)
1007 {
1008 	return alsa_play_cmd;
1009 }
1010 
1011 /* Provide the Alsa backend. */
1012 static spd_audio_plugin_t alsa_functions = {
1013 	"alsa",
1014 	alsa_open,
1015 	alsa_play,
1016 	alsa_stop,
1017 	alsa_close,
1018 	alsa_set_volume,
1019 	alsa_set_loglevel,
1020 	alsa_get_playcmd,
1021 	alsa_begin,
1022 	alsa_feed_sync,
1023 	alsa_feed_sync_overlap,
1024 	alsa_end,
1025 };
1026 
alsa_plugin_get(void)1027 spd_audio_plugin_t *alsa_plugin_get(void)
1028 {
1029 	return &alsa_functions;
1030 }
1031 
1032 spd_audio_plugin_t *SPD_AUDIO_PLUGIN_ENTRY(void)
1033     __attribute__ ((weak, alias("alsa_plugin_get")));
1034 #undef MSG
1035 #undef ERR
1036