2 #include "qemu-common.h"
5 #include <pulse/simple.h>
6 #include <pulse/error.h>
8 #define AUDIO_CAP "pulseaudio"
10 #include "audio_pt_int.h"
43 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
48 AUD_vlog (AUDIO_CAP, fmt, ap);
51 AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
54 static void *qpa_thread_out (void *arg)
57 HWVoiceOut *hw = &pa->hw;
59 if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
64 int decr, to_mix, rpos;
75 if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
80 decr = to_mix = audio_MIN (pa->live, conf.samples >> 2);
83 if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
89 int chunk = audio_MIN (to_mix, hw->samples - rpos);
90 struct st_sample *src = hw->mix_buf + rpos;
92 hw->clip (pa->pcm_buf, src, chunk);
94 if (pa_simple_write (pa->s, pa->pcm_buf,
95 chunk << hw->info.shift, &error) < 0) {
96 qpa_logerr (error, "pa_simple_write failed\n");
100 rpos = (rpos + chunk) % hw->samples;
104 if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
114 audio_pt_unlock (&pa->pt, AUDIO_FUNC);
118 static int qpa_run_out (HWVoiceOut *hw, int live)
121 PAVoiceOut *pa = (PAVoiceOut *) hw;
123 if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
127 decr = audio_MIN (live, pa->decr);
129 pa->live = live - decr;
132 audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
135 audio_pt_unlock (&pa->pt, AUDIO_FUNC);
140 static int qpa_write (SWVoiceOut *sw, void *buf, int len)
142 return audio_pcm_sw_write (sw, buf, len);
146 static void *qpa_thread_in (void *arg)
149 HWVoiceIn *hw = &pa->hw;
151 if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
156 int incr, to_grab, wpos;
167 if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
172 incr = to_grab = audio_MIN (pa->dead, conf.samples >> 2);
175 if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
181 int chunk = audio_MIN (to_grab, hw->samples - wpos);
182 void *buf = advance (pa->pcm_buf, wpos);
184 if (pa_simple_read (pa->s, buf,
185 chunk << hw->info.shift, &error) < 0) {
186 qpa_logerr (error, "pa_simple_read failed\n");
190 hw->conv (hw->conv_buf + wpos, buf, chunk);
191 wpos = (wpos + chunk) % hw->samples;
195 if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
205 audio_pt_unlock (&pa->pt, AUDIO_FUNC);
209 static int qpa_run_in (HWVoiceIn *hw)
211 int live, incr, dead;
212 PAVoiceIn *pa = (PAVoiceIn *) hw;
214 if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
218 live = audio_pcm_hw_get_live_in (hw);
219 dead = hw->samples - live;
220 incr = audio_MIN (dead, pa->incr);
222 pa->dead = dead - incr;
225 audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
228 audio_pt_unlock (&pa->pt, AUDIO_FUNC);
233 static int qpa_read (SWVoiceIn *sw, void *buf, int len)
235 return audio_pcm_sw_read (sw, buf, len);
238 static pa_sample_format_t audfmt_to_pa (audfmt_e afmt, int endianness)
245 format = PA_SAMPLE_U8;
249 format = endianness ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
253 format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
256 dolog ("Internal logic error: Bad audio format %d\n", afmt);
257 format = PA_SAMPLE_U8;
263 static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
268 case PA_SAMPLE_S16BE:
271 case PA_SAMPLE_S16LE:
274 case PA_SAMPLE_S32BE:
277 case PA_SAMPLE_S32LE:
281 dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt);
286 static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
289 static pa_sample_spec ss;
290 static pa_buffer_attr ba;
291 struct audsettings obt_as = *as;
292 PAVoiceOut *pa = (PAVoiceOut *) hw;
294 ss.format = audfmt_to_pa (as->fmt, as->endianness);
295 ss.channels = as->nchannels;
299 * qemu audio tick runs at 250 Hz (by default), so processing
300 * data chunks worth 4 ms of sound should be a good fit.
302 ba.tlength = pa_usec_to_bytes (4 * 1000, &ss);
303 ba.minreq = pa_usec_to_bytes (2 * 1000, &ss);
307 obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
309 pa->s = pa_simple_new (
316 NULL, /* channel map */
317 &ba, /* buffering attributes */
321 qpa_logerr (error, "pa_simple_new for playback failed\n");
325 audio_pcm_init_info (&hw->info, &obt_as);
326 hw->samples = conf.samples;
327 pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
330 dolog ("Could not allocate buffer (%d bytes)\n",
331 hw->samples << hw->info.shift);
335 if (audio_pt_init (&pa->pt, qpa_thread_out, hw, AUDIO_CAP, AUDIO_FUNC)) {
342 qemu_free (pa->pcm_buf);
345 pa_simple_free (pa->s);
351 static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
354 static pa_sample_spec ss;
355 struct audsettings obt_as = *as;
356 PAVoiceIn *pa = (PAVoiceIn *) hw;
358 ss.format = audfmt_to_pa (as->fmt, as->endianness);
359 ss.channels = as->nchannels;
362 obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
364 pa->s = pa_simple_new (
371 NULL, /* channel map */
372 NULL, /* buffering attributes */
376 qpa_logerr (error, "pa_simple_new for capture failed\n");
380 audio_pcm_init_info (&hw->info, &obt_as);
381 hw->samples = conf.samples;
382 pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
385 dolog ("Could not allocate buffer (%d bytes)\n",
386 hw->samples << hw->info.shift);
390 if (audio_pt_init (&pa->pt, qpa_thread_in, hw, AUDIO_CAP, AUDIO_FUNC)) {
397 qemu_free (pa->pcm_buf);
400 pa_simple_free (pa->s);
406 static void qpa_fini_out (HWVoiceOut *hw)
409 PAVoiceOut *pa = (PAVoiceOut *) hw;
411 audio_pt_lock (&pa->pt, AUDIO_FUNC);
413 audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
414 audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
417 pa_simple_free (pa->s);
421 audio_pt_fini (&pa->pt, AUDIO_FUNC);
422 qemu_free (pa->pcm_buf);
426 static void qpa_fini_in (HWVoiceIn *hw)
429 PAVoiceIn *pa = (PAVoiceIn *) hw;
431 audio_pt_lock (&pa->pt, AUDIO_FUNC);
433 audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
434 audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
437 pa_simple_free (pa->s);
441 audio_pt_fini (&pa->pt, AUDIO_FUNC);
442 qemu_free (pa->pcm_buf);
446 static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
453 static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
461 static void *qpa_audio_init (void)
466 static void qpa_audio_fini (void *opaque)
471 struct audio_option qpa_options[] = {
475 .valp = &conf.samples,
476 .descr = "buffer size in samples"
481 .valp = &conf.server,
482 .descr = "server address"
488 .descr = "sink device name"
493 .valp = &conf.source,
494 .descr = "source device name"
496 { /* End of list */ }
499 static struct audio_pcm_ops qpa_pcm_ops = {
500 .init_out = qpa_init_out,
501 .fini_out = qpa_fini_out,
502 .run_out = qpa_run_out,
504 .ctl_out = qpa_ctl_out,
506 .init_in = qpa_init_in,
507 .fini_in = qpa_fini_in,
508 .run_in = qpa_run_in,
513 struct audio_driver pa_audio_driver = {
515 .descr = "http://www.pulseaudio.org/",
516 .options = qpa_options,
517 .init = qpa_audio_init,
518 .fini = qpa_audio_fini,
519 .pcm_ops = &qpa_pcm_ops,
521 .max_voices_out = INT_MAX,
522 .max_voices_in = INT_MAX,
523 .voice_size_out = sizeof (PAVoiceOut),
524 .voice_size_in = sizeof (PAVoiceIn)