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