xref: /third_party/alsa-utils/alsaloop/pcmjob.c (revision c72fcc34)
1/*
2 *  A simple PCM loopback utility
3 *  Copyright (c) 2010 by Jaroslav Kysela <perex@perex.cz>
4 *
5 *     Author: Jaroslav Kysela <perex@perex.cz>
6 *
7 *
8 *   This program is free software; you can redistribute it and/or modify
9 *   it under the terms of the GNU General Public License as published by
10 *   the Free Software Foundation; either version 2 of the License, or
11 *   (at your option) any later version.
12 *
13 *   This program 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
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 *
22 */
23
24#include "aconfig.h"
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sched.h>
29#include <errno.h>
30#include <getopt.h>
31#include <alsa/asoundlib.h>
32#include <sys/time.h>
33#include <math.h>
34#include <syslog.h>
35#include <pthread.h>
36#include "alsaloop.h"
37#include "os_compat.h"
38
39#define XRUN_PROFILE_UNKNOWN (-10000000)
40
41static int set_rate_shift(struct loopback_handle *lhandle, double pitch);
42static int get_rate(struct loopback_handle *lhandle);
43
44#define SYNCTYPE(v) [SYNC_TYPE_##v] = #v
45
46static const char *sync_types[] = {
47	SYNCTYPE(NONE),
48	SYNCTYPE(SIMPLE),
49	SYNCTYPE(CAPTRATESHIFT),
50	SYNCTYPE(PLAYRATESHIFT),
51	SYNCTYPE(SAMPLERATE),
52	SYNCTYPE(AUTO)
53};
54
55#define SRCTYPE(v) [SRC_##v] = "SRC_" #v
56
57#ifdef USE_SAMPLERATE
58static const char *src_types[] = {
59	SRCTYPE(SINC_BEST_QUALITY),
60	SRCTYPE(SINC_MEDIUM_QUALITY),
61	SRCTYPE(SINC_FASTEST),
62	SRCTYPE(ZERO_ORDER_HOLD),
63	SRCTYPE(LINEAR)
64};
65#endif
66
67static pthread_once_t pcm_open_mutex_once = PTHREAD_ONCE_INIT;
68static pthread_mutex_t pcm_open_mutex;
69
70static void pcm_open_init_mutex(void)
71{
72	pthread_mutexattr_t attr;
73
74	pthread_mutexattr_init(&attr);
75	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
76	pthread_mutex_init(&pcm_open_mutex, &attr);
77	pthread_mutexattr_destroy(&attr);
78}
79
80static inline void pcm_open_lock(void)
81{
82	pthread_once(&pcm_open_mutex_once, pcm_open_init_mutex);
83	if (workarounds & WORKAROUND_SERIALOPEN)
84	        pthread_mutex_lock(&pcm_open_mutex);
85}
86
87static inline void pcm_open_unlock(void)
88{
89	if (workarounds & WORKAROUND_SERIALOPEN)
90	        pthread_mutex_unlock(&pcm_open_mutex);
91}
92
93static inline snd_pcm_uframes_t get_whole_latency(struct loopback *loop)
94{
95	return loop->latency;
96}
97
98static inline unsigned long long
99			frames_to_time(unsigned int rate,
100				       snd_pcm_uframes_t frames)
101{
102	return (frames * 1000000ULL) / rate;
103}
104
105static inline snd_pcm_uframes_t time_to_frames(unsigned int rate,
106					       unsigned long long time)
107{
108	return (time * rate) / 1000000ULL;
109}
110
111static int setparams_stream(struct loopback_handle *lhandle,
112			    snd_pcm_hw_params_t *params)
113{
114	snd_pcm_t *handle = lhandle->handle;
115	int err;
116	unsigned int rrate;
117
118	err = snd_pcm_hw_params_any(handle, params);
119	if (err < 0) {
120		logit(LOG_CRIT, "Broken configuration for %s PCM: no configurations available: %s\n", lhandle->id, snd_strerror(err));
121		return err;
122	}
123	err = snd_pcm_hw_params_set_rate_resample(handle, params, lhandle->resample);
124	if (err < 0) {
125		logit(LOG_CRIT, "Resample setup failed for %s (val %u): %s\n", lhandle->id, lhandle->resample, snd_strerror(err));
126		return err;
127	}
128	err = snd_pcm_hw_params_set_access(handle, params, lhandle->access);
129	if (err < 0) {
130		logit(LOG_CRIT, "Access type not available for %s: %s\n", lhandle->id, snd_strerror(err));
131		return err;
132	}
133	err = snd_pcm_hw_params_set_format(handle, params, lhandle->format);
134	if (err < 0) {
135		logit(LOG_CRIT, "Sample format not available for %s: %s\n", lhandle->id, snd_strerror(err));
136		return err;
137	}
138	err = snd_pcm_hw_params_set_channels(handle, params, lhandle->channels);
139	if (err < 0) {
140		logit(LOG_CRIT, "Channels count (%u) not available for %s: %s\n", lhandle->channels, lhandle->id, snd_strerror(err));
141		return err;
142	}
143	rrate = lhandle->rate_req;
144	err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
145	if (err < 0) {
146		logit(LOG_CRIT, "Rate %uHz not available for %s: %s\n", lhandle->rate_req, lhandle->id, snd_strerror(err));
147		return err;
148	}
149	rrate = 0;
150	snd_pcm_hw_params_get_rate(params, &rrate, 0);
151	lhandle->rate = rrate;
152	if (
153#ifdef USE_SAMPLERATE
154	    !lhandle->loopback->src_enable &&
155#endif
156	    rrate != lhandle->rate) {
157		logit(LOG_CRIT, "Rate does not match (requested %uHz, got %uHz, resample %u)\n", lhandle->rate, rrate, lhandle->resample);
158		return -EINVAL;
159	}
160	lhandle->pitch = (double)lhandle->rate_req / (double)lhandle->rate;
161	return 0;
162}
163
164static int setparams_bufsize(struct loopback_handle *lhandle,
165			     snd_pcm_hw_params_t *params,
166			     snd_pcm_hw_params_t *tparams,
167			     snd_pcm_uframes_t bufsize)
168{
169	snd_pcm_t *handle = lhandle->handle;
170	int err;
171	snd_pcm_uframes_t periodsize;
172	snd_pcm_uframes_t buffersize;
173	snd_pcm_uframes_t last_bufsize = 0;
174
175	if (lhandle->buffer_size_req > 0) {
176		bufsize = lhandle->buffer_size_req;
177		last_bufsize = bufsize;
178		goto __set_it;
179	}
180      __again:
181	if (lhandle->buffer_size_req > 0) {
182		logit(LOG_CRIT, "Unable to set buffer size %li for %s\n", (long)lhandle->buffer_size, lhandle->id);
183		return -EIO;
184	}
185	if (last_bufsize == bufsize)
186		bufsize += 4;
187	last_bufsize = bufsize;
188	if (bufsize > 10*1024*1024) {
189		logit(LOG_CRIT, "Buffer size too big\n");
190		return -EIO;
191	}
192      __set_it:
193	snd_pcm_hw_params_copy(params, tparams);
194	periodsize = bufsize * 8;
195	err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &periodsize);
196	if (err < 0) {
197		logit(LOG_CRIT, "Unable to set buffer size %li for %s: %s\n", periodsize, lhandle->id, snd_strerror(err));
198		goto __again;
199	}
200	snd_pcm_hw_params_get_buffer_size(params, &periodsize);
201	if (verbose > 6)
202		snd_output_printf(lhandle->loopback->output, "%s: buffer_size=%li\n", lhandle->id, periodsize);
203	if (lhandle->period_size_req > 0)
204		periodsize = lhandle->period_size_req;
205	else
206		periodsize /= 8;
207	err = snd_pcm_hw_params_set_period_size_near(handle, params, &periodsize, 0);
208	if (err < 0) {
209		logit(LOG_CRIT, "Unable to set period size %li for %s: %s\n", periodsize, lhandle->id, snd_strerror(err));
210		goto __again;
211	}
212	snd_pcm_hw_params_get_period_size(params, &periodsize, NULL);
213	if (verbose > 6)
214		snd_output_printf(lhandle->loopback->output, "%s: period_size=%li\n", lhandle->id, periodsize);
215	if (periodsize != bufsize)
216		bufsize = periodsize;
217	snd_pcm_hw_params_get_buffer_size(params, &buffersize);
218	if (periodsize * 2 > buffersize)
219		goto __again;
220	lhandle->period_size = periodsize;
221	lhandle->buffer_size = buffersize;
222	return 0;
223}
224
225static int setparams_set(struct loopback_handle *lhandle,
226			 snd_pcm_hw_params_t *params,
227			 snd_pcm_sw_params_t *swparams,
228			 snd_pcm_uframes_t bufsize)
229{
230	snd_pcm_t *handle = lhandle->handle;
231	int err;
232	snd_pcm_uframes_t val, period_size, buffer_size;
233
234	err = snd_pcm_hw_params(handle, params);
235	if (err < 0) {
236		logit(LOG_CRIT, "Unable to set hw params for %s: %s\n", lhandle->id, snd_strerror(err));
237		return err;
238	}
239	err = snd_pcm_sw_params_current(handle, swparams);
240	if (err < 0) {
241		logit(LOG_CRIT, "Unable to determine current swparams for %s: %s\n", lhandle->id, snd_strerror(err));
242		return err;
243	}
244	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0x7fffffff);
245	if (err < 0) {
246		logit(LOG_CRIT, "Unable to set start threshold mode for %s: %s\n", lhandle->id, snd_strerror(err));
247		return err;
248	}
249	snd_pcm_hw_params_get_period_size(params, &period_size, NULL);
250	snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
251	if (lhandle->nblock) {
252		if (lhandle == lhandle->loopback->play) {
253			val = buffer_size - (2 * period_size - 4);
254		} else {
255			val = 4;
256		}
257		if (verbose > 6)
258			snd_output_printf(lhandle->loopback->output, "%s: avail_min1=%li\n", lhandle->id, val);
259	} else {
260		if (lhandle == lhandle->loopback->play) {
261			val = bufsize + bufsize / 2;
262			if (val > (buffer_size * 3) / 4)
263				val = (buffer_size * 3) / 4;
264			val = buffer_size - val;
265		} else {
266			val = bufsize / 2;
267			if (val > buffer_size / 4)
268				val = buffer_size / 4;
269		}
270		if (verbose > 6)
271			snd_output_printf(lhandle->loopback->output, "%s: avail_min2=%li\n", lhandle->id, val);
272	}
273	err = snd_pcm_sw_params_set_avail_min(handle, swparams, val);
274	if (err < 0) {
275		logit(LOG_CRIT, "Unable to set avail min for %s: %s\n", lhandle->id, snd_strerror(err));
276		return err;
277	}
278	snd_pcm_sw_params_get_avail_min(swparams, &lhandle->avail_min);
279	err = snd_pcm_sw_params(handle, swparams);
280	if (err < 0) {
281		logit(LOG_CRIT, "Unable to set sw params for %s: %s\n", lhandle->id, snd_strerror(err));
282		return err;
283	}
284	return 0;
285}
286
287static int increase_playback_avail_min(struct loopback_handle *lhandle)
288{
289	snd_pcm_t *handle = lhandle->handle;
290	snd_pcm_sw_params_t *swparams;
291	struct timespec ts;
292	int err;
293
294	if (lhandle->avail_min + (lhandle->period_size / 2) > lhandle->buffer_size) {
295		/* avoid 100% CPU usage for broken plugins */
296		ts.tv_sec = 0;
297		ts.tv_nsec = 10000;
298		nanosleep(&ts, NULL);
299		return 0;
300	}
301	snd_pcm_sw_params_alloca(&swparams);
302	err = snd_pcm_sw_params_current(handle, swparams);
303	if (err < 0) {
304		logit(LOG_CRIT, "Unable to determine current swparams for %s: %s\n", lhandle->id, snd_strerror(err));
305		return err;
306	}
307	err = snd_pcm_sw_params_set_avail_min(handle, swparams, lhandle->avail_min + 4);
308	if (err < 0) {
309		logit(LOG_CRIT, "Unable to set avail min for %s: %s\n", lhandle->id, snd_strerror(err));
310		return err;
311	}
312	snd_pcm_sw_params_get_avail_min(swparams, &lhandle->avail_min);
313	if (verbose > 6)
314		snd_output_printf(lhandle->loopback->output, "%s: change avail_min=%li\n", lhandle->id, lhandle->avail_min);
315	err = snd_pcm_sw_params(handle, swparams);
316	if (err < 0) {
317		logit(LOG_CRIT, "Unable to set sw params for %s: %s\n", lhandle->id, snd_strerror(err));
318		return err;
319	}
320	return 0;
321}
322
323static int setparams(struct loopback *loop, snd_pcm_uframes_t bufsize)
324{
325	int err;
326	snd_pcm_hw_params_t *pt_params, *ct_params;	/* templates with rate, format and channels */
327	snd_pcm_hw_params_t *p_params, *c_params;
328	snd_pcm_sw_params_t *p_swparams, *c_swparams;
329
330	snd_pcm_hw_params_alloca(&p_params);
331	snd_pcm_hw_params_alloca(&c_params);
332	snd_pcm_hw_params_alloca(&pt_params);
333	snd_pcm_hw_params_alloca(&ct_params);
334	snd_pcm_sw_params_alloca(&p_swparams);
335	snd_pcm_sw_params_alloca(&c_swparams);
336	if ((err = setparams_stream(loop->play, pt_params)) < 0) {
337		logit(LOG_CRIT, "Unable to set parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
338		return err;
339	}
340	if ((err = setparams_stream(loop->capt, ct_params)) < 0) {
341		logit(LOG_CRIT, "Unable to set parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
342		return err;
343	}
344
345	if ((err = setparams_bufsize(loop->play, p_params, pt_params, bufsize / loop->play->pitch)) < 0) {
346		logit(LOG_CRIT, "Unable to set buffer parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
347		return err;
348	}
349	if ((err = setparams_bufsize(loop->capt, c_params, ct_params, bufsize / loop->capt->pitch)) < 0) {
350		logit(LOG_CRIT, "Unable to set buffer parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
351		return err;
352	}
353
354	if ((err = setparams_set(loop->play, p_params, p_swparams, bufsize / loop->play->pitch)) < 0) {
355		logit(LOG_CRIT, "Unable to set sw parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
356		return err;
357	}
358	if ((err = setparams_set(loop->capt, c_params, c_swparams, bufsize / loop->capt->pitch)) < 0) {
359		logit(LOG_CRIT, "Unable to set sw parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
360		return err;
361	}
362
363#if 0
364	if (!loop->linked)
365		if (snd_pcm_link(loop->capt->handle, loop->play->handle) >= 0)
366			loop->linked = 1;
367#endif
368	if ((err = snd_pcm_prepare(loop->play->handle)) < 0) {
369		logit(LOG_CRIT, "Prepare %s error: %s\n", loop->play->id, snd_strerror(err));
370		return err;
371	}
372	if (!loop->linked && (err = snd_pcm_prepare(loop->capt->handle)) < 0) {
373		logit(LOG_CRIT, "Prepare %s error: %s\n", loop->capt->id, snd_strerror(err));
374		return err;
375	}
376
377	if (verbose) {
378		snd_pcm_dump(loop->play->handle, loop->output);
379		snd_pcm_dump(loop->capt->handle, loop->output);
380	}
381	return 0;
382}
383
384static void showlatency(snd_output_t *out, size_t latency, unsigned int rate,
385			char *prefix)
386{
387	double d;
388	d = (double)latency / (double)rate;
389	snd_output_printf(out, "%s %li frames, %.3fus, %.6fms (%.4fHz)\n", prefix, (long)latency, d * 1000000, d * 1000, (double)1 / d);
390}
391
392static long timediff(snd_timestamp_t t1, snd_timestamp_t t2)
393{
394	signed long l;
395
396	t1.tv_sec -= t2.tv_sec;
397	if (t1.tv_usec < t2.tv_usec) {
398		l = ((t1.tv_usec + 1000000) - t2.tv_usec) % 1000000;
399		t1.tv_sec--;
400	} else {
401		l = t1.tv_usec - t2.tv_usec;
402	}
403	return (t1.tv_sec * 1000000) + l;
404}
405
406static int getcurtimestamp(snd_timestamp_t *ts)
407{
408	struct timeval tv;
409	gettimeofday(&tv, NULL);
410	ts->tv_sec = tv.tv_sec;
411	ts->tv_usec = tv.tv_usec;
412	return 0;
413}
414
415static void xrun_profile0(struct loopback *loop)
416{
417	snd_pcm_sframes_t pdelay, cdelay;
418
419	if (snd_pcm_delay(loop->play->handle, &pdelay) >= 0 &&
420	    snd_pcm_delay(loop->capt->handle, &cdelay) >= 0) {
421		getcurtimestamp(&loop->xrun_last_update);
422		loop->xrun_last_pdelay = pdelay;
423		loop->xrun_last_cdelay = cdelay;
424		loop->xrun_buf_pcount = loop->play->buf_count;
425		loop->xrun_buf_ccount = loop->capt->buf_count;
426#ifdef USE_SAMPLERATE
427		loop->xrun_out_frames = loop->src_out_frames;
428#endif
429	}
430}
431
432static inline void xrun_profile(struct loopback *loop)
433{
434	if (loop->xrun)
435		xrun_profile0(loop);
436}
437
438static void xrun_stats0(struct loopback *loop)
439{
440	snd_timestamp_t t;
441	double expected, last, wake, check, queued = -1, proc, missing = -1;
442	double maxbuf, pfilled, cfilled, cqueued = -1, avail_min;
443	double sincejob;
444
445	expected = ((double)loop->latency /
446				(double)loop->play->rate_req) * 1000;
447	getcurtimestamp(&t);
448	last = (double)timediff(t, loop->xrun_last_update) / 1000;
449	wake = (double)timediff(t, loop->xrun_last_wake) / 1000;
450	check = (double)timediff(t, loop->xrun_last_check) / 1000;
451	sincejob = (double)timediff(t, loop->tstamp_start) / 1000;
452	if (loop->xrun_last_pdelay != XRUN_PROFILE_UNKNOWN)
453		queued = ((double)loop->xrun_last_pdelay /
454				(double)loop->play->rate) * 1000;
455	if (loop->xrun_last_cdelay != XRUN_PROFILE_UNKNOWN)
456		cqueued = ((double)loop->xrun_last_cdelay /
457				(double)loop->capt->rate) * 1000;
458	maxbuf = ((double)loop->play->buffer_size /
459				(double)loop->play->rate) * 1000;
460	proc = (double)loop->xrun_max_proctime / 1000;
461	pfilled = ((double)(loop->xrun_buf_pcount + loop->xrun_out_frames) /
462				(double)loop->play->rate) * 1000;
463	cfilled = ((double)loop->xrun_buf_ccount /
464				(double)loop->capt->rate) * 1000;
465	avail_min = (((double)loop->play->buffer_size -
466				(double)loop->play->avail_min ) /
467				(double)loop->play->rate) * 1000;
468	avail_min = expected - avail_min;
469	if (queued >= 0)
470		missing = last - queued;
471	if (missing >= 0 && loop->xrun_max_missing < missing)
472		loop->xrun_max_missing = missing;
473	loop->xrun_max_proctime = 0;
474	getcurtimestamp(&t);
475	logit(LOG_INFO, "  last write before %.4fms, queued %.4fms/%.4fms -> missing %.4fms\n", last, queued, cqueued, missing);
476	logit(LOG_INFO, "  expected %.4fms, processing %.4fms, max missing %.4fms\n", expected, proc, loop->xrun_max_missing);
477	logit(LOG_INFO, "  last wake %.4fms, last check %.4fms, avail_min %.4fms\n", wake, check, avail_min);
478	logit(LOG_INFO, "  max buf %.4fms, pfilled %.4fms, cfilled %.4fms\n", maxbuf, pfilled, cfilled);
479	logit(LOG_INFO, "  job started before %.4fms\n", sincejob);
480}
481
482static inline void xrun_stats(struct loopback *loop)
483{
484	if (loop->xrun)
485		xrun_stats0(loop);
486}
487
488static inline snd_pcm_uframes_t buf_avail(struct loopback_handle *lhandle)
489{
490	return lhandle->buf_size - lhandle->buf_count;
491}
492
493static void buf_remove(struct loopback *loop, snd_pcm_uframes_t count)
494{
495	/* remove samples from the capture buffer */
496	if (count <= 0)
497		return;
498	if (loop->play->buf == loop->capt->buf) {
499		if (count < loop->capt->buf_count)
500			loop->capt->buf_count -= count;
501		else
502			loop->capt->buf_count = 0;
503	}
504}
505
506#if 0
507static void buf_add_copy(struct loopback *loop)
508{
509	struct loopback_handle *capt = loop->capt;
510	struct loopback_handle *play = loop->play;
511	snd_pcm_uframes_t count, count1, cpos, ppos;
512
513	count = capt->buf_count;
514	cpos = capt->buf_pos - count;
515	if (cpos > capt->buf_size)
516		cpos += capt->buf_size;
517	ppos = (play->buf_pos + play->buf_count) % play->buf_size;
518	while (count > 0) {
519		count1 = count;
520		if (count1 + cpos > capt->buf_size)
521			count1 = capt->buf_size - cpos;
522		if (count1 > buf_avail(play))
523			count1 = buf_avail(play);
524		if (count1 + ppos > play->buf_size)
525			count1 = play->buf_size - ppos;
526		if (count1 == 0)
527			break;
528		memcpy(play->buf + ppos * play->frame_size,
529		       capt->buf + cpos * capt->frame_size,
530		       count1 * capt->frame_size);
531		play->buf_count += count1;
532		capt->buf_count -= count1;
533		ppos += count1;
534		ppos %= play->buf_size;
535		cpos += count1;
536		cpos %= capt->buf_size;
537		count -= count1;
538	}
539}
540#endif
541
542#ifdef USE_SAMPLERATE
543static void buf_add_src(struct loopback *loop)
544{
545	struct loopback_handle *capt = loop->capt;
546	struct loopback_handle *play = loop->play;
547	float *old_data_out;
548	snd_pcm_uframes_t count, pos, count1, pos1;
549	count = capt->buf_count;
550	pos = 0;
551	pos1 = capt->buf_pos - count;
552	if (pos1 > capt->buf_size)
553		pos1 += capt->buf_size;
554	while (count > 0) {
555		count1 = count;
556		if (count1 + pos1 > capt->buf_size)
557			count1 = capt->buf_size - pos1;
558		if (capt->format == SND_PCM_FORMAT_S32)
559			src_int_to_float_array((int *)(capt->buf +
560						pos1 * capt->frame_size),
561					 (float *)loop->src_data.data_in +
562					   pos * capt->channels,
563					 count1 * capt->channels);
564		else
565			src_short_to_float_array((short *)(capt->buf +
566						pos1 * capt->frame_size),
567					 (float *)loop->src_data.data_in +
568					   pos * capt->channels,
569					 count1 * capt->channels);
570		count -= count1;
571		pos += count1;
572		pos1 += count1;
573		pos1 %= capt->buf_size;
574	}
575	loop->src_data.input_frames = pos;
576	loop->src_data.output_frames = play->buf_size -
577						loop->src_out_frames;
578	loop->src_data.end_of_input = 0;
579	old_data_out = loop->src_data.data_out;
580	loop->src_data.data_out = old_data_out + loop->src_out_frames;
581	src_process(loop->src_state, &loop->src_data);
582	loop->src_data.data_out = old_data_out;
583	capt->buf_count -= loop->src_data.input_frames_used;
584	count = loop->src_data.output_frames_gen +
585		loop->src_out_frames;
586	pos = 0;
587	pos1 = (play->buf_pos + play->buf_count) % play->buf_size;
588	while (count > 0) {
589		count1 = count;
590		if (count1 + pos1 > play->buf_size)
591			count1 = play->buf_size - pos1;
592		if (count1 > buf_avail(play))
593			count1 = buf_avail(play);
594		if (count1 == 0)
595			break;
596		if (capt->format == SND_PCM_FORMAT_S32)
597			src_float_to_int_array(loop->src_data.data_out +
598					   pos * play->channels,
599					 (int *)(play->buf +
600					   pos1 * play->frame_size),
601					 count1 * play->channels);
602		else
603			src_float_to_short_array(loop->src_data.data_out +
604					   pos * play->channels,
605					 (short *)(play->buf +
606					   pos1 * play->frame_size),
607					 count1 * play->channels);
608		play->buf_count += count1;
609		count -= count1;
610		pos += count1;
611		pos1 += count1;
612		pos1 %= play->buf_size;
613	}
614#if 0
615	printf("src: pos = %li, gen = %li, out = %li, count = %li\n",
616		(long)pos, (long)loop->src_data.output_frames_gen,
617		(long)loop->src_out_frames, play->buf_count);
618#endif
619	loop->src_out_frames = (loop->src_data.output_frames_gen +
620					loop->src_out_frames) - pos;
621	if (loop->src_out_frames > 0) {
622		memmove(loop->src_data.data_out,
623			loop->src_data.data_out + pos * play->channels,
624			loop->src_out_frames * play->channels * sizeof(float));
625	}
626}
627#else
628static void buf_add_src(struct loopback *loop ATTRIBUTE_UNUSED)
629{
630}
631#endif
632
633static void buf_add(struct loopback *loop, snd_pcm_uframes_t count)
634{
635	/* copy samples from capture to playback buffer */
636	if (count <= 0)
637		return;
638	if (loop->play->buf == loop->capt->buf) {
639		loop->play->buf_count += count;
640	} else {
641		buf_add_src(loop);
642	}
643}
644
645static int xrun(struct loopback_handle *lhandle)
646{
647	int err;
648
649	if (lhandle == lhandle->loopback->play) {
650		logit(LOG_DEBUG, "underrun for %s\n", lhandle->id);
651		xrun_stats(lhandle->loopback);
652		if ((err = snd_pcm_prepare(lhandle->handle)) < 0)
653			return err;
654		lhandle->xrun_pending = 1;
655	} else {
656		logit(LOG_DEBUG, "overrun for %s\n", lhandle->id);
657		xrun_stats(lhandle->loopback);
658		if ((err = snd_pcm_prepare(lhandle->handle)) < 0)
659			return err;
660		lhandle->xrun_pending = 1;
661	}
662	return 0;
663}
664
665static int suspend(struct loopback_handle *lhandle)
666{
667	int err;
668
669	while ((err = snd_pcm_resume(lhandle->handle)) == -EAGAIN)
670		usleep(1);
671	if (err < 0)
672		return xrun(lhandle);
673	return 0;
674}
675
676static int readit(struct loopback_handle *lhandle)
677{
678	snd_pcm_sframes_t r, res = 0;
679	snd_pcm_sframes_t avail;
680	int err;
681
682	avail = snd_pcm_avail_update(lhandle->handle);
683	if (avail == -EPIPE) {
684		return xrun(lhandle);
685	} else if (avail == -ESTRPIPE) {
686		if ((err = suspend(lhandle)) < 0)
687			return err;
688	}
689	if ((snd_pcm_uframes_t)avail > buf_avail(lhandle)) {
690		lhandle->buf_over += avail - buf_avail(lhandle);
691		avail = buf_avail(lhandle);
692	} else if (avail == 0) {
693		if (snd_pcm_state(lhandle->handle) == SND_PCM_STATE_DRAINING) {
694			lhandle->loopback->reinit = 1;
695			return 0;
696		}
697	}
698	while (avail > 0) {
699		r = buf_avail(lhandle);
700		if (r + lhandle->buf_pos > lhandle->buf_size)
701			r = lhandle->buf_size - lhandle->buf_pos;
702		if (r > avail)
703			r = avail;
704		r = snd_pcm_readi(lhandle->handle,
705				  lhandle->buf +
706				  lhandle->buf_pos *
707				  lhandle->frame_size, r);
708		if (r == 0)
709			return res;
710		if (r < 0) {
711			if (r == -EPIPE) {
712				err = xrun(lhandle);
713				return res > 0 ? res : err;
714			} else if (r == -ESTRPIPE) {
715				if ((err = suspend(lhandle)) < 0)
716					return res > 0 ? res : err;
717				r = 0;
718			} else {
719				return res > 0 ? res : r;
720			}
721		}
722#ifdef FILE_CWRITE
723		if (lhandle->loopback->cfile)
724			fwrite(lhandle->buf + lhandle->buf_pos * lhandle->frame_size,
725			       r, lhandle->frame_size, lhandle->loopback->cfile);
726#endif
727		res += r;
728		if (lhandle->max < (snd_pcm_uframes_t)res)
729			lhandle->max = res;
730		lhandle->counter += r;
731		lhandle->buf_count += r;
732		lhandle->buf_pos += r;
733		lhandle->buf_pos %= lhandle->buf_size;
734		avail -= r;
735	}
736	return res;
737}
738
739static int writeit(struct loopback_handle *lhandle)
740{
741	snd_pcm_sframes_t avail;
742	snd_pcm_sframes_t r, res = 0;
743	int err;
744
745      __again:
746	avail = snd_pcm_avail_update(lhandle->handle);
747	if (avail == -EPIPE) {
748		if ((err = xrun(lhandle)) < 0)
749			return err;
750		return res;
751	} else if (avail == -ESTRPIPE) {
752		if ((err = suspend(lhandle)) < 0)
753			return err;
754		goto __again;
755	}
756	while (avail > 0 && lhandle->buf_count > 0) {
757		r = lhandle->buf_count;
758		if (r + lhandle->buf_pos > lhandle->buf_size)
759			r = lhandle->buf_size - lhandle->buf_pos;
760		if (r > avail)
761			r = avail;
762		r = snd_pcm_writei(lhandle->handle,
763				   lhandle->buf +
764				   lhandle->buf_pos *
765				   lhandle->frame_size, r);
766		if (r <= 0) {
767			if (r == -EPIPE) {
768				if ((err = xrun(lhandle)) < 0)
769					return err;
770				return res;
771			} else if (r == -ESTRPIPE) {
772			}
773			return res > 0 ? res : r;
774		}
775#ifdef FILE_PWRITE
776		if (lhandle->loopback->pfile)
777			fwrite(lhandle->buf + lhandle->buf_pos * lhandle->frame_size,
778			       r, lhandle->frame_size, lhandle->loopback->pfile);
779#endif
780		res += r;
781		lhandle->counter += r;
782		lhandle->buf_count -= r;
783		lhandle->buf_pos += r;
784		lhandle->buf_pos %= lhandle->buf_size;
785		xrun_profile(lhandle->loopback);
786		if (lhandle->loopback->stop_pending) {
787			lhandle->loopback->stop_count += r;
788			if (lhandle->loopback->stop_count * lhandle->pitch >
789			    lhandle->loopback->latency * 3) {
790				lhandle->loopback->stop_pending = 0;
791				lhandle->loopback->reinit = 1;
792				break;
793			}
794		}
795	}
796	return res;
797}
798
799static snd_pcm_sframes_t remove_samples(struct loopback *loop,
800					int capture_preferred,
801					snd_pcm_sframes_t count)
802{
803	struct loopback_handle *play = loop->play;
804	struct loopback_handle *capt = loop->capt;
805
806	if (loop->play->buf == loop->capt->buf) {
807		if ((snd_pcm_uframes_t)count > loop->play->buf_count)
808			count = loop->play->buf_count;
809		if ((snd_pcm_uframes_t)count > loop->capt->buf_count)
810			count = loop->capt->buf_count;
811		capt->buf_count -= count;
812		play->buf_pos += count;
813		play->buf_pos %= play->buf_size;
814		play->buf_count -= count;
815		return count;
816	}
817	if (capture_preferred) {
818		if ((snd_pcm_uframes_t)count > capt->buf_count)
819			count = capt->buf_count;
820		capt->buf_count -= count;
821	} else {
822		if ((snd_pcm_uframes_t)count > play->buf_count)
823			count = play->buf_count;
824		play->buf_count -= count;
825	}
826	return count;
827}
828
829static int xrun_sync(struct loopback *loop)
830{
831	struct loopback_handle *play = loop->play;
832	struct loopback_handle *capt = loop->capt;
833	snd_pcm_sframes_t fill = get_whole_latency(loop);
834	snd_pcm_sframes_t pdelay, cdelay, delay1, pdelay1, cdelay1, diff;
835	int err;
836
837      __again:
838	if (verbose > 5)
839		snd_output_printf(loop->output, "%s: xrun sync %i %i\n", loop->id, capt->xrun_pending, play->xrun_pending);
840	if (capt->xrun_pending) {
841	      __pagain:
842		capt->xrun_pending = 0;
843		if ((err = snd_pcm_prepare(capt->handle)) < 0) {
844			logit(LOG_CRIT, "%s prepare failed: %s\n", capt->id, snd_strerror(err));
845			return err;
846		}
847		if ((err = snd_pcm_start(capt->handle)) < 0) {
848			logit(LOG_CRIT, "%s start failed: %s\n", capt->id, snd_strerror(err));
849			return err;
850		}
851	} else {
852		diff = readit(capt);
853		buf_add(loop, diff);
854		if (capt->xrun_pending)
855			goto __pagain;
856	}
857	/* skip additional playback samples */
858	if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0) {
859		if (err == -EPIPE) {
860			capt->xrun_pending = 1;
861			goto __again;
862		}
863		if (err == -ESTRPIPE) {
864			err = suspend(capt);
865			if (err < 0)
866				return err;
867			goto __again;
868		}
869		logit(LOG_CRIT, "%s capture delay failed: %s\n", capt->id, snd_strerror(err));
870		return err;
871	}
872	if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0) {
873		if (err == -EPIPE) {
874			pdelay = 0;
875			play->xrun_pending = 1;
876		} else if (err == -ESTRPIPE) {
877			err = suspend(play);
878			if (err < 0)
879				return err;
880			goto __again;
881		} else {
882			logit(LOG_CRIT, "%s playback delay failed: %s\n", play->id, snd_strerror(err));
883			return err;
884		}
885	}
886	capt->counter = cdelay;
887	play->counter = pdelay;
888	if (play->buf != capt->buf)
889		cdelay += capt->buf_count;
890	pdelay += play->buf_count;
891#ifdef USE_SAMPLERATE
892	pdelay += loop->src_out_frames;
893#endif
894	cdelay1 = cdelay * capt->pitch;
895	pdelay1 = pdelay * play->pitch;
896	delay1 = cdelay1 + pdelay1;
897	capt->total_queued = 0;
898	play->total_queued = 0;
899	loop->total_queued_count = 0;
900	loop->pitch_diff = loop->pitch_diff_min = loop->pitch_diff_max = 0;
901	if (verbose > 6) {
902		snd_output_printf(loop->output,
903			"sync: cdelay=%li(%li), pdelay=%li(%li), fill=%li (delay=%li)"
904#ifdef USE_SAMPLERATE
905			", src_out=%li"
906#endif
907			"\n",
908			(long)cdelay, (long)cdelay1, (long)pdelay, (long)pdelay1,
909			(long)fill, (long)delay1
910#ifdef USE_SAMPLERATE
911			, (long)loop->src_out_frames
912#endif
913			);
914		snd_output_printf(loop->output,
915			"sync: cbufcount=%li, pbufcount=%li\n",
916			(long)capt->buf_count, (long)play->buf_count);
917	}
918	if (delay1 > fill && capt->counter > 0) {
919		if ((err = snd_pcm_drop(capt->handle)) < 0)
920			return err;
921		if ((err = snd_pcm_prepare(capt->handle)) < 0)
922			return err;
923		if ((err = snd_pcm_start(capt->handle)) < 0)
924			return err;
925		diff = remove_samples(loop, 1, (delay1 - fill) / capt->pitch);
926		if (verbose > 6)
927			snd_output_printf(loop->output,
928				"sync: capt stop removed %li samples\n", (long)diff);
929		goto __again;
930	}
931	if (delay1 > fill) {
932		diff = (delay1 - fill) / play->pitch;
933		if ((snd_pcm_uframes_t)diff > play->buf_count)
934			diff = play->buf_count;
935		if (verbose > 6)
936			snd_output_printf(loop->output,
937				"sync: removing %li playback samples, delay1=%li\n", (long)diff, (long)delay1);
938		diff = remove_samples(loop, 0, diff);
939		pdelay -= diff;
940		pdelay1 = pdelay * play->pitch;
941		delay1 = cdelay1 + pdelay1;
942		if (verbose > 6)
943			snd_output_printf(loop->output,
944				"sync: removed %li playback samples, delay1=%li\n", (long)diff, (long)delay1);
945	}
946	if (delay1 > fill) {
947		diff = (delay1 - fill) / capt->pitch;
948		if ((snd_pcm_uframes_t)diff > capt->buf_count)
949			diff = capt->buf_count;
950		if (verbose > 6)
951			snd_output_printf(loop->output,
952				"sync: removing %li captured samples, delay1=%li\n", (long)diff, (long)delay1);
953		diff -= remove_samples(loop, 1, diff);
954		cdelay -= diff;
955		cdelay1 = cdelay * capt->pitch;
956		delay1 = cdelay1 + pdelay1;
957		if (verbose > 6)
958			snd_output_printf(loop->output,
959				"sync: removed %li captured samples, delay1=%li\n", (long)diff, (long)delay1);
960	}
961	if (play->xrun_pending) {
962		play->xrun_pending = 0;
963		diff = (fill - delay1) / play->pitch;
964		if (verbose > 6)
965			snd_output_printf(loop->output,
966				"sync: xrun_pending, silence filling %li / buf_count=%li\n", (long)diff, play->buf_count);
967		if (fill > delay1 && play->buf_count < (snd_pcm_uframes_t)diff) {
968			diff = diff - play->buf_count;
969			if (verbose > 6)
970				snd_output_printf(loop->output,
971					"sync: playback silence added %li samples\n", (long)diff);
972			play->buf_pos -= diff;
973			play->buf_pos %= play->buf_size;
974			err =  snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->frame_size,
975							  diff * play->channels);
976			if (err < 0)
977				return err;
978			play->buf_count += diff;
979		}
980		if ((err = snd_pcm_prepare(play->handle)) < 0) {
981			logit(LOG_CRIT, "%s prepare failed: %s\n", play->id, snd_strerror(err));
982			return err;
983		}
984		delay1 = writeit(play);
985		if (verbose > 6)
986			snd_output_printf(loop->output,
987				"sync: playback wrote %li samples\n", (long)delay1);
988		if (delay1 > diff) {
989			buf_remove(loop, delay1 - diff);
990			if (verbose > 6)
991				snd_output_printf(loop->output,
992					"sync: playback buf_remove %li samples\n", (long)(delay1 - diff));
993		}
994		if ((err = snd_pcm_start(play->handle)) < 0) {
995			logit(LOG_CRIT, "%s start failed: %s\n", play->id, snd_strerror(err));
996			return err;
997		}
998	} else if (delay1 < (snd_pcm_sframes_t)fill) {
999		diff = (fill - delay1) / play->pitch;
1000		while (diff > 0) {
1001			delay1 = play->buf_size - play->buf_pos;
1002			if (verbose > 6)
1003				snd_output_printf(loop->output,
1004					"sync: playback short, silence filling %li / buf_count=%li\n", (long)delay1, play->buf_count);
1005			if (delay1 > diff)
1006				delay1 = diff;
1007			err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->frame_size,
1008							 delay1 * play->channels);
1009			if (err < 0)
1010				return err;
1011			play->buf_pos += delay1;
1012			play->buf_pos %= play->buf_size;
1013			play->buf_count += delay1;
1014			diff -= delay1;
1015		}
1016		writeit(play);
1017	}
1018	if (verbose > 5) {
1019		snd_output_printf(loop->output, "%s: xrun sync ok\n", loop->id);
1020		if (verbose > 6) {
1021			if (snd_pcm_delay(capt->handle, &cdelay) < 0)
1022				cdelay = -1;
1023			if (snd_pcm_delay(play->handle, &pdelay) < 0)
1024				pdelay = -1;
1025			if (play->buf != capt->buf)
1026				cdelay += capt->buf_count;
1027			pdelay += play->buf_count;
1028#ifdef USE_SAMPLERATE
1029			pdelay += loop->src_out_frames;
1030#endif
1031			cdelay1 = cdelay * capt->pitch;
1032			pdelay1 = pdelay * play->pitch;
1033			delay1 = cdelay1 + pdelay1;
1034			snd_output_printf(loop->output, "%s: sync verify: %li\n", loop->id, delay1);
1035		}
1036	}
1037	loop->xrun_max_proctime = 0;
1038	return 0;
1039}
1040
1041static int set_notify(struct loopback_handle *lhandle, int enable)
1042{
1043	int err;
1044
1045	if (lhandle->ctl_notify == NULL)
1046		return 0;
1047	snd_ctl_elem_value_set_boolean(lhandle->ctl_notify, 0, enable);
1048	err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_notify);
1049	if (err < 0) {
1050		logit(LOG_CRIT, "Cannot set PCM Notify element for %s: %s\n", lhandle->id, snd_strerror(err));
1051		return err;
1052	}
1053	err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_notify);
1054	if (err < 0) {
1055		logit(LOG_CRIT, "Cannot get PCM Notify element for %s: %s\n", lhandle->id, snd_strerror(err));
1056		return err;
1057	}
1058	return 0;
1059}
1060
1061static int set_rate_shift(struct loopback_handle *lhandle, double pitch)
1062{
1063	int err;
1064
1065	if (lhandle->ctl_rate_shift) {
1066		snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, pitch * 100000);
1067		err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_rate_shift);
1068	} else if (lhandle->ctl_pitch) {
1069		// 'Playback/Capture Pitch 1000000' requires reciprocal to pitch
1070		snd_ctl_elem_value_set_integer(lhandle->ctl_pitch, 0, (1 / pitch) * 1000000);
1071		err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_pitch);
1072	} else {
1073		return 0;
1074	}
1075	if (err < 0) {
1076		logit(LOG_CRIT, "Cannot set PCM Rate Shift element for %s: %s\n", lhandle->id, snd_strerror(err));
1077		return err;
1078	}
1079	return 0;
1080}
1081
1082void update_pitch(struct loopback *loop)
1083{
1084	double pitch = loop->pitch;
1085
1086#ifdef USE_SAMPLERATE
1087	if (loop->sync == SYNC_TYPE_SAMPLERATE) {
1088		loop->src_data.src_ratio = (double)1.0 / (pitch *
1089				loop->play->pitch * loop->capt->pitch);
1090		if (verbose > 2)
1091			snd_output_printf(loop->output, "%s: Samplerate src_ratio update1: %.8f\n", loop->id, loop->src_data.src_ratio);
1092	} else
1093#endif
1094	if (loop->sync == SYNC_TYPE_CAPTRATESHIFT) {
1095		set_rate_shift(loop->capt, pitch);
1096#ifdef USE_SAMPLERATE
1097		if (loop->use_samplerate) {
1098			loop->src_data.src_ratio =
1099				(double)1.0 /
1100					(loop->play->pitch * loop->capt->pitch);
1101			if (verbose > 2)
1102				snd_output_printf(loop->output, "%s: Samplerate src_ratio update2: %.8f\n", loop->id, loop->src_data.src_ratio);
1103		}
1104#endif
1105	}
1106	else if (loop->sync == SYNC_TYPE_PLAYRATESHIFT) {
1107		// pitch is capture-based, playback side requires reciprocal
1108		set_rate_shift(loop->play, 1 / pitch);
1109#ifdef USE_SAMPLERATE
1110		if (loop->use_samplerate) {
1111			loop->src_data.src_ratio =
1112				(double)1.0 /
1113					(loop->play->pitch * loop->capt->pitch);
1114			if (verbose > 2)
1115				snd_output_printf(loop->output, "%s: Samplerate src_ratio update3: %.8f\n", loop->id, loop->src_data.src_ratio);
1116		}
1117#endif
1118	}
1119	if (verbose)
1120		snd_output_printf(loop->output, "New pitch for %s: %.8f (min/max samples = %li/%li)\n", loop->id, pitch, loop->pitch_diff_min, loop->pitch_diff_max);
1121}
1122
1123static int get_active(struct loopback_handle *lhandle)
1124{
1125	int err;
1126
1127	if (lhandle->ctl_active == NULL)
1128		return 0;
1129	err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_active);
1130	if (err < 0) {
1131		logit(LOG_CRIT, "Cannot get PCM Slave Active element for %s: %s\n", lhandle->id, snd_strerror(err));
1132		return err;
1133	}
1134	return snd_ctl_elem_value_get_boolean(lhandle->ctl_active, 0);
1135}
1136
1137static int get_format(struct loopback_handle *lhandle)
1138{
1139	int err;
1140
1141	if (lhandle->ctl_format == NULL)
1142		return 0;
1143	err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_format);
1144	if (err < 0) {
1145		logit(LOG_CRIT, "Cannot get PCM Format element for %s: %s\n", lhandle->id, snd_strerror(err));
1146		return err;
1147	}
1148	return snd_ctl_elem_value_get_integer(lhandle->ctl_format, 0);
1149}
1150
1151static int get_rate(struct loopback_handle *lhandle)
1152{
1153	int err;
1154
1155	if (lhandle->ctl_rate == NULL)
1156		return 0;
1157	err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_rate);
1158	if (err < 0) {
1159		logit(LOG_CRIT, "Cannot get PCM Rate element for %s: %s\n", lhandle->id, snd_strerror(err));
1160		return err;
1161	}
1162	return snd_ctl_elem_value_get_integer(lhandle->ctl_rate, 0);
1163}
1164
1165static int get_channels(struct loopback_handle *lhandle)
1166{
1167	int err;
1168
1169	if (lhandle->ctl_channels == NULL)
1170		return 0;
1171	err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_channels);
1172	if (err < 0) {
1173		logit(LOG_CRIT, "Cannot get PCM Channels element for %s: %s\n", lhandle->id, snd_strerror(err));
1174		return err;
1175	}
1176	return snd_ctl_elem_value_get_integer(lhandle->ctl_channels, 0);
1177}
1178
1179static int openctl_elem_id(struct loopback_handle *lhandle, snd_ctl_elem_id_t *id,
1180		snd_ctl_elem_value_t **elem)
1181{
1182	int err;
1183
1184	if (snd_ctl_elem_value_malloc(elem) < 0) {
1185		*elem = NULL;
1186		return -ENOMEM;
1187	}
1188	snd_ctl_elem_value_set_id(*elem, id);
1189	snd_ctl_elem_value_set_interface(*elem, SND_CTL_ELEM_IFACE_PCM);
1190	err = snd_ctl_elem_read(lhandle->ctl, *elem);
1191	if (err < 0) {
1192		snd_ctl_elem_value_free(*elem);
1193		*elem = NULL;
1194		return err;
1195	} else {
1196		snd_output_printf(lhandle->loopback->output,
1197				"Opened PCM element %s of %s, device %d, subdevice %d\n",
1198				snd_ctl_elem_id_get_name(id), snd_ctl_name(lhandle->ctl),
1199				snd_ctl_elem_id_get_device(id),
1200				snd_ctl_elem_id_get_subdevice(id));
1201		return 0;
1202	}
1203}
1204
1205static int openctl_elem(struct loopback_handle *lhandle,
1206			 int device, int subdevice,
1207			 const char *name,
1208			 snd_ctl_elem_value_t **elem)
1209{
1210	snd_ctl_elem_id_t *id;
1211
1212	snd_ctl_elem_id_alloca(&id);
1213	snd_ctl_elem_id_set_device(id, device);
1214	snd_ctl_elem_id_set_subdevice(id, subdevice);
1215	snd_ctl_elem_id_set_name(id, name);
1216	return openctl_elem_id(lhandle, id, elem);
1217}
1218
1219static int openctl_elem_ascii(struct loopback_handle *lhandle, char *ascii_name,
1220		snd_ctl_elem_value_t **elem)
1221{
1222	snd_ctl_elem_id_t *id;
1223
1224	snd_ctl_elem_id_alloca(&id);
1225	if (snd_ctl_ascii_elem_id_parse(id, ascii_name)) {
1226		fprintf(stderr, "Wrong control identifier: %s\n", ascii_name);
1227		return -EINVAL;
1228	}
1229	return openctl_elem_id(lhandle, id, elem);
1230}
1231
1232static int openctl(struct loopback_handle *lhandle, int device, int subdevice)
1233{
1234	int err;
1235
1236	lhandle->ctl_rate_shift = NULL;
1237	if (lhandle->loopback->play == lhandle) {
1238		// play only
1239		if (lhandle->prateshift_name) {
1240			err = openctl_elem_ascii(lhandle, lhandle->prateshift_name,
1241					&lhandle->ctl_rate_shift);
1242			if (err < 0) {
1243				logit(LOG_CRIT, "Unable to open playback PCM Rate Shift elem '%s'.\n",
1244						lhandle->prateshift_name);
1245				exit(EXIT_FAILURE);
1246			}
1247		} else
1248			openctl_elem(lhandle, device, subdevice, "Playback Pitch 1000000",
1249					&lhandle->ctl_pitch);
1250		set_rate_shift(lhandle, 1);
1251		if (lhandle->loopback->controls)
1252			goto __events;
1253		return 0;
1254	}
1255	// capture only
1256	openctl_elem(lhandle, device, subdevice, "PCM Notify",
1257			&lhandle->ctl_notify);
1258	openctl_elem(lhandle, device, subdevice, "PCM Rate Shift 100000",
1259			&lhandle->ctl_rate_shift);
1260	openctl_elem(lhandle, device, subdevice, "Capture Pitch 1000000",
1261			&lhandle->ctl_pitch);
1262	set_rate_shift(lhandle, 1);
1263	openctl_elem(lhandle, device, subdevice, "PCM Slave Active",
1264			&lhandle->ctl_active);
1265	openctl_elem(lhandle, device, subdevice, "PCM Slave Format",
1266			&lhandle->ctl_format);
1267	openctl_elem(lhandle, device, subdevice, "PCM Slave Rate",
1268			&lhandle->ctl_rate);
1269	openctl_elem(lhandle, device, subdevice, "PCM Slave Channels",
1270			&lhandle->ctl_channels);
1271	if ((lhandle->ctl_active &&
1272	     lhandle->ctl_format &&
1273	     lhandle->ctl_rate &&
1274	     lhandle->ctl_channels) ||
1275	    lhandle->loopback->controls) {
1276	      __events:
1277		if ((err = snd_ctl_poll_descriptors_count(lhandle->ctl)) < 0)
1278			lhandle->ctl_pollfd_count = 0;
1279		else
1280			lhandle->ctl_pollfd_count = err;
1281		if (snd_ctl_subscribe_events(lhandle->ctl, 1) < 0)
1282			lhandle->ctl_pollfd_count = 0;
1283	}
1284	return 0;
1285}
1286
1287static int openit(struct loopback_handle *lhandle)
1288{
1289	snd_pcm_info_t *info;
1290	int stream = lhandle == lhandle->loopback->play ?
1291				SND_PCM_STREAM_PLAYBACK :
1292				SND_PCM_STREAM_CAPTURE;
1293	int err, card, device, subdevice;
1294	pcm_open_lock();
1295	err = snd_pcm_open(&lhandle->handle, lhandle->device, stream, SND_PCM_NONBLOCK);
1296	pcm_open_unlock();
1297	if (err < 0) {
1298		logit(LOG_CRIT, "%s open error: %s\n", lhandle->id, snd_strerror(err));
1299		return err;
1300	}
1301	if ((err = snd_pcm_info_malloc(&info)) < 0)
1302		return err;
1303	if ((err = snd_pcm_info(lhandle->handle, info)) < 0) {
1304		snd_pcm_info_free(info);
1305		return err;
1306	}
1307	card = snd_pcm_info_get_card(info);
1308	device = snd_pcm_info_get_device(info);
1309	subdevice = snd_pcm_info_get_subdevice(info);
1310	snd_pcm_info_free(info);
1311	lhandle->card_number = card;
1312	lhandle->ctl = NULL;
1313	if (card >= 0 || lhandle->ctldev) {
1314		char name[16], *dev = lhandle->ctldev;
1315		if (dev == NULL) {
1316			sprintf(name, "hw:%i", card);
1317			dev = name;
1318		}
1319		pcm_open_lock();
1320		err = snd_ctl_open(&lhandle->ctl, dev, SND_CTL_NONBLOCK);
1321		pcm_open_unlock();
1322		if (err < 0) {
1323			logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, dev, snd_strerror(err));
1324			lhandle->ctl = NULL;
1325		}
1326		if (lhandle->ctl)
1327			openctl(lhandle, device, subdevice);
1328	}
1329	return 0;
1330}
1331
1332static int freeit(struct loopback_handle *lhandle)
1333{
1334	free(lhandle->buf);
1335	lhandle->buf = NULL;
1336	return 0;
1337}
1338
1339static int closeit(struct loopback_handle *lhandle)
1340{
1341	int err = 0;
1342
1343	set_rate_shift(lhandle, 1);
1344	if (lhandle->ctl_rate_shift)
1345		snd_ctl_elem_value_free(lhandle->ctl_rate_shift);
1346	lhandle->ctl_rate_shift = NULL;
1347	if (lhandle->ctl_pitch)
1348		snd_ctl_elem_value_free(lhandle->ctl_pitch);
1349	lhandle->ctl_pitch = NULL;
1350	if (lhandle->ctl)
1351		err = snd_ctl_close(lhandle->ctl);
1352	lhandle->ctl = NULL;
1353	if (lhandle->handle)
1354		err = snd_pcm_close(lhandle->handle);
1355	lhandle->handle = NULL;
1356	return err;
1357}
1358
1359static int init_handle(struct loopback_handle *lhandle, int alloc)
1360{
1361	snd_pcm_uframes_t lat;
1362	lhandle->frame_size = (snd_pcm_format_physical_width(lhandle->format)
1363						/ 8) * lhandle->channels;
1364	lhandle->sync_point = lhandle->rate * 15;	/* every 15 seconds */
1365	lat = lhandle->loopback->latency;
1366	if (lhandle->buffer_size > lat)
1367		lat = lhandle->buffer_size;
1368	lhandle->buf_size = lat * 2;
1369	if (alloc) {
1370		lhandle->buf = calloc(1, lhandle->buf_size * lhandle->frame_size);
1371		if (lhandle->buf == NULL)
1372			return -ENOMEM;
1373	}
1374	return 0;
1375}
1376
1377int pcmjob_init(struct loopback *loop)
1378{
1379	int err;
1380	char id[128];
1381
1382#ifdef FILE_CWRITE
1383	loop->cfile = fopen(FILE_CWRITE, "w+");
1384#endif
1385#ifdef FILE_PWRITE
1386	loop->pfile = fopen(FILE_PWRITE, "w+");
1387#endif
1388	if ((err = openit(loop->play)) < 0)
1389		goto __error;
1390	if ((err = openit(loop->capt)) < 0)
1391		goto __error;
1392	snprintf(id, sizeof(id), "%s/%s", loop->play->id, loop->capt->id);
1393	id[sizeof(id)-1] = '\0';
1394	loop->id = strdup(id);
1395	if (loop->sync == SYNC_TYPE_AUTO && (loop->capt->ctl_rate_shift || loop->capt->ctl_pitch))
1396		loop->sync = SYNC_TYPE_CAPTRATESHIFT;
1397	if (loop->sync == SYNC_TYPE_AUTO && (loop->play->ctl_rate_shift || loop->play->ctl_pitch))
1398		loop->sync = SYNC_TYPE_PLAYRATESHIFT;
1399#ifdef USE_SAMPLERATE
1400	if (loop->sync == SYNC_TYPE_AUTO && loop->src_enable)
1401		loop->sync = SYNC_TYPE_SAMPLERATE;
1402#endif
1403	if (loop->sync == SYNC_TYPE_AUTO)
1404		loop->sync = SYNC_TYPE_SIMPLE;
1405	if (loop->slave == SLAVE_TYPE_AUTO &&
1406	    loop->capt->ctl_notify &&
1407	    loop->capt->ctl_active &&
1408	    loop->capt->ctl_format &&
1409	    loop->capt->ctl_rate &&
1410	    loop->capt->ctl_channels)
1411		loop->slave = SLAVE_TYPE_ON;
1412	if (loop->slave == SLAVE_TYPE_ON) {
1413		err = set_notify(loop->capt, 1);
1414		if (err < 0)
1415			goto __error;
1416		if (loop->capt->ctl_notify == NULL ||
1417		    snd_ctl_elem_value_get_boolean(loop->capt->ctl_notify, 0) == 0) {
1418			logit(LOG_CRIT, "unable to enable slave mode for %s\n", loop->id);
1419			err = -EINVAL;
1420			goto __error;
1421		}
1422	}
1423	err = control_init(loop);
1424	if (err < 0)
1425		goto __error;
1426	return 0;
1427      __error:
1428	pcmjob_done(loop);
1429	return err;
1430}
1431
1432static void freeloop(struct loopback *loop)
1433{
1434#ifdef USE_SAMPLERATE
1435	if (loop->use_samplerate) {
1436		if (loop->src_state)
1437			src_delete(loop->src_state);
1438		loop->src_state = NULL;
1439		free((void *)loop->src_data.data_in);
1440		loop->src_data.data_in = NULL;
1441		free(loop->src_data.data_out);
1442		loop->src_data.data_out = NULL;
1443	}
1444#endif
1445	if (loop->play->buf == loop->capt->buf)
1446		loop->play->buf = NULL;
1447	freeit(loop->play);
1448	freeit(loop->capt);
1449}
1450
1451int pcmjob_done(struct loopback *loop)
1452{
1453	control_done(loop);
1454	closeit(loop->play);
1455	closeit(loop->capt);
1456	freeloop(loop);
1457	free(loop->id);
1458	loop->id = NULL;
1459#ifdef FILE_PWRITE
1460	if (loop->pfile) {
1461		fclose(loop->pfile);
1462		loop->pfile = NULL;
1463	}
1464#endif
1465#ifdef FILE_CWRITE
1466	if (loop->cfile) {
1467		fclose(loop->cfile);
1468		loop->cfile = NULL;
1469	}
1470#endif
1471	return 0;
1472}
1473
1474static void lhandle_start(struct loopback_handle *lhandle)
1475{
1476	lhandle->buf_pos = 0;
1477	lhandle->buf_count = 0;
1478	lhandle->counter = 0;
1479	lhandle->total_queued = 0;
1480}
1481
1482static void fix_format(struct loopback *loop, int force)
1483{
1484	snd_pcm_format_t format = loop->capt->format;
1485
1486	if (!force && loop->sync != SYNC_TYPE_SAMPLERATE)
1487		return;
1488	if (format == SND_PCM_FORMAT_S16 ||
1489	    format == SND_PCM_FORMAT_S32)
1490		return;
1491	if (snd_pcm_format_width(format) > 16)
1492		format = SND_PCM_FORMAT_S32;
1493	else
1494		format = SND_PCM_FORMAT_S16;
1495	loop->capt->format = format;
1496	loop->play->format = format;
1497}
1498
1499int pcmjob_start(struct loopback *loop)
1500{
1501	snd_pcm_uframes_t count;
1502	int err;
1503
1504	loop->pollfd_count = loop->play->ctl_pollfd_count +
1505			     loop->capt->ctl_pollfd_count;
1506	if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
1507		goto __error;
1508	loop->play->pollfd_count = err;
1509	loop->pollfd_count += err;
1510	if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
1511		goto __error;
1512	loop->capt->pollfd_count = err;
1513	loop->pollfd_count += err;
1514	if (loop->slave == SLAVE_TYPE_ON) {
1515		err = get_active(loop->capt);
1516		if (err < 0)
1517			goto __error;
1518		if (err == 0)		/* stream is not active */
1519			return 0;
1520		err = get_format(loop->capt);
1521		if (err < 0)
1522			goto __error;
1523		loop->play->format = loop->capt->format = err;
1524		fix_format(loop, 0);
1525		err = get_rate(loop->capt);
1526		if (err < 0)
1527			goto __error;
1528		loop->play->rate_req = loop->capt->rate_req = err;
1529		err = get_channels(loop->capt);
1530		if (err < 0)
1531			goto __error;
1532		loop->play->channels = loop->capt->channels = err;
1533	}
1534	loop->reinit = 0;
1535	loop->use_samplerate = 0;
1536__again:
1537	if (loop->latency_req) {
1538		loop->latency_reqtime = frames_to_time(loop->play->rate_req,
1539						       loop->latency_req);
1540		loop->latency_req = 0;
1541	}
1542	loop->latency = time_to_frames(loop->play->rate_req, loop->latency_reqtime);
1543	if ((err = setparams(loop, loop->latency/2)) < 0)
1544		goto __error;
1545	if (verbose)
1546		showlatency(loop->output, loop->latency, loop->play->rate_req, "Latency");
1547	if (loop->play->access == loop->capt->access &&
1548	    loop->play->format == loop->capt->format &&
1549	    loop->play->rate == loop->capt->rate &&
1550	    loop->play->channels == loop->capt->channels &&
1551	    loop->sync != SYNC_TYPE_SAMPLERATE) {
1552		if (verbose > 1)
1553			snd_output_printf(loop->output, "shared buffer!!!\n");
1554		if ((err = init_handle(loop->play, 1)) < 0)
1555			goto __error;
1556		if ((err = init_handle(loop->capt, 0)) < 0)
1557			goto __error;
1558		if (loop->play->buf_size < loop->capt->buf_size) {
1559			char *nbuf = realloc(loop->play->buf,
1560					     loop->capt->buf_size *
1561					       loop->capt->frame_size);
1562			if (nbuf == NULL) {
1563				err = -ENOMEM;
1564				goto __error;
1565			}
1566			loop->play->buf = nbuf;
1567			loop->play->buf_size = loop->capt->buf_size;
1568		} else if (loop->capt->buf_size < loop->play->buf_size) {
1569			char *nbuf = realloc(loop->capt->buf,
1570					     loop->play->buf_size *
1571					       loop->play->frame_size);
1572			if (nbuf == NULL) {
1573				err = -ENOMEM;
1574				goto __error;
1575			}
1576			loop->capt->buf = nbuf;
1577			loop->capt->buf_size = loop->play->buf_size;
1578		}
1579		loop->capt->buf = loop->play->buf;
1580	} else {
1581		if ((err = init_handle(loop->play, 1)) < 0)
1582			goto __error;
1583		if ((err = init_handle(loop->capt, 1)) < 0)
1584			goto __error;
1585		if (loop->play->rate_req != loop->play->rate ||
1586                    loop->capt->rate_req != loop->capt->rate) {
1587                        snd_pcm_format_t format1, format2;
1588			loop->use_samplerate = 1;
1589                        format1 = loop->play->format;
1590                        format2 = loop->capt->format;
1591                        fix_format(loop, 1);
1592                        if (loop->play->format != format1 ||
1593                            loop->capt->format != format2) {
1594                                pcmjob_stop(loop);
1595                                goto __again;
1596                        }
1597                }
1598	}
1599#ifdef USE_SAMPLERATE
1600	if (loop->sync == SYNC_TYPE_SAMPLERATE)
1601		loop->use_samplerate = 1;
1602	if (loop->use_samplerate && !loop->src_enable) {
1603		logit(LOG_CRIT, "samplerate conversion required but disabled\n");
1604		loop->use_samplerate = 0;
1605		err = -EIO;
1606		goto __error;
1607	}
1608	if (loop->use_samplerate) {
1609		if ((loop->capt->format != SND_PCM_FORMAT_S16 ||
1610		    loop->play->format != SND_PCM_FORMAT_S16) &&
1611		    (loop->capt->format != SND_PCM_FORMAT_S32 ||
1612		     loop->play->format != SND_PCM_FORMAT_S32)) {
1613			logit(LOG_CRIT, "samplerate conversion supports only %s or %s formats (play=%s, capt=%s)\n", snd_pcm_format_name(SND_PCM_FORMAT_S16), snd_pcm_format_name(SND_PCM_FORMAT_S32), snd_pcm_format_name(loop->play->format), snd_pcm_format_name(loop->capt->format));
1614			loop->use_samplerate = 0;
1615			err = -EIO;
1616			goto __error;
1617		}
1618		loop->src_state = src_new(loop->src_converter_type,
1619					  loop->play->channels, &err);
1620		loop->src_data.data_in = calloc(1, sizeof(float)*loop->capt->channels*loop->capt->buf_size);
1621		if (loop->src_data.data_in == NULL) {
1622			err = -ENOMEM;
1623			goto __error;
1624		}
1625		loop->src_data.data_out =  calloc(1, sizeof(float)*loop->play->channels*loop->play->buf_size);
1626		if (loop->src_data.data_out == NULL) {
1627			err = -ENOMEM;
1628			goto __error;
1629		}
1630		loop->src_data.src_ratio = (double)loop->play->rate /
1631					   (double)loop->capt->rate;
1632		loop->src_data.end_of_input = 0;
1633		loop->src_out_frames = 0;
1634	} else {
1635		loop->src_state = NULL;
1636	}
1637#else
1638	if (loop->sync == SYNC_TYPE_SAMPLERATE || loop->use_samplerate) {
1639		logit(LOG_CRIT, "alsaloop is compiled without libsamplerate support\n");
1640		err = -EIO;
1641		goto __error;
1642	}
1643#endif
1644	if (verbose) {
1645		snd_output_printf(loop->output, "%s sync type: %s", loop->id, sync_types[loop->sync]);
1646#ifdef USE_SAMPLERATE
1647		if (loop->sync == SYNC_TYPE_SAMPLERATE)
1648			snd_output_printf(loop->output, " (%s)", src_types[loop->src_converter_type]);
1649#endif
1650		snd_output_printf(loop->output, "\n");
1651	}
1652	lhandle_start(loop->play);
1653	lhandle_start(loop->capt);
1654	if ((err = snd_pcm_format_set_silence(loop->play->format,
1655					      loop->play->buf,
1656					      loop->play->buf_size * loop->play->channels)) < 0) {
1657		logit(LOG_CRIT, "%s: silence error\n", loop->id);
1658		goto __error;
1659	}
1660	if (verbose > 4)
1661		snd_output_printf(loop->output, "%s: capt->buffer_size = %li, play->buffer_size = %li\n", loop->id, loop->capt->buf_size, loop->play->buf_size);
1662	loop->pitch = 1.0;
1663	update_pitch(loop);
1664	loop->pitch_delta = 1.0 / ((double)loop->capt->rate * 4);
1665	loop->total_queued_count = 0;
1666	loop->pitch_diff = 0;
1667	count = get_whole_latency(loop) / loop->play->pitch;
1668	loop->play->buf_count = count;
1669	if (loop->play->buf == loop->capt->buf)
1670		loop->capt->buf_pos = count;
1671	err = writeit(loop->play);
1672	if (verbose > 4)
1673		snd_output_printf(loop->output, "%s: silence queued %i samples\n", loop->id, err);
1674	if (count > loop->play->buffer_size)
1675		count = loop->play->buffer_size;
1676	if (err != (int)count) {
1677		logit(LOG_CRIT, "%s: initial playback fill error (%i/%i/%u)\n", loop->id, err, (int)count, loop->play->buffer_size);
1678		err = -EIO;
1679		goto __error;
1680	}
1681	loop->running = 1;
1682	loop->stop_pending = 0;
1683	if (loop->xrun) {
1684		getcurtimestamp(&loop->xrun_last_update);
1685		loop->xrun_last_pdelay = XRUN_PROFILE_UNKNOWN;
1686		loop->xrun_last_cdelay = XRUN_PROFILE_UNKNOWN;
1687		loop->xrun_max_proctime = 0;
1688	}
1689	if ((err = snd_pcm_start(loop->capt->handle)) < 0) {
1690		logit(LOG_CRIT, "pcm start %s error: %s\n", loop->capt->id, snd_strerror(err));
1691		goto __error;
1692	}
1693	if (!loop->linked) {
1694		if ((err = snd_pcm_start(loop->play->handle)) < 0) {
1695			logit(LOG_CRIT, "pcm start %s error: %s\n", loop->play->id, snd_strerror(err));
1696			goto __error;
1697		}
1698	}
1699	return 0;
1700      __error:
1701	pcmjob_stop(loop);
1702	return err;
1703}
1704
1705int pcmjob_stop(struct loopback *loop)
1706{
1707	int err;
1708
1709	if (loop->running) {
1710		if ((err = snd_pcm_drop(loop->capt->handle)) < 0)
1711			logit(LOG_WARNING, "pcm drop %s error: %s\n", loop->capt->id, snd_strerror(err));
1712		if ((err = snd_pcm_drop(loop->play->handle)) < 0)
1713			logit(LOG_WARNING, "pcm drop %s error: %s\n", loop->play->id, snd_strerror(err));
1714		if ((err = snd_pcm_hw_free(loop->capt->handle)) < 0)
1715			logit(LOG_WARNING, "pcm hw_free %s error: %s\n", loop->capt->id, snd_strerror(err));
1716		if ((err = snd_pcm_hw_free(loop->play->handle)) < 0)
1717			logit(LOG_WARNING, "pcm hw_free %s error: %s\n", loop->play->id, snd_strerror(err));
1718		loop->running = 0;
1719	}
1720	freeloop(loop);
1721	return 0;
1722}
1723
1724int pcmjob_pollfds_init(struct loopback *loop, struct pollfd *fds)
1725{
1726	int err, idx = 0;
1727
1728	if (loop->running) {
1729		err = snd_pcm_poll_descriptors(loop->play->handle, fds + idx, loop->play->pollfd_count);
1730		if (err < 0)
1731			return err;
1732		idx += loop->play->pollfd_count;
1733		err = snd_pcm_poll_descriptors(loop->capt->handle, fds + idx, loop->capt->pollfd_count);
1734		if (err < 0)
1735			return err;
1736		idx += loop->capt->pollfd_count;
1737	}
1738	if (loop->play->ctl_pollfd_count > 0 &&
1739	    (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1740		err = snd_ctl_poll_descriptors(loop->play->ctl, fds + idx, loop->play->ctl_pollfd_count);
1741		if (err < 0)
1742			return err;
1743		idx += loop->play->ctl_pollfd_count;
1744	}
1745	if (loop->capt->ctl_pollfd_count > 0 &&
1746	    (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1747		err = snd_ctl_poll_descriptors(loop->capt->ctl, fds + idx, loop->capt->ctl_pollfd_count);
1748		if (err < 0)
1749			return err;
1750		idx += loop->capt->ctl_pollfd_count;
1751	}
1752	loop->active_pollfd_count = idx;
1753	return idx;
1754}
1755
1756static snd_pcm_sframes_t get_queued_playback_samples(struct loopback *loop)
1757{
1758	snd_pcm_sframes_t delay;
1759
1760	if (snd_pcm_delay(loop->play->handle, &delay) < 0)
1761		return 0;
1762	loop->play->last_delay = delay;
1763	delay += loop->play->buf_count;
1764#ifdef USE_SAMPLERATE
1765	delay += loop->src_out_frames;
1766#endif
1767	return delay;
1768}
1769
1770static snd_pcm_sframes_t get_queued_capture_samples(struct loopback *loop)
1771{
1772	snd_pcm_sframes_t delay;
1773	int err;
1774
1775	if ((err = snd_pcm_delay(loop->capt->handle, &delay)) < 0)
1776		return 0;
1777	loop->capt->last_delay = delay;
1778	delay += loop->capt->buf_count;
1779	return delay;
1780}
1781
1782static int ctl_event_check(snd_ctl_elem_value_t *val, snd_ctl_event_t *ev)
1783{
1784	snd_ctl_elem_id_t *id1, *id2;
1785	snd_ctl_elem_id_alloca(&id1);
1786	snd_ctl_elem_id_alloca(&id2);
1787	snd_ctl_elem_value_get_id(val, id1);
1788	snd_ctl_event_elem_get_id(ev, id2);
1789	if (snd_ctl_event_elem_get_mask(ev) == SND_CTL_EVENT_MASK_REMOVE)
1790		return 0;
1791	if ((snd_ctl_event_elem_get_mask(ev) & SND_CTL_EVENT_MASK_VALUE) == 0)
1792		return 0;
1793	return control_id_match(id1, id2);
1794}
1795
1796static int handle_ctl_events(struct loopback_handle *lhandle,
1797			     unsigned short events ATTRIBUTE_UNUSED)
1798{
1799	struct loopback *loop = lhandle->loopback;
1800	snd_ctl_event_t *ev;
1801	int err, restart = 0;
1802
1803	snd_ctl_event_alloca(&ev);
1804	while ((err = snd_ctl_read(lhandle->ctl, ev)) != 0 && err != -EAGAIN) {
1805		if (err < 0)
1806			break;
1807		if (snd_ctl_event_get_type(ev) != SND_CTL_EVENT_ELEM)
1808			continue;
1809		if (lhandle == loop->play)
1810			goto __ctl_check;
1811		if (verbose > 6)
1812			snd_output_printf(loop->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
1813		if (ctl_event_check(lhandle->ctl_active, ev)) {
1814			continue;
1815		} else if (ctl_event_check(lhandle->ctl_format, ev)) {
1816			err = get_format(lhandle);
1817			if (lhandle->format != err)
1818				restart = 1;
1819			continue;
1820		} else if (ctl_event_check(lhandle->ctl_rate, ev)) {
1821			err = get_rate(lhandle);
1822			if ((int)lhandle->rate != err)
1823				restart = 1;
1824			continue;
1825		} else if (ctl_event_check(lhandle->ctl_channels, ev)) {
1826			err = get_channels(lhandle);
1827			if ((int)lhandle->channels != err)
1828				restart = 1;
1829			continue;
1830		}
1831	      __ctl_check:
1832		control_event(lhandle, ev);
1833	}
1834	err = get_active(lhandle);
1835	if (verbose > 7)
1836		snd_output_printf(loop->output, "%s: ctl event active %i\n", lhandle->id, err);
1837	if (!err) {
1838		if (lhandle->loopback->running) {
1839			loop->stop_pending = 1;
1840			loop->stop_count = 0;
1841		}
1842	} else {
1843		loop->stop_pending = 0;
1844		if (loop->running == 0)
1845			restart = 1;
1846	}
1847	if (restart) {
1848		pcmjob_stop(loop);
1849		err = pcmjob_start(loop);
1850		if (err < 0)
1851			return err;
1852	}
1853	return 1;
1854}
1855
1856int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
1857{
1858	struct loopback_handle *play = loop->play;
1859	struct loopback_handle *capt = loop->capt;
1860	unsigned short prevents, crevents, events;
1861	snd_pcm_uframes_t ccount, pcount;
1862	int err, loopcount = 0, idx;
1863
1864	if (verbose > 11)
1865		snd_output_printf(loop->output, "%s: pollfds handle\n", loop->id);
1866	if (verbose > 13 || loop->xrun)
1867		getcurtimestamp(&loop->tstamp_start);
1868	if (verbose > 12) {
1869		snd_pcm_sframes_t pdelay, cdelay;
1870		if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
1871			snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
1872		else
1873			snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
1874		if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
1875			snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
1876		else
1877			snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
1878	}
1879	idx = 0;
1880	if (loop->running) {
1881		err = snd_pcm_poll_descriptors_revents(play->handle, fds,
1882						       play->pollfd_count,
1883						       &prevents);
1884		if (err < 0)
1885			return err;
1886		idx += play->pollfd_count;
1887		err = snd_pcm_poll_descriptors_revents(capt->handle, fds + idx,
1888						       capt->pollfd_count,
1889						       &crevents);
1890		if (err < 0)
1891			return err;
1892		idx += capt->pollfd_count;
1893		if (loop->xrun) {
1894			if (prevents || crevents) {
1895				loop->xrun_last_wake = loop->xrun_last_wake0;
1896				loop->xrun_last_wake0 = loop->tstamp_start;
1897			}
1898			loop->xrun_last_check = loop->xrun_last_check0;
1899			loop->xrun_last_check0 = loop->tstamp_start;
1900		}
1901	} else {
1902		prevents = crevents = 0;
1903	}
1904	if (play->ctl_pollfd_count > 0 &&
1905	    (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1906		err = snd_ctl_poll_descriptors_revents(play->ctl, fds + idx,
1907						       play->ctl_pollfd_count,
1908						       &events);
1909		if (err < 0)
1910			return err;
1911		if (events) {
1912			err = handle_ctl_events(play, events);
1913			if (err == 1)
1914				return 0;
1915			if (err < 0)
1916				return err;
1917		}
1918		idx += play->ctl_pollfd_count;
1919	}
1920	if (capt->ctl_pollfd_count > 0 &&
1921	    (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1922		err = snd_ctl_poll_descriptors_revents(capt->ctl, fds + idx,
1923						       capt->ctl_pollfd_count,
1924						       &events);
1925		if (err < 0)
1926			return err;
1927		if (events) {
1928			err = handle_ctl_events(capt, events);
1929			if (err == 1)
1930				return 0;
1931			if (err < 0)
1932				return err;
1933		}
1934		idx += capt->ctl_pollfd_count;
1935	}
1936	if (verbose > 9)
1937		snd_output_printf(loop->output, "%s: prevents = 0x%x, crevents = 0x%x\n", loop->id, prevents, crevents);
1938	if (!loop->running)
1939		goto __pcm_end;
1940	do {
1941		ccount = readit(capt);
1942		if (prevents != 0 && crevents == 0 &&
1943		    ccount == 0 && loopcount == 0) {
1944			if (play->stall > 20) {
1945				play->stall = 0;
1946				increase_playback_avail_min(play);
1947				break;
1948			}
1949			play->stall++;
1950			break;
1951		}
1952		if (ccount > 0)
1953			play->stall = 0;
1954		buf_add(loop, ccount);
1955		if (capt->xrun_pending || loop->reinit)
1956			break;
1957		/* we read new samples, if we have a room in the playback
1958		   buffer, feed them there */
1959		pcount = writeit(play);
1960		buf_remove(loop, pcount);
1961		if (pcount > 0)
1962			play->stall = 0;
1963		if (play->xrun_pending || loop->reinit)
1964			break;
1965		loopcount++;
1966	} while ((ccount > 0 || pcount > 0) && loopcount < 10);
1967	if (play->xrun_pending || capt->xrun_pending) {
1968		if ((err = xrun_sync(loop)) < 0)
1969			return err;
1970	}
1971	if (loop->reinit) {
1972		err = pcmjob_stop(loop);
1973		if (err < 0)
1974			return err;
1975		err = pcmjob_start(loop);
1976		if (err < 0)
1977			return err;
1978	}
1979	if (loop->sync != SYNC_TYPE_NONE &&
1980	    play->counter >= play->sync_point &&
1981	    capt->counter >= play->sync_point) {
1982		snd_pcm_sframes_t diff, lat = get_whole_latency(loop);
1983		diff = ((double)(((double)play->total_queued * play->pitch) +
1984				 ((double)capt->total_queued * capt->pitch)) /
1985			(double)loop->total_queued_count) - lat;
1986		/* FIXME: this algorithm may be slightly better */
1987		if (verbose > 3)
1988			snd_output_printf(loop->output, "%s: sync diff %li old diff %li\n", loop->id, diff, loop->pitch_diff);
1989		if (diff > 0) {
1990			if (diff == loop->pitch_diff)
1991				loop->pitch += loop->pitch_delta;
1992			else if (diff > loop->pitch_diff)
1993				loop->pitch += loop->pitch_delta*2;
1994		} else if (diff < 0) {
1995			if (diff == loop->pitch_diff)
1996				loop->pitch -= loop->pitch_delta;
1997			else if (diff < loop->pitch_diff)
1998				loop->pitch -= loop->pitch_delta*2;
1999		}
2000		loop->pitch_diff = diff;
2001		if (loop->pitch_diff_min > diff)
2002			loop->pitch_diff_min = diff;
2003		if (loop->pitch_diff_max < diff)
2004			loop->pitch_diff_max = diff;
2005		update_pitch(loop);
2006		play->counter -= play->sync_point;
2007		capt->counter -= play->sync_point;
2008		play->total_queued = 0;
2009		capt->total_queued = 0;
2010		loop->total_queued_count = 0;
2011	}
2012	if (loop->sync != SYNC_TYPE_NONE) {
2013		snd_pcm_sframes_t pqueued, cqueued;
2014
2015		/* Reduce cumulative error by interleaving playback vs capture reading order */
2016		if (loop->total_queued_count & 1) {
2017			pqueued = get_queued_playback_samples(loop);
2018			cqueued = get_queued_capture_samples(loop);
2019		} else {
2020			cqueued = get_queued_capture_samples(loop);
2021			pqueued = get_queued_playback_samples(loop);
2022		}
2023
2024		if (verbose > 4)
2025			snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued);
2026		if (pqueued > 0)
2027			play->total_queued += pqueued;
2028		if (cqueued > 0)
2029			capt->total_queued += cqueued;
2030		if (pqueued > 0 || cqueued > 0)
2031			loop->total_queued_count += 1;
2032	}
2033	if (verbose > 12) {
2034		snd_pcm_sframes_t pdelay, cdelay;
2035		if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
2036			snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
2037		else
2038			snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
2039		if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
2040			snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
2041		else
2042			snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
2043	}
2044      __pcm_end:
2045	if (verbose > 13 || loop->xrun) {
2046		long diff;
2047		getcurtimestamp(&loop->tstamp_end);
2048		diff = timediff(loop->tstamp_end, loop->tstamp_start);
2049		if (verbose > 13)
2050			snd_output_printf(loop->output, "%s: processing time %lius\n", loop->id, diff);
2051		if (loop->xrun && loop->xrun_max_proctime < diff)
2052			loop->xrun_max_proctime = diff;
2053	}
2054	return 0;
2055}
2056
2057#define OUT(args...) \
2058	snd_output_printf(loop->state, ##args)
2059
2060static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
2061
2062static void show_handle(struct loopback_handle *lhandle, const char *id)
2063{
2064	struct loopback *loop = lhandle->loopback;
2065
2066	OUT("  %s: %s:\n", id, lhandle->id);
2067	OUT("    device = '%s', ctldev '%s'\n", lhandle->device, lhandle->ctldev);
2068	OUT("    card_number = %i\n", lhandle->card_number);
2069	if (!loop->running)
2070		return;
2071	OUT("    access = %s, format = %s, rate = %u, channels = %u\n", snd_pcm_access_name(lhandle->access), snd_pcm_format_name(lhandle->format), lhandle->rate, lhandle->channels);
2072	OUT("    buffer_size = %u, period_size = %u, avail_min = %li\n", lhandle->buffer_size, lhandle->period_size, lhandle->avail_min);
2073	OUT("    xrun_pending = %i\n", lhandle->xrun_pending);
2074	OUT("    buf_size = %li, buf_pos = %li, buf_count = %li, buf_over = %li\n", lhandle->buf_size, lhandle->buf_pos, lhandle->buf_count, lhandle->buf_over);
2075	OUT("    pitch = %.8f\n", lhandle->pitch);
2076}
2077
2078void pcmjob_state(struct loopback *loop)
2079{
2080	pthread_t self = pthread_self();
2081	pthread_mutex_lock(&state_mutex);
2082	OUT("State dump for thread %p job %i: %s:\n", (void *)self, loop->thread, loop->id);
2083	OUT("  running = %i\n", loop->running);
2084	OUT("  sync = %i\n", loop->sync);
2085	OUT("  slave = %i\n", loop->slave);
2086	if (!loop->running)
2087		goto __skip;
2088	OUT("  pollfd_count = %i\n", loop->pollfd_count);
2089	OUT("  pitch = %.8f, delta = %.8f, diff = %li, min = %li, max = %li\n", loop->pitch, loop->pitch_delta, loop->pitch_diff, loop->pitch_diff_min, loop->pitch_diff_max);
2090	OUT("  use_samplerate = %i\n", loop->use_samplerate);
2091      __skip:
2092	show_handle(loop->play, "playback");
2093	show_handle(loop->capt, "capture");
2094	pthread_mutex_unlock(&state_mutex);
2095}
2096