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"
45 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err
, const char *fmt
, ...)
50 AUD_vlog (AUDIO_CAP
, fmt
, ap
);
53 AUD_log (AUDIO_CAP
, "Reason: %s\n", pa_strerror (err
));
56 static void *qpa_thread_out (void *arg
)
59 HWVoiceOut
*hw
= &pa
->hw
;
62 threshold
= conf
.divisor
? hw
->samples
/ conf
.divisor
: 0;
64 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
69 int decr
, to_mix
, rpos
;
76 if (pa
->live
> threshold
) {
80 if (audio_pt_wait (&pa
->pt
, AUDIO_FUNC
)) {
85 decr
= to_mix
= pa
->live
;
88 if (audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
)) {
94 int chunk
= audio_MIN (to_mix
, hw
->samples
- rpos
);
95 struct st_sample
*src
= hw
->mix_buf
+ rpos
;
97 hw
->clip (pa
->pcm_buf
, src
, chunk
);
99 if (pa_simple_write (pa
->s
, pa
->pcm_buf
,
100 chunk
<< hw
->info
.shift
, &error
) < 0) {
101 qpa_logerr (error
, "pa_simple_write failed\n");
105 rpos
= (rpos
+ chunk
) % hw
->samples
;
109 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
119 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
123 static int qpa_run_out (HWVoiceOut
*hw
)
126 PAVoiceOut
*pa
= (PAVoiceOut
*) hw
;
128 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
132 live
= audio_pcm_hw_get_live_out (hw
);
133 decr
= audio_MIN (live
, pa
->decr
);
135 pa
->live
= live
- decr
;
138 audio_pt_unlock_and_signal (&pa
->pt
, AUDIO_FUNC
);
141 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
146 static int qpa_write (SWVoiceOut
*sw
, void *buf
, int len
)
148 return audio_pcm_sw_write (sw
, buf
, len
);
152 static void *qpa_thread_in (void *arg
)
155 HWVoiceIn
*hw
= &pa
->hw
;
158 threshold
= conf
.divisor
? hw
->samples
/ conf
.divisor
: 0;
160 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
165 int incr
, to_grab
, wpos
;
172 if (pa
->dead
> threshold
) {
176 if (audio_pt_wait (&pa
->pt
, AUDIO_FUNC
)) {
181 incr
= to_grab
= pa
->dead
;
184 if (audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
)) {
190 int chunk
= audio_MIN (to_grab
, hw
->samples
- wpos
);
191 void *buf
= advance (pa
->pcm_buf
, wpos
);
193 if (pa_simple_read (pa
->s
, buf
,
194 chunk
<< hw
->info
.shift
, &error
) < 0) {
195 qpa_logerr (error
, "pa_simple_read failed\n");
199 hw
->conv (hw
->conv_buf
+ wpos
, buf
, chunk
, &nominal_volume
);
200 wpos
= (wpos
+ chunk
) % hw
->samples
;
204 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
214 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
218 static int qpa_run_in (HWVoiceIn
*hw
)
220 int live
, incr
, dead
;
221 PAVoiceIn
*pa
= (PAVoiceIn
*) hw
;
223 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
227 live
= audio_pcm_hw_get_live_in (hw
);
228 dead
= hw
->samples
- live
;
229 incr
= audio_MIN (dead
, pa
->incr
);
231 pa
->dead
= dead
- incr
;
234 audio_pt_unlock_and_signal (&pa
->pt
, AUDIO_FUNC
);
237 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
242 static int qpa_read (SWVoiceIn
*sw
, void *buf
, int len
)
244 return audio_pcm_sw_read (sw
, buf
, len
);
247 static pa_sample_format_t
audfmt_to_pa (audfmt_e afmt
, int endianness
)
254 format
= PA_SAMPLE_U8
;
258 format
= endianness
? PA_SAMPLE_S16BE
: PA_SAMPLE_S16LE
;
262 format
= endianness
? PA_SAMPLE_S32BE
: PA_SAMPLE_S32LE
;
265 dolog ("Internal logic error: Bad audio format %d\n", afmt
);
266 format
= PA_SAMPLE_U8
;
272 static audfmt_e
pa_to_audfmt (pa_sample_format_t fmt
, int *endianness
)
277 case PA_SAMPLE_S16BE
:
280 case PA_SAMPLE_S16LE
:
283 case PA_SAMPLE_S32BE
:
286 case PA_SAMPLE_S32LE
:
290 dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt
);
295 static int qpa_init_out (HWVoiceOut
*hw
, struct audsettings
*as
)
298 static pa_sample_spec ss
;
299 struct audsettings obt_as
= *as
;
300 PAVoiceOut
*pa
= (PAVoiceOut
*) hw
;
302 ss
.format
= audfmt_to_pa (as
->fmt
, as
->endianness
);
303 ss
.channels
= as
->nchannels
;
306 obt_as
.fmt
= pa_to_audfmt (ss
.format
, &obt_as
.endianness
);
308 pa
->s
= pa_simple_new (
315 NULL
, /* channel map */
316 NULL
, /* buffering attributes */
320 qpa_logerr (error
, "pa_simple_new for playback failed\n");
324 audio_pcm_init_info (&hw
->info
, &obt_as
);
325 hw
->samples
= conf
.samples
;
326 pa
->pcm_buf
= audio_calloc (AUDIO_FUNC
, hw
->samples
, 1 << hw
->info
.shift
);
328 dolog ("Could not allocate buffer (%d bytes)\n",
329 hw
->samples
<< hw
->info
.shift
);
333 if (audio_pt_init (&pa
->pt
, qpa_thread_out
, hw
, AUDIO_CAP
, AUDIO_FUNC
)) {
340 qemu_free (pa
->pcm_buf
);
343 pa_simple_free (pa
->s
);
349 static int qpa_init_in (HWVoiceIn
*hw
, struct audsettings
*as
)
352 static pa_sample_spec ss
;
353 struct audsettings obt_as
= *as
;
354 PAVoiceIn
*pa
= (PAVoiceIn
*) hw
;
356 ss
.format
= audfmt_to_pa (as
->fmt
, as
->endianness
);
357 ss
.channels
= as
->nchannels
;
360 obt_as
.fmt
= pa_to_audfmt (ss
.format
, &obt_as
.endianness
);
362 pa
->s
= pa_simple_new (
369 NULL
, /* channel map */
370 NULL
, /* buffering attributes */
374 qpa_logerr (error
, "pa_simple_new for capture failed\n");
378 audio_pcm_init_info (&hw
->info
, &obt_as
);
379 hw
->samples
= conf
.samples
;
380 pa
->pcm_buf
= audio_calloc (AUDIO_FUNC
, hw
->samples
, 1 << hw
->info
.shift
);
382 dolog ("Could not allocate buffer (%d bytes)\n",
383 hw
->samples
<< hw
->info
.shift
);
387 if (audio_pt_init (&pa
->pt
, qpa_thread_in
, hw
, AUDIO_CAP
, AUDIO_FUNC
)) {
394 qemu_free (pa
->pcm_buf
);
397 pa_simple_free (pa
->s
);
403 static void qpa_fini_out (HWVoiceOut
*hw
)
406 PAVoiceOut
*pa
= (PAVoiceOut
*) hw
;
408 audio_pt_lock (&pa
->pt
, AUDIO_FUNC
);
410 audio_pt_unlock_and_signal (&pa
->pt
, AUDIO_FUNC
);
411 audio_pt_join (&pa
->pt
, &ret
, AUDIO_FUNC
);
414 pa_simple_free (pa
->s
);
418 audio_pt_fini (&pa
->pt
, AUDIO_FUNC
);
419 qemu_free (pa
->pcm_buf
);
423 static void qpa_fini_in (HWVoiceIn
*hw
)
426 PAVoiceIn
*pa
= (PAVoiceIn
*) hw
;
428 audio_pt_lock (&pa
->pt
, AUDIO_FUNC
);
430 audio_pt_unlock_and_signal (&pa
->pt
, AUDIO_FUNC
);
431 audio_pt_join (&pa
->pt
, &ret
, AUDIO_FUNC
);
434 pa_simple_free (pa
->s
);
438 audio_pt_fini (&pa
->pt
, AUDIO_FUNC
);
439 qemu_free (pa
->pcm_buf
);
443 static int qpa_ctl_out (HWVoiceOut
*hw
, int cmd
, ...)
450 static int qpa_ctl_in (HWVoiceIn
*hw
, int cmd
, ...)
458 static void *qpa_audio_init (void)
463 static void qpa_audio_fini (void *opaque
)
468 struct audio_option qpa_options
[] = {
472 .valp
= &conf
.samples
,
473 .descr
= "buffer size in samples"
478 .valp
= &conf
.divisor
,
479 .descr
= "threshold divisor"
484 .valp
= &conf
.server
,
485 .descr
= "server address"
491 .descr
= "sink device name"
496 .valp
= &conf
.source
,
497 .descr
= "source device name"
499 { /* End of list */ }
502 static struct audio_pcm_ops qpa_pcm_ops
= {
503 .init_out
= qpa_init_out
,
504 .fini_out
= qpa_fini_out
,
505 .run_out
= qpa_run_out
,
507 .ctl_out
= qpa_ctl_out
,
509 .init_in
= qpa_init_in
,
510 .fini_in
= qpa_fini_in
,
511 .run_in
= qpa_run_in
,
516 struct audio_driver pa_audio_driver
= {
518 .descr
= "http://www.pulseaudio.org/",
519 .options
= qpa_options
,
520 .init
= qpa_audio_init
,
521 .fini
= qpa_audio_fini
,
522 .pcm_ops
= &qpa_pcm_ops
,
524 .max_voices_out
= INT_MAX
,
525 .max_voices_in
= INT_MAX
,
526 .voice_size_out
= sizeof (PAVoiceOut
),
527 .voice_size_in
= sizeof (PAVoiceIn
)