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
)