tarina

git clone https://git.tarina.org/tarina
Log | Files | Refs | README | LICENSE

pcmjob.c (61118B)


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