static void *qpa_thread_in (void *arg) { PAVoiceIn *pa = arg; HWVoiceIn *hw = &pa->hw; if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) { return NULL; } for (;;) { int incr, to_grab, wpos; for (;;) { if (pa->done) { goto exit; } if (pa->dead > 0) { break; } if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) { goto exit; } } incr = to_grab = audio_MIN (pa->dead, conf.samples >> 2); wpos = pa->wpos; if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) { return NULL; } while (to_grab) { int error; int chunk = audio_MIN (to_grab, hw->samples - wpos); void *buf = advance (pa->pcm_buf, wpos); if (pa_simple_read (pa->s, buf, chunk << hw->info.shift, &error) < 0) { qpa_logerr (error, "pa_simple_read failed\n"); return NULL; } hw->conv (hw->conv_buf + wpos, buf, chunk); wpos = (wpos + chunk) % hw->samples; to_grab -= chunk; } if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) { return NULL; } pa->wpos = wpos; pa->dead -= incr; pa->incr += incr; } exit: audio_pt_unlock (&pa->pt, AUDIO_FUNC); return NULL; }