static void qpa_fini_in (HWVoiceIn *hw) { void *ret; PAVoiceIn *pa = (PAVoiceIn *) hw; audio_pt_lock(&pa->pt, __func__); pa->done = 1; audio_pt_unlock_and_signal(&pa->pt, __func__); audio_pt_join(&pa->pt, &ret, __func__); if (pa->stream) { pa_stream_unref (pa->stream); pa->stream = NULL; } audio_pt_fini(&pa->pt, __func__); g_free (pa->pcm_buf); pa->pcm_buf = NULL; }
static void qpa_fini_in (HWVoiceIn *hw) { void *ret; PAVoiceIn *pa = (PAVoiceIn *) hw; audio_pt_lock (&pa->pt, AUDIO_FUNC); pa->done = 1; audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC); audio_pt_join (&pa->pt, &ret, AUDIO_FUNC); if (pa->s) { FF(pa_simple_free) (pa->s); pa->s = NULL; } audio_pt_fini (&pa->pt, AUDIO_FUNC); qemu_free (pa->pcm_buf); pa->pcm_buf = NULL; }
static int qpa_run_out (HWVoiceOut *hw, int live) { int decr; PAVoiceOut *pa = (PAVoiceOut *) hw; if (audio_pt_lock(&pa->pt, __func__)) { return 0; } decr = audio_MIN (live, pa->decr); pa->decr -= decr; pa->live = live - decr; hw->rpos = pa->rpos; if (pa->live > 0) { audio_pt_unlock_and_signal(&pa->pt, __func__); } else { audio_pt_unlock(&pa->pt, __func__); } return decr; }
static int qpa_run_out (HWVoiceOut *hw) { int live, decr; PAVoiceOut *pa = (PAVoiceOut *) hw; if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) { return 0; } live = audio_pcm_hw_get_live_out (hw); decr = audio_MIN (live, pa->decr); pa->decr -= decr; pa->live = live - decr; hw->rpos = pa->rpos; if (pa->live > 0) { audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC); } else { audio_pt_unlock (&pa->pt, AUDIO_FUNC); } return decr; }
static int qpa_run_in (HWVoiceIn *hw) { int live, incr, dead; PAVoiceIn *pa = (PAVoiceIn *) hw; if (audio_pt_lock(&pa->pt, __func__)) { return 0; } live = audio_pcm_hw_get_live_in (hw); dead = hw->samples - live; incr = audio_MIN (dead, pa->incr); pa->incr -= incr; pa->dead = dead - incr; hw->wpos = pa->wpos; if (pa->dead > 0) { audio_pt_unlock_and_signal(&pa->pt, __func__); } else { audio_pt_unlock(&pa->pt, __func__); } return incr; }
/* capture */ static void *qpa_thread_in (void *arg) { PAVoiceIn *pa = arg; HWVoiceIn *hw = &pa->hw; if (audio_pt_lock(&pa->pt, __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, __func__)) { goto exit; } } incr = to_grab = audio_MIN(pa->dead, pa->samples >> 5); wpos = pa->wpos; if (audio_pt_unlock(&pa->pt, __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 (qpa_simple_read (pa, 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, __func__)) { return NULL; } pa->wpos = wpos; pa->dead -= incr; pa->incr += incr; } exit: audio_pt_unlock(&pa->pt, __func__); return NULL; }
static void *qpa_thread_out (void *arg) { PAVoiceOut *pa = arg; HWVoiceOut *hw = &pa->hw; if (audio_pt_lock(&pa->pt, __func__)) { return NULL; } for (;;) { int decr, to_mix, rpos; for (;;) { if (pa->done) { goto exit; } if (pa->live > 0) { break; } if (audio_pt_wait(&pa->pt, __func__)) { goto exit; } } decr = to_mix = audio_MIN(pa->live, pa->samples >> 5); rpos = pa->rpos; if (audio_pt_unlock(&pa->pt, __func__)) { return NULL; } while (to_mix) { int error; int chunk = audio_MIN (to_mix, hw->samples - rpos); struct st_sample *src = hw->mix_buf + rpos; hw->clip (pa->pcm_buf, src, chunk); if (qpa_simple_write (pa, pa->pcm_buf, chunk << hw->info.shift, &error) < 0) { qpa_logerr (error, "pa_simple_write failed\n"); return NULL; } rpos = (rpos + chunk) % hw->samples; to_mix -= chunk; } if (audio_pt_lock(&pa->pt, __func__)) { return NULL; } pa->rpos = rpos; pa->live -= decr; pa->decr += decr; } exit: audio_pt_unlock(&pa->pt, __func__); return NULL; }
/* capture */ static void *qpa_thread_in (void *arg) { PAVoiceIn *pa = arg; HWVoiceIn *hw = &pa->hw; int threshold; threshold = conf.divisor ? hw->samples / conf.divisor : 0; 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 > threshold) { break; } if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) { goto exit; } } incr = to_grab = pa->dead; wpos = hw->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 (FF(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, &nominal_volume); 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; }