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