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
g_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
g_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
g_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
g_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)