• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
41 static int set_rate_shift(struct loopback_handle *lhandle, double pitch);
42 static int get_rate(struct loopback_handle *lhandle);
43 
44 #define SYNCTYPE(v) [SYNC_TYPE_##v] = #v
45 
46 static 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
58 static 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 
67 static pthread_once_t pcm_open_mutex_once = PTHREAD_ONCE_INIT;
68 static pthread_mutex_t pcm_open_mutex;
69 
pcm_open_init_mutex(void)70 static 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 
pcm_open_lock(void)80 static 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 
pcm_open_unlock(void)87 static inline void pcm_open_unlock(void)
88 {
89 	if (workarounds & WORKAROUND_SERIALOPEN)
90 	        pthread_mutex_unlock(&pcm_open_mutex);
91 }
92 
get_whole_latency(struct loopback * loop)93 static inline snd_pcm_uframes_t get_whole_latency(struct loopback *loop)
94 {
95 	return loop->latency;
96 }
97 
98 static inline unsigned long long
frames_to_time(unsigned int rate,snd_pcm_uframes_t frames)99 			frames_to_time(unsigned int rate,
100 				       snd_pcm_uframes_t frames)
101 {
102 	return (frames * 1000000ULL) / rate;
103 }
104 
time_to_frames(unsigned int rate,unsigned long long time)105 static inline snd_pcm_uframes_t time_to_frames(unsigned int rate,
106 					       unsigned long long time)
107 {
108 	return (time * rate) / 1000000ULL;
109 }
110 
setparams_stream(struct loopback_handle * lhandle,snd_pcm_hw_params_t * params)111 static 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 
setparams_bufsize(struct loopback_handle * lhandle,snd_pcm_hw_params_t * params,snd_pcm_hw_params_t * tparams,snd_pcm_uframes_t bufsize)164 static 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 
setparams_set(struct loopback_handle * lhandle,snd_pcm_hw_params_t * params,snd_pcm_sw_params_t * swparams,snd_pcm_uframes_t bufsize)225 static 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 
increase_playback_avail_min(struct loopback_handle * lhandle)287 static 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 
setparams(struct loopback * loop,snd_pcm_uframes_t bufsize)323 static 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 
showlatency(snd_output_t * out,size_t latency,unsigned int rate,char * prefix)384 static 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 
timediff(snd_timestamp_t t1,snd_timestamp_t t2)392 static 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 
getcurtimestamp(snd_timestamp_t * ts)406 static 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 
xrun_profile0(struct loopback * loop)415 static 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 
xrun_profile(struct loopback * loop)432 static inline void xrun_profile(struct loopback *loop)
433 {
434 	if (loop->xrun)
435 		xrun_profile0(loop);
436 }
437 
xrun_stats0(struct loopback * loop)438 static 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 
xrun_stats(struct loopback * loop)482 static inline void xrun_stats(struct loopback *loop)
483 {
484 	if (loop->xrun)
485 		xrun_stats0(loop);
486 }
487 
buf_avail(struct loopback_handle * lhandle)488 static inline snd_pcm_uframes_t buf_avail(struct loopback_handle *lhandle)
489 {
490 	return lhandle->buf_size - lhandle->buf_count;
491 }
492 
buf_remove(struct loopback * loop,snd_pcm_uframes_t count)493 static 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
507 static 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
buf_add_src(struct loopback * loop)543 static 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
buf_add_src(struct loopback * loop ATTRIBUTE_UNUSED)628 static void buf_add_src(struct loopback *loop ATTRIBUTE_UNUSED)
629 {
630 }
631 #endif
632 
buf_add(struct loopback * loop,snd_pcm_uframes_t count)633 static 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 
xrun(struct loopback_handle * lhandle)645 static 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 
suspend(struct loopback_handle * lhandle)665 static 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 
readit(struct loopback_handle * lhandle)676 static 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 
writeit(struct loopback_handle * lhandle)739 static 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 
remove_samples(struct loopback * loop,int capture_preferred,snd_pcm_sframes_t count)799 static 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 
xrun_sync(struct loopback * loop)829 static 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 
set_notify(struct loopback_handle * lhandle,int enable)1041 static 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 
set_rate_shift(struct loopback_handle * lhandle,double pitch)1061 static 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 
update_pitch(struct loopback * loop)1082 void 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 
get_active(struct loopback_handle * lhandle)1123 static 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 
get_format(struct loopback_handle * lhandle)1137 static 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 
get_rate(struct loopback_handle * lhandle)1151 static 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 
get_channels(struct loopback_handle * lhandle)1165 static 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 
openctl_elem_id(struct loopback_handle * lhandle,snd_ctl_elem_id_t * id,snd_ctl_elem_value_t ** elem)1179 static 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 
openctl_elem(struct loopback_handle * lhandle,int device,int subdevice,const char * name,snd_ctl_elem_value_t ** elem)1205 static 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 
openctl_elem_ascii(struct loopback_handle * lhandle,char * ascii_name,snd_ctl_elem_value_t ** elem)1219 static 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 
openctl(struct loopback_handle * lhandle,int device,int subdevice)1232 static 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 
openit(struct loopback_handle * lhandle)1287 static 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 
freeit(struct loopback_handle * lhandle)1332 static int freeit(struct loopback_handle *lhandle)
1333 {
1334 	free(lhandle->buf);
1335 	lhandle->buf = NULL;
1336 	return 0;
1337 }
1338 
closeit(struct loopback_handle * lhandle)1339 static 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 
init_handle(struct loopback_handle * lhandle,int alloc)1359 static 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 
pcmjob_init(struct loopback * loop)1377 int 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 
freeloop(struct loopback * loop)1432 static 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 
pcmjob_done(struct loopback * loop)1451 int 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 
lhandle_start(struct loopback_handle * lhandle)1474 static 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 
fix_format(struct loopback * loop,int force)1482 static 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 
pcmjob_start(struct loopback * loop)1499 int 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 
pcmjob_stop(struct loopback * loop)1705 int 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 
pcmjob_pollfds_init(struct loopback * loop,struct pollfd * fds)1724 int 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 
get_queued_playback_samples(struct loopback * loop)1756 static 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 
get_queued_capture_samples(struct loopback * loop)1770 static 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 
ctl_event_check(snd_ctl_elem_value_t * val,snd_ctl_event_t * ev)1782 static 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 
handle_ctl_events(struct loopback_handle * lhandle,unsigned short events ATTRIBUTE_UNUSED)1796 static 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 
pcmjob_pollfds_handle(struct loopback * loop,struct pollfd * fds)1856 int 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 
2060 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
2061 
show_handle(struct loopback_handle * lhandle,const char * id)2062 static 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 
pcmjob_state(struct loopback * loop)2078 void 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