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