1 /*
2 Copyright (C) 2005-2006 Remon Sijrier
3 
4 (December 2005) Ported to C++ for Traverso by Remon Sijrier
5 Copyright (C) 2001 Paul Davis
6 
7 This file is part of Traverso
8 
9 Traverso is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
22 
23 */
24 
25 /* ALSA driver based on jack-audio-connection-kit-0.109.0 alsa_driver.c */
26 
27 
28 #include "AlsaDriver.h"
29 #include "AudioChannel.h"
30 #include <Utils.h>
31 
32 #include <math.h>
33 #include <stdio.h>
34 #include <memory.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <stdarg.h>
39 #include <signal.h>
40 #include <sys/types.h>
41 #include <regex.h>
42 
43 #include <string.h>
44 #include <sys/time.h>
45 #include <time.h>
46 
47 #include "AudioDevice.h"
48 
49 // Always put me below _all_ includes, this is needed
50 // in case we run with memory leak detection enabled!
51 #include "Debugger.h"
52 
53 #undef DEBUG_WAKEUP
54 
55 /* Delay (in process calls) before Traverso will report an xrun */
56 #define XRUN_REPORT_DELAY 0
57 
58 
AlsaDriver(AudioDevice * dev,int rate,nframes_t bufferSize)59 AlsaDriver::AlsaDriver(AudioDevice* dev, int rate, nframes_t bufferSize)
60 		: Driver(dev, rate, bufferSize)
61 {
62 	read = MakeDelegate(this, &AlsaDriver::_read);
63 	write = MakeDelegate(this, &AlsaDriver::_write);
64 	run_cycle = RunCycleCallback(this, &AlsaDriver::_run_cycle);
65 }
66 
~AlsaDriver()67 AlsaDriver::~AlsaDriver()
68 {
69 	PENTERDES;
70 	if (capture_handle) {
71 		snd_pcm_close (capture_handle);
72 	}
73 
74 	if (playback_handle) {
75 		snd_pcm_close (playback_handle);
76 	}
77 
78 	if (capture_hw_params) {
79 		snd_pcm_hw_params_free (capture_hw_params);
80 	}
81 
82 	if (playback_hw_params) {
83 		snd_pcm_hw_params_free (playback_hw_params);
84 	}
85 
86 	if (capture_sw_params) {
87 		snd_pcm_sw_params_free (capture_sw_params);
88 	}
89 
90 	if (playback_sw_params) {
91 		snd_pcm_sw_params_free (playback_sw_params);
92 	}
93 
94 	if (pfd) {
95 		free (pfd);
96 	}
97 
98 	release_channel_dependent_memory ();
99 }
100 
101 
setup(bool capture,bool playback,const QString & pcmName,const QString & ditherShape)102 int AlsaDriver::setup(bool capture, bool playback, const QString& pcmName, const QString& ditherShape)
103 {
104 	unsigned long user_nperiods = device->get_driver_property("numberofperiods", 3).toInt();
105     char *playback_pcm_name = strdup(pcmName.toLatin1().data());
106     char *capture_pcm_name = strdup(pcmName.toLatin1().data());
107 	int shorts_first = false;
108 
109 	/* duplex is the default */
110 	if (!capture && !playback) {
111 		capture = true;
112 		playback = true;
113 	}
114 
115 
116 	int err;
117 	playback_handle = (snd_pcm_t*) 0;
118 	capture_handle = (snd_pcm_t*) 0;
119 	ctl_handle = 0;
120 	capture_and_playback_not_synced = false;
121 	capture_interleaved = false;
122 	playback_interleaved = false;
123 	max_nchannels = 0;
124 	user_nchannels = 0;
125 	playback_nchannels = 0;
126 	capture_nchannels = 0;
127 	playback_sample_bytes = (shorts_first ? 2:4);
128 	capture_sample_bytes = (shorts_first ? 2:4);
129 	capture_frame_latency = 0;
130 	playback_frame_latency = 0;
131 	channels_done = 0;
132 	channels_not_done = 0;
133 	dither_state = 0;
134 
135 	playback_addr = 0;
136 	capture_addr = 0;
137 	playback_interleave_skip = NULL;
138 	capture_interleave_skip = NULL;
139 
140 
141 	playback_hw_params = 0;
142 	capture_hw_params = 0;
143 	playback_sw_params = 0;
144 	capture_sw_params = 0;
145 
146 
147 	silent = 0;
148 
149 	pfd = 0;
150 	playback_nfds = 0;
151 	capture_nfds = 0;
152 
153 	if (ditherShape == "Rectangular") {
154 		dither = Rectangular;
155 	} else if (ditherShape == "Shaped") {
156 		dither = Shaped;
157 	} else if (ditherShape == "Triangular") {
158 		dither = Triangular;
159 	} else {
160 		dither = None;
161 	}
162 
163 	soft_mode = false;
164 
165 	quirk_bswap = 0;
166 
167 	process_count = 0;
168 
169 	alsa_name_playback = strdup (playback_pcm_name);
170 	alsa_name_capture = strdup (capture_pcm_name);
171 
172 
173 	printf ("creating alsa driver ... %s|%s|%d|%lu|%d|%d|%d|%s|%s\n",
174 		playback ? playback_pcm_name : "-",
175 		capture ? capture_pcm_name : "-",
176 		frames_per_cycle, user_nperiods, frame_rate,
177 		(int)capture_nchannels, (int)playback_nchannels,
178 		soft_mode ? "soft-mode":"-",
179 		shorts_first ? "16bit":"32bit");
180 
181 
182 	if (playback) {
183 		if (snd_pcm_open (&playback_handle, alsa_name_playback, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) {
184 			switch (errno) {
185 			case EBUSY:
186 				device->message(tr("ALSA Driver: The playback device %1 is already in use. Please stop the"
187 					" application using it and run Traverso again").arg(playback_pcm_name), AudioDevice::INFO);
188 				return -1;
189 				break;
190 
191 			case EPERM:
192 				device->message(tr("ALSA Driver: You do not have permission to open the audio device %1 for playback").arg(playback_pcm_name), AudioDevice::INFO);
193 				return -1;
194 				break;
195 			default:
196 				device->message(tr("snd_pcm_open(playback_handle, ..) failed with unknown error type"), AudioDevice::WARNING);
197 			}
198 
199 			playback_handle = 0;
200 		}
201 
202 		if (playback_handle) {
203 			snd_pcm_nonblock (playback_handle, 0);
204 		}
205 	}
206 
207 	if (capture) {
208 		if (snd_pcm_open (&capture_handle, alsa_name_capture, SND_PCM_STREAM_CAPTURE,  SND_PCM_NONBLOCK) < 0) {
209 			switch (errno) {
210 			case EBUSY:
211 				device->message(tr("ALSA Driver: The capture device %1 is already in use. Please stop the"
212 				" application using it and run Traverso again").arg(capture_pcm_name), AudioDevice::INFO);
213 				return -1;
214 				break;
215 
216 			case EPERM:
217 				device->message(tr("ALSA Driver: You do not have permission to open the audio device %1 for capture").arg(capture_pcm_name), AudioDevice::WARNING);
218 				return -1;
219 				break;
220 			default:
221 				device->message(tr("ALSA Driver: snd_pcm_open(capture_handle, ...) failed with unknown error type"), AudioDevice::WARNING);
222 			}
223 
224 			capture_handle = 0;
225 		}
226 
227 		if (capture_handle) {
228 			snd_pcm_nonblock (capture_handle, 0);
229 		}
230 	}
231 
232 	if (playback_handle == 0) {
233 		if (playback) {
234 
235 			/* they asked for playback, but we can't do it */
236 
237 			device->message(tr("ALSA Driver: Cannot open PCM device %1 for playback. Falling back to capture-only mode").arg("alsa_pcm"), AudioDevice::WARNING);
238 
239 			if (capture_handle == 0) {
240 				/* can't do anything */
241 				return -1;
242 			}
243 			playback = false;
244 		}
245 	}
246 
247 	if (capture_handle == 0) {
248 		if (capture) {
249 
250 			/* they asked for capture, but we can't do it */
251 
252 			device->message(tr("ALSA: Cannot open PCM device %1 for capture. Falling back to playback-only mode").arg("alsa_pcm"), AudioDevice::WARNING);
253 
254 			if (playback_handle == 0) {
255 				/* can't do anything */
256 				return -1;
257 			}
258 			capture = false;
259 		}
260 	}
261 
262 
263 	if (playback_handle) {
264 		if ((err = snd_pcm_hw_params_malloc (&playback_hw_params)) < 0) {
265 			PWARN ("ALSA: could not allocate playback hw params structure");
266 			return -1;
267 		}
268 
269 		if ((err = snd_pcm_sw_params_malloc (&playback_sw_params)) < 0) {
270 			PWARN ("ALSA: could not allocate playback sw params structure");
271 			return -1;
272 		}
273 	}
274 
275 	if (capture_handle) {
276 		if ((err = snd_pcm_hw_params_malloc (&capture_hw_params)) < 0) {
277 			PWARN ("ALSA: could not allocate capture hw params structure");
278 			return -1;
279 		}
280 
281 		if ((err = snd_pcm_sw_params_malloc (&capture_sw_params)) < 0) {
282 			PWARN ("ALSA: could not allocate capture sw params structure");
283 			return -1;
284 		}
285 	}
286 
287 
288 
289 	if (set_parameters (frames_per_cycle, user_nperiods, frame_rate)) {
290 		return -1;
291 	}
292 
293 	capture_and_playback_not_synced = false;
294 
295 	if (capture_handle && playback_handle) {
296 		if (snd_pcm_link (playback_handle, capture_handle) != 0) {
297 			capture_and_playback_not_synced = true;
298 		}
299 	}
300 
301 
302 	return 1;
303 }
304 
305 
306 
release_channel_dependent_memory()307 void AlsaDriver::release_channel_dependent_memory ()
308 {
309 	bitset_destroy (&channels_done);
310 	bitset_destroy (&channels_not_done);
311 
312 	if (playback_addr) {
313 		free(playback_addr);
314 		playback_addr = 0;
315 	}
316 
317 	if (capture_addr) {
318 		free(capture_addr);
319 		capture_addr = 0;
320 	}
321 
322 	if (playback_interleave_skip) {
323 		free (playback_interleave_skip);
324 		playback_interleave_skip = NULL;
325 	}
326 
327 	if (capture_interleave_skip) {
328 		free (capture_interleave_skip);
329 		capture_interleave_skip = NULL;
330 	}
331 
332 
333 	if (silent) {
334 		free(silent);
335 		silent = 0;
336 	}
337 
338 	if (dither_state) {
339 		free(dither_state);
340 		dither_state = 0;
341 	}
342 }
343 
344 
setup_io_function_pointers()345 void AlsaDriver::setup_io_function_pointers()
346 {
347 	switch (playback_sample_bytes) {
348 	case 2:
349 		if (playback_interleaved) {
350 			channel_copy = memcpy_interleave_d16_s16;
351 		} else {
352 			channel_copy = memcpy_fake;
353 		}
354 
355 		switch (dither) {
356 		case Rectangular:
357 			fprintf (stderr,"Rectangular dithering at 16 bits\n");
358 			write_via_copy = quirk_bswap?
359 				sample_move_dither_rect_d16_sSs:
360 				sample_move_dither_rect_d16_sS;
361 			break;
362 
363 		case Triangular:
364 			printf("Triangular dithering at 16 bits\n");
365 			write_via_copy = quirk_bswap?
366 				sample_move_dither_tri_d16_sSs:
367 				sample_move_dither_tri_d16_sS;
368 			break;
369 
370 		case Shaped:
371 			printf("Noise-shaped dithering at 16 bits\n");
372 			write_via_copy = quirk_bswap?
373 				sample_move_dither_shaped_d16_sSs:
374 				sample_move_dither_shaped_d16_sS;
375 			break;
376 
377 		default:
378 			write_via_copy = quirk_bswap?
379 				sample_move_d16_sSs : sample_move_d16_sS;
380 			break;
381 		}
382 		break;
383 
384 	case 3:
385 		if (playback_interleaved) {
386 			channel_copy = memcpy_interleave_d24_s24;
387 		} else {
388 			channel_copy = memcpy_fake;
389 		}
390 
391 		switch (dither) {
392 		case Rectangular:
393 			printf("Rectangular dithering at 24 bits\n");
394 			write_via_copy = quirk_bswap?
395 				sample_move_dither_rect_d24_sSs:
396 				sample_move_dither_rect_d24_sS;
397 			break;
398 
399 		case Triangular:
400 			printf("Triangular dithering at 24 bits\n");
401 			write_via_copy = quirk_bswap?
402 				sample_move_dither_tri_d24_sSs:
403 				sample_move_dither_tri_d24_sS;
404 			break;
405 
406 		case Shaped:
407 			printf("Noise-shaped dithering at 24 bits\n");
408 			write_via_copy = quirk_bswap?
409 				sample_move_dither_shaped_d24_sSs:
410 				sample_move_dither_shaped_d24_sS;
411 			break;
412 
413 			default:
414 			write_via_copy = quirk_bswap?
415 				sample_move_d24_sSs : sample_move_d24_sS;
416 				break;
417 		}
418 		break;
419 
420 	case 4:
421 		if (playback_interleaved) {
422 			channel_copy = memcpy_interleave_d32_s32;
423 		} else {
424 			channel_copy = memcpy_fake;
425 		}
426 
427 		switch (dither) {
428 		case Rectangular:
429 			printf("Rectangular dithering at 32 bits\n");
430 			write_via_copy = quirk_bswap?
431 				sample_move_dither_rect_d32u24_sSs:
432 				sample_move_dither_rect_d32u24_sS;
433 			break;
434 
435 		case Triangular:
436 			printf("Triangular dithering at 16 bits\n");
437 			write_via_copy = quirk_bswap?
438 				sample_move_dither_tri_d32u24_sSs:
439 				sample_move_dither_tri_d32u24_sS;
440 			break;
441 
442 		case Shaped:
443 			printf("Noise-shaped dithering at 32 bits\n");
444 			write_via_copy = quirk_bswap?
445 				sample_move_dither_shaped_d32u24_sSs:
446 				sample_move_dither_shaped_d32u24_sS;
447 			break;
448 
449 		default:
450 			write_via_copy = quirk_bswap?
451 				sample_move_d32u24_sSs : sample_move_d32u24_sS;
452 			break;
453 		}
454 		break;
455 	}
456 
457 	switch (capture_sample_bytes) {
458 	case 2:
459 		read_via_copy = quirk_bswap?
460 			sample_move_dS_s16s : sample_move_dS_s16;
461 		break;
462 	case 3:
463 		read_via_copy = quirk_bswap?
464 			sample_move_dS_s24s : sample_move_dS_s24;
465 		break;
466 	case 4:
467 		read_via_copy = quirk_bswap?
468 			sample_move_dS_s32u24s : sample_move_dS_s32u24;
469 		break;
470 	}
471 }
472 
configure_stream(char * device_name,const char * stream_name,snd_pcm_t * handle,snd_pcm_hw_params_t * hw_params,snd_pcm_sw_params_t * sw_params,unsigned int * nperiodsp,unsigned long * nchns,unsigned long sample_width)473 int AlsaDriver::configure_stream(char *device_name,
474 				const char *stream_name,
475 				snd_pcm_t *handle,
476 				snd_pcm_hw_params_t *hw_params,
477 				snd_pcm_sw_params_t *sw_params,
478 				unsigned int *nperiodsp,
479 				unsigned long *nchns,
480 				unsigned long sample_width)
481 {
482 	int err, format;
483 	snd_pcm_uframes_t stop_th;
484 	static struct {
485 		char Name[32];
486 		snd_pcm_format_t format;
487 		int swapped;
488 		int bitdepth;
489 	} formats[] = {
490 		{"32bit little-endian", SND_PCM_FORMAT_S32_LE, IS_LE, 32},
491 		{"32bit big-endian", SND_PCM_FORMAT_S32_BE, IS_BE, 32},
492 		{"24bit little-endian", SND_PCM_FORMAT_S24_3LE, IS_LE, 24},
493 		{"24bit big-endian", SND_PCM_FORMAT_S24_3BE, IS_BE, 24},
494 		{"16bit little-endian", SND_PCM_FORMAT_S16_LE, IS_LE, 16},
495 		{"16bit big-endian", SND_PCM_FORMAT_S16_BE, IS_BE, 16},
496 	};
497 #define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
498 #define FIRST_16BIT_FORMAT 4
499 
500 	if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0)  {
501 		printf("ALSA: no playback configurations available (%s)\n", snd_strerror (err));
502 		return -1;
503 	}
504 
505 	if ((err = snd_pcm_hw_params_set_periods_integer (handle, hw_params))  < 0) {
506 		printf("ALSA: cannot restrict period size to integral value.\n");
507 		return -1;
508 	}
509 
510 	if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0) {
511 		if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
512 			if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_COMPLEX)) < 0) {
513 				printf("ALSA: mmap-based access is not possible for the %s "
514 					"stream of this audio interface\n", stream_name);
515 			return -1;
516 			}
517 		}
518 	}
519 
520 	format = (sample_width == 4) ? 0 : (NUMFORMATS - 1);
521 	while (1) {
522 		if ((err = snd_pcm_hw_params_set_format ( handle, hw_params, formats[format].format)) < 0) {
523 
524 			if (( (sample_width == 4) ? (format++ >= int(NUMFORMATS) - 1) : (format-- <= 0))) {
525 				printf("ALSA Driver: Sorry. The audio interface \"%s\" doesn't support any of the"
526 					" hardware sample formats that Traverso's alsa-driver can use.\n", device_name);
527 				return -1;
528 			}
529 		} else {
530 			if (formats[format].swapped) {
531 				quirk_bswap = 1;
532 			} else {
533 				quirk_bswap = 0;
534 			}
535 			printf("ALSA: final selected sample format for %s: %s\n", stream_name, formats[format].Name);
536 			device->set_bit_depth(formats[format].bitdepth);
537 			break;
538 		}
539 	}
540 
541 	if ( (err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &frame_rate, NULL)) < 0) {
542 		printf("ALSA: cannot set sample/frame rate to % for %s\n", (double)frame_rate, stream_name);
543 		return -1;
544 	}
545 
546 	if (!*nchns) {
547 		/*if not user-specified, try to find the maximum number of channels */
548 		unsigned int channels_max ;
549 		err = snd_pcm_hw_params_get_channels_max (hw_params, &channels_max);
550 		*nchns = channels_max;
551 
552 		if (*nchns > 1024) {
553 
554 			/* the hapless user is an unwitting victim of
555 			the "default" ALSA PCM device, which can
556 			support up to 16 million channels. since
557 			they can't be bothered to set up a proper
558 			default device, limit the number of
559 			channels for them to a sane default.
560 			*/
561 
562 			PERROR (
563 				"ALSA Driver: You appear to be using the ALSA software \"plug\" layer, probably\n"
564 				"a result of using the \"default\" ALSA device. This is less\n"
565 				"efficient than it could be. Consider using a hardware device\n"
566 				"instead rather than using the plug layer. Usually the name of the\n"
567 				"hardware device that corresponds to the first sound card is hw:0\n"
568 			);
569 			*nchns = 2;
570 		}
571 	}
572 
573 	if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, *nchns)) < 0) {
574 		printf("ALSA: cannot set channel count to %lu for %s\n", *nchns, stream_name);
575 		return -1;
576 	}
577 	int frperscycle = frames_per_cycle;
578 	if ((err = snd_pcm_hw_params_set_period_size (handle, hw_params, frames_per_cycle, 0)) < 0) {
579 		printf("ALSA: cannot set period size to %d frames for %s\n", frperscycle, stream_name);
580 		return -1;
581 	}
582 
583 	*nperiodsp = user_nperiods;
584 	snd_pcm_hw_params_set_periods_min (handle, hw_params, nperiodsp, NULL);
585 	if (*nperiodsp < user_nperiods)
586 		*nperiodsp = user_nperiods;
587 
588 	if (snd_pcm_hw_params_set_periods_near (handle, hw_params, nperiodsp, NULL) < 0) {
589 		printf("ALSA: cannot set number of periods to %u for %s\n", *nperiodsp, stream_name);
590 		return -1;
591 	}
592 
593 	if (*nperiodsp < user_nperiods) {
594 		printf("ALSA: use %d periods for %s\n", *nperiodsp, stream_name);
595 		return -1;
596 	}
597 
598 	if (!is_power_of_two(frames_per_cycle)) {
599 		printf("Traverso: frames must be a power of two (64, 512, 1024, ...)\n");
600 		return -1;
601 	}
602 
603 	if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params,  *nperiodsp * frames_per_cycle)) < 0) {
604 		printf("ALSA: cannot set buffer length to %d for %s\n", *nperiodsp * frames_per_cycle, stream_name);
605 		return -1;
606 	}
607 
608 	if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) {
609 		printf("ALSA: cannot set hardware parameters for %s\n", stream_name);
610 		device->message(tr("ALSA Driver: Unable to configure hardware, is it in use by another application?"), AudioDevice::WARNING);
611 		return -1;
612 	}
613 
614 	snd_pcm_sw_params_current (handle, sw_params);
615 
616 	if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, 0U)) < 0) {
617 		printf("ALSA: cannot set start mode for %s\n", stream_name);
618 		return -1;
619 	}
620 
621 	stop_th = *nperiodsp * frames_per_cycle;
622 	if (soft_mode) {
623 		stop_th = (snd_pcm_uframes_t)-1;
624 	}
625 
626 	if ((err = snd_pcm_sw_params_set_stop_threshold (handle, sw_params, stop_th)) < 0) {
627 		printf("ALSA: cannot set stop mode for %s\n", stream_name);
628 		return -1;
629 	}
630 
631 	if ((err = snd_pcm_sw_params_set_silence_threshold (handle, sw_params, 0)) < 0) {
632 		printf("ALSA: cannot set silence threshold for %s\n", stream_name);
633 		return -1;
634 	}
635 
636 #if 0
637 	fprintf (stderr, "set silence size to %lu * %lu = %lu\n",
638 		frames_per_cycle, *nperiodsp,
639 		frames_per_cycle * *nperiodsp);
640 
641 	if ((err = snd_pcm_sw_params_set_silence_size (
642 				handle, sw_params,
643 				frames_per_cycle * *nperiodsp)) < 0) {
644 		PERROR ("ALSA: cannot set silence size for %s",
645 			stream_name);
646 		return -1;
647 	}
648 #endif
649 
650 	if (handle == playback_handle)
651 		err = snd_pcm_sw_params_set_avail_min (handle, sw_params, frames_per_cycle * (*nperiodsp - user_nperiods + 1));
652 	else
653 		err = snd_pcm_sw_params_set_avail_min (handle, sw_params, frames_per_cycle);
654 
655 	if (err < 0) {
656 		printf("ALSA: cannot set avail min for %s\n", stream_name);
657 		return -1;
658 	}
659 
660 	if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) {
661 		printf("ALSA: cannot set software parameters for %s\n",	stream_name);
662 		return -1;
663 	}
664 
665 	return 0;
666 }
667 
set_parameters(nframes_t frames_per_interupt,nframes_t nperiods,nframes_t rate)668 int  AlsaDriver::set_parameters (nframes_t frames_per_interupt,
669 				nframes_t nperiods,
670 				nframes_t rate)
671 {
672 	int dir;
673 	snd_pcm_uframes_t p_period_size = 0;
674 	snd_pcm_uframes_t c_period_size = 0;
675 	channel_t chn;
676 	unsigned int pr = 0;
677 	unsigned int cr = 0;
678 	int err;
679 
680 	frame_rate = rate;
681 	frames_per_cycle = frames_per_interupt;
682 	user_nperiods = nperiods;
683 
684 	fprintf (stderr, "configuring for %d Hz, period=%ld frames (%.1f ms), buffer=%ld periods\n",
685 		 rate, (long)frames_per_cycle,(((float)frames_per_cycle / (float) rate) * 1000.0f), user_nperiods);
686 	if (capture_handle) {
687 		if (configure_stream (
688 					alsa_name_capture,
689 					"capture",
690 					capture_handle,
691 					capture_hw_params,
692 					capture_sw_params,
693 					&capture_nperiods,
694 					&capture_nchannels,
695 					capture_sample_bytes)) {
696 			PERROR ("ALSA: cannot configure capture channel");
697 			return -1;
698 		}
699 	}
700 
701 	if (playback_handle) {
702 		if (configure_stream (
703 					alsa_name_playback,
704 					"playback",
705 					playback_handle,
706 					playback_hw_params,
707 					playback_sw_params,
708 					&playback_nperiods,
709 					&playback_nchannels,
710 					playback_sample_bytes)) {
711 			PERROR ("ALSA: cannot configure playback channel");
712 			return -1;
713 		}
714 	}
715 
716 	/* check the rate, since thats rather important */
717 
718 	if (playback_handle) {
719 		snd_pcm_hw_params_get_rate (playback_hw_params, &pr, &dir);
720 	}
721 
722 	if (capture_handle) {
723 		snd_pcm_hw_params_get_rate (capture_hw_params, &cr, &dir);
724 	}
725 
726 	if (capture_handle && playback_handle) {
727 		if (cr != pr) {
728 			PERROR ("ALSA Driver: playback and capture sample rates do not match (%d vs. %d)", pr, cr);
729 		}
730 
731 		/* only change if *both* capture and playback rates
732 		* don't match requested certain hardware actually
733 		* still works properly in full-duplex with slightly
734 		* different rate values between adc and dac
735 		*/
736 		if (cr != frame_rate && pr != frame_rate) {
737 			PERROR ("ALSA Driver: sample rate in use (%d Hz) does not match requested rate (%d Hz)", cr, frame_rate);
738 			frame_rate = cr;
739 		}
740 
741 	} else if (capture_handle && cr != frame_rate) {
742 		PERROR ("ALSA Driver: capture sample rate in use (%d Hz) does not match requested rate (%d Hz)", cr, frame_rate);
743 		frame_rate = cr;
744 	} else if (playback_handle && pr != frame_rate) {
745 		PERROR ("ALSA Driver: playback sample rate in use (%d Hz) does not match requested rate (%d Hz)", pr, frame_rate);
746 		frame_rate = pr;
747 	}
748 
749 
750 	/* check the fragment size, since thats non-negotiable */
751 
752 	if (playback_handle) {
753 		snd_pcm_access_t access;
754 
755 		err = snd_pcm_hw_params_get_period_size (playback_hw_params, &p_period_size, &dir);
756 		err = snd_pcm_hw_params_get_format (playback_hw_params,	&playback_sample_format);
757 		err = snd_pcm_hw_params_get_access (playback_hw_params, &access);
758 		playback_interleaved = (access == SND_PCM_ACCESS_MMAP_INTERLEAVED)
759 					|| (access == SND_PCM_ACCESS_MMAP_COMPLEX);
760 
761 		if (p_period_size != frames_per_cycle) {
762 			PERROR ("alsa_pcm: requested an interrupt every %ld frames but got %ld frames for playback", (long)frames_per_cycle, p_period_size);
763 			return -1;
764 		}
765 	}
766 
767 	if (capture_handle) {
768 		snd_pcm_access_t access;
769 
770 		err = snd_pcm_hw_params_get_period_size (capture_hw_params, &c_period_size, &dir);
771 		err = snd_pcm_hw_params_get_format (capture_hw_params, &(capture_sample_format));
772 		err = snd_pcm_hw_params_get_access (capture_hw_params, &access);
773 		capture_interleaved = (access == SND_PCM_ACCESS_MMAP_INTERLEAVED)
774 					|| (access == SND_PCM_ACCESS_MMAP_COMPLEX);
775 
776 
777 		if (c_period_size != frames_per_cycle) {
778 			PERROR ("alsa_pcm: requested an interrupt every %ld frames but got %ld frames for capture", (long)frames_per_cycle, p_period_size);
779 			return -1;
780 		}
781 	}
782 
783 	playback_sample_bytes =	snd_pcm_format_physical_width(playback_sample_format)	/ 8;
784 	capture_sample_bytes =	snd_pcm_format_physical_width(capture_sample_format)	/ 8;
785 
786 	if (playback_handle) {
787 		switch (playback_sample_format) {
788 		case SND_PCM_FORMAT_S32_LE:
789 		case SND_PCM_FORMAT_S24_3LE:
790 		case SND_PCM_FORMAT_S24_3BE:
791 		case SND_PCM_FORMAT_S16_LE:
792 		case SND_PCM_FORMAT_S32_BE:
793 		case SND_PCM_FORMAT_S16_BE:
794 			break;
795 
796 		default:
797 			PERROR ("ALSA Driver: programming error: unhandled format type for playback");
798 			return -1;
799 		}
800 	}
801 
802 	if (capture_handle) {
803 		switch (capture_sample_format) {
804 		case SND_PCM_FORMAT_S32_LE:
805 		case SND_PCM_FORMAT_S24_3LE:
806 		case SND_PCM_FORMAT_S24_3BE:
807 		case SND_PCM_FORMAT_S16_LE:
808 		case SND_PCM_FORMAT_S32_BE:
809 		case SND_PCM_FORMAT_S16_BE:
810 			break;
811 
812 		default:
813 			PERROR ("ALSA Driver: programming error: unhandled format type for capture");
814 			return -1;
815 		}
816 	}
817 
818 	if (playback_interleaved) {
819 		const snd_pcm_channel_area_t *my_areas;
820 		snd_pcm_uframes_t offset, frames;
821 		if (snd_pcm_mmap_begin(playback_handle, &my_areas, &offset, &frames) < 0) {
822 			PERROR ("ALSA: %s: mmap areas info error", alsa_name_playback);
823 			return -1;
824 		}
825 
826 		interleave_unit = snd_pcm_format_physical_width(playback_sample_format) / 8;
827 	} else {
828 		interleave_unit = 0;  /* NOT USED */
829 	}
830 
831 	if (capture_interleaved) {
832 		const snd_pcm_channel_area_t *my_areas;
833 		snd_pcm_uframes_t offset, frames;
834 		if (snd_pcm_mmap_begin(capture_handle, &my_areas, &offset, &frames) < 0) {
835 			PERROR ("ALSA: %s: mmap areas info error", alsa_name_capture);
836 			return -1;
837 		}
838 	}
839 
840 	if (playback_nchannels > capture_nchannels) {
841 		max_nchannels = playback_nchannels;
842 		user_nchannels = capture_nchannels;
843 	} else {
844 		max_nchannels = capture_nchannels;
845 		user_nchannels = playback_nchannels;
846 	}
847 
848 	setup_io_function_pointers ();
849 
850 	/* Allocate and initialize structures that rely on the
851 	channels counts.
852 
853 	Set up the bit pattern that is used to record which
854 	channels require action on every cycle. any bits that are
855 	not set after the engine's process() call indicate channels
856 	that potentially need to be silenced.
857 	*/
858 
859 	bitset_create (&channels_done, max_nchannels);
860 	bitset_create (&channels_not_done, max_nchannels);
861 
862 	if (playback_handle) {
863 		playback_addr =  (char**) malloc (sizeof (char *) * playback_nchannels);
864 		memset (playback_addr, 0, sizeof (char *) * playback_nchannels);
865 		playback_interleave_skip = (unsigned long *) malloc (sizeof (unsigned long *) * playback_nchannels);
866 		memset (playback_interleave_skip, 0, sizeof (unsigned long *) * playback_nchannels);
867 		silent = (unsigned long *) malloc (sizeof (unsigned long) * playback_nchannels);
868 
869 		for (chn = 0; chn < playback_nchannels; chn++) {
870 			silent[chn] = 0;
871 		}
872 
873 		for (chn = 0; chn < playback_nchannels; chn++) {
874 			bitset_add (channels_done, chn);
875 		}
876 
877 		dither_state = (dither_state_t *) calloc ( playback_nchannels, sizeof (dither_state_t));
878 	}
879 
880 	if (capture_handle) {
881 		capture_addr = (char **) malloc (sizeof (char *) * capture_nchannels);
882 		memset (capture_addr, 0, sizeof (char *) * capture_nchannels);
883 		capture_interleave_skip = (unsigned long *) malloc (sizeof (unsigned long *) * capture_nchannels);
884 		memset (capture_interleave_skip, 0, sizeof (unsigned long *) * capture_nchannels);
885 	}
886 
887 	period_usecs = (trav_time_t) floor ((((float) frames_per_cycle) / frame_rate) * 1000000.0f);
888 	poll_timeout = (int) floor (1.5f * period_usecs);
889 
890 	device->set_buffer_size(frames_per_cycle);
891 
892 	return 0;
893 }
894 
reset_parameters(nframes_t frames_per_cycle,nframes_t user_nperiods,nframes_t rate)895 int AlsaDriver::reset_parameters (nframes_t frames_per_cycle,
896 				nframes_t user_nperiods,
897 				nframes_t rate)
898 {
899 	/* XXX unregister old ports ? */
900 	release_channel_dependent_memory ();
901 	return set_parameters (frames_per_cycle, user_nperiods, rate);
902 }
903 
get_channel_addresses(snd_pcm_uframes_t * capture_avail,snd_pcm_uframes_t * playback_avail,snd_pcm_uframes_t * capture_offset,snd_pcm_uframes_t * playback_offset)904 int AlsaDriver::get_channel_addresses (snd_pcm_uframes_t *capture_avail,
905 				snd_pcm_uframes_t *playback_avail,
906 				snd_pcm_uframes_t *capture_offset,
907 				snd_pcm_uframes_t *playback_offset)
908 {
909 	int err;
910 	channel_t chn;
911 
912 	if (capture_avail) {
913 		if ((err = snd_pcm_mmap_begin (capture_handle, &capture_areas, capture_offset, capture_avail)) < 0) {
914 			PERROR ("ALSA: %s: mmap areas info error", alsa_name_capture);
915 			return -1;
916 		}
917 
918 		for (chn = 0; chn < capture_nchannels; chn++) {
919 			const snd_pcm_channel_area_t *a = &capture_areas[chn];
920 			capture_addr[chn] = (char *) a->addr + ((a->first + a->step * *capture_offset) / 8);
921 			capture_interleave_skip[chn] = (unsigned long ) (a->step / 8);
922 		}
923 	}
924 
925 	if (playback_avail) {
926 		if ((err = snd_pcm_mmap_begin (playback_handle, &playback_areas, playback_offset, playback_avail)) < 0) {
927 			PERROR ("ALSA: %s: mmap areas info error ", alsa_name_playback);
928 			return -1;
929 		}
930 
931 		for (chn = 0; chn < playback_nchannels; chn++) {
932 			const snd_pcm_channel_area_t *a = &playback_areas[chn];
933 			playback_addr[chn] = (char *) a->addr + ((a->first + a->step * *playback_offset) / 8);
934 			playback_interleave_skip[chn] = (unsigned long ) (a->step / 8);
935 		}
936 	}
937 
938 	return 0;
939 }
940 
start()941 int AlsaDriver::start()
942 {
943 	int err;
944 	snd_pcm_uframes_t poffset, pavail;
945 	channel_t chn;
946 
947 	poll_last = 0;
948 	poll_next = 0;
949 
950 	if (playback_handle) {
951 		if ((err = snd_pcm_prepare (playback_handle)) < 0) {
952 			PERROR ("ALSA: prepare error for playback on \"%s\" (%s)", alsa_name_playback, snd_strerror(err));
953 			return -1;
954 		}
955 	}
956 
957 	if ((capture_handle && capture_and_playback_not_synced)  || !playback_handle) {
958 		if ((err = snd_pcm_prepare (capture_handle)) < 0) {
959 			PERROR ("ALSA: prepare error for capture on \"%s\" (%s)", alsa_name_capture,  snd_strerror(err));
960 			return -1;
961 		}
962 	}
963 
964 
965 	if (playback_handle) {
966 		playback_nfds = snd_pcm_poll_descriptors_count (playback_handle);
967 	} else {
968 		playback_nfds = 0;
969 	}
970 
971 	if (capture_handle) {
972 		capture_nfds = snd_pcm_poll_descriptors_count (capture_handle);
973 	} else {
974 		capture_nfds = 0;
975 	}
976 
977 	if (pfd) {
978 		free (pfd);
979 	}
980 
981 	pfd = (struct pollfd *)	malloc (sizeof (struct pollfd) * (playback_nfds + capture_nfds + 2));
982 
983 	if (playback_handle) {
984 		/* fill playback buffer with zeroes, and mark
985 		all fragments as having data.
986 		*/
987 
988 		pavail = snd_pcm_avail_update (playback_handle);
989 
990 		if (pavail !=  frames_per_cycle * playback_nperiods) {
991 			PERROR ("ALSA: full buffer not available at start");
992 			return -1;
993 		}
994 
995 		if (get_channel_addresses (0, &pavail, 0, &poffset)) {
996 			return -1;
997 		}
998 
999 		/* XXX this is cheating. ALSA offers no guarantee that
1000 		we can access the entire buffer at any one time. It
1001 		works on most hardware tested so far, however, buts
1002 		its a liability in the long run. I think that
1003 		alsa-lib may have a better function for doing this
1004 		here, where the goal is to silence the entire
1005 		buffer.
1006 		*/
1007 
1008 		for (chn = 0; chn < playback_nchannels; chn++) {
1009 			silence_on_channel (chn, user_nperiods * frames_per_cycle);
1010 		}
1011 
1012 		snd_pcm_mmap_commit (playback_handle, poffset, user_nperiods * frames_per_cycle);
1013 
1014 		if ((err = snd_pcm_start (playback_handle)) < 0) {
1015 			PERROR ("ALSA: could not start playback (%s)", snd_strerror (err));
1016 			return -1;
1017 		}
1018 	}
1019 
1020 	if ((capture_handle && capture_and_playback_not_synced)  || !playback_handle) {
1021 		if ((err = snd_pcm_start (capture_handle)) < 0) {
1022 			PERROR ("ALSA: could not start capture (%s)", snd_strerror (err));
1023 			return -1;
1024 		}
1025 	}
1026 
1027 	return 0;
1028 }
1029 
stop()1030 int AlsaDriver::stop()
1031 {
1032 	int err;
1033 	audio_sample_t* buf;
1034 
1035 	/* silence all capture port buffers, because we might
1036 	be entering offline mode.
1037 	*/
1038 
1039 	for (int i=0; i<captureChannels.size(); ++i) {
1040 		AudioChannel* chan = captureChannels.at(i);
1041 		buf = chan->get_buffer(frames_per_cycle);
1042 		memset (buf, 0, sizeof (audio_sample_t) * frames_per_cycle);
1043 	}
1044 
1045 	if (playback_handle) {
1046 		if ((err = snd_pcm_drop (playback_handle)) < 0) {
1047 			PERROR ("ALSA: channel flush for playback failed (%s)", snd_strerror (err));
1048 			return -1;
1049 		}
1050 	}
1051 
1052 	if (!playback_handle || capture_and_playback_not_synced) {
1053 		if (capture_handle) {
1054 			if ((err = snd_pcm_drop (capture_handle)) < 0) {
1055 				PERROR ("ALSA: channel flush for capture failed (%s)", snd_strerror (err));
1056 				return -1;
1057 			}
1058 		}
1059 	}
1060 
1061 
1062 	return 0;
1063 }
1064 
restart()1065 int AlsaDriver::restart()
1066 {
1067 	if (stop())
1068 		return -1;
1069 	return start();
1070 }
1071 
xrun_recovery(float * delayed_usecs)1072 int AlsaDriver::xrun_recovery (float *delayed_usecs)
1073 {
1074 	PWARN("xrun");
1075 	snd_pcm_status_t *status;
1076 	int res;
1077 
1078 	snd_pcm_status_alloca(&status);
1079 
1080 	if (capture_handle) {
1081 		if ((res = snd_pcm_status(capture_handle, status))  < 0) {
1082 			printf ("status error: %s", snd_strerror(res));
1083 		}
1084 	} else {
1085 		if ((res = snd_pcm_status(playback_handle, status)) < 0) {
1086 			printf ("status error: %s", snd_strerror(res));
1087 		}
1088 	}
1089 
1090 	if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN && process_count > XRUN_REPORT_DELAY) {
1091 		struct timeval now, diff, tstamp;
1092 		gettimeofday(&now, 0);
1093 		snd_pcm_status_get_trigger_tstamp(status, &tstamp);
1094 		timersub(&now, &tstamp, &diff);
1095 		*delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec;
1096 		printf ("\n**** alsa_pcm: xrun of at least %.3f msecs\n\n", *delayed_usecs / 1000.0);
1097 		device->xrun();
1098 	}
1099 
1100 	if (restart()) {
1101 		return -1;
1102 	}
1103 
1104 	return 0;
1105 }
1106 
silence_untouched_channels(nframes_t nframes)1107 void AlsaDriver::silence_untouched_channels (nframes_t nframes)
1108 {
1109 	channel_t chn;
1110 	nframes_t buffer_frames = frames_per_cycle * playback_nperiods;
1111 
1112 	for (chn = 0; chn < playback_nchannels; chn++) {
1113 		if (bitset_contains (channels_not_done, chn)) {
1114 			if (silent[chn] < buffer_frames) {
1115 				silence_on_channel_no_mark (chn, nframes);
1116 				silent[chn] += nframes;
1117 			}
1118 		}
1119 	}
1120 }
1121 
1122 static int under_gdb = false;
1123 
wait(int extra_fd,int * status,float * delayed_usecs)1124 int AlsaDriver::wait(int extra_fd, int *status, float *delayed_usecs)
1125 {
1126 	snd_pcm_sframes_t avail = 0;
1127 	snd_pcm_sframes_t capture_avail = 0;
1128 	snd_pcm_sframes_t playback_avail = 0;
1129 	int xrun_detected = false;
1130 	int need_capture;
1131 	int need_playback;
1132 	unsigned int i;
1133 	trav_time_t poll_enter;
1134 	trav_time_t poll_ret = 0;
1135 
1136 	*status = -1;
1137 	*delayed_usecs = 0;
1138 
1139 	need_capture = capture_handle ? 1 : 0;
1140 
1141 	if (extra_fd >= 0) {
1142 		need_playback = 0;
1143 	} else {
1144 		need_playback = playback_handle ? 1 : 0;
1145 	}
1146 
1147 again:
1148 
1149 	while (need_playback || need_capture) {
1150 
1151 		int poll_result;
1152 		unsigned int ci = 0;
1153 		unsigned int nfds;
1154 		unsigned short revents;
1155 
1156 		nfds = 0;
1157 
1158 		if (need_playback) {
1159 			snd_pcm_poll_descriptors (playback_handle, &pfd[0], playback_nfds);
1160 			nfds += playback_nfds;
1161 		}
1162 
1163 		if (need_capture) {
1164 			snd_pcm_poll_descriptors (capture_handle, &pfd[nfds], capture_nfds);
1165 			ci = nfds;
1166 			nfds += capture_nfds;
1167 		}
1168 
1169 		/* ALSA doesn't set POLLERR in some versions of 0.9.X */
1170 
1171 		for (i = 0; i < nfds; i++) {
1172 			pfd[i].events |= POLLERR;
1173 		}
1174 
1175 		if (extra_fd >= 0) {
1176 			pfd[nfds].fd = extra_fd;
1177 			pfd[nfds].events =
1178 				POLLIN|POLLERR|POLLHUP|POLLNVAL;
1179 			nfds++;
1180 		}
1181 
1182 		poll_enter = get_microseconds ();
1183 
1184 		if (poll_enter > poll_next) {
1185 			/*
1186 			* This processing cycle was delayed past the
1187 			* next due interrupt!  Do not account this as
1188 			* a wakeup delay:
1189 			*/
1190 			poll_next = 0;
1191 		}
1192 
1193 		device->transport_cycle_end(poll_enter);
1194 
1195 		poll_result = poll (pfd, nfds, poll_timeout);
1196 		if (poll_result < 0) {
1197 
1198 			if (errno == EINTR) {
1199 				printf ("poll interrupt\n");
1200 				// this happens mostly when run
1201 				// under gdb, or when exiting due to a signal
1202 				if (under_gdb) {
1203 					goto again;
1204 				}
1205 				*status = -2;
1206 				return 0;
1207 			}
1208 
1209 			PERROR ("ALSA: poll call failed (%s)",
1210 				strerror (errno));
1211 			*status = -3;
1212 			return 0;
1213 
1214 		}
1215 
1216 		poll_ret = get_microseconds ();
1217 
1218 		if (extra_fd < 0) {
1219 			if (poll_next && poll_ret > poll_next) {
1220 				*delayed_usecs = poll_ret - poll_next;
1221 			}
1222 			poll_last = poll_ret;
1223 			poll_next = poll_ret + period_usecs;
1224 			device->transport_cycle_start (poll_ret);
1225 		}
1226 
1227 #ifdef DEBUG_WAKEUP
1228 		fprintf (stderr, "%" PRIu64 ": checked %d fds, %" PRIu64
1229 			" usecs since poll entered\n", poll_ret, nfds,
1230 			poll_ret - poll_enter);
1231 #endif
1232 
1233 		/* check to see if it was the extra FD that caused us
1234 		* to return from poll */
1235 
1236 		if (extra_fd >= 0) {
1237 
1238 			if (pfd[nfds-1].revents == 0) {
1239 				/* we timed out on the extra fd */
1240 
1241 				*status = -4;
1242 				return -1;
1243 			}
1244 
1245 			/* if POLLIN was the only bit set, we're OK */
1246 
1247 			*status = 0;
1248 			return (pfd[nfds-1].revents == POLLIN) ? 0 : -1;
1249 		}
1250 
1251 		if (need_playback) {
1252 			if (snd_pcm_poll_descriptors_revents(playback_handle, &pfd[0], playback_nfds, &revents) < 0) {
1253 				qWarning("ALSA: playback revents failed");
1254 				*status = -6;
1255 				return 0;
1256 			}
1257 
1258 			if (revents & POLLERR) {
1259                 xrun_detected = true;
1260 			}
1261 
1262 			if (revents & POLLOUT) {
1263 				need_playback = 0;
1264 
1265 #ifdef DEBUG_WAKEUP
1266 
1267 				fprintf (stderr, "%" PRIu64
1268 					" playback stream ready\n",
1269 					poll_ret);
1270 #endif
1271 
1272 			}
1273 		}
1274 
1275 		if (need_capture) {
1276 			if (snd_pcm_poll_descriptors_revents(capture_handle, &pfd[ci], capture_nfds, &revents) < 0) {
1277 				qWarning ("ALSA: capture revents failed");
1278 				*status = -6;
1279 				return 0;
1280 			}
1281 
1282 			if (revents & POLLERR) {
1283                 xrun_detected = true;
1284 			}
1285 
1286 			if (revents & POLLIN) {
1287 				need_capture = 0;
1288 #ifdef DEBUG_WAKEUP
1289 
1290 				fprintf (stderr, "%" PRIu64
1291 					" capture stream ready\n",
1292 					poll_ret);
1293 #endif
1294 
1295 			}
1296 		}
1297 
1298 		if (poll_result == 0) {
1299 			qWarning ("ALSA: poll time out, polled for %ld usecs", (long)(poll_ret - poll_enter));
1300 			*status = -5;
1301 			return 0;
1302 		}
1303 
1304 	}
1305 
1306 	if (capture_handle) {
1307 		if ((capture_avail = snd_pcm_avail_update (capture_handle)) < 0) {
1308 			if (capture_avail == -EPIPE) {
1309 				xrun_detected = true;
1310 			} else {
1311 				PERROR ("ALSA Driver: unknown avail_update return value (%ld)", capture_avail);
1312 			}
1313 		}
1314 	} else {
1315 		/* odd, but see min() computation below */
1316 		capture_avail = INT_MAX;
1317 	}
1318 
1319 	if (playback_handle) {
1320 		if ((playback_avail = snd_pcm_avail_update (playback_handle)) < 0) {
1321 			if (playback_avail == -EPIPE) {
1322 				xrun_detected = true;
1323 			} else {
1324 				PERROR ("ALSA Driver: unknown avail_update return value (%ld)", playback_avail);
1325 			}
1326 		}
1327 	} else {
1328 		/* odd, but see min() computation below */
1329 		playback_avail = INT_MAX;
1330 	}
1331 
1332 	if (xrun_detected) {
1333 		*status = xrun_recovery (delayed_usecs);
1334 		return 0;
1335 	}
1336 
1337 	*status = 0;
1338 	last_wait_ust = poll_ret;
1339 
1340 	avail = capture_avail < playback_avail ? capture_avail : playback_avail;
1341 
1342 #ifdef DEBUG_WAKEUP
1343 
1344 	fprintf (stderr, "wakeup complete, avail = %lu, pavail = %lu "
1345 		"cavail = %lu\n",
1346 		avail, playback_avail, capture_avail);
1347 #endif
1348 
1349 	/* mark all channels not done for now. read/write will change this */
1350 
1351 	bitset_copy (channels_not_done, channels_done);
1352 
1353 	/* constrain the available count to the nearest (round down) number of
1354 	periods.
1355 	*/
1356 
1357 	return avail - (avail % frames_per_cycle);
1358 }
1359 
_null_cycle(nframes_t nframes)1360 int AlsaDriver::_null_cycle(nframes_t nframes)
1361 {
1362 	nframes_t nf;
1363 	snd_pcm_uframes_t offset;
1364 	snd_pcm_uframes_t contiguous;
1365 	uint chn;
1366 
1367 	if (nframes > frames_per_cycle) {
1368 		return -1;
1369 	}
1370 
1371 	if (capture_handle) {
1372 		nf = nframes;
1373 		offset = 0;
1374 		while (nf) {
1375 			contiguous = nf;
1376 
1377 			if (snd_pcm_mmap_begin (
1378 						capture_handle,
1379 						&capture_areas,
1380 						(snd_pcm_uframes_t *) &offset,
1381 						(snd_pcm_uframes_t *) &contiguous)) {
1382 				return -1;
1383 			}
1384 
1385 			if (snd_pcm_mmap_commit (capture_handle, offset, contiguous) < 0) {
1386 				return -1;
1387 			}
1388 
1389 			nf -= contiguous;
1390 		}
1391 	}
1392 
1393 	if (playback_handle) {
1394 		nf = nframes;
1395 		offset = 0;
1396 		while (nf) {
1397 			contiguous = nf;
1398 
1399 			if (snd_pcm_mmap_begin (
1400 						playback_handle,
1401 						&playback_areas,
1402 						(snd_pcm_uframes_t *) &offset,
1403 						(snd_pcm_uframes_t *) &contiguous)) {
1404 				return -1;
1405 			}
1406 
1407 			for (chn = 0; chn < playback_nchannels; chn++) {
1408 				silence_on_channel (chn, contiguous);
1409 			}
1410 
1411 			if (snd_pcm_mmap_commit (playback_handle, offset, contiguous) < 0) {
1412 				return -1;
1413 			}
1414 
1415 			nf -= contiguous;
1416 		}
1417 	}
1418 
1419 	return 0;
1420 }
1421 
bufsize(nframes_t nframes)1422 int AlsaDriver::bufsize(nframes_t nframes)
1423 {
1424 	return reset_parameters (nframes, user_nperiods,frame_rate);
1425 }
1426 
_read(nframes_t nframes)1427 int AlsaDriver::_read(nframes_t nframes)
1428 {
1429 	snd_pcm_uframes_t contiguous;
1430 	snd_pcm_uframes_t nread;
1431 	snd_pcm_uframes_t offset;
1432 	nframes_t  orig_nframes;
1433 	audio_sample_t* buf;
1434 	int err;
1435 
1436 	if (nframes > frames_per_cycle) {
1437 		return -1;
1438 	}
1439 
1440 	if (!capture_handle) {
1441 		return 0;
1442 	}
1443 
1444 	nread = 0;
1445 	contiguous = 0;
1446 	orig_nframes = nframes;
1447 
1448 	while (nframes) {
1449 
1450 		contiguous = nframes;
1451 
1452 		if (get_channel_addresses (&contiguous, (snd_pcm_uframes_t *) 0, &offset, 0) < 0) {
1453 			return -1;
1454 		}
1455 
1456 		for (int i=0; i<captureChannels.size(); ++i) {
1457 			AudioChannel* channel = captureChannels.at(i);
1458 
1459 			if (!channel->has_data()) {
1460 				//no-copy optimization
1461 				continue;
1462 			}
1463 			buf = channel->get_data();
1464 			read_from_channel (channel->get_number(), buf + nread, contiguous);
1465 		}
1466 
1467 		if ((err = snd_pcm_mmap_commit (capture_handle, offset, contiguous)) < 0) {
1468 			PERROR ("ALSA: could not complete read of %ld frames: error = %d\n", contiguous, err);
1469 			return -1;
1470 		}
1471 
1472 		nframes -= contiguous;
1473 		nread += contiguous;
1474 	}
1475 
1476 	return 0;
1477 }
1478 
_write(nframes_t nframes)1479 int AlsaDriver::_write(nframes_t nframes)
1480 {
1481 	audio_sample_t* buf;
1482 	nframes_t orig_nframes;
1483 	snd_pcm_uframes_t nwritten;
1484 	snd_pcm_uframes_t contiguous;
1485 	snd_pcm_uframes_t offset;
1486 	int err;
1487 
1488 	process_count++;
1489 
1490 	if (! playback_handle) {
1491 		return 0;
1492 	}
1493 
1494 	if (nframes > frames_per_cycle) {
1495 		return -1;
1496 	}
1497 
1498 	nwritten = 0;
1499 	contiguous = 0;
1500 	orig_nframes = nframes;
1501 
1502 	while (nframes) {
1503 
1504 		contiguous = nframes;
1505 
1506 		if (get_channel_addresses ((snd_pcm_uframes_t *) 0, &contiguous, 0, &offset) < 0) {
1507 			return -1;
1508 		}
1509 
1510 		for (int i=0; i<playbackChannels.size(); ++i) {
1511 			AudioChannel* channel = playbackChannels.at(i);
1512 			if (!channel->has_data()) {
1513 				continue;
1514 			}
1515 			buf = channel->get_data();
1516 			write_to_channel (channel->get_number(), buf + nwritten, contiguous);
1517 			channel->silence_buffer(nframes);
1518 		}
1519 
1520 
1521 		if (!bitset_empty (channels_not_done)) {
1522 			silence_untouched_channels (contiguous);
1523 		}
1524 
1525 		if ((err = snd_pcm_mmap_commit (playback_handle, offset, contiguous)) < 0) {
1526 			PERROR ("ALSA: could not complete playback of %ld frames: error = %d", contiguous, err);
1527 			if (err != EPIPE && err != ESTRPIPE)
1528 				return -1;
1529 		}
1530 
1531 		nframes -= contiguous;
1532 		nwritten += contiguous;
1533 	}
1534 	return 0;
1535 }
1536 
_run_cycle()1537 int AlsaDriver::_run_cycle()
1538 {
1539 	int wait_status;
1540 	float delayed_usecs;
1541 	nframes_t nframes;
1542 
1543 	// 	PWARN ("alsa run cycle wait\n");
1544 
1545 	nframes = wait (-1, &wait_status, &delayed_usecs);
1546 
1547 
1548 	if (nframes == 0) {
1549 
1550 		/* we detected an xrun and restarted: notify
1551 		* clients about the delay.
1552 		*/
1553 		device->delay(delayed_usecs);
1554 		return 0;
1555 	}
1556 
1557 	if (wait_status == 0)
1558 		return device->run_cycle (nframes, delayed_usecs);
1559 
1560 	if (wait_status < 0)
1561 		return -1;		/* driver failed */
1562 	else
1563 		return 0;
1564 }
1565 
attach()1566 int AlsaDriver::attach()
1567 {
1568 	char buf[32];
1569 	channel_t chn;
1570 	AudioChannel* chan;
1571 	int port_flags;
1572 
1573 	device->set_buffer_size (frames_per_cycle);
1574 	device->set_sample_rate (frame_rate);
1575 
1576 	port_flags = PortIsOutput|PortIsPhysical|PortIsTerminal;
1577 
1578 	for (chn = 0; chn < capture_nchannels; chn++) {
1579 
1580 		snprintf (buf, sizeof(buf) - 1, "capture_%lu", chn+1);
1581 
1582 		chan = device->register_capture_channel(buf, "32 bit float audio", port_flags, frames_per_cycle, chn);
1583 		chan->set_latency( frames_per_cycle + capture_frame_latency );
1584 		captureChannels.append(chan);
1585 
1586 	}
1587 
1588 	port_flags = PortIsInput|PortIsPhysical|PortIsTerminal;
1589 
1590 	for (chn = 0; chn < playback_nchannels; chn++) {
1591 
1592 		snprintf (buf, sizeof(buf) - 1, "playback_%lu", chn+1);
1593 
1594 		chan = device->register_playback_channel(buf, "32 bit float audio", port_flags, frames_per_cycle, chn);
1595 		chan->set_latency( frames_per_cycle + capture_frame_latency );
1596 		playbackChannels.append(chan);
1597 	}
1598 
1599 
1600 	return 1;
1601 }
1602 
detach()1603 int AlsaDriver::detach ()
1604 {
1605 	return 0;
1606 }
1607 
get_device_name()1608 QString AlsaDriver::get_device_name( )
1609 {
1610 	return alsa_device_name(false);
1611 }
1612 
get_device_longname()1613 QString AlsaDriver::get_device_longname( )
1614 {
1615 	return alsa_device_name(true);
1616 }
1617 
alsa_device_name(bool longname,int devicenumber)1618 QString AlsaDriver::alsa_device_name(bool longname, int devicenumber)
1619 {
1620 	snd_ctl_card_info_t *info;
1621 	snd_ctl_t *handle;
1622 	char name[32];
1623 	sprintf(name, "hw:%d", devicenumber);
1624 	int err = 0;
1625 
1626 	snd_ctl_card_info_alloca(&info);
1627 
1628 	if ((err = snd_ctl_open(&handle, name, devicenumber)) < 0) {
1629 		PMESG("AlsaDriver::alsa_device_name: Control open (device %i): %s", devicenumber, snd_strerror(err));
1630 		return "";
1631 	}
1632 
1633 	if ((err = snd_ctl_card_info(handle, info)) < 0) {
1634 		PMESG("Control hardware info (%i): %s", 0, snd_strerror(err));
1635 	}
1636 
1637 	snd_ctl_close(handle);
1638 
1639 	if (err < 0) {
1640 		return "Device name unknown";
1641 	}
1642 
1643 
1644 	if (longname) {
1645 		return snd_ctl_card_info_get_name(info);
1646 	}
1647 
1648 	return snd_ctl_card_info_get_id(info);
1649 }
1650 
1651 //eof
1652