static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) { int error; pa_sample_spec ss; struct audsettings obt_as = *as; PAVoiceIn *pa = (PAVoiceIn *) hw; paaudio *g = pa->g = drv_opaque; AudiodevPaOptions *popts = &g->dev->u.pa; AudiodevPaPerDirectionOptions *ppdo = popts->in; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; ss.rate = as->freq; obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); pa->stream = qpa_simple_new ( g, "qemu", PA_STREAM_RECORD, ppdo->has_name ? ppdo->name : NULL, &ss, NULL, /* channel map */ NULL, /* buffering attributes */ &error ); if (!pa->stream) { qpa_logerr (error, "pa_simple_new for capture failed\n"); goto fail1; } audio_pcm_init_info (&hw->info, &obt_as); hw->samples = pa->samples = audio_buffer_samples( qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440); pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); pa->wpos = hw->wpos; if (!pa->pcm_buf) { dolog ("Could not allocate buffer (%d bytes)\n", hw->samples << hw->info.shift); goto fail2; } if (audio_pt_init(&pa->pt, qpa_thread_in, hw, AUDIO_CAP, __func__)) { goto fail3; } return 0; fail3: g_free (pa->pcm_buf); pa->pcm_buf = NULL; fail2: if (pa->stream) { pa_stream_unref (pa->stream); pa->stream = NULL; } fail1: return -1; }
static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as) { int error; static pa_sample_spec ss; struct audsettings obt_as = *as; PAVoiceIn *pa = (PAVoiceIn *) hw; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; ss.rate = as->freq; obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); pa->s = FF(pa_simple_new) ( conf.server, "qemu", PA_STREAM_RECORD, conf.source, "pcm.capture", &ss, NULL, /* channel map */ NULL, /* buffering attributes */ &error ); if (!pa->s) { qpa_logerr (error, "pa_simple_new for capture failed\n"); goto fail1; } audio_pcm_init_info (&hw->info, &obt_as); hw->samples = conf.samples; pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); if (!pa->pcm_buf) { dolog ("Could not allocate buffer (%d bytes)\n", hw->samples << hw->info.shift); goto fail2; } if (audio_pt_init (&pa->pt, qpa_thread_in, hw, AUDIO_CAP, AUDIO_FUNC)) { goto fail3; } return 0; fail3: qemu_free (pa->pcm_buf); pa->pcm_buf = NULL; fail2: FF(pa_simple_free) (pa->s); pa->s = NULL; fail1: return -1; }
/* * Prepare processing. */ void *st_rate_start (int inrate, int outrate) { struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate)); if (!rate) { dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate)); return NULL; } rate->opos = 0; /* increment */ rate->opos_inc = ((uint64_t) inrate << 32) / outrate; rate->ipos = 0; rate->ilast.l = 0; rate->ilast.r = 0; return rate; }
static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { int error; pa_sample_spec ss; pa_buffer_attr ba; struct audsettings obt_as = *as; PAVoiceOut *pa = (PAVoiceOut *) hw; paaudio *g = pa->g = drv_opaque; AudiodevPaOptions *popts = &g->dev->u.pa; AudiodevPaPerDirectionOptions *ppdo = popts->out; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; ss.rate = as->freq; /* * qemu audio tick runs at 100 Hz (by default), so processing * data chunks worth 10 ms of sound should be a good fit. */ ba.tlength = pa_usec_to_bytes (10 * 1000, &ss); ba.minreq = pa_usec_to_bytes (5 * 1000, &ss); ba.maxlength = -1; ba.prebuf = -1; obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); pa->stream = qpa_simple_new ( g, "qemu", PA_STREAM_PLAYBACK, ppdo->has_name ? ppdo->name : NULL, &ss, NULL, /* channel map */ &ba, /* buffering attributes */ &error ); if (!pa->stream) { qpa_logerr (error, "pa_simple_new for playback failed\n"); goto fail1; } audio_pcm_init_info (&hw->info, &obt_as); hw->samples = pa->samples = audio_buffer_samples( qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440); pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); pa->rpos = hw->rpos; if (!pa->pcm_buf) { dolog ("Could not allocate buffer (%d bytes)\n", hw->samples << hw->info.shift); goto fail2; } if (audio_pt_init(&pa->pt, qpa_thread_out, hw, AUDIO_CAP, __func__)) { goto fail3; } return 0; fail3: g_free (pa->pcm_buf); pa->pcm_buf = NULL; fail2: if (pa->stream) { pa_stream_unref (pa->stream); pa->stream = NULL; } fail1: return -1; }
static int qesd_init_in (HWVoiceIn *hw, struct audsettings *as) { ESDVoiceIn *esd = (ESDVoiceIn *) hw; struct audsettings obt_as = *as; int esdfmt = ESD_STREAM | ESD_RECORD; int result = -1; /* shut down verbose debug spew */ if (!D_ACTIVE) stdio_disable(); esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO; switch (as->fmt) { case AUD_FMT_S8: case AUD_FMT_U8: esdfmt |= ESD_BITS8; obt_as.fmt = AUD_FMT_U8; break; case AUD_FMT_S16: case AUD_FMT_U16: esdfmt |= ESD_BITS16; obt_as.fmt = AUD_FMT_S16; break; case AUD_FMT_S32: case AUD_FMT_U32: dolog ("Will use 16 instead of 32 bit samples\n"); esdfmt |= ESD_BITS16; obt_as.fmt = AUD_FMT_S16; break; } obt_as.endianness = AUDIO_HOST_ENDIANNESS; audio_pcm_init_info (&hw->info, &obt_as); hw->samples = conf.samples; esd->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); if (!esd->pcm_buf) { dolog ("Could not allocate buffer (%d bytes)\n", hw->samples << hw->info.shift); goto exit; } esd->fd = FF(esd_record_stream) (esdfmt, as->freq, conf.adc_host, NULL); if (esd->fd < 0) { if (conf.adc_host == NULL) { esd->fd = FF(esd_record_stream) (esdfmt, as->freq, "localhost", NULL); } if (esd->fd < 0) { qesd_logerr (errno, "esd_record_stream failed\n"); goto fail2; } } { int flags; flags = fcntl(esd->fd, F_GETFL); fcntl(esd->fd, F_SETFL, flags | O_NONBLOCK); } result = 0; /* success */ goto exit; fail2: qemu_free (esd->pcm_buf); esd->pcm_buf = NULL; exit: if (!D_ACTIVE) stdio_enable(); return result; }
static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as) { int i; int err; MMRESULT mr; WAVEFORMATEX wfx; WaveVoiceIn *wave; wave = (WaveVoiceIn *) hw; InitializeCriticalSection (&wave->crit_sect); err = waveformat_from_audio_settings (&wfx, as); if (err) { goto err0; } mr = waveInOpen (&wave->hwi, WAVE_MAPPER, &wfx, (DWORD_PTR) winwave_callback_in, (DWORD_PTR) wave, CALLBACK_FUNCTION); if (mr != MMSYSERR_NOERROR) { winwave_logerr (mr, "waveInOpen"); goto err1; } wave->hdrs = audio_calloc (AUDIO_FUNC, conf.dac_headers, sizeof (*wave->hdrs)); if (!wave->hdrs) { goto err2; } audio_pcm_init_info (&hw->info, as); hw->samples = conf.adc_samples * conf.adc_headers; wave->avail = 0; wave->pcm_buf = audio_calloc (AUDIO_FUNC, conf.adc_samples, conf.adc_headers << hw->info.shift); if (!wave->pcm_buf) { goto err3; } for (i = 0; i < conf.adc_headers; ++i) { WAVEHDR *h = &wave->hdrs[i]; h->dwUser = 0; h->dwBufferLength = conf.adc_samples << hw->info.shift; h->lpData = advance (wave->pcm_buf, i * h->dwBufferLength); h->dwFlags = 0; mr = waveInPrepareHeader (wave->hwi, h, sizeof (*h)); if (mr != MMSYSERR_NOERROR) { winwave_logerr (mr, "waveInPrepareHeader(%d)", i); goto err4; } } wave->paused = 1; winwave_add_buffers (wave, hw->samples); return 0; err4: g_free (wave->pcm_buf); err3: g_free (wave->hdrs); err2: winwave_anal_close_in (wave); err1: err0: return -1; }