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 (void *)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 (void *)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 if ((err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->channels, diff)) < 0)
973 return err;
974 play->buf_count += diff;
975 }
976 if ((err = snd_pcm_prepare(play->handle)) < 0) {
977 logit(LOG_CRIT, "%s prepare failed: %s\n", play->id, snd_strerror(err));
978
979 return err;
980 }
981 delay1 = writeit(play);
982 if (verbose > 6)
983 snd_output_printf(loop->output,
984 "sync: playback wrote %li samples\n", (long)delay1);
985 if (delay1 > diff) {
986 buf_remove(loop, delay1 - diff);
987 if (verbose > 6)
988 snd_output_printf(loop->output,
989 "sync: playback buf_remove %li samples\n", (long)(delay1 - diff));
990 }
991 if ((err = snd_pcm_start(play->handle)) < 0) {
992 logit(LOG_CRIT, "%s start failed: %s\n", play->id, snd_strerror(err));
993 return err;
994 }
995 } else if (delay1 < fill) {
996 diff = (fill - delay1) / play->pitch;
997 while (diff > 0) {
998 delay1 = play->buf_size - play->buf_pos;
999 if (verbose > 6)
1000 snd_output_printf(loop->output,
1001 "sync: playback short, silence filling %li / buf_count=%li\n", (long)delay1, play->buf_count);
1002 if (delay1 > diff)
1003 delay1 = diff;
1004 if ((err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->channels, delay1)) < 0)
1005 return err;
1006 play->buf_pos += delay1;
1007 play->buf_pos %= play->buf_size;
1008 play->buf_count += delay1;
1009 diff -= delay1;
1010 }
1011 writeit(play);
1012 }
1013 if (verbose > 5) {
1014 snd_output_printf(loop->output, "%s: xrun sync ok\n", loop->id);
1015 if (verbose > 6) {
1016 if (snd_pcm_delay(capt->handle, &cdelay) < 0)
1017 cdelay = -1;
1018 if (snd_pcm_delay(play->handle, &pdelay) < 0)
1019 pdelay = -1;
1020 if (play->buf != capt->buf)
1021 cdelay += capt->buf_count;
1022 pdelay += play->buf_count;
1023 #ifdef USE_SAMPLERATE
1024 pdelay += loop->src_out_frames;
1025 #endif
1026 cdelay1 = cdelay * capt->pitch;
1027 pdelay1 = pdelay * play->pitch;
1028 delay1 = cdelay1 + pdelay1;
1029 snd_output_printf(loop->output, "%s: sync verify: %li\n", loop->id, delay1);
1030 }
1031 }
1032 loop->xrun_max_proctime = 0;
1033 return 0;
1034 }
1035
set_notify(struct loopback_handle * lhandle,int enable)1036 static int set_notify(struct loopback_handle *lhandle, int enable)
1037 {
1038 int err;
1039
1040 if (lhandle->ctl_notify == NULL)
1041 return 0;
1042 snd_ctl_elem_value_set_boolean(lhandle->ctl_notify, 0, enable);
1043 err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_notify);
1044 if (err < 0) {
1045 logit(LOG_CRIT, "Cannot set PCM Notify element for %s: %s\n", lhandle->id, snd_strerror(err));
1046 return err;
1047 }
1048 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_notify);
1049 if (err < 0) {
1050 logit(LOG_CRIT, "Cannot get PCM Notify element for %s: %s\n", lhandle->id, snd_strerror(err));
1051 return err;
1052 }
1053 return 0;
1054 }
1055
set_rate_shift(struct loopback_handle * lhandle,double pitch)1056 static int set_rate_shift(struct loopback_handle *lhandle, double pitch)
1057 {
1058 int err;
1059
1060 if (lhandle->ctl_rate_shift == NULL)
1061 return 0;
1062 snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, pitch * 100000);
1063 err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_rate_shift);
1064 if (err < 0) {
1065 logit(LOG_CRIT, "Cannot set PCM Rate Shift element for %s: %s\n", lhandle->id, snd_strerror(err));
1066 return err;
1067 }
1068 return 0;
1069 }
1070
update_pitch(struct loopback * loop)1071 void update_pitch(struct loopback *loop)
1072 {
1073 double pitch = loop->pitch;
1074
1075 #ifdef USE_SAMPLERATE
1076 if (loop->sync == SYNC_TYPE_SAMPLERATE) {
1077 loop->src_data.src_ratio = (double)1.0 / (pitch *
1078 loop->play->pitch * loop->capt->pitch);
1079 if (verbose > 2)
1080 snd_output_printf(loop->output, "%s: Samplerate src_ratio update1: %.8f\n", loop->id, loop->src_data.src_ratio);
1081 } else
1082 #endif
1083 if (loop->sync == SYNC_TYPE_CAPTRATESHIFT) {
1084 set_rate_shift(loop->capt, pitch);
1085 #ifdef USE_SAMPLERATE
1086 if (loop->use_samplerate) {
1087 loop->src_data.src_ratio =
1088 (double)1.0 /
1089 (loop->play->pitch * loop->capt->pitch);
1090 if (verbose > 2)
1091 snd_output_printf(loop->output, "%s: Samplerate src_ratio update2: %.8f\n", loop->id, loop->src_data.src_ratio);
1092 }
1093 #endif
1094 }
1095 else if (loop->sync == SYNC_TYPE_PLAYRATESHIFT) {
1096 set_rate_shift(loop->play, pitch);
1097 #ifdef USE_SAMPLERATE
1098 if (loop->use_samplerate) {
1099 loop->src_data.src_ratio =
1100 (double)1.0 /
1101 (loop->play->pitch * loop->capt->pitch);
1102 if (verbose > 2)
1103 snd_output_printf(loop->output, "%s: Samplerate src_ratio update3: %.8f\n", loop->id, loop->src_data.src_ratio);
1104 }
1105 #endif
1106 }
1107 if (verbose)
1108 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);
1109 }
1110
get_active(struct loopback_handle * lhandle)1111 static int get_active(struct loopback_handle *lhandle)
1112 {
1113 int err;
1114
1115 if (lhandle->ctl_active == NULL)
1116 return 0;
1117 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_active);
1118 if (err < 0) {
1119 logit(LOG_CRIT, "Cannot get PCM Slave Active element for %s: %s\n", lhandle->id, snd_strerror(err));
1120 return err;
1121 }
1122 return snd_ctl_elem_value_get_boolean(lhandle->ctl_active, 0);
1123 }
1124
get_format(struct loopback_handle * lhandle)1125 static int get_format(struct loopback_handle *lhandle)
1126 {
1127 int err;
1128
1129 if (lhandle->ctl_format == NULL)
1130 return 0;
1131 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_format);
1132 if (err < 0) {
1133 logit(LOG_CRIT, "Cannot get PCM Format element for %s: %s\n", lhandle->id, snd_strerror(err));
1134 return err;
1135 }
1136 return snd_ctl_elem_value_get_integer(lhandle->ctl_format, 0);
1137 }
1138
get_rate(struct loopback_handle * lhandle)1139 static int get_rate(struct loopback_handle *lhandle)
1140 {
1141 int err;
1142
1143 if (lhandle->ctl_rate == NULL)
1144 return 0;
1145 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_rate);
1146 if (err < 0) {
1147 logit(LOG_CRIT, "Cannot get PCM Rate element for %s: %s\n", lhandle->id, snd_strerror(err));
1148 return err;
1149 }
1150 return snd_ctl_elem_value_get_integer(lhandle->ctl_rate, 0);
1151 }
1152
get_channels(struct loopback_handle * lhandle)1153 static int get_channels(struct loopback_handle *lhandle)
1154 {
1155 int err;
1156
1157 if (lhandle->ctl_channels == NULL)
1158 return 0;
1159 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_channels);
1160 if (err < 0) {
1161 logit(LOG_CRIT, "Cannot get PCM Channels element for %s: %s\n", lhandle->id, snd_strerror(err));
1162 return err;
1163 }
1164 return snd_ctl_elem_value_get_integer(lhandle->ctl_channels, 0);
1165 }
1166
openctl_elem(struct loopback_handle * lhandle,int device,int subdevice,const char * name,snd_ctl_elem_value_t ** elem)1167 static void openctl_elem(struct loopback_handle *lhandle,
1168 int device, int subdevice,
1169 const char *name,
1170 snd_ctl_elem_value_t **elem)
1171 {
1172 int err;
1173
1174 if (snd_ctl_elem_value_malloc(elem) < 0) {
1175 *elem = NULL;
1176 } else {
1177 snd_ctl_elem_value_set_interface(*elem,
1178 SND_CTL_ELEM_IFACE_PCM);
1179 snd_ctl_elem_value_set_device(*elem, device);
1180 snd_ctl_elem_value_set_subdevice(*elem, subdevice);
1181 snd_ctl_elem_value_set_name(*elem, name);
1182 err = snd_ctl_elem_read(lhandle->ctl, *elem);
1183 if (err < 0) {
1184 snd_ctl_elem_value_free(*elem);
1185 *elem = NULL;
1186 }
1187 }
1188 }
1189
openctl(struct loopback_handle * lhandle,int device,int subdevice)1190 static int openctl(struct loopback_handle *lhandle, int device, int subdevice)
1191 {
1192 int err;
1193
1194 lhandle->ctl_rate_shift = NULL;
1195 if (lhandle->loopback->play == lhandle) {
1196 if (lhandle->loopback->controls)
1197 goto __events;
1198 return 0;
1199 }
1200 openctl_elem(lhandle, device, subdevice, "PCM Notify",
1201 &lhandle->ctl_notify);
1202 openctl_elem(lhandle, device, subdevice, "PCM Rate Shift 100000",
1203 &lhandle->ctl_rate_shift);
1204 set_rate_shift(lhandle, 1);
1205 openctl_elem(lhandle, device, subdevice, "PCM Slave Active",
1206 &lhandle->ctl_active);
1207 openctl_elem(lhandle, device, subdevice, "PCM Slave Format",
1208 &lhandle->ctl_format);
1209 openctl_elem(lhandle, device, subdevice, "PCM Slave Rate",
1210 &lhandle->ctl_rate);
1211 openctl_elem(lhandle, device, subdevice, "PCM Slave Channels",
1212 &lhandle->ctl_channels);
1213 if ((lhandle->ctl_active &&
1214 lhandle->ctl_format &&
1215 lhandle->ctl_rate &&
1216 lhandle->ctl_channels) ||
1217 lhandle->loopback->controls) {
1218 __events:
1219 if ((err = snd_ctl_poll_descriptors_count(lhandle->ctl)) < 0)
1220 lhandle->ctl_pollfd_count = 0;
1221 else
1222 lhandle->ctl_pollfd_count = err;
1223 if (snd_ctl_subscribe_events(lhandle->ctl, 1) < 0)
1224 lhandle->ctl_pollfd_count = 0;
1225 }
1226 return 0;
1227 }
1228
openit(struct loopback_handle * lhandle)1229 static int openit(struct loopback_handle *lhandle)
1230 {
1231 snd_pcm_info_t *info;
1232 int stream = lhandle == lhandle->loopback->play ?
1233 SND_PCM_STREAM_PLAYBACK :
1234 SND_PCM_STREAM_CAPTURE;
1235 int err, card, device, subdevice;
1236 pcm_open_lock();
1237 err = snd_pcm_open(&lhandle->handle, lhandle->device, stream, SND_PCM_NONBLOCK);
1238 pcm_open_unlock();
1239 if (err < 0) {
1240 logit(LOG_CRIT, "%s open error: %s\n", lhandle->id, snd_strerror(err));
1241 return err;
1242 }
1243 if ((err = snd_pcm_info_malloc(&info)) < 0)
1244 return err;
1245 if ((err = snd_pcm_info(lhandle->handle, info)) < 0) {
1246 snd_pcm_info_free(info);
1247 return err;
1248 }
1249 card = snd_pcm_info_get_card(info);
1250 device = snd_pcm_info_get_device(info);
1251 subdevice = snd_pcm_info_get_subdevice(info);
1252 snd_pcm_info_free(info);
1253 lhandle->card_number = card;
1254 lhandle->ctl = NULL;
1255 if (card >= 0 || lhandle->ctldev) {
1256 char name[16], *dev = lhandle->ctldev;
1257 if (dev == NULL) {
1258 sprintf(name, "hw:%i", card);
1259 dev = name;
1260 }
1261 pcm_open_lock();
1262 err = snd_ctl_open(&lhandle->ctl, dev, SND_CTL_NONBLOCK);
1263 pcm_open_unlock();
1264 if (err < 0) {
1265 logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, dev, snd_strerror(err));
1266 lhandle->ctl = NULL;
1267 }
1268 if (lhandle->ctl)
1269 openctl(lhandle, device, subdevice);
1270 }
1271 return 0;
1272 }
1273
freeit(struct loopback_handle * lhandle)1274 static int freeit(struct loopback_handle *lhandle)
1275 {
1276 free(lhandle->buf);
1277 lhandle->buf = NULL;
1278 return 0;
1279 }
1280
closeit(struct loopback_handle * lhandle)1281 static int closeit(struct loopback_handle *lhandle)
1282 {
1283 int err = 0;
1284
1285 set_rate_shift(lhandle, 1);
1286 if (lhandle->ctl_rate_shift)
1287 snd_ctl_elem_value_free(lhandle->ctl_rate_shift);
1288 lhandle->ctl_rate_shift = NULL;
1289 if (lhandle->ctl)
1290 err = snd_ctl_close(lhandle->ctl);
1291 lhandle->ctl = NULL;
1292 if (lhandle->handle)
1293 err = snd_pcm_close(lhandle->handle);
1294 lhandle->handle = NULL;
1295 return err;
1296 }
1297
init_handle(struct loopback_handle * lhandle,int alloc)1298 static int init_handle(struct loopback_handle *lhandle, int alloc)
1299 {
1300 snd_pcm_uframes_t lat;
1301 lhandle->frame_size = (snd_pcm_format_physical_width(lhandle->format)
1302 / 8) * lhandle->channels;
1303 lhandle->sync_point = lhandle->rate * 15; /* every 15 seconds */
1304 lat = lhandle->loopback->latency;
1305 if (lhandle->buffer_size > lat)
1306 lat = lhandle->buffer_size;
1307 lhandle->buf_size = lat * 2;
1308 if (alloc) {
1309 lhandle->buf = calloc(1, lhandle->buf_size * lhandle->frame_size);
1310 if (lhandle->buf == NULL)
1311 return -ENOMEM;
1312 }
1313 return 0;
1314 }
1315
pcmjob_init(struct loopback * loop)1316 int pcmjob_init(struct loopback *loop)
1317 {
1318 int err;
1319 char id[128];
1320
1321 #ifdef FILE_CWRITE
1322 loop->cfile = fopen(FILE_CWRITE, "w+");
1323 #endif
1324 #ifdef FILE_PWRITE
1325 loop->pfile = fopen(FILE_PWRITE, "w+");
1326 #endif
1327 if ((err = openit(loop->play)) < 0)
1328 goto __error;
1329 if ((err = openit(loop->capt)) < 0)
1330 goto __error;
1331 snprintf(id, sizeof(id), "%s/%s", loop->play->id, loop->capt->id);
1332 id[sizeof(id)-1] = '\0';
1333 loop->id = strdup(id);
1334 if (loop->sync == SYNC_TYPE_AUTO && loop->capt->ctl_rate_shift)
1335 loop->sync = SYNC_TYPE_CAPTRATESHIFT;
1336 if (loop->sync == SYNC_TYPE_AUTO && loop->play->ctl_rate_shift)
1337 loop->sync = SYNC_TYPE_PLAYRATESHIFT;
1338 #ifdef USE_SAMPLERATE
1339 if (loop->sync == SYNC_TYPE_AUTO && loop->src_enable)
1340 loop->sync = SYNC_TYPE_SAMPLERATE;
1341 #endif
1342 if (loop->sync == SYNC_TYPE_AUTO)
1343 loop->sync = SYNC_TYPE_SIMPLE;
1344 if (loop->slave == SLAVE_TYPE_AUTO &&
1345 loop->capt->ctl_notify &&
1346 loop->capt->ctl_active &&
1347 loop->capt->ctl_format &&
1348 loop->capt->ctl_rate &&
1349 loop->capt->ctl_channels)
1350 loop->slave = SLAVE_TYPE_ON;
1351 if (loop->slave == SLAVE_TYPE_ON) {
1352 err = set_notify(loop->capt, 1);
1353 if (err < 0)
1354 goto __error;
1355 if (loop->capt->ctl_notify == NULL ||
1356 snd_ctl_elem_value_get_boolean(loop->capt->ctl_notify, 0) == 0) {
1357 logit(LOG_CRIT, "unable to enable slave mode for %s\n", loop->id);
1358 err = -EINVAL;
1359 goto __error;
1360 }
1361 }
1362 err = control_init(loop);
1363 if (err < 0)
1364 goto __error;
1365 return 0;
1366 __error:
1367 pcmjob_done(loop);
1368 return err;
1369 }
1370
freeloop(struct loopback * loop)1371 static void freeloop(struct loopback *loop)
1372 {
1373 #ifdef USE_SAMPLERATE
1374 if (loop->use_samplerate) {
1375 if (loop->src_state)
1376 src_delete(loop->src_state);
1377 loop->src_state = NULL;
1378 free((void *)loop->src_data.data_in);
1379 loop->src_data.data_in = NULL;
1380 free(loop->src_data.data_out);
1381 loop->src_data.data_out = NULL;
1382 }
1383 #endif
1384 if (loop->play->buf == loop->capt->buf)
1385 loop->play->buf = NULL;
1386 freeit(loop->play);
1387 freeit(loop->capt);
1388 }
1389
pcmjob_done(struct loopback * loop)1390 int pcmjob_done(struct loopback *loop)
1391 {
1392 control_done(loop);
1393 closeit(loop->play);
1394 closeit(loop->capt);
1395 freeloop(loop);
1396 free(loop->id);
1397 loop->id = NULL;
1398 #ifdef FILE_PWRITE
1399 if (loop->pfile) {
1400 fclose(loop->pfile);
1401 loop->pfile = NULL;
1402 }
1403 #endif
1404 #ifdef FILE_CWRITE
1405 if (loop->cfile) {
1406 fclose(loop->cfile);
1407 loop->cfile = NULL;
1408 }
1409 #endif
1410 return 0;
1411 }
1412
lhandle_start(struct loopback_handle * lhandle)1413 static void lhandle_start(struct loopback_handle *lhandle)
1414 {
1415 lhandle->buf_pos = 0;
1416 lhandle->buf_count = 0;
1417 lhandle->counter = 0;
1418 lhandle->total_queued = 0;
1419 }
1420
fix_format(struct loopback * loop,int force)1421 static void fix_format(struct loopback *loop, int force)
1422 {
1423 snd_pcm_format_t format = loop->capt->format;
1424
1425 if (!force && loop->sync != SYNC_TYPE_SAMPLERATE)
1426 return;
1427 if (format == SND_PCM_FORMAT_S16 ||
1428 format == SND_PCM_FORMAT_S32)
1429 return;
1430 if (snd_pcm_format_width(format) > 16)
1431 format = SND_PCM_FORMAT_S32;
1432 else
1433 format = SND_PCM_FORMAT_S16;
1434 loop->capt->format = format;
1435 loop->play->format = format;
1436 }
1437
pcmjob_start(struct loopback * loop)1438 int pcmjob_start(struct loopback *loop)
1439 {
1440 snd_pcm_uframes_t count;
1441 int err;
1442
1443 loop->pollfd_count = loop->play->ctl_pollfd_count +
1444 loop->capt->ctl_pollfd_count;
1445 if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
1446 goto __error;
1447 loop->play->pollfd_count = err;
1448 loop->pollfd_count += err;
1449 if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
1450 goto __error;
1451 loop->capt->pollfd_count = err;
1452 loop->pollfd_count += err;
1453 if (loop->slave == SLAVE_TYPE_ON) {
1454 err = get_active(loop->capt);
1455 if (err < 0)
1456 goto __error;
1457 if (err == 0) /* stream is not active */
1458 return 0;
1459 err = get_format(loop->capt);
1460 if (err < 0)
1461 goto __error;
1462 loop->play->format = loop->capt->format = err;
1463 fix_format(loop, 0);
1464 err = get_rate(loop->capt);
1465 if (err < 0)
1466 goto __error;
1467 loop->play->rate_req = loop->capt->rate_req = err;
1468 err = get_channels(loop->capt);
1469 if (err < 0)
1470 goto __error;
1471 loop->play->channels = loop->capt->channels = err;
1472 }
1473 loop->reinit = 0;
1474 loop->use_samplerate = 0;
1475 __again:
1476 if (loop->latency_req) {
1477 loop->latency_reqtime = frames_to_time(loop->play->rate_req,
1478 loop->latency_req);
1479 loop->latency_req = 0;
1480 }
1481 loop->latency = time_to_frames(loop->play->rate_req, loop->latency_reqtime);
1482 if ((err = setparams(loop, loop->latency/2)) < 0)
1483 goto __error;
1484 if (verbose)
1485 showlatency(loop->output, loop->latency, loop->play->rate_req, "Latency");
1486 if (loop->play->access == loop->capt->access &&
1487 loop->play->format == loop->capt->format &&
1488 loop->play->rate == loop->capt->rate &&
1489 loop->play->channels == loop->capt->channels &&
1490 loop->sync != SYNC_TYPE_SAMPLERATE) {
1491 if (verbose > 1)
1492 snd_output_printf(loop->output, "shared buffer!!!\n");
1493 if ((err = init_handle(loop->play, 1)) < 0)
1494 goto __error;
1495 if ((err = init_handle(loop->capt, 0)) < 0)
1496 goto __error;
1497 if (loop->play->buf_size < loop->capt->buf_size) {
1498 char *nbuf = realloc(loop->play->buf,
1499 loop->capt->buf_size *
1500 loop->capt->frame_size);
1501 if (nbuf == NULL) {
1502 err = -ENOMEM;
1503 goto __error;
1504 }
1505 loop->play->buf = nbuf;
1506 loop->play->buf_size = loop->capt->buf_size;
1507 } else if (loop->capt->buf_size < loop->play->buf_size) {
1508 char *nbuf = realloc(loop->capt->buf,
1509 loop->play->buf_size *
1510 loop->play->frame_size);
1511 if (nbuf == NULL) {
1512 err = -ENOMEM;
1513 goto __error;
1514 }
1515 loop->capt->buf = nbuf;
1516 loop->capt->buf_size = loop->play->buf_size;
1517 }
1518 loop->capt->buf = loop->play->buf;
1519 } else {
1520 if ((err = init_handle(loop->play, 1)) < 0)
1521 goto __error;
1522 if ((err = init_handle(loop->capt, 1)) < 0)
1523 goto __error;
1524 if (loop->play->rate_req != loop->play->rate ||
1525 loop->capt->rate_req != loop->capt->rate) {
1526 snd_pcm_format_t format1, format2;
1527 loop->use_samplerate = 1;
1528 format1 = loop->play->format;
1529 format2 = loop->capt->format;
1530 fix_format(loop, 1);
1531 if (loop->play->format != format1 ||
1532 loop->capt->format != format2) {
1533 pcmjob_stop(loop);
1534 goto __again;
1535 }
1536 }
1537 }
1538 #ifdef USE_SAMPLERATE
1539 if (loop->sync == SYNC_TYPE_SAMPLERATE)
1540 loop->use_samplerate = 1;
1541 if (loop->use_samplerate && !loop->src_enable) {
1542 logit(LOG_CRIT, "samplerate conversion required but disabled\n");
1543 loop->use_samplerate = 0;
1544 err = -EIO;
1545 goto __error;
1546 }
1547 if (loop->use_samplerate) {
1548 if ((loop->capt->format != SND_PCM_FORMAT_S16 ||
1549 loop->play->format != SND_PCM_FORMAT_S16) &&
1550 (loop->capt->format != SND_PCM_FORMAT_S32 ||
1551 loop->play->format != SND_PCM_FORMAT_S32)) {
1552 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));
1553 loop->use_samplerate = 0;
1554 err = -EIO;
1555 goto __error;
1556 }
1557 loop->src_state = src_new(loop->src_converter_type,
1558 loop->play->channels, &err);
1559 loop->src_data.data_in = calloc(1, sizeof(float)*loop->capt->channels*loop->capt->buf_size);
1560 if (loop->src_data.data_in == NULL) {
1561 err = -ENOMEM;
1562 goto __error;
1563 }
1564 loop->src_data.data_out = calloc(1, sizeof(float)*loop->play->channels*loop->play->buf_size);
1565 if (loop->src_data.data_out == NULL) {
1566 err = -ENOMEM;
1567 goto __error;
1568 }
1569 loop->src_data.src_ratio = (double)loop->play->rate /
1570 (double)loop->capt->rate;
1571 loop->src_data.end_of_input = 0;
1572 loop->src_out_frames = 0;
1573 } else {
1574 loop->src_state = NULL;
1575 }
1576 #else
1577 if (loop->sync == SYNC_TYPE_SAMPLERATE || loop->use_samplerate) {
1578 logit(LOG_CRIT, "alsaloop is compiled without libsamplerate support\n");
1579 err = -EIO;
1580 goto __error;
1581 }
1582 #endif
1583 if (verbose) {
1584 snd_output_printf(loop->output, "%s sync type: %s", loop->id, sync_types[loop->sync]);
1585 #ifdef USE_SAMPLERATE
1586 if (loop->sync == SYNC_TYPE_SAMPLERATE)
1587 snd_output_printf(loop->output, " (%s)", src_types[loop->src_converter_type]);
1588 #endif
1589 snd_output_printf(loop->output, "\n");
1590 }
1591 lhandle_start(loop->play);
1592 lhandle_start(loop->capt);
1593 if ((err = snd_pcm_format_set_silence(loop->play->format,
1594 loop->play->buf,
1595 loop->play->buf_size * loop->play->channels)) < 0) {
1596 logit(LOG_CRIT, "%s: silence error\n", loop->id);
1597 goto __error;
1598 }
1599 if (verbose > 4)
1600 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);
1601 loop->pitch = 1.0;
1602 update_pitch(loop);
1603 loop->pitch_delta = 1.0 / ((double)loop->capt->rate * 4);
1604 loop->total_queued_count = 0;
1605 loop->pitch_diff = 0;
1606 count = get_whole_latency(loop) / loop->play->pitch;
1607 loop->play->buf_count = count;
1608 if (loop->play->buf == loop->capt->buf)
1609 loop->capt->buf_pos = count;
1610 err = writeit(loop->play);
1611 if (verbose > 4)
1612 snd_output_printf(loop->output, "%s: silence queued %i samples\n", loop->id, err);
1613 if (count > loop->play->buffer_size)
1614 count = loop->play->buffer_size;
1615 if (err != count) {
1616 logit(LOG_CRIT, "%s: initial playback fill error (%i/%i/%u)\n", loop->id, err, (int)count, loop->play->buffer_size);
1617 err = -EIO;
1618 goto __error;
1619 }
1620 loop->running = 1;
1621 loop->stop_pending = 0;
1622 if (loop->xrun) {
1623 getcurtimestamp(&loop->xrun_last_update);
1624 loop->xrun_last_pdelay = XRUN_PROFILE_UNKNOWN;
1625 loop->xrun_last_cdelay = XRUN_PROFILE_UNKNOWN;
1626 loop->xrun_max_proctime = 0;
1627 }
1628 if ((err = snd_pcm_start(loop->capt->handle)) < 0) {
1629 logit(LOG_CRIT, "pcm start %s error: %s\n", loop->capt->id, snd_strerror(err));
1630 goto __error;
1631 }
1632 if (!loop->linked) {
1633 if ((err = snd_pcm_start(loop->play->handle)) < 0) {
1634 logit(LOG_CRIT, "pcm start %s error: %s\n", loop->play->id, snd_strerror(err));
1635 goto __error;
1636 }
1637 }
1638 return 0;
1639 __error:
1640 pcmjob_stop(loop);
1641 return err;
1642 }
1643
pcmjob_stop(struct loopback * loop)1644 int pcmjob_stop(struct loopback *loop)
1645 {
1646 int err;
1647
1648 if (loop->running) {
1649 if ((err = snd_pcm_drop(loop->capt->handle)) < 0)
1650 logit(LOG_WARNING, "pcm drop %s error: %s\n", loop->capt->id, snd_strerror(err));
1651 if ((err = snd_pcm_drop(loop->play->handle)) < 0)
1652 logit(LOG_WARNING, "pcm drop %s error: %s\n", loop->play->id, snd_strerror(err));
1653 if ((err = snd_pcm_hw_free(loop->capt->handle)) < 0)
1654 logit(LOG_WARNING, "pcm hw_free %s error: %s\n", loop->capt->id, snd_strerror(err));
1655 if ((err = snd_pcm_hw_free(loop->play->handle)) < 0)
1656 logit(LOG_WARNING, "pcm hw_free %s error: %s\n", loop->play->id, snd_strerror(err));
1657 loop->running = 0;
1658 }
1659 freeloop(loop);
1660 return 0;
1661 }
1662
pcmjob_pollfds_init(struct loopback * loop,struct pollfd * fds)1663 int pcmjob_pollfds_init(struct loopback *loop, struct pollfd *fds)
1664 {
1665 int err, idx = 0;
1666
1667 if (loop->running) {
1668 err = snd_pcm_poll_descriptors(loop->play->handle, fds + idx, loop->play->pollfd_count);
1669 if (err < 0)
1670 return err;
1671 idx += loop->play->pollfd_count;
1672 err = snd_pcm_poll_descriptors(loop->capt->handle, fds + idx, loop->capt->pollfd_count);
1673 if (err < 0)
1674 return err;
1675 idx += loop->capt->pollfd_count;
1676 }
1677 if (loop->play->ctl_pollfd_count > 0 &&
1678 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1679 err = snd_ctl_poll_descriptors(loop->play->ctl, fds + idx, loop->play->ctl_pollfd_count);
1680 if (err < 0)
1681 return err;
1682 idx += loop->play->ctl_pollfd_count;
1683 }
1684 if (loop->capt->ctl_pollfd_count > 0 &&
1685 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1686 err = snd_ctl_poll_descriptors(loop->capt->ctl, fds + idx, loop->capt->ctl_pollfd_count);
1687 if (err < 0)
1688 return err;
1689 idx += loop->capt->ctl_pollfd_count;
1690 }
1691 loop->active_pollfd_count = idx;
1692 return idx;
1693 }
1694
get_queued_playback_samples(struct loopback * loop)1695 static snd_pcm_sframes_t get_queued_playback_samples(struct loopback *loop)
1696 {
1697 snd_pcm_sframes_t delay;
1698 int err;
1699
1700 if ((err = snd_pcm_delay(loop->play->handle, &delay)) < 0)
1701 return 0;
1702 loop->play->last_delay = delay;
1703 delay += loop->play->buf_count;
1704 #ifdef USE_SAMPLERATE
1705 delay += loop->src_out_frames;
1706 #endif
1707 return delay;
1708 }
1709
get_queued_capture_samples(struct loopback * loop)1710 static snd_pcm_sframes_t get_queued_capture_samples(struct loopback *loop)
1711 {
1712 snd_pcm_sframes_t delay;
1713 int err;
1714
1715 if ((err = snd_pcm_delay(loop->capt->handle, &delay)) < 0)
1716 return 0;
1717 loop->capt->last_delay = delay;
1718 delay += loop->capt->buf_count;
1719 return delay;
1720 }
1721
ctl_event_check(snd_ctl_elem_value_t * val,snd_ctl_event_t * ev)1722 static int ctl_event_check(snd_ctl_elem_value_t *val, snd_ctl_event_t *ev)
1723 {
1724 snd_ctl_elem_id_t *id1, *id2;
1725 snd_ctl_elem_id_alloca(&id1);
1726 snd_ctl_elem_id_alloca(&id2);
1727 snd_ctl_elem_value_get_id(val, id1);
1728 snd_ctl_event_elem_get_id(ev, id2);
1729 if (snd_ctl_event_elem_get_mask(ev) == SND_CTL_EVENT_MASK_REMOVE)
1730 return 0;
1731 if ((snd_ctl_event_elem_get_mask(ev) & SND_CTL_EVENT_MASK_VALUE) == 0)
1732 return 0;
1733 return control_id_match(id1, id2);
1734 }
1735
handle_ctl_events(struct loopback_handle * lhandle,unsigned short events)1736 static int handle_ctl_events(struct loopback_handle *lhandle,
1737 unsigned short events)
1738 {
1739 struct loopback *loop = lhandle->loopback;
1740 snd_ctl_event_t *ev;
1741 int err, restart = 0;
1742
1743 snd_ctl_event_alloca(&ev);
1744 while ((err = snd_ctl_read(lhandle->ctl, ev)) != 0 && err != -EAGAIN) {
1745 if (err < 0)
1746 break;
1747 if (snd_ctl_event_get_type(ev) != SND_CTL_EVENT_ELEM)
1748 continue;
1749 if (lhandle == loop->play)
1750 goto __ctl_check;
1751 if (verbose > 6)
1752 snd_output_printf(loop->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
1753 if (ctl_event_check(lhandle->ctl_active, ev)) {
1754 continue;
1755 } else if (ctl_event_check(lhandle->ctl_format, ev)) {
1756 err = get_format(lhandle);
1757 if (lhandle->format != err)
1758 restart = 1;
1759 continue;
1760 } else if (ctl_event_check(lhandle->ctl_rate, ev)) {
1761 err = get_rate(lhandle);
1762 if (lhandle->rate != err)
1763 restart = 1;
1764 continue;
1765 } else if (ctl_event_check(lhandle->ctl_channels, ev)) {
1766 err = get_channels(lhandle);
1767 if (lhandle->channels != err)
1768 restart = 1;
1769 continue;
1770 }
1771 __ctl_check:
1772 control_event(lhandle, ev);
1773 }
1774 err = get_active(lhandle);
1775 if (verbose > 7)
1776 snd_output_printf(loop->output, "%s: ctl event active %i\n", lhandle->id, err);
1777 if (!err) {
1778 if (lhandle->loopback->running) {
1779 loop->stop_pending = 1;
1780 loop->stop_count = 0;
1781 }
1782 } else {
1783 loop->stop_pending = 0;
1784 if (loop->running == 0)
1785 restart = 1;
1786 }
1787 if (restart) {
1788 pcmjob_stop(loop);
1789 err = pcmjob_start(loop);
1790 if (err < 0)
1791 return err;
1792 }
1793 return 1;
1794 }
1795
pcmjob_pollfds_handle(struct loopback * loop,struct pollfd * fds)1796 int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
1797 {
1798 struct loopback_handle *play = loop->play;
1799 struct loopback_handle *capt = loop->capt;
1800 unsigned short prevents, crevents, events;
1801 snd_pcm_uframes_t ccount, pcount;
1802 int err, loopcount = 0, idx;
1803
1804 if (verbose > 11)
1805 snd_output_printf(loop->output, "%s: pollfds handle\n", loop->id);
1806 if (verbose > 13 || loop->xrun)
1807 getcurtimestamp(&loop->tstamp_start);
1808 if (verbose > 12) {
1809 snd_pcm_sframes_t pdelay, cdelay;
1810 if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
1811 snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
1812 else
1813 snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
1814 if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
1815 snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
1816 else
1817 snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
1818 }
1819 idx = 0;
1820 if (loop->running) {
1821 err = snd_pcm_poll_descriptors_revents(play->handle, fds,
1822 play->pollfd_count,
1823 &prevents);
1824 if (err < 0)
1825 return err;
1826 idx += play->pollfd_count;
1827 err = snd_pcm_poll_descriptors_revents(capt->handle, fds + idx,
1828 capt->pollfd_count,
1829 &crevents);
1830 if (err < 0)
1831 return err;
1832 idx += capt->pollfd_count;
1833 if (loop->xrun) {
1834 if (prevents || crevents) {
1835 loop->xrun_last_wake = loop->xrun_last_wake0;
1836 loop->xrun_last_wake0 = loop->tstamp_start;
1837 }
1838 loop->xrun_last_check = loop->xrun_last_check0;
1839 loop->xrun_last_check0 = loop->tstamp_start;
1840 }
1841 } else {
1842 prevents = crevents = 0;
1843 }
1844 if (play->ctl_pollfd_count > 0 &&
1845 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1846 err = snd_ctl_poll_descriptors_revents(play->ctl, fds + idx,
1847 play->ctl_pollfd_count,
1848 &events);
1849 if (err < 0)
1850 return err;
1851 if (events) {
1852 err = handle_ctl_events(play, events);
1853 if (err == 1)
1854 return 0;
1855 if (err < 0)
1856 return err;
1857 }
1858 idx += play->ctl_pollfd_count;
1859 }
1860 if (capt->ctl_pollfd_count > 0 &&
1861 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1862 err = snd_ctl_poll_descriptors_revents(capt->ctl, fds + idx,
1863 capt->ctl_pollfd_count,
1864 &events);
1865 if (err < 0)
1866 return err;
1867 if (events) {
1868 err = handle_ctl_events(capt, events);
1869 if (err == 1)
1870 return 0;
1871 if (err < 0)
1872 return err;
1873 }
1874 idx += capt->ctl_pollfd_count;
1875 }
1876 if (verbose > 9)
1877 snd_output_printf(loop->output, "%s: prevents = 0x%x, crevents = 0x%x\n", loop->id, prevents, crevents);
1878 if (!loop->running)
1879 goto __pcm_end;
1880 do {
1881 ccount = readit(capt);
1882 if (prevents != 0 && crevents == 0 &&
1883 ccount == 0 && loopcount == 0) {
1884 if (play->stall > 20) {
1885 play->stall = 0;
1886 increase_playback_avail_min(play);
1887 break;
1888 }
1889 play->stall++;
1890 break;
1891 }
1892 if (ccount > 0)
1893 play->stall = 0;
1894 buf_add(loop, ccount);
1895 if (capt->xrun_pending || loop->reinit)
1896 break;
1897 /* we read new samples, if we have a room in the playback
1898 buffer, feed them there */
1899 pcount = writeit(play);
1900 buf_remove(loop, pcount);
1901 if (pcount > 0)
1902 play->stall = 0;
1903 if (play->xrun_pending || loop->reinit)
1904 break;
1905 loopcount++;
1906 } while ((ccount > 0 || pcount > 0) && loopcount > 10);
1907 if (play->xrun_pending || capt->xrun_pending) {
1908 if ((err = xrun_sync(loop)) < 0)
1909 return err;
1910 }
1911 if (loop->reinit) {
1912 err = pcmjob_stop(loop);
1913 if (err < 0)
1914 return err;
1915 err = pcmjob_start(loop);
1916 if (err < 0)
1917 return err;
1918 }
1919 if (loop->sync != SYNC_TYPE_NONE &&
1920 play->counter >= play->sync_point &&
1921 capt->counter >= play->sync_point) {
1922 snd_pcm_sframes_t diff, lat = get_whole_latency(loop);
1923 diff = ((double)(((double)play->total_queued * play->pitch) +
1924 ((double)capt->total_queued * capt->pitch)) /
1925 (double)loop->total_queued_count) - lat;
1926 /* FIXME: this algorithm may be slightly better */
1927 if (verbose > 3)
1928 snd_output_printf(loop->output, "%s: sync diff %li old diff %li\n", loop->id, diff, loop->pitch_diff);
1929 if (diff > 0) {
1930 if (diff == loop->pitch_diff)
1931 loop->pitch += loop->pitch_delta;
1932 else if (diff > loop->pitch_diff)
1933 loop->pitch += loop->pitch_delta*2;
1934 } else if (diff < 0) {
1935 if (diff == loop->pitch_diff)
1936 loop->pitch -= loop->pitch_delta;
1937 else if (diff < loop->pitch_diff)
1938 loop->pitch -= loop->pitch_delta*2;
1939 }
1940 loop->pitch_diff = diff;
1941 if (loop->pitch_diff_min > diff)
1942 loop->pitch_diff_min = diff;
1943 if (loop->pitch_diff_max < diff)
1944 loop->pitch_diff_max = diff;
1945 update_pitch(loop);
1946 play->counter -= play->sync_point;
1947 capt->counter -= play->sync_point;
1948 play->total_queued = 0;
1949 capt->total_queued = 0;
1950 loop->total_queued_count = 0;
1951 }
1952 if (loop->sync != SYNC_TYPE_NONE) {
1953 snd_pcm_sframes_t pqueued, cqueued;
1954 pqueued = get_queued_playback_samples(loop);
1955 cqueued = get_queued_capture_samples(loop);
1956 if (verbose > 4)
1957 snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued);
1958 if (pqueued > 0)
1959 play->total_queued += pqueued;
1960 if (cqueued > 0)
1961 capt->total_queued += cqueued;
1962 if (pqueued > 0 || cqueued > 0)
1963 loop->total_queued_count += 1;
1964 }
1965 if (verbose > 12) {
1966 snd_pcm_sframes_t pdelay, cdelay;
1967 if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
1968 snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
1969 else
1970 snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
1971 if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
1972 snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
1973 else
1974 snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
1975 }
1976 __pcm_end:
1977 if (verbose > 13 || loop->xrun) {
1978 long diff;
1979 getcurtimestamp(&loop->tstamp_end);
1980 diff = timediff(loop->tstamp_end, loop->tstamp_start);
1981 if (verbose > 13)
1982 snd_output_printf(loop->output, "%s: processing time %lius\n", loop->id, diff);
1983 if (loop->xrun && loop->xrun_max_proctime < diff)
1984 loop->xrun_max_proctime = diff;
1985 }
1986 return 0;
1987 }
1988
1989 #define OUT(args...) \
1990 snd_output_printf(loop->state, ##args)
1991
1992 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
1993
show_handle(struct loopback_handle * lhandle,const char * id)1994 static void show_handle(struct loopback_handle *lhandle, const char *id)
1995 {
1996 struct loopback *loop = lhandle->loopback;
1997
1998 OUT(" %s: %s:\n", id, lhandle->id);
1999 OUT(" device = '%s', ctldev '%s'\n", lhandle->device, lhandle->ctldev);
2000 OUT(" card_number = %i\n", lhandle->card_number);
2001 if (!loop->running)
2002 return;
2003 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);
2004 OUT(" buffer_size = %u, period_size = %u, avail_min = %li\n", lhandle->buffer_size, lhandle->period_size, lhandle->avail_min);
2005 OUT(" xrun_pending = %i\n", lhandle->xrun_pending);
2006 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);
2007 OUT(" pitch = %.8f\n", lhandle->pitch);
2008 }
2009
pcmjob_state(struct loopback * loop)2010 void pcmjob_state(struct loopback *loop)
2011 {
2012 pthread_t self = pthread_self();
2013 pthread_mutex_lock(&state_mutex);
2014 OUT("State dump for thread %p job %i: %s:\n", (void *)self, loop->thread, loop->id);
2015 OUT(" running = %i\n", loop->running);
2016 OUT(" sync = %i\n", loop->sync);
2017 OUT(" slave = %i\n", loop->slave);
2018 if (!loop->running)
2019 goto __skip;
2020 OUT(" pollfd_count = %i\n", loop->pollfd_count);
2021 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);
2022 OUT(" use_samplerate = %i\n", loop->use_samplerate);
2023 __skip:
2024 show_handle(loop->play, "playback");
2025 show_handle(loop->capt, "capture");
2026 pthread_mutex_unlock(&state_mutex);
2027 }
2028