2 * A simple PCM loopback utility
3 * Copyright (c) 2010 by Jaroslav Kysela <perex@perex.cz>
5 * Author: Jaroslav Kysela <perex@perex.cz>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <alsa/asoundlib.h>
37 #define XRUN_PROFILE_UNKNOWN (-10000000)
39 static int set_rate_shift(struct loopback_handle *lhandle, double pitch);
40 static int get_rate(struct loopback_handle *lhandle);
42 #define SYNCTYPE(v) [SYNC_TYPE_##v] = #v
44 static const char *sync_types[] = {
47 SYNCTYPE(CAPTRATESHIFT),
48 SYNCTYPE(PLAYRATESHIFT),
53 #define SRCTYPE(v) [SRC_##v] = "SRC_" #v
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),
65 static pthread_once_t pcm_open_mutex_once = PTHREAD_ONCE_INIT;
66 static pthread_mutex_t pcm_open_mutex;
68 static void pcm_open_init_mutex(void)
70 pthread_mutexattr_t attr;
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);
78 static inline void pcm_open_lock(void)
80 pthread_once(&pcm_open_mutex_once, pcm_open_init_mutex);
81 if (workarounds & WORKAROUND_SERIALOPEN)
82 pthread_mutex_lock(&pcm_open_mutex);
85 static inline void pcm_open_unlock(void)
87 if (workarounds & WORKAROUND_SERIALOPEN)
88 pthread_mutex_unlock(&pcm_open_mutex);
91 static inline snd_pcm_uframes_t get_whole_latency(struct loopback *loop)
96 static inline unsigned long long
97 frames_to_time(unsigned int rate,
98 snd_pcm_uframes_t frames)
100 return (frames * 1000000ULL) / rate;
103 static inline snd_pcm_uframes_t time_to_frames(unsigned int rate,
104 unsigned long long time)
106 return (time * rate) / 1000000ULL;
109 static int setparams_stream(struct loopback_handle *lhandle,
110 snd_pcm_hw_params_t *params)
112 snd_pcm_t *handle = lhandle->handle;
116 err = snd_pcm_hw_params_any(handle, params);
118 logit(LOG_CRIT, "Broken configuration for %s PCM: no configurations available: %s\n", lhandle->id, snd_strerror(err));
121 err = snd_pcm_hw_params_set_rate_resample(handle, params, lhandle->resample);
123 logit(LOG_CRIT, "Resample setup failed for %s (val %i): %s\n", lhandle->id, lhandle->resample, snd_strerror(err));
126 err = snd_pcm_hw_params_set_access(handle, params, lhandle->access);
128 logit(LOG_CRIT, "Access type not available for %s: %s\n", lhandle->id, snd_strerror(err));
131 err = snd_pcm_hw_params_set_format(handle, params, lhandle->format);
133 logit(LOG_CRIT, "Sample format not available for %s: %s\n", lhandle->id, snd_strerror(err));
136 err = snd_pcm_hw_params_set_channels(handle, params, lhandle->channels);
138 logit(LOG_CRIT, "Channels count (%i) not available for %s: %s\n", lhandle->channels, lhandle->id, snd_strerror(err));
141 rrate = lhandle->rate_req;
142 err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
144 logit(LOG_CRIT, "Rate %iHz not available for %s: %s\n", lhandle->rate_req, lhandle->id, snd_strerror(err));
148 snd_pcm_hw_params_get_rate(params, &rrate, 0);
149 lhandle->rate = rrate;
151 #ifdef USE_SAMPLERATE
152 !lhandle->loopback->src_enable &&
154 (int)rrate != lhandle->rate) {
155 logit(LOG_CRIT, "Rate does not match (requested %iHz, got %iHz, resample %i)\n", lhandle->rate, rrate, lhandle->resample);
158 lhandle->pitch = (double)lhandle->rate_req / (double)lhandle->rate;
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)
167 snd_pcm_t *handle = lhandle->handle;
169 snd_pcm_uframes_t periodsize;
170 snd_pcm_uframes_t buffersize;
171 snd_pcm_uframes_t last_bufsize = 0;
173 if (lhandle->buffer_size_req > 0) {
174 bufsize = lhandle->buffer_size_req;
175 last_bufsize = bufsize;
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);
183 if (last_bufsize == bufsize)
185 last_bufsize = bufsize;
186 if (bufsize > 10*1024*1024) {
187 logit(LOG_CRIT, "Buffer size too big\n");
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);
195 logit(LOG_CRIT, "Unable to set buffer size %li for %s: %s\n", periodsize, lhandle->id, snd_strerror(err));
198 snd_pcm_hw_params_get_buffer_size(params, &periodsize);
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;
205 err = snd_pcm_hw_params_set_period_size_near(handle, params, &periodsize, 0);
207 logit(LOG_CRIT, "Unable to set period size %li for %s: %s\n", periodsize, lhandle->id, snd_strerror(err));
210 snd_pcm_hw_params_get_period_size(params, &periodsize, NULL);
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)
218 lhandle->period_size = periodsize;
219 lhandle->buffer_size = buffersize;
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)
228 snd_pcm_t *handle = lhandle->handle;
230 snd_pcm_uframes_t val, period_size, buffer_size;
232 err = snd_pcm_hw_params(handle, params);
234 logit(LOG_CRIT, "Unable to set hw params for %s: %s\n", lhandle->id, snd_strerror(err));
237 err = snd_pcm_sw_params_current(handle, swparams);
239 logit(LOG_CRIT, "Unable to determine current swparams for %s: %s\n", lhandle->id, snd_strerror(err));
242 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0x7fffffff);
244 logit(LOG_CRIT, "Unable to set start threshold mode for %s: %s\n", lhandle->id, snd_strerror(err));
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);
256 snd_output_printf(lhandle->loopback->output, "%s: avail_min1=%li\n", lhandle->id, val);
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;
265 if (val > buffer_size / 4)
266 val = buffer_size / 4;
269 snd_output_printf(lhandle->loopback->output, "%s: avail_min2=%li\n", lhandle->id, val);
271 err = snd_pcm_sw_params_set_avail_min(handle, swparams, val);
273 logit(LOG_CRIT, "Unable to set avail min for %s: %s\n", lhandle->id, snd_strerror(err));
276 snd_pcm_sw_params_get_avail_min(swparams, &lhandle->avail_min);
277 err = snd_pcm_sw_params(handle, swparams);
279 logit(LOG_CRIT, "Unable to set sw params for %s: %s\n", lhandle->id, snd_strerror(err));
285 static int setparams(struct loopback *loop, snd_pcm_uframes_t bufsize)
288 snd_pcm_hw_params_t *pt_params, *ct_params; /* templates with rate, format and channels */
289 snd_pcm_hw_params_t *p_params, *c_params;
290 snd_pcm_sw_params_t *p_swparams, *c_swparams;
292 snd_pcm_hw_params_alloca(&p_params);
293 snd_pcm_hw_params_alloca(&c_params);
294 snd_pcm_hw_params_alloca(&pt_params);
295 snd_pcm_hw_params_alloca(&ct_params);
296 snd_pcm_sw_params_alloca(&p_swparams);
297 snd_pcm_sw_params_alloca(&c_swparams);
298 if ((err = setparams_stream(loop->play, pt_params)) < 0) {
299 logit(LOG_CRIT, "Unable to set parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
302 if ((err = setparams_stream(loop->capt, ct_params)) < 0) {
303 logit(LOG_CRIT, "Unable to set parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
307 if ((err = setparams_bufsize(loop->play, p_params, pt_params, bufsize / loop->play->pitch)) < 0) {
308 logit(LOG_CRIT, "Unable to set buffer parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
311 if ((err = setparams_bufsize(loop->capt, c_params, ct_params, bufsize / loop->capt->pitch)) < 0) {
312 logit(LOG_CRIT, "Unable to set buffer parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
316 if ((err = setparams_set(loop->play, p_params, p_swparams, bufsize / loop->play->pitch)) < 0) {
317 logit(LOG_CRIT, "Unable to set sw parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
320 if ((err = setparams_set(loop->capt, c_params, c_swparams, bufsize / loop->capt->pitch)) < 0) {
321 logit(LOG_CRIT, "Unable to set sw parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
327 if (snd_pcm_link(loop->capt->handle, loop->play->handle) >= 0)
330 if ((err = snd_pcm_prepare(loop->play->handle)) < 0) {
331 logit(LOG_CRIT, "Prepare %s error: %s\n", loop->play->id, snd_strerror(err));
334 if (!loop->linked && (err = snd_pcm_prepare(loop->capt->handle)) < 0) {
335 logit(LOG_CRIT, "Prepare %s error: %s\n", loop->capt->id, snd_strerror(err));
340 snd_pcm_dump(loop->play->handle, loop->output);
341 snd_pcm_dump(loop->capt->handle, loop->output);
346 static void showlatency(snd_output_t *out, size_t latency, unsigned int rate,
350 d = (double)latency / (double)rate;
351 snd_output_printf(out, "%s %li frames, %.3fus, %.6fms (%.4fHz)\n", prefix, (long)latency, d * 1000000, d * 1000, (double)1 / d);
354 static long timediff(snd_timestamp_t t1, snd_timestamp_t t2)
358 t1.tv_sec -= t2.tv_sec;
359 if (t1.tv_usec < t2.tv_usec) {
360 l = ((t1.tv_usec + 1000000) - t2.tv_usec) % 1000000;
363 l = t1.tv_usec - t2.tv_usec;
365 return (t1.tv_sec * 1000000) + l;
368 static int getcurtimestamp(snd_timestamp_t *ts)
371 gettimeofday(&tv, NULL);
372 ts->tv_sec = tv.tv_sec;
373 ts->tv_usec = tv.tv_usec;
377 static void xrun_profile0(struct loopback *loop)
379 snd_pcm_sframes_t pdelay, cdelay;
381 if (snd_pcm_delay(loop->play->handle, &pdelay) >= 0 &&
382 snd_pcm_delay(loop->capt->handle, &cdelay) >= 0) {
383 getcurtimestamp(&loop->xrun_last_update);
384 loop->xrun_last_pdelay = pdelay;
385 loop->xrun_last_cdelay = cdelay;
386 loop->xrun_buf_pcount = loop->play->buf_count;
387 loop->xrun_buf_ccount = loop->capt->buf_count;
388 #ifdef USE_SAMPLERATE
389 loop->xrun_out_frames = loop->src_out_frames;
394 static inline void xrun_profile(struct loopback *loop)
400 static void xrun_stats0(struct loopback *loop)
403 double expected, last, wake, check, queued = -1, proc, missing = -1;
404 double maxbuf, pfilled, cfilled, cqueued = -1, avail_min;
407 expected = ((double)loop->latency /
408 (double)loop->play->rate_req) * 1000;
410 last = (double)timediff(t, loop->xrun_last_update) / 1000;
411 wake = (double)timediff(t, loop->xrun_last_wake) / 1000;
412 check = (double)timediff(t, loop->xrun_last_check) / 1000;
413 sincejob = (double)timediff(t, loop->tstamp_start) / 1000;
414 if (loop->xrun_last_pdelay != XRUN_PROFILE_UNKNOWN)
415 queued = ((double)loop->xrun_last_pdelay /
416 (double)loop->play->rate) * 1000;
417 if (loop->xrun_last_cdelay != XRUN_PROFILE_UNKNOWN)
418 cqueued = ((double)loop->xrun_last_cdelay /
419 (double)loop->capt->rate) * 1000;
420 maxbuf = ((double)loop->play->buffer_size /
421 (double)loop->play->rate) * 1000;
422 proc = (double)loop->xrun_max_proctime / 1000;
423 pfilled = ((double)(loop->xrun_buf_pcount + loop->xrun_out_frames) /
424 (double)loop->play->rate) * 1000;
425 cfilled = ((double)loop->xrun_buf_ccount /
426 (double)loop->capt->rate) * 1000;
427 avail_min = (((double)loop->play->buffer_size -
428 (double)loop->play->avail_min ) /
429 (double)loop->play->rate) * 1000;
430 avail_min = expected - avail_min;
432 missing = last - queued;
433 if (missing >= 0 && loop->xrun_max_missing < missing)
434 loop->xrun_max_missing = missing;
435 loop->xrun_max_proctime = 0;
437 logit(LOG_INFO, " last write before %.4fms, queued %.4fms/%.4fms -> missing %.4fms\n", last, queued, cqueued, missing);
438 logit(LOG_INFO, " expected %.4fms, processing %.4fms, max missing %.4fms\n", expected, proc, loop->xrun_max_missing);
439 logit(LOG_INFO, " last wake %.4fms, last check %.4fms, avail_min %.4fms\n", wake, check, avail_min);
440 logit(LOG_INFO, " max buf %.4fms, pfilled %.4fms, cfilled %.4fms\n", maxbuf, pfilled, cfilled);
441 logit(LOG_INFO, " job started before %.4fms\n", sincejob);
444 static inline void xrun_stats(struct loopback *loop)
450 static inline snd_pcm_uframes_t buf_avail(struct loopback_handle *lhandle)
452 return lhandle->buf_size - lhandle->buf_count;
455 static void buf_remove(struct loopback *loop, snd_pcm_uframes_t count)
457 /* remove samples from the capture buffer */
460 if (loop->play->buf == loop->capt->buf) {
461 if (count < loop->capt->buf_count)
462 loop->capt->buf_count -= count;
464 loop->capt->buf_count = 0;
469 static void buf_add_copy(struct loopback *loop)
471 struct loopback_handle *capt = loop->capt;
472 struct loopback_handle *play = loop->play;
473 snd_pcm_uframes_t count, count1, cpos, ppos;
475 count = capt->buf_count;
476 cpos = capt->buf_pos - count;
477 if (cpos > capt->buf_size)
478 cpos += capt->buf_size;
479 ppos = (play->buf_pos + play->buf_count) % play->buf_size;
482 if (count1 + cpos > capt->buf_size)
483 count1 = capt->buf_size - cpos;
484 if (count1 > buf_avail(play))
485 count1 = buf_avail(play);
486 if (count1 + ppos > play->buf_size)
487 count1 = play->buf_size - ppos;
490 memcpy(play->buf + ppos * play->frame_size,
491 capt->buf + cpos * capt->frame_size,
492 count1 * capt->frame_size);
493 play->buf_count += count1;
494 capt->buf_count -= count1;
496 ppos %= play->buf_size;
498 cpos %= capt->buf_size;
504 #ifdef USE_SAMPLERATE
505 static void buf_add_src(struct loopback *loop)
507 struct loopback_handle *capt = loop->capt;
508 struct loopback_handle *play = loop->play;
510 snd_pcm_uframes_t count, pos, count1, pos1;
511 count = capt->buf_count;
513 pos1 = capt->buf_pos - count;
514 if (pos1 > capt->buf_size)
515 pos1 += capt->buf_size;
518 if (count1 + pos1 > capt->buf_size)
519 count1 = capt->buf_size - pos1;
520 if (capt->format == SND_PCM_FORMAT_S32)
521 src_int_to_float_array((int *)(capt->buf +
522 pos1 * capt->frame_size),
523 loop->src_data.data_in +
524 pos * capt->channels,
525 count1 * capt->channels);
527 src_short_to_float_array((short *)(capt->buf +
528 pos1 * capt->frame_size),
529 loop->src_data.data_in +
530 pos * capt->channels,
531 count1 * capt->channels);
535 pos1 %= capt->buf_size;
537 loop->src_data.input_frames = pos;
538 loop->src_data.output_frames = play->buf_size -
539 loop->src_out_frames;
540 loop->src_data.end_of_input = 0;
541 old_data_out = loop->src_data.data_out;
542 loop->src_data.data_out = old_data_out + loop->src_out_frames;
543 src_process(loop->src_state, &loop->src_data);
544 loop->src_data.data_out = old_data_out;
545 capt->buf_count -= loop->src_data.input_frames_used;
546 count = loop->src_data.output_frames_gen +
547 loop->src_out_frames;
549 pos1 = (play->buf_pos + play->buf_count) % play->buf_size;
552 if (count1 + pos1 > play->buf_size)
553 count1 = play->buf_size - pos1;
554 if (count1 > buf_avail(play))
555 count1 = buf_avail(play);
558 if (capt->format == SND_PCM_FORMAT_S32)
559 src_float_to_int_array(loop->src_data.data_out +
560 pos * play->channels,
562 pos1 * play->frame_size),
563 count1 * play->channels);
565 src_float_to_short_array(loop->src_data.data_out +
566 pos * play->channels,
567 (short *)(play->buf +
568 pos1 * play->frame_size),
569 count1 * play->channels);
570 play->buf_count += count1;
574 pos1 %= play->buf_size;
577 printf("src: pos = %li, gen = %li, out = %li, count = %li\n",
578 (long)pos, (long)loop->src_data.output_frames_gen,
579 (long)loop->src_out_frames, play->buf_count);
581 loop->src_out_frames = (loop->src_data.output_frames_gen +
582 loop->src_out_frames) - pos;
583 if (loop->src_out_frames > 0) {
584 memmove(loop->src_data.data_out,
585 loop->src_data.data_out + pos * play->channels,
586 loop->src_out_frames * play->channels * sizeof(float));
590 static void buf_add_src(struct loopback *loop)
595 static void buf_add(struct loopback *loop, snd_pcm_uframes_t count)
597 /* copy samples from capture to playback buffer */
600 if (loop->play->buf == loop->capt->buf) {
601 loop->play->buf_count += count;
607 static int xrun(struct loopback_handle *lhandle)
611 if (lhandle == lhandle->loopback->play) {
612 logit(LOG_DEBUG, "underrun for %s\n", lhandle->id);
613 xrun_stats(lhandle->loopback);
614 if ((err = snd_pcm_prepare(lhandle->handle)) < 0)
616 lhandle->xrun_pending = 1;
618 logit(LOG_DEBUG, "overrun for %s\n", lhandle->id);
619 xrun_stats(lhandle->loopback);
620 if ((err = snd_pcm_prepare(lhandle->handle)) < 0)
622 lhandle->xrun_pending = 1;
627 static int suspend(struct loopback_handle *lhandle)
631 while ((err = snd_pcm_resume(lhandle->handle)) == -EAGAIN)
634 return xrun(lhandle);
638 static int readit(struct loopback_handle *lhandle)
640 snd_pcm_sframes_t r, res = 0;
641 snd_pcm_sframes_t avail;
644 avail = snd_pcm_avail_update(lhandle->handle);
645 if (avail == -EPIPE) {
646 return xrun(lhandle);
647 } else if (avail == -ESTRPIPE) {
648 if ((err = suspend(lhandle)) < 0)
651 if (avail > buf_avail(lhandle)) {
652 lhandle->buf_over += avail - buf_avail(lhandle);
653 avail = buf_avail(lhandle);
654 } else if (avail == 0) {
655 if (snd_pcm_state(lhandle->handle) == SND_PCM_STATE_DRAINING) {
656 lhandle->loopback->reinit = 1;
661 r = buf_avail(lhandle);
662 if (r + lhandle->buf_pos > lhandle->buf_size)
663 r = lhandle->buf_size - lhandle->buf_pos;
666 r = snd_pcm_readi(lhandle->handle,
669 lhandle->frame_size, r);
675 return res > 0 ? res : err;
676 } else if (r == -ESTRPIPE) {
677 if ((err = suspend(lhandle)) < 0)
678 return res > 0 ? res : err;
681 return res > 0 ? res : r;
685 if (lhandle->loopback->cfile)
686 fwrite(lhandle->buf + lhandle->buf_pos * lhandle->frame_size,
687 r, lhandle->frame_size, lhandle->loopback->cfile);
690 if (lhandle->max < res)
692 lhandle->counter += r;
693 lhandle->buf_count += r;
694 lhandle->buf_pos += r;
695 lhandle->buf_pos %= lhandle->buf_size;
701 static int writeit(struct loopback_handle *lhandle)
703 snd_pcm_sframes_t avail;
704 snd_pcm_sframes_t r, res = 0;
708 avail = snd_pcm_avail_update(lhandle->handle);
709 if (avail == -EPIPE) {
710 if ((err = xrun(lhandle)) < 0)
713 } else if (avail == -ESTRPIPE) {
714 if ((err = suspend(lhandle)) < 0)
718 while (avail > 0 && lhandle->buf_count > 0) {
719 r = lhandle->buf_count;
720 if (r + lhandle->buf_pos > lhandle->buf_size)
721 r = lhandle->buf_size - lhandle->buf_pos;
724 r = snd_pcm_writei(lhandle->handle,
727 lhandle->frame_size, r);
730 if ((err = xrun(lhandle)) < 0)
733 } else if (r == -ESTRPIPE) {
735 return res > 0 ? res : r;
738 if (lhandle->loopback->pfile)
739 fwrite(lhandle->buf + lhandle->buf_pos * lhandle->frame_size,
740 r, lhandle->frame_size, lhandle->loopback->pfile);
743 lhandle->counter += r;
744 lhandle->buf_count -= r;
745 lhandle->buf_pos += r;
746 lhandle->buf_pos %= lhandle->buf_size;
747 xrun_profile(lhandle->loopback);
748 if (lhandle->loopback->stop_pending) {
749 lhandle->loopback->stop_count += r;
750 if (lhandle->loopback->stop_count * lhandle->pitch >
751 lhandle->loopback->latency * 3) {
752 lhandle->loopback->stop_pending = 0;
753 lhandle->loopback->reinit = 1;
761 static snd_pcm_sframes_t remove_samples(struct loopback *loop,
762 int capture_preferred,
763 snd_pcm_sframes_t count)
765 struct loopback_handle *play = loop->play;
766 struct loopback_handle *capt = loop->capt;
768 if (loop->play->buf == loop->capt->buf) {
769 if (count > loop->play->buf_count)
770 count = loop->play->buf_count;
771 if (count > loop->capt->buf_count)
772 count = loop->capt->buf_count;
773 capt->buf_count -= count;
774 play->buf_pos += count;
775 play->buf_pos %= play->buf_size;
776 play->buf_count -= count;
779 if (capture_preferred) {
780 if (count > capt->buf_count)
781 count = capt->buf_count;
782 capt->buf_count -= count;
784 if (count > play->buf_count)
785 count = play->buf_count;
786 play->buf_count -= count;
791 static int xrun_sync(struct loopback *loop)
793 struct loopback_handle *play = loop->play;
794 struct loopback_handle *capt = loop->capt;
795 snd_pcm_uframes_t fill = get_whole_latency(loop);
796 snd_pcm_sframes_t pdelay, cdelay, delay1, pdelay1, cdelay1, diff;
801 snd_output_printf(loop->output, "%s: xrun sync %i %i\n", loop->id, capt->xrun_pending, play->xrun_pending);
802 if (capt->xrun_pending) {
804 capt->xrun_pending = 0;
805 if ((err = snd_pcm_prepare(capt->handle)) < 0) {
806 logit(LOG_CRIT, "%s prepare failed: %s\n", capt->id, snd_strerror(err));
809 if ((err = snd_pcm_start(capt->handle)) < 0) {
810 logit(LOG_CRIT, "%s start failed: %s\n", capt->id, snd_strerror(err));
816 if (capt->xrun_pending)
819 /* skip additional playback samples */
820 if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0) {
822 capt->xrun_pending = 1;
825 if (err == -ESTRPIPE) {
831 logit(LOG_CRIT, "%s capture delay failed: %s\n", capt->id, snd_strerror(err));
834 if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0) {
837 play->xrun_pending = 1;
838 } else if (err == -ESTRPIPE) {
844 logit(LOG_CRIT, "%s playback delay failed: %s\n", play->id, snd_strerror(err));
848 capt->counter = cdelay;
849 play->counter = pdelay;
850 if (play->buf != capt->buf)
851 cdelay += capt->buf_count;
852 pdelay += play->buf_count;
853 #ifdef USE_SAMPLERATE
854 pdelay += loop->src_out_frames;
856 cdelay1 = cdelay * capt->pitch;
857 pdelay1 = pdelay * play->pitch;
858 delay1 = cdelay1 + pdelay1;
859 capt->total_queued = 0;
860 play->total_queued = 0;
861 loop->total_queued_count = 0;
862 loop->pitch_diff = loop->pitch_diff_min = loop->pitch_diff_max = 0;
864 snd_output_printf(loop->output,
865 "sync: cdelay=%li(%li), pdelay=%li(%li), fill=%li (delay=%li)"
866 #ifdef USE_SAMPLERATE
870 (long)cdelay, (long)cdelay1, (long)pdelay, (long)pdelay1,
871 (long)fill, (long)delay1
872 #ifdef USE_SAMPLERATE
873 , (long)loop->src_out_frames
876 snd_output_printf(loop->output,
877 "sync: cbufcount=%li, pbufcount=%li\n",
878 (long)capt->buf_count, (long)play->buf_count);
880 if (delay1 > fill && capt->counter > 0) {
881 if ((err = snd_pcm_drop(capt->handle)) < 0)
883 if ((err = snd_pcm_prepare(capt->handle)) < 0)
885 if ((err = snd_pcm_start(capt->handle)) < 0)
887 diff = remove_samples(loop, 1, (delay1 - fill) / capt->pitch);
889 snd_output_printf(loop->output,
890 "sync: capt stop removed %li samples\n", (long)diff);
894 diff = (delay1 - fill) / play->pitch;
895 if (diff > play->buf_count)
896 diff = play->buf_count;
898 snd_output_printf(loop->output,
899 "sync: removing %li playback samples, delay1=%li\n", (long)diff, (long)delay1);
900 diff = remove_samples(loop, 0, diff);
902 pdelay1 = pdelay * play->pitch;
903 delay1 = cdelay1 + pdelay1;
905 snd_output_printf(loop->output,
906 "sync: removed %li playback samples, delay1=%li\n", (long)diff, (long)delay1);
909 diff = (delay1 - fill) / capt->pitch;
910 if (diff > capt->buf_count)
911 diff = capt->buf_count;
913 snd_output_printf(loop->output,
914 "sync: removing %li captured samples, delay1=%li\n", (long)diff, (long)delay1);
915 diff -= remove_samples(loop, 1, diff);
917 cdelay1 = cdelay * capt->pitch;
918 delay1 = cdelay1 + pdelay1;
920 snd_output_printf(loop->output,
921 "sync: removed %li captured samples, delay1=%li\n", (long)diff, (long)delay1);
923 if (play->xrun_pending) {
924 play->xrun_pending = 0;
925 diff = (fill - delay1) / play->pitch;
927 snd_output_printf(loop->output,
928 "sync: xrun_pending, silence filling %li / buf_count=%li\n", (long)diff, play->buf_count);
929 if (fill > delay1 && play->buf_count < diff) {
930 diff = diff - play->buf_count;
932 snd_output_printf(loop->output,
933 "sync: playback silence added %li samples\n", (long)diff);
934 play->buf_pos -= diff;
935 play->buf_pos %= play->buf_size;
936 if ((err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->channels, diff)) < 0)
938 play->buf_count += diff;
940 if ((err = snd_pcm_prepare(play->handle)) < 0) {
941 logit(LOG_CRIT, "%s prepare failed: %s\n", play->id, snd_strerror(err));
945 delay1 = writeit(play);
947 snd_output_printf(loop->output,
948 "sync: playback wrote %li samples\n", (long)delay1);
950 buf_remove(loop, delay1 - diff);
952 snd_output_printf(loop->output,
953 "sync: playback buf_remove %li samples\n", (long)(delay1 - diff));
955 if ((err = snd_pcm_start(play->handle)) < 0) {
956 logit(LOG_CRIT, "%s start failed: %s\n", play->id, snd_strerror(err));
959 } else if (delay1 < fill) {
960 diff = (fill - delay1) / play->pitch;
962 delay1 = play->buf_size - play->buf_pos;
964 snd_output_printf(loop->output,
965 "sync: playback short, silence filling %li / buf_count=%li\n", (long)delay1, play->buf_count);
968 if ((err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->channels, delay1)) < 0)
970 play->buf_pos += delay1;
971 play->buf_pos %= play->buf_size;
972 play->buf_count += delay1;
978 snd_output_printf(loop->output, "%s: xrun sync ok\n", loop->id);
980 if (snd_pcm_delay(capt->handle, &cdelay) < 0)
982 if (snd_pcm_delay(play->handle, &pdelay) < 0)
984 if (play->buf != capt->buf)
985 cdelay += capt->buf_count;
986 pdelay += play->buf_count;
987 #ifdef USE_SAMPLERATE
988 pdelay += loop->src_out_frames;
990 cdelay1 = cdelay * capt->pitch;
991 pdelay1 = pdelay * play->pitch;
992 delay1 = cdelay1 + pdelay1;
993 snd_output_printf(loop->output, "%s: sync verify: %li\n", loop->id, delay1);
996 loop->xrun_max_proctime = 0;
1000 static int set_notify(struct loopback_handle *lhandle, int enable)
1004 if (lhandle->ctl_notify == NULL)
1006 snd_ctl_elem_value_set_boolean(lhandle->ctl_notify, 0, enable);
1007 err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_notify);
1009 logit(LOG_CRIT, "Cannot set PCM Notify element for %s: %s\n", lhandle->id, snd_strerror(err));
1012 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_notify);
1014 logit(LOG_CRIT, "Cannot get PCM Notify element for %s: %s\n", lhandle->id, snd_strerror(err));
1020 static int set_rate_shift(struct loopback_handle *lhandle, double pitch)
1024 if (lhandle->ctl_rate_shift == NULL)
1026 snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, pitch * 100000);
1027 err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_rate_shift);
1029 logit(LOG_CRIT, "Cannot set PCM Rate Shift element for %s: %s\n", lhandle->id, snd_strerror(err));
1035 void update_pitch(struct loopback *loop)
1037 double pitch = loop->pitch;
1039 #ifdef USE_SAMPLERATE
1040 if (loop->sync == SYNC_TYPE_SAMPLERATE) {
1041 loop->src_data.src_ratio = (double)1.0 / (pitch *
1042 loop->play->pitch * loop->capt->pitch);
1044 snd_output_printf(loop->output, "%s: Samplerate src_ratio update1: %.8f\n", loop->id, loop->src_data.src_ratio);
1047 if (loop->sync == SYNC_TYPE_CAPTRATESHIFT) {
1048 set_rate_shift(loop->capt, pitch);
1049 #ifdef USE_SAMPLERATE
1050 if (loop->use_samplerate) {
1051 loop->src_data.src_ratio =
1053 (loop->play->pitch * loop->capt->pitch);
1055 snd_output_printf(loop->output, "%s: Samplerate src_ratio update2: %.8f\n", loop->id, loop->src_data.src_ratio);
1059 else if (loop->sync == SYNC_TYPE_PLAYRATESHIFT) {
1060 set_rate_shift(loop->play, pitch);
1061 #ifdef USE_SAMPLERATE
1062 if (loop->use_samplerate) {
1063 loop->src_data.src_ratio =
1065 (loop->play->pitch * loop->capt->pitch);
1067 snd_output_printf(loop->output, "%s: Samplerate src_ratio update3: %.8f\n", loop->id, loop->src_data.src_ratio);
1072 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);
1075 static int get_active(struct loopback_handle *lhandle)
1079 if (lhandle->ctl_active == NULL)
1081 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_active);
1083 logit(LOG_CRIT, "Cannot get PCM Slave Active element for %s: %s\n", lhandle->id, snd_strerror(err));
1086 return snd_ctl_elem_value_get_boolean(lhandle->ctl_active, 0);
1089 static int get_format(struct loopback_handle *lhandle)
1093 if (lhandle->ctl_format == NULL)
1095 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_format);
1097 logit(LOG_CRIT, "Cannot get PCM Format element for %s: %s\n", lhandle->id, snd_strerror(err));
1100 return snd_ctl_elem_value_get_integer(lhandle->ctl_format, 0);
1103 static int get_rate(struct loopback_handle *lhandle)
1107 if (lhandle->ctl_rate == NULL)
1109 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_rate);
1111 logit(LOG_CRIT, "Cannot get PCM Rate element for %s: %s\n", lhandle->id, snd_strerror(err));
1114 return snd_ctl_elem_value_get_integer(lhandle->ctl_rate, 0);
1117 static int get_channels(struct loopback_handle *lhandle)
1121 if (lhandle->ctl_channels == NULL)
1123 err = snd_ctl_elem_read(lhandle->ctl, lhandle->ctl_channels);
1125 logit(LOG_CRIT, "Cannot get PCM Channels element for %s: %s\n", lhandle->id, snd_strerror(err));
1128 return snd_ctl_elem_value_get_integer(lhandle->ctl_channels, 0);
1131 static void openctl_elem(struct loopback_handle *lhandle,
1132 int device, int subdevice,
1134 snd_ctl_elem_value_t **elem)
1138 if (snd_ctl_elem_value_malloc(elem) < 0) {
1141 snd_ctl_elem_value_set_interface(*elem,
1142 SND_CTL_ELEM_IFACE_PCM);
1143 snd_ctl_elem_value_set_device(*elem, device);
1144 snd_ctl_elem_value_set_subdevice(*elem, subdevice);
1145 snd_ctl_elem_value_set_name(*elem, name);
1146 err = snd_ctl_elem_read(lhandle->ctl, *elem);
1148 snd_ctl_elem_value_free(*elem);
1154 static int openctl(struct loopback_handle *lhandle, int device, int subdevice)
1158 lhandle->ctl_rate_shift = NULL;
1159 if (lhandle->loopback->play == lhandle) {
1160 if (lhandle->loopback->controls)
1164 openctl_elem(lhandle, device, subdevice, "PCM Notify",
1165 &lhandle->ctl_notify);
1166 openctl_elem(lhandle, device, subdevice, "PCM Rate Shift 100000",
1167 &lhandle->ctl_rate_shift);
1168 set_rate_shift(lhandle, 1);
1169 openctl_elem(lhandle, device, subdevice, "PCM Slave Active",
1170 &lhandle->ctl_active);
1171 openctl_elem(lhandle, device, subdevice, "PCM Slave Format",
1172 &lhandle->ctl_format);
1173 openctl_elem(lhandle, device, subdevice, "PCM Slave Rate",
1174 &lhandle->ctl_rate);
1175 openctl_elem(lhandle, device, subdevice, "PCM Slave Channels",
1176 &lhandle->ctl_channels);
1177 if ((lhandle->ctl_active &&
1178 lhandle->ctl_format &&
1179 lhandle->ctl_rate &&
1180 lhandle->ctl_channels) ||
1181 lhandle->loopback->controls) {
1183 if ((err = snd_ctl_poll_descriptors_count(lhandle->ctl)) < 0)
1184 lhandle->ctl_pollfd_count = 0;
1186 lhandle->ctl_pollfd_count = err;
1187 if (snd_ctl_subscribe_events(lhandle->ctl, 1) < 0)
1188 lhandle->ctl_pollfd_count = 0;
1193 static int openit(struct loopback_handle *lhandle)
1195 snd_pcm_info_t *info;
1196 int stream = lhandle == lhandle->loopback->play ?
1197 SND_PCM_STREAM_PLAYBACK :
1198 SND_PCM_STREAM_CAPTURE;
1199 int err, card, device, subdevice;
1201 err = snd_pcm_open(&lhandle->handle, lhandle->device, stream, SND_PCM_NONBLOCK);
1204 logit(LOG_CRIT, "%s open error: %s\n", lhandle->id, snd_strerror(err));
1207 if ((err = snd_pcm_info_malloc(&info)) < 0)
1209 if ((err = snd_pcm_info(lhandle->handle, info)) < 0) {
1210 snd_pcm_info_free(info);
1213 card = snd_pcm_info_get_card(info);
1214 device = snd_pcm_info_get_device(info);
1215 subdevice = snd_pcm_info_get_subdevice(info);
1216 snd_pcm_info_free(info);
1217 lhandle->card_number = card;
1218 lhandle->ctl = NULL;
1219 if (card >= 0 || lhandle->ctldev) {
1220 char name[16], *dev = lhandle->ctldev;
1222 sprintf(name, "hw:%i", card);
1226 err = snd_ctl_open(&lhandle->ctl, dev, SND_CTL_NONBLOCK);
1229 logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, dev, snd_strerror(err));
1230 lhandle->ctl = NULL;
1233 openctl(lhandle, device, subdevice);
1238 static int freeit(struct loopback_handle *lhandle)
1241 lhandle->buf = NULL;
1245 static int closeit(struct loopback_handle *lhandle)
1249 set_rate_shift(lhandle, 1);
1250 if (lhandle->ctl_rate_shift)
1251 snd_ctl_elem_value_free(lhandle->ctl_rate_shift);
1252 lhandle->ctl_rate_shift = NULL;
1254 err = snd_ctl_close(lhandle->ctl);
1255 lhandle->ctl = NULL;
1256 if (lhandle->handle)
1257 err = snd_pcm_close(lhandle->handle);
1258 lhandle->handle = NULL;
1262 static int init_handle(struct loopback_handle *lhandle, int alloc)
1264 snd_pcm_uframes_t lat;
1265 lhandle->frame_size = (snd_pcm_format_physical_width(lhandle->format)
1266 / 8) * lhandle->channels;
1267 lhandle->sync_point = lhandle->rate * 15; /* every 15 seconds */
1268 lat = lhandle->loopback->latency;
1269 if (lhandle->buffer_size > lat)
1270 lat = lhandle->buffer_size;
1271 lhandle->buf_size = lat * 2;
1273 lhandle->buf = calloc(1, lhandle->buf_size * lhandle->frame_size);
1274 if (lhandle->buf == NULL)
1280 int pcmjob_init(struct loopback *loop)
1286 loop->cfile = fopen(FILE_CWRITE, "w+");
1289 loop->pfile = fopen(FILE_PWRITE, "w+");
1291 if ((err = openit(loop->play)) < 0)
1293 if ((err = openit(loop->capt)) < 0)
1295 snprintf(id, sizeof(id), "%s/%s", loop->play->id, loop->capt->id);
1296 id[sizeof(id)-1] = '\0';
1297 loop->id = strdup(id);
1298 if (loop->sync == SYNC_TYPE_AUTO && loop->capt->ctl_rate_shift)
1299 loop->sync = SYNC_TYPE_CAPTRATESHIFT;
1300 if (loop->sync == SYNC_TYPE_AUTO && loop->play->ctl_rate_shift)
1301 loop->sync = SYNC_TYPE_PLAYRATESHIFT;
1302 #ifdef USE_SAMPLERATE
1303 if (loop->sync == SYNC_TYPE_AUTO && loop->src_enable)
1304 loop->sync = SYNC_TYPE_SAMPLERATE;
1306 if (loop->sync == SYNC_TYPE_AUTO)
1307 loop->sync = SYNC_TYPE_SIMPLE;
1308 if (loop->slave == SLAVE_TYPE_AUTO &&
1309 loop->capt->ctl_notify &&
1310 loop->capt->ctl_active &&
1311 loop->capt->ctl_format &&
1312 loop->capt->ctl_rate &&
1313 loop->capt->ctl_channels)
1314 loop->slave = SLAVE_TYPE_ON;
1315 if (loop->slave == SLAVE_TYPE_ON) {
1316 err = set_notify(loop->capt, 1);
1319 if (loop->capt->ctl_notify == NULL ||
1320 snd_ctl_elem_value_get_boolean(loop->capt->ctl_notify, 0) == 0) {
1321 logit(LOG_CRIT, "unable to enable slave mode for %s\n", loop->id);
1326 err = control_init(loop);
1335 static void freeloop(struct loopback *loop)
1337 #ifdef USE_SAMPLERATE
1338 if (loop->use_samplerate) {
1339 if (loop->src_state)
1340 src_delete(loop->src_state);
1341 loop->src_state = NULL;
1342 free(loop->src_data.data_in);
1343 loop->src_data.data_in = NULL;
1344 free(loop->src_data.data_out);
1345 loop->src_data.data_out = NULL;
1348 if (loop->play->buf == loop->capt->buf)
1349 loop->play->buf = NULL;
1354 int pcmjob_done(struct loopback *loop)
1357 closeit(loop->play);
1358 closeit(loop->capt);
1364 fclose(loop->pfile);
1370 fclose(loop->cfile);
1377 static void lhandle_start(struct loopback_handle *lhandle)
1379 lhandle->buf_pos = 0;
1380 lhandle->buf_count = 0;
1381 lhandle->counter = 0;
1382 lhandle->total_queued = 0;
1385 static void fix_format(struct loopback *loop, int force)
1387 snd_pcm_format_t format = loop->capt->format;
1389 if (!force && loop->sync != SYNC_TYPE_SAMPLERATE)
1391 if (format == SND_PCM_FORMAT_S16 ||
1392 format == SND_PCM_FORMAT_S32)
1394 if (snd_pcm_format_width(format) > 16)
1395 format = SND_PCM_FORMAT_S32;
1397 format = SND_PCM_FORMAT_S16;
1398 loop->capt->format = format;
1399 loop->play->format = format;
1402 int pcmjob_start(struct loopback *loop)
1404 snd_pcm_uframes_t count;
1407 loop->pollfd_count = loop->play->ctl_pollfd_count +
1408 loop->capt->ctl_pollfd_count;
1409 if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
1411 loop->play->pollfd_count = err;
1412 loop->pollfd_count += err;
1413 if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
1415 loop->capt->pollfd_count = err;
1416 loop->pollfd_count += err;
1417 if (loop->slave == SLAVE_TYPE_ON) {
1418 err = get_active(loop->capt);
1421 if (err == 0) /* stream is not active */
1423 err = get_format(loop->capt);
1426 loop->play->format = loop->capt->format = err;
1427 fix_format(loop, 0);
1428 err = get_rate(loop->capt);
1431 loop->play->rate_req = loop->capt->rate_req = err;
1432 err = get_channels(loop->capt);
1435 loop->play->channels = loop->capt->channels = err;
1438 loop->use_samplerate = 0;
1440 if (loop->latency_req) {
1441 loop->latency_reqtime = frames_to_time(loop->play->rate_req,
1443 loop->latency_req = 0;
1445 loop->latency = time_to_frames(loop->play->rate_req, loop->latency_reqtime);
1446 if ((err = setparams(loop, loop->latency/2)) < 0)
1449 showlatency(loop->output, loop->latency, loop->play->rate_req, "Latency");
1450 if (loop->play->access == loop->capt->access &&
1451 loop->play->format == loop->capt->format &&
1452 loop->play->rate == loop->capt->rate &&
1453 loop->play->channels == loop->play->channels &&
1454 loop->sync != SYNC_TYPE_SAMPLERATE) {
1456 snd_output_printf(loop->output, "shared buffer!!!\n");
1457 if ((err = init_handle(loop->play, 1)) < 0)
1459 if ((err = init_handle(loop->capt, 0)) < 0)
1461 if (loop->play->buf_size < loop->capt->buf_size) {
1462 char *nbuf = realloc(loop->play->buf,
1463 loop->capt->buf_size *
1464 loop->capt->frame_size);
1469 loop->play->buf = nbuf;
1470 loop->play->buf_size = loop->capt->buf_size;
1471 } else if (loop->capt->buf_size < loop->play->buf_size) {
1472 char *nbuf = realloc(loop->capt->buf,
1473 loop->play->buf_size *
1474 loop->play->frame_size);
1479 loop->capt->buf = nbuf;
1480 loop->capt->buf_size = loop->play->buf_size;
1482 loop->capt->buf = loop->play->buf;
1484 if ((err = init_handle(loop->play, 1)) < 0)
1486 if ((err = init_handle(loop->capt, 1)) < 0)
1488 if (loop->play->rate_req != loop->play->rate ||
1489 loop->capt->rate_req != loop->capt->rate) {
1490 snd_pcm_format_t format1, format2;
1491 loop->use_samplerate = 1;
1492 format1 = loop->play->format;
1493 format2 = loop->capt->format;
1494 fix_format(loop, 1);
1495 if (loop->play->format != format1 ||
1496 loop->capt->format != format2) {
1502 #ifdef USE_SAMPLERATE
1503 if (loop->sync == SYNC_TYPE_SAMPLERATE)
1504 loop->use_samplerate = 1;
1505 if (loop->use_samplerate && !loop->src_enable) {
1506 logit(LOG_CRIT, "samplerate conversion required but disabled\n");
1507 loop->use_samplerate = 0;
1511 if (loop->use_samplerate) {
1512 if ((loop->capt->format != SND_PCM_FORMAT_S16 ||
1513 loop->play->format != SND_PCM_FORMAT_S16) &&
1514 (loop->capt->format != SND_PCM_FORMAT_S32 ||
1515 loop->play->format != SND_PCM_FORMAT_S32)) {
1516 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));
1517 loop->use_samplerate = 0;
1521 loop->src_state = src_new(loop->src_converter_type,
1522 loop->play->channels, &err);
1523 loop->src_data.data_in = calloc(1, sizeof(float)*loop->capt->channels*loop->capt->buf_size);
1524 if (loop->src_data.data_in == NULL) {
1528 loop->src_data.data_out = calloc(1, sizeof(float)*loop->play->channels*loop->play->buf_size);
1529 if (loop->src_data.data_out == NULL) {
1533 loop->src_data.src_ratio = (double)loop->play->rate /
1534 (double)loop->capt->rate;
1535 loop->src_data.end_of_input = 0;
1536 loop->src_out_frames = 0;
1538 loop->src_state = NULL;
1541 if (loop->sync == SYNC_TYPE_SAMPLERATE || loop->use_samplerate) {
1542 logit(LOG_CRIT, "alsaloop is compiled without libsamplerate support\n");
1548 snd_output_printf(loop->output, "%s sync type: %s", loop->id, sync_types[loop->sync]);
1549 #ifdef USE_SAMPLERATE
1550 if (loop->sync == SYNC_TYPE_SAMPLERATE)
1551 snd_output_printf(loop->output, " (%s)", src_types[loop->src_converter_type]);
1553 snd_output_printf(loop->output, "\n");
1555 lhandle_start(loop->play);
1556 lhandle_start(loop->capt);
1557 if ((err = snd_pcm_format_set_silence(loop->play->format,
1559 loop->play->buf_size * loop->play->channels)) < 0) {
1560 logit(LOG_CRIT, "%s: silence error\n", loop->id);
1564 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);
1567 loop->pitch_delta = 1.0 / ((double)loop->capt->rate * 4);
1568 loop->total_queued_count = 0;
1569 loop->pitch_diff = 0;
1570 count = get_whole_latency(loop) / loop->play->pitch;
1571 loop->play->buf_count = count;
1572 if (loop->play->buf == loop->capt->buf)
1573 loop->capt->buf_pos = count;
1574 err = writeit(loop->play);
1576 snd_output_printf(loop->output, "%s: silence queued %i samples\n", loop->id, err);
1577 if (count > loop->play->buffer_size)
1578 count = loop->play->buffer_size;
1580 logit(LOG_CRIT, "%s: initial playback fill error (%i/%i/%i)\n", loop->id, err, (int)count, loop->play->buffer_size);
1585 loop->stop_pending = 0;
1587 getcurtimestamp(&loop->xrun_last_update);
1588 loop->xrun_last_pdelay = XRUN_PROFILE_UNKNOWN;
1589 loop->xrun_last_cdelay = XRUN_PROFILE_UNKNOWN;
1590 loop->xrun_max_proctime = 0;
1592 if ((err = snd_pcm_start(loop->capt->handle)) < 0) {
1593 logit(LOG_CRIT, "pcm start %s error: %s\n", loop->capt->id, snd_strerror(err));
1596 if (!loop->linked) {
1597 if ((err = snd_pcm_start(loop->play->handle)) < 0) {
1598 logit(LOG_CRIT, "pcm start %s error: %s\n", loop->play->id, snd_strerror(err));
1608 int pcmjob_stop(struct loopback *loop)
1612 if (loop->running) {
1613 if ((err = snd_pcm_drop(loop->capt->handle)) < 0)
1614 logit(LOG_WARNING, "pcm drop %s error: %s\n", loop->capt->id, snd_strerror(err));
1615 if ((err = snd_pcm_drop(loop->play->handle)) < 0)
1616 logit(LOG_WARNING, "pcm drop %s error: %s\n", loop->play->id, snd_strerror(err));
1617 if ((err = snd_pcm_hw_free(loop->capt->handle)) < 0)
1618 logit(LOG_WARNING, "pcm hw_free %s error: %s\n", loop->capt->id, snd_strerror(err));
1619 if ((err = snd_pcm_hw_free(loop->play->handle)) < 0)
1620 logit(LOG_WARNING, "pcm hw_free %s error: %s\n", loop->play->id, snd_strerror(err));
1627 int pcmjob_pollfds_init(struct loopback *loop, struct pollfd *fds)
1631 if (loop->running) {
1632 err = snd_pcm_poll_descriptors(loop->play->handle, fds + idx, loop->play->pollfd_count);
1635 idx += loop->play->pollfd_count;
1636 err = snd_pcm_poll_descriptors(loop->capt->handle, fds + idx, loop->capt->pollfd_count);
1639 idx += loop->capt->pollfd_count;
1641 if (loop->play->ctl_pollfd_count > 0 &&
1642 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1643 err = snd_ctl_poll_descriptors(loop->play->ctl, fds + idx, loop->play->ctl_pollfd_count);
1646 idx += loop->play->ctl_pollfd_count;
1648 if (loop->capt->ctl_pollfd_count > 0 &&
1649 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1650 err = snd_ctl_poll_descriptors(loop->capt->ctl, fds + idx, loop->capt->ctl_pollfd_count);
1653 idx += loop->capt->ctl_pollfd_count;
1655 loop->active_pollfd_count = idx;
1659 static snd_pcm_sframes_t get_queued_playback_samples(struct loopback *loop)
1661 snd_pcm_sframes_t delay;
1664 if ((err = snd_pcm_delay(loop->play->handle, &delay)) < 0)
1666 loop->play->last_delay = delay;
1667 delay += loop->play->buf_count;
1668 #ifdef USE_SAMPLERATE
1669 delay += loop->src_out_frames;
1674 static snd_pcm_sframes_t get_queued_capture_samples(struct loopback *loop)
1676 snd_pcm_sframes_t delay;
1679 if ((err = snd_pcm_delay(loop->capt->handle, &delay)) < 0)
1681 loop->capt->last_delay = delay;
1682 delay += loop->capt->buf_count;
1686 static int ctl_event_check(snd_ctl_elem_value_t *val, snd_ctl_event_t *ev)
1688 snd_ctl_elem_id_t *id1, *id2;
1689 snd_ctl_elem_id_alloca(&id1);
1690 snd_ctl_elem_id_alloca(&id2);
1691 snd_ctl_elem_value_get_id(val, id1);
1692 snd_ctl_event_elem_get_id(ev, id2);
1693 if (snd_ctl_event_elem_get_mask(ev) == SND_CTL_EVENT_MASK_REMOVE)
1695 if ((snd_ctl_event_elem_get_mask(ev) & SND_CTL_EVENT_MASK_VALUE) == 0)
1697 return control_id_match(id1, id2);
1700 static int handle_ctl_events(struct loopback_handle *lhandle,
1701 unsigned short events)
1703 struct loopback *loop = lhandle->loopback;
1704 snd_ctl_event_t *ev;
1705 int err, restart = 0;
1707 snd_ctl_event_alloca(&ev);
1708 while ((err = snd_ctl_read(lhandle->ctl, ev)) != 0 && err != -EAGAIN) {
1711 if (snd_ctl_event_get_type(ev) != SND_CTL_EVENT_ELEM)
1713 if (lhandle == loop->play)
1716 snd_output_printf(loop->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
1717 if (ctl_event_check(lhandle->ctl_active, ev)) {
1719 } else if (ctl_event_check(lhandle->ctl_format, ev)) {
1720 err = get_format(lhandle);
1721 if (lhandle->format != err)
1724 } else if (ctl_event_check(lhandle->ctl_rate, ev)) {
1725 err = get_rate(lhandle);
1726 if (lhandle->rate != err)
1729 } else if (ctl_event_check(lhandle->ctl_channels, ev)) {
1730 err = get_channels(lhandle);
1731 if (lhandle->channels != err)
1736 control_event(lhandle, ev);
1738 err = get_active(lhandle);
1740 snd_output_printf(loop->output, "%s: ctl event active %i\n", lhandle->id, err);
1742 if (lhandle->loopback->running) {
1743 loop->stop_pending = 1;
1744 loop->stop_count = 0;
1747 loop->stop_pending = 0;
1748 if (loop->running == 0)
1753 err = pcmjob_start(loop);
1760 int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
1762 struct loopback_handle *play = loop->play;
1763 struct loopback_handle *capt = loop->capt;
1764 unsigned short prevents, crevents, events;
1765 snd_pcm_uframes_t ccount, pcount;
1766 int err, loopcount = 10, idx;
1769 snd_output_printf(loop->output, "%s: pollfds handle\n", loop->id);
1770 if (verbose > 13 || loop->xrun)
1771 getcurtimestamp(&loop->tstamp_start);
1773 snd_pcm_sframes_t pdelay, cdelay;
1774 if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
1775 snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
1777 snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
1778 if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
1779 snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
1781 snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
1784 if (loop->running) {
1785 err = snd_pcm_poll_descriptors_revents(play->handle, fds,
1790 idx += play->pollfd_count;
1791 err = snd_pcm_poll_descriptors_revents(capt->handle, fds + idx,
1796 idx += capt->pollfd_count;
1798 if (prevents || crevents) {
1799 loop->xrun_last_wake = loop->xrun_last_wake0;
1800 loop->xrun_last_wake0 = loop->tstamp_start;
1802 loop->xrun_last_check = loop->xrun_last_check0;
1803 loop->xrun_last_check0 = loop->tstamp_start;
1806 prevents = crevents = 0;
1808 if (play->ctl_pollfd_count > 0 &&
1809 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1810 err = snd_ctl_poll_descriptors_revents(play->ctl, fds + idx,
1811 play->ctl_pollfd_count,
1816 err = handle_ctl_events(play, events);
1822 idx += play->ctl_pollfd_count;
1824 if (capt->ctl_pollfd_count > 0 &&
1825 (loop->slave == SLAVE_TYPE_ON || loop->controls)) {
1826 err = snd_ctl_poll_descriptors_revents(capt->ctl, fds + idx,
1827 capt->ctl_pollfd_count,
1832 err = handle_ctl_events(capt, events);
1838 idx += capt->ctl_pollfd_count;
1841 snd_output_printf(loop->output, "%s: prevents = 0x%x, crevents = 0x%x\n", loop->id, prevents, crevents);
1845 ccount = readit(capt);
1846 buf_add(loop, ccount);
1847 if (capt->xrun_pending || loop->reinit)
1849 /* we read new samples, if we have a room in the playback
1850 buffer, feed them there */
1851 pcount = writeit(play);
1852 buf_remove(loop, pcount);
1853 if (play->xrun_pending || loop->reinit)
1856 } while ((ccount > 0 || pcount > 0) && loopcount > 0);
1857 if (play->xrun_pending || capt->xrun_pending) {
1858 if ((err = xrun_sync(loop)) < 0)
1862 err = pcmjob_stop(loop);
1865 err = pcmjob_start(loop);
1869 if (loop->sync != SYNC_TYPE_NONE &&
1870 play->counter >= play->sync_point &&
1871 capt->counter >= play->sync_point) {
1872 snd_pcm_sframes_t diff, lat = get_whole_latency(loop);
1873 diff = ((double)(((double)play->total_queued * play->pitch) +
1874 ((double)capt->total_queued * capt->pitch)) /
1875 (double)loop->total_queued_count) - lat;
1876 /* FIXME: this algorithm may be slightly better */
1878 snd_output_printf(loop->output, "%s: sync diff %li old diff %li\n", loop->id, diff, loop->pitch_diff);
1880 if (diff == loop->pitch_diff)
1881 loop->pitch += loop->pitch_delta;
1882 else if (diff > loop->pitch_diff)
1883 loop->pitch += loop->pitch_delta*2;
1884 } else if (diff < 0) {
1885 if (diff == loop->pitch_diff)
1886 loop->pitch -= loop->pitch_delta;
1887 else if (diff < loop->pitch_diff)
1888 loop->pitch -= loop->pitch_delta*2;
1890 loop->pitch_diff = diff;
1891 if (loop->pitch_diff_min > diff)
1892 loop->pitch_diff_min = diff;
1893 if (loop->pitch_diff_max < diff)
1894 loop->pitch_diff_max = diff;
1896 play->counter -= play->sync_point;
1897 capt->counter -= play->sync_point;
1898 play->total_queued = 0;
1899 capt->total_queued = 0;
1900 loop->total_queued_count = 0;
1902 if (loop->sync != SYNC_TYPE_NONE) {
1903 snd_pcm_sframes_t pqueued, cqueued;
1904 pqueued = get_queued_playback_samples(loop);
1905 cqueued = get_queued_capture_samples(loop);
1907 snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued);
1909 play->total_queued += pqueued;
1911 capt->total_queued += cqueued;
1912 if (pqueued > 0 || cqueued > 0)
1913 loop->total_queued_count += 1;
1916 snd_pcm_sframes_t pdelay, cdelay;
1917 if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
1918 snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
1920 snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
1921 if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
1922 snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
1924 snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
1927 if (verbose > 13 || loop->xrun) {
1929 getcurtimestamp(&loop->tstamp_end);
1930 diff = timediff(loop->tstamp_end, loop->tstamp_start);
1932 snd_output_printf(loop->output, "%s: processing time %lius\n", loop->id, diff);
1933 if (loop->xrun && loop->xrun_max_proctime < diff)
1934 loop->xrun_max_proctime = diff;
1939 #define OUT(args...) \
1940 snd_output_printf(loop->state, ##args)
1942 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
1944 static void show_handle(struct loopback_handle *lhandle, const char *id)
1946 struct loopback *loop = lhandle->loopback;
1948 OUT(" %s: %s:\n", id, lhandle->id);
1949 OUT(" device = '%s', ctldev '%s'\n", lhandle->device, lhandle->ctldev);
1950 OUT(" card_number = %i\n", lhandle->card_number);
1953 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);
1954 OUT(" buffer_size = %u, period_size = %u, avail_min = %li\n", lhandle->buffer_size, lhandle->period_size, lhandle->avail_min);
1955 OUT(" xrun_pending = %i\n", lhandle->xrun_pending);
1956 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);
1957 OUT(" pitch = %.8f\n", lhandle->pitch);
1960 void pcmjob_state(struct loopback *loop)
1962 pthread_t self = pthread_self();
1963 pthread_mutex_lock(&state_mutex);
1964 OUT("State dump for thread %p job %i: %s:\n", (void *)self, loop->thread, loop->id);
1965 OUT(" running = %i\n", loop->running);
1966 OUT(" sync = %i\n", loop->sync);
1967 OUT(" slave = %i\n", loop->slave);
1970 OUT(" pollfd_count = %i\n", loop->pollfd_count);
1971 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);
1972 OUT(" use_samplerate = %i\n", loop->use_samplerate);
1974 show_handle(loop->play, "playback");
1975 show_handle(loop->capt, "capture");
1976 pthread_mutex_unlock(&state_mutex);