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"
48 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err
, const char *fmt
, ...)
53 AUD_vlog (AUDIO_CAP
, fmt
, ap
);
56 AUD_log (AUDIO_CAP
, "Reason: %s\n", pa_strerror (err
));
59 static void *qpa_thread_out (void *arg
)
62 HWVoiceOut
*hw
= &pa
->hw
;
65 threshold
= conf
.divisor
? hw
->samples
/ conf
.divisor
: 0;
67 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
72 int decr
, to_mix
, rpos
;
79 if (pa
->live
> threshold
) {
83 if (audio_pt_wait (&pa
->pt
, AUDIO_FUNC
)) {
88 decr
= to_mix
= pa
->live
;
91 if (audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
)) {
97 int chunk
= audio_MIN (to_mix
, hw
->samples
- rpos
);
98 struct st_sample
*src
= hw
->mix_buf
+ rpos
;
100 hw
->clip (pa
->pcm_buf
, src
, chunk
);
102 if (pa_simple_write (pa
->s
, pa
->pcm_buf
,
103 chunk
<< hw
->info
.shift
, &error
) < 0) {
104 qpa_logerr (error
, "pa_simple_write failed\n");
108 rpos
= (rpos
+ chunk
) % hw
->samples
;
112 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
122 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
126 static int qpa_run_out (HWVoiceOut
*hw
)
129 PAVoiceOut
*pa
= (PAVoiceOut
*) hw
;
131 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
135 live
= audio_pcm_hw_get_live_out (hw
);
136 decr
= audio_MIN (live
, pa
->decr
);
138 pa
->live
= live
- decr
;
141 audio_pt_unlock_and_signal (&pa
->pt
, AUDIO_FUNC
);
144 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
149 static int qpa_write (SWVoiceOut
*sw
, void *buf
, int len
)
151 return audio_pcm_sw_write (sw
, buf
, len
);
155 static void *qpa_thread_in (void *arg
)
158 HWVoiceIn
*hw
= &pa
->hw
;
161 threshold
= conf
.divisor
? hw
->samples
/ conf
.divisor
: 0;
163 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
168 int incr
, to_grab
, wpos
;
175 if (pa
->dead
> threshold
) {
179 if (audio_pt_wait (&pa
->pt
, AUDIO_FUNC
)) {
184 incr
= to_grab
= pa
->dead
;
187 if (audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
)) {
193 int chunk
= audio_MIN (to_grab
, hw
->samples
- wpos
);
194 void *buf
= advance (pa
->pcm_buf
, wpos
);
196 if (pa_simple_read (pa
->s
, buf
,
197 chunk
<< hw
->info
.shift
, &error
) < 0) {
198 qpa_logerr (error
, "pa_simple_read failed\n");
202 hw
->conv (hw
->conv_buf
+ wpos
, buf
, chunk
, &nominal_volume
);
203 wpos
= (wpos
+ chunk
) % hw
->samples
;
207 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
217 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
221 static int qpa_run_in (HWVoiceIn
*hw
)
223 int live
, incr
, dead
;
224 PAVoiceIn
*pa
= (PAVoiceIn
*) hw
;
226 if (audio_pt_lock (&pa
->pt
, AUDIO_FUNC
)) {
230 live
= audio_pcm_hw_get_live_in (hw
);
231 dead
= hw
->samples
- live
;
232 incr
= audio_MIN (dead
, pa
->incr
);
234 pa
->dead
= dead
- incr
;
237 audio_pt_unlock_and_signal (&pa
->pt
, AUDIO_FUNC
);
240 audio_pt_unlock (&pa
->pt
, AUDIO_FUNC
);
245 static int qpa_read (SWVoiceIn
*sw
, void *buf
, int len
)
247 return audio_pcm_sw_read (sw
, buf
, len
);
250 static pa_sample_format_t
audfmt_to_pa (audfmt_e afmt
, int endianness
)
257 format
= PA_SAMPLE_U8
;
261 format
= endianness
? PA_SAMPLE_S16BE
: PA_SAMPLE_S16LE
;
265 format
= endianness
? PA_SAMPLE_S32BE
: PA_SAMPLE_S32LE
;
268 dolog ("Internal logic error: Bad audio format %d\n", afmt
);
269 format
= PA_SAMPLE_U8
;
275 static audfmt_e
pa_to_audfmt (pa_sample_format_t fmt
, int *endianness
)
280 case PA_SAMPLE_S16BE
:
283 case PA_SAMPLE_S16LE
:
286 case PA_SAMPLE_S32BE
:
289 case PA_SAMPLE_S32LE
:
293 dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt
);
298 static int qpa_init_out (HWVoiceOut
*hw
, struct audsettings
*as
)
301 static pa_sample_spec ss
;
302 struct audsettings obt_as
= *as
;
303 PAVoiceOut
*pa
= (PAVoiceOut
*) hw
;
305 ss
.format
= audfmt_to_pa (as
->fmt
, as
->endianness
);
306 ss
.channels
= as
->nchannels
;
309 obt_as
.fmt
= pa_to_audfmt (ss
.format
, &obt_as
.endianness
);
311 pa
->s
= pa_simple_new (
318 NULL
, /* channel map */
319 NULL
, /* buffering attributes */
323 qpa_logerr (error
, "pa_simple_new for playback failed\n");
327 audio_pcm_init_info (&hw
->info
, &obt_as
);
328 hw
->samples
= conf
.samples
;
329 pa
->pcm_buf
= audio_calloc (AUDIO_FUNC
, hw
->samples
, 1 << hw
->info
.shift
);
331 dolog ("Could not allocate buffer (%d bytes)\n",
332 hw
->samples
<< hw
->info
.shift
);
336 if (audio_pt_init (&pa
->pt
, qpa_thread_out
, hw
, AUDIO_CAP
, AUDIO_FUNC
)) {
343 qemu_free (pa
->pcm_buf
);
346 pa_simple_free (pa
->s
);
352 static int qpa_init_in (HWVoiceIn
*hw
, struct audsettings
*as
)
355 static pa_sample_spec ss
;
356 struct audsettings obt_as
= *as
;
357 PAVoiceIn
*pa
= (PAVoiceIn
*) hw
;
359 ss
.format
= audfmt_to_pa (as
->fmt
, as
->endianness
);
360 ss
.channels
= as
->nchannels
;
363 obt_as
.fmt
= pa_to_audfmt (ss
.format
, &obt_as
.endianness
);
365 pa
->s
= pa_simple_new (
372 NULL
, /* channel map */
373 NULL
, /* buffering attributes */
377 qpa_logerr (error
, "pa_simple_new for capture failed\n");
381 audio_pcm_init_info (&hw
->info
, &obt_as
);
382 hw
->samples
= conf
.samples
;
383 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
[] = {
474 .valp
= &conf
.samples
,
475 .descr
= "buffer size in samples"},
478 .valp
= &conf
.divisor
,
479 .descr
= "threshold divisor"},
482 .valp
= &conf
.server
,
483 .descr
= "server address"},
487 .descr
= "sink device name"},
490 .valp
= &conf
.source
,
491 .descr
= "source device name"},
492 { /* End of list */ }
495 static struct audio_pcm_ops qpa_pcm_ops
= {
496 .init_out
= qpa_init_out
,
497 .fini_out
= qpa_fini_out
,
498 .run_out
= qpa_run_out
,
500 .ctl_out
= qpa_ctl_out
,
502 .init_in
= qpa_init_in
,
503 .fini_in
= qpa_fini_in
,
504 .run_in
= qpa_run_in
,
509 struct audio_driver pa_audio_driver
= {
511 .descr
= "http://www.pulseaudio.org/",
512 .options
= qpa_options
,
513 .init
= qpa_audio_init
,
514 .fini
= qpa_audio_fini
,
515 .pcm_ops
= &qpa_pcm_ops
,
517 .max_voices_out
= INT_MAX
,
518 .max_voices_in
= INT_MAX
,
519 .voice_size_out
= sizeof (PAVoiceOut
),
520 .voice_size_in
= sizeof (PAVoiceIn
)