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 st_sample_t
*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
, audsettings_t
*as
)
301 static pa_sample_spec ss
;
302 audsettings_t 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
)) {
346 pa_simple_free (pa
->s
);
352 static int qpa_init_in (HWVoiceIn
*hw
, audsettings_t
*as
)
355 static pa_sample_spec ss
;
356 audsettings_t 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
)) {
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
[] = {
472 {"SAMPLES", AUD_OPT_INT
, &conf
.samples
,
473 "buffer size in samples", NULL
, 0},
475 {"DIVISOR", AUD_OPT_INT
, &conf
.divisor
,
476 "threshold divisor", NULL
, 0},
478 {"SERVER", AUD_OPT_STR
, &conf
.server
,
479 "server address", NULL
, 0},
481 {"SINK", AUD_OPT_STR
, &conf
.sink
,
482 "sink device name", NULL
, 0},
484 {"SOURCE", AUD_OPT_STR
, &conf
.source
,
485 "source device name", NULL
, 0},
487 {NULL
, 0, NULL
, NULL
, NULL
, 0}
490 static struct audio_pcm_ops qpa_pcm_ops
= {
503 struct audio_driver pa_audio_driver
= {
504 INIT_FIELD (name
= ) "pa",
505 INIT_FIELD (descr
= ) "http://www.pulseaudio.org/",
506 INIT_FIELD (options
= ) qpa_options
,
507 INIT_FIELD (init
= ) qpa_audio_init
,
508 INIT_FIELD (fini
= ) qpa_audio_fini
,
509 INIT_FIELD (pcm_ops
= ) &qpa_pcm_ops
,
510 INIT_FIELD (can_be_default
= ) 0,
511 INIT_FIELD (max_voices_out
= ) INT_MAX
,
512 INIT_FIELD (max_voices_in
= ) INT_MAX
,
513 INIT_FIELD (voice_size_out
= ) sizeof (PAVoiceOut
),
514 INIT_FIELD (voice_size_in
= ) sizeof (PAVoiceIn
)