]> git.proxmox.com Git - mirror_qemu.git/blob - audio/pwaudio.c
Merge tag 'pull-request-2023-12-20' of https://gitlab.com/thuth/qemu into staging
[mirror_qemu.git] / audio / pwaudio.c
1 /*
2 * QEMU PipeWire audio driver
3 *
4 * Copyright (c) 2023 Red Hat Inc.
5 *
6 * Author: Dorinda Bassey <dbassey@redhat.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "qemu/osdep.h"
12 #include "qemu/module.h"
13 #include "audio.h"
14 #include <errno.h>
15 #include "qemu/error-report.h"
16 #include "qapi/error.h"
17 #include <spa/param/audio/format-utils.h>
18 #include <spa/utils/ringbuffer.h>
19 #include <spa/utils/result.h>
20 #include <spa/param/props.h>
21
22 #include <pipewire/pipewire.h>
23 #include "trace.h"
24
25 #define AUDIO_CAP "pipewire"
26 #define RINGBUFFER_SIZE (1u << 22)
27 #define RINGBUFFER_MASK (RINGBUFFER_SIZE - 1)
28
29 #include "audio_int.h"
30
31 typedef struct pwvolume {
32 uint32_t channels;
33 float values[SPA_AUDIO_MAX_CHANNELS];
34 } pwvolume;
35
36 typedef struct pwaudio {
37 Audiodev *dev;
38 struct pw_thread_loop *thread_loop;
39 struct pw_context *context;
40
41 struct pw_core *core;
42 struct spa_hook core_listener;
43 int last_seq, pending_seq, error;
44 } pwaudio;
45
46 typedef struct PWVoice {
47 pwaudio *g;
48 struct pw_stream *stream;
49 struct spa_hook stream_listener;
50 struct spa_audio_info_raw info;
51 uint32_t highwater_mark;
52 uint32_t frame_size, req;
53 struct spa_ringbuffer ring;
54 uint8_t buffer[RINGBUFFER_SIZE];
55
56 pwvolume volume;
57 bool muted;
58 } PWVoice;
59
60 typedef struct PWVoiceOut {
61 HWVoiceOut hw;
62 PWVoice v;
63 } PWVoiceOut;
64
65 typedef struct PWVoiceIn {
66 HWVoiceIn hw;
67 PWVoice v;
68 } PWVoiceIn;
69
70 #define PW_VOICE_IN(v) ((PWVoiceIn *)v)
71 #define PW_VOICE_OUT(v) ((PWVoiceOut *)v)
72
73 static void
74 stream_destroy(void *data)
75 {
76 PWVoice *v = (PWVoice *) data;
77 spa_hook_remove(&v->stream_listener);
78 v->stream = NULL;
79 }
80
81 /* output data processing function to read stuffs from the buffer */
82 static void
83 playback_on_process(void *data)
84 {
85 PWVoice *v = data;
86 void *p;
87 struct pw_buffer *b;
88 struct spa_buffer *buf;
89 uint32_t req, index, n_bytes;
90 int32_t avail;
91
92 assert(v->stream);
93
94 /* obtain a buffer to read from */
95 b = pw_stream_dequeue_buffer(v->stream);
96 if (b == NULL) {
97 error_report("out of buffers: %s", strerror(errno));
98 return;
99 }
100
101 buf = b->buffer;
102 p = buf->datas[0].data;
103 if (p == NULL) {
104 return;
105 }
106 /* calculate the total no of bytes to read data from buffer */
107 req = b->requested * v->frame_size;
108 if (req == 0) {
109 req = v->req;
110 }
111 n_bytes = SPA_MIN(req, buf->datas[0].maxsize);
112
113 /* get no of available bytes to read data from buffer */
114 avail = spa_ringbuffer_get_read_index(&v->ring, &index);
115
116 if (avail <= 0) {
117 PWVoiceOut *vo = container_of(data, PWVoiceOut, v);
118 audio_pcm_info_clear_buf(&vo->hw.info, p, n_bytes / v->frame_size);
119 } else {
120 if ((uint32_t) avail < n_bytes) {
121 /*
122 * PipeWire immediately calls this callback again if we provide
123 * less than n_bytes. Then audio_pcm_info_clear_buf() fills the
124 * rest of the buffer with silence.
125 */
126 n_bytes = avail;
127 }
128
129 spa_ringbuffer_read_data(&v->ring,
130 v->buffer, RINGBUFFER_SIZE,
131 index & RINGBUFFER_MASK, p, n_bytes);
132
133 index += n_bytes;
134 spa_ringbuffer_read_update(&v->ring, index);
135
136 }
137 buf->datas[0].chunk->offset = 0;
138 buf->datas[0].chunk->stride = v->frame_size;
139 buf->datas[0].chunk->size = n_bytes;
140
141 /* queue the buffer for playback */
142 pw_stream_queue_buffer(v->stream, b);
143 }
144
145 /* output data processing function to generate stuffs in the buffer */
146 static void
147 capture_on_process(void *data)
148 {
149 PWVoice *v = (PWVoice *) data;
150 void *p;
151 struct pw_buffer *b;
152 struct spa_buffer *buf;
153 int32_t filled;
154 uint32_t index, offs, n_bytes;
155
156 assert(v->stream);
157
158 /* obtain a buffer */
159 b = pw_stream_dequeue_buffer(v->stream);
160 if (b == NULL) {
161 error_report("out of buffers: %s", strerror(errno));
162 return;
163 }
164
165 /* Write data into buffer */
166 buf = b->buffer;
167 p = buf->datas[0].data;
168 if (p == NULL) {
169 return;
170 }
171 offs = SPA_MIN(buf->datas[0].chunk->offset, buf->datas[0].maxsize);
172 n_bytes = SPA_MIN(buf->datas[0].chunk->size, buf->datas[0].maxsize - offs);
173
174 filled = spa_ringbuffer_get_write_index(&v->ring, &index);
175
176
177 if (filled < 0) {
178 error_report("%p: underrun write:%u filled:%d", p, index, filled);
179 } else {
180 if ((uint32_t) filled + n_bytes > RINGBUFFER_SIZE) {
181 error_report("%p: overrun write:%u filled:%d + size:%u > max:%u",
182 p, index, filled, n_bytes, RINGBUFFER_SIZE);
183 }
184 }
185 spa_ringbuffer_write_data(&v->ring,
186 v->buffer, RINGBUFFER_SIZE,
187 index & RINGBUFFER_MASK,
188 SPA_PTROFF(p, offs, void), n_bytes);
189 index += n_bytes;
190 spa_ringbuffer_write_update(&v->ring, index);
191
192 /* queue the buffer for playback */
193 pw_stream_queue_buffer(v->stream, b);
194 }
195
196 static void
197 on_stream_state_changed(void *data, enum pw_stream_state old,
198 enum pw_stream_state state, const char *error)
199 {
200 PWVoice *v = (PWVoice *) data;
201
202 trace_pw_state_changed(pw_stream_get_node_id(v->stream),
203 pw_stream_state_as_string(state));
204 }
205
206 static const struct pw_stream_events capture_stream_events = {
207 PW_VERSION_STREAM_EVENTS,
208 .destroy = stream_destroy,
209 .state_changed = on_stream_state_changed,
210 .process = capture_on_process
211 };
212
213 static const struct pw_stream_events playback_stream_events = {
214 PW_VERSION_STREAM_EVENTS,
215 .destroy = stream_destroy,
216 .state_changed = on_stream_state_changed,
217 .process = playback_on_process
218 };
219
220 static size_t
221 qpw_read(HWVoiceIn *hw, void *data, size_t len)
222 {
223 PWVoiceIn *pw = (PWVoiceIn *) hw;
224 PWVoice *v = &pw->v;
225 pwaudio *c = v->g;
226 const char *error = NULL;
227 size_t l;
228 int32_t avail;
229 uint32_t index;
230
231 pw_thread_loop_lock(c->thread_loop);
232 if (pw_stream_get_state(v->stream, &error) != PW_STREAM_STATE_STREAMING) {
233 /* wait for stream to become ready */
234 l = 0;
235 goto done_unlock;
236 }
237 /* get no of available bytes to read data from buffer */
238 avail = spa_ringbuffer_get_read_index(&v->ring, &index);
239
240 trace_pw_read(avail, index, len);
241
242 if (avail < (int32_t) len) {
243 len = avail;
244 }
245
246 spa_ringbuffer_read_data(&v->ring,
247 v->buffer, RINGBUFFER_SIZE,
248 index & RINGBUFFER_MASK, data, len);
249 index += len;
250 spa_ringbuffer_read_update(&v->ring, index);
251 l = len;
252
253 done_unlock:
254 pw_thread_loop_unlock(c->thread_loop);
255 return l;
256 }
257
258 static size_t qpw_buffer_get_free(HWVoiceOut *hw)
259 {
260 PWVoiceOut *pw = (PWVoiceOut *)hw;
261 PWVoice *v = &pw->v;
262 pwaudio *c = v->g;
263 const char *error = NULL;
264 int32_t filled, avail;
265 uint32_t index;
266
267 pw_thread_loop_lock(c->thread_loop);
268 if (pw_stream_get_state(v->stream, &error) != PW_STREAM_STATE_STREAMING) {
269 /* wait for stream to become ready */
270 avail = 0;
271 goto done_unlock;
272 }
273
274 filled = spa_ringbuffer_get_write_index(&v->ring, &index);
275 avail = v->highwater_mark - filled;
276
277 done_unlock:
278 pw_thread_loop_unlock(c->thread_loop);
279 return avail;
280 }
281
282 static size_t
283 qpw_write(HWVoiceOut *hw, void *data, size_t len)
284 {
285 PWVoiceOut *pw = (PWVoiceOut *) hw;
286 PWVoice *v = &pw->v;
287 pwaudio *c = v->g;
288 const char *error = NULL;
289 int32_t filled, avail;
290 uint32_t index;
291
292 pw_thread_loop_lock(c->thread_loop);
293 if (pw_stream_get_state(v->stream, &error) != PW_STREAM_STATE_STREAMING) {
294 /* wait for stream to become ready */
295 len = 0;
296 goto done_unlock;
297 }
298 filled = spa_ringbuffer_get_write_index(&v->ring, &index);
299 avail = v->highwater_mark - filled;
300
301 trace_pw_write(filled, avail, index, len);
302
303 if (len > avail) {
304 len = avail;
305 }
306
307 if (filled < 0) {
308 error_report("%p: underrun write:%u filled:%d", pw, index, filled);
309 } else {
310 if ((uint32_t) filled + len > RINGBUFFER_SIZE) {
311 error_report("%p: overrun write:%u filled:%d + size:%zu > max:%u",
312 pw, index, filled, len, RINGBUFFER_SIZE);
313 }
314 }
315
316 spa_ringbuffer_write_data(&v->ring,
317 v->buffer, RINGBUFFER_SIZE,
318 index & RINGBUFFER_MASK, data, len);
319 index += len;
320 spa_ringbuffer_write_update(&v->ring, index);
321
322 done_unlock:
323 pw_thread_loop_unlock(c->thread_loop);
324 return len;
325 }
326
327 static int
328 audfmt_to_pw(AudioFormat fmt, int endianness)
329 {
330 int format;
331
332 switch (fmt) {
333 case AUDIO_FORMAT_S8:
334 format = SPA_AUDIO_FORMAT_S8;
335 break;
336 case AUDIO_FORMAT_U8:
337 format = SPA_AUDIO_FORMAT_U8;
338 break;
339 case AUDIO_FORMAT_S16:
340 format = endianness ? SPA_AUDIO_FORMAT_S16_BE : SPA_AUDIO_FORMAT_S16_LE;
341 break;
342 case AUDIO_FORMAT_U16:
343 format = endianness ? SPA_AUDIO_FORMAT_U16_BE : SPA_AUDIO_FORMAT_U16_LE;
344 break;
345 case AUDIO_FORMAT_S32:
346 format = endianness ? SPA_AUDIO_FORMAT_S32_BE : SPA_AUDIO_FORMAT_S32_LE;
347 break;
348 case AUDIO_FORMAT_U32:
349 format = endianness ? SPA_AUDIO_FORMAT_U32_BE : SPA_AUDIO_FORMAT_U32_LE;
350 break;
351 case AUDIO_FORMAT_F32:
352 format = endianness ? SPA_AUDIO_FORMAT_F32_BE : SPA_AUDIO_FORMAT_F32_LE;
353 break;
354 default:
355 dolog("Internal logic error: Bad audio format %d\n", fmt);
356 format = SPA_AUDIO_FORMAT_U8;
357 break;
358 }
359 return format;
360 }
361
362 static AudioFormat
363 pw_to_audfmt(enum spa_audio_format fmt, int *endianness,
364 uint32_t *sample_size)
365 {
366 switch (fmt) {
367 case SPA_AUDIO_FORMAT_S8:
368 *sample_size = 1;
369 return AUDIO_FORMAT_S8;
370 case SPA_AUDIO_FORMAT_U8:
371 *sample_size = 1;
372 return AUDIO_FORMAT_U8;
373 case SPA_AUDIO_FORMAT_S16_BE:
374 *sample_size = 2;
375 *endianness = 1;
376 return AUDIO_FORMAT_S16;
377 case SPA_AUDIO_FORMAT_S16_LE:
378 *sample_size = 2;
379 *endianness = 0;
380 return AUDIO_FORMAT_S16;
381 case SPA_AUDIO_FORMAT_U16_BE:
382 *sample_size = 2;
383 *endianness = 1;
384 return AUDIO_FORMAT_U16;
385 case SPA_AUDIO_FORMAT_U16_LE:
386 *sample_size = 2;
387 *endianness = 0;
388 return AUDIO_FORMAT_U16;
389 case SPA_AUDIO_FORMAT_S32_BE:
390 *sample_size = 4;
391 *endianness = 1;
392 return AUDIO_FORMAT_S32;
393 case SPA_AUDIO_FORMAT_S32_LE:
394 *sample_size = 4;
395 *endianness = 0;
396 return AUDIO_FORMAT_S32;
397 case SPA_AUDIO_FORMAT_U32_BE:
398 *sample_size = 4;
399 *endianness = 1;
400 return AUDIO_FORMAT_U32;
401 case SPA_AUDIO_FORMAT_U32_LE:
402 *sample_size = 4;
403 *endianness = 0;
404 return AUDIO_FORMAT_U32;
405 case SPA_AUDIO_FORMAT_F32_BE:
406 *sample_size = 4;
407 *endianness = 1;
408 return AUDIO_FORMAT_F32;
409 case SPA_AUDIO_FORMAT_F32_LE:
410 *sample_size = 4;
411 *endianness = 0;
412 return AUDIO_FORMAT_F32;
413 default:
414 *sample_size = 1;
415 dolog("Internal logic error: Bad spa_audio_format %d\n", fmt);
416 return AUDIO_FORMAT_U8;
417 }
418 }
419
420 static int
421 qpw_stream_new(pwaudio *c, PWVoice *v, const char *stream_name,
422 const char *name, enum spa_direction dir)
423 {
424 int res;
425 uint32_t n_params;
426 const struct spa_pod *params[2];
427 uint8_t buffer[1024];
428 struct spa_pod_builder b;
429 uint64_t buf_samples;
430 struct pw_properties *props;
431
432 props = pw_properties_new(NULL, NULL);
433 if (!props) {
434 error_report("Failed to create PW properties: %s", g_strerror(errno));
435 return -1;
436 }
437
438 /* 75% of the timer period for faster updates */
439 buf_samples = (uint64_t)v->g->dev->timer_period * v->info.rate
440 * 3 / 4 / 1000000;
441 pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%" PRIu64 "/%u",
442 buf_samples, v->info.rate);
443
444 trace_pw_period(buf_samples, v->info.rate);
445 if (name) {
446 pw_properties_set(props, PW_KEY_TARGET_OBJECT, name);
447 }
448 v->stream = pw_stream_new(c->core, stream_name, props);
449 if (v->stream == NULL) {
450 error_report("Failed to create PW stream: %s", g_strerror(errno));
451 return -1;
452 }
453
454 if (dir == SPA_DIRECTION_INPUT) {
455 pw_stream_add_listener(v->stream,
456 &v->stream_listener, &capture_stream_events, v);
457 } else {
458 pw_stream_add_listener(v->stream,
459 &v->stream_listener, &playback_stream_events, v);
460 }
461
462 n_params = 0;
463 spa_pod_builder_init(&b, buffer, sizeof(buffer));
464 params[n_params++] = spa_format_audio_raw_build(&b,
465 SPA_PARAM_EnumFormat,
466 &v->info);
467
468 /* connect the stream to a sink or source */
469 res = pw_stream_connect(v->stream,
470 dir ==
471 SPA_DIRECTION_INPUT ? PW_DIRECTION_INPUT :
472 PW_DIRECTION_OUTPUT, PW_ID_ANY,
473 PW_STREAM_FLAG_AUTOCONNECT |
474 PW_STREAM_FLAG_INACTIVE |
475 PW_STREAM_FLAG_MAP_BUFFERS |
476 PW_STREAM_FLAG_RT_PROCESS, params, n_params);
477 if (res < 0) {
478 error_report("Failed to connect PW stream: %s", g_strerror(errno));
479 pw_stream_destroy(v->stream);
480 return -1;
481 }
482
483 return 0;
484 }
485
486 static void
487 qpw_set_position(uint32_t channels, uint32_t position[SPA_AUDIO_MAX_CHANNELS])
488 {
489 memcpy(position, (uint32_t[SPA_AUDIO_MAX_CHANNELS]) { SPA_AUDIO_CHANNEL_UNKNOWN, },
490 sizeof(uint32_t) * SPA_AUDIO_MAX_CHANNELS);
491 /*
492 * TODO: This currently expects the only frontend supporting more than 2
493 * channels is the usb-audio. We will need some means to set channel
494 * order when a new frontend gains multi-channel support.
495 */
496 switch (channels) {
497 case 8:
498 position[6] = SPA_AUDIO_CHANNEL_SL;
499 position[7] = SPA_AUDIO_CHANNEL_SR;
500 /* fallthrough */
501 case 6:
502 position[2] = SPA_AUDIO_CHANNEL_FC;
503 position[3] = SPA_AUDIO_CHANNEL_LFE;
504 position[4] = SPA_AUDIO_CHANNEL_RL;
505 position[5] = SPA_AUDIO_CHANNEL_RR;
506 /* fallthrough */
507 case 2:
508 position[0] = SPA_AUDIO_CHANNEL_FL;
509 position[1] = SPA_AUDIO_CHANNEL_FR;
510 break;
511 case 1:
512 position[0] = SPA_AUDIO_CHANNEL_MONO;
513 break;
514 default:
515 dolog("Internal error: unsupported channel count %d\n", channels);
516 }
517 }
518
519 static int
520 qpw_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
521 {
522 PWVoiceOut *pw = (PWVoiceOut *) hw;
523 PWVoice *v = &pw->v;
524 struct audsettings obt_as = *as;
525 pwaudio *c = v->g = drv_opaque;
526 AudiodevPipewireOptions *popts = &c->dev->u.pipewire;
527 AudiodevPipewirePerDirectionOptions *ppdo = popts->out;
528 int r;
529
530 pw_thread_loop_lock(c->thread_loop);
531
532 v->info.format = audfmt_to_pw(as->fmt, as->endianness);
533 v->info.channels = as->nchannels;
534 qpw_set_position(as->nchannels, v->info.position);
535 v->info.rate = as->freq;
536
537 obt_as.fmt =
538 pw_to_audfmt(v->info.format, &obt_as.endianness, &v->frame_size);
539 v->frame_size *= as->nchannels;
540
541 v->req = (uint64_t)c->dev->timer_period * v->info.rate
542 * 1 / 2 / 1000000 * v->frame_size;
543
544 /* call the function that creates a new stream for playback */
545 r = qpw_stream_new(c, v, ppdo->stream_name ? : c->dev->id,
546 ppdo->name, SPA_DIRECTION_OUTPUT);
547 if (r < 0) {
548 pw_thread_loop_unlock(c->thread_loop);
549 return -1;
550 }
551
552 /* report the audio format we support */
553 audio_pcm_init_info(&hw->info, &obt_as);
554
555 /* report the buffer size to qemu */
556 hw->samples = audio_buffer_frames(
557 qapi_AudiodevPipewirePerDirectionOptions_base(ppdo), &obt_as, 46440);
558 v->highwater_mark = MIN(RINGBUFFER_SIZE,
559 (ppdo->has_latency ? ppdo->latency : 46440)
560 * (uint64_t)v->info.rate / 1000000 * v->frame_size);
561
562 pw_thread_loop_unlock(c->thread_loop);
563 return 0;
564 }
565
566 static int
567 qpw_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
568 {
569 PWVoiceIn *pw = (PWVoiceIn *) hw;
570 PWVoice *v = &pw->v;
571 struct audsettings obt_as = *as;
572 pwaudio *c = v->g = drv_opaque;
573 AudiodevPipewireOptions *popts = &c->dev->u.pipewire;
574 AudiodevPipewirePerDirectionOptions *ppdo = popts->in;
575 int r;
576
577 pw_thread_loop_lock(c->thread_loop);
578
579 v->info.format = audfmt_to_pw(as->fmt, as->endianness);
580 v->info.channels = as->nchannels;
581 qpw_set_position(as->nchannels, v->info.position);
582 v->info.rate = as->freq;
583
584 obt_as.fmt =
585 pw_to_audfmt(v->info.format, &obt_as.endianness, &v->frame_size);
586 v->frame_size *= as->nchannels;
587
588 /* call the function that creates a new stream for recording */
589 r = qpw_stream_new(c, v, ppdo->stream_name ? : c->dev->id,
590 ppdo->name, SPA_DIRECTION_INPUT);
591 if (r < 0) {
592 pw_thread_loop_unlock(c->thread_loop);
593 return -1;
594 }
595
596 /* report the audio format we support */
597 audio_pcm_init_info(&hw->info, &obt_as);
598
599 /* report the buffer size to qemu */
600 hw->samples = audio_buffer_frames(
601 qapi_AudiodevPipewirePerDirectionOptions_base(ppdo), &obt_as, 46440);
602
603 pw_thread_loop_unlock(c->thread_loop);
604 return 0;
605 }
606
607 static void
608 qpw_voice_fini(PWVoice *v)
609 {
610 pwaudio *c = v->g;
611
612 if (!v->stream) {
613 return;
614 }
615 pw_thread_loop_lock(c->thread_loop);
616 pw_stream_destroy(v->stream);
617 v->stream = NULL;
618 pw_thread_loop_unlock(c->thread_loop);
619 }
620
621 static void
622 qpw_fini_out(HWVoiceOut *hw)
623 {
624 qpw_voice_fini(&PW_VOICE_OUT(hw)->v);
625 }
626
627 static void
628 qpw_fini_in(HWVoiceIn *hw)
629 {
630 qpw_voice_fini(&PW_VOICE_IN(hw)->v);
631 }
632
633 static void
634 qpw_voice_set_enabled(PWVoice *v, bool enable)
635 {
636 pwaudio *c = v->g;
637 pw_thread_loop_lock(c->thread_loop);
638 pw_stream_set_active(v->stream, enable);
639 pw_thread_loop_unlock(c->thread_loop);
640 }
641
642 static void
643 qpw_enable_out(HWVoiceOut *hw, bool enable)
644 {
645 qpw_voice_set_enabled(&PW_VOICE_OUT(hw)->v, enable);
646 }
647
648 static void
649 qpw_enable_in(HWVoiceIn *hw, bool enable)
650 {
651 qpw_voice_set_enabled(&PW_VOICE_IN(hw)->v, enable);
652 }
653
654 static void
655 qpw_voice_set_volume(PWVoice *v, Volume *vol)
656 {
657 pwaudio *c = v->g;
658 int i, ret;
659
660 pw_thread_loop_lock(c->thread_loop);
661 v->volume.channels = vol->channels;
662
663 for (i = 0; i < vol->channels; ++i) {
664 v->volume.values[i] = (float)vol->vol[i] / 255;
665 }
666
667 ret = pw_stream_set_control(v->stream,
668 SPA_PROP_channelVolumes, v->volume.channels, v->volume.values, 0);
669 trace_pw_vol(ret == 0 ? "success" : "failed");
670
671 v->muted = vol->mute;
672 float val = v->muted ? 1.f : 0.f;
673 ret = pw_stream_set_control(v->stream, SPA_PROP_mute, 1, &val, 0);
674 pw_thread_loop_unlock(c->thread_loop);
675 }
676
677 static void
678 qpw_volume_out(HWVoiceOut *hw, Volume *vol)
679 {
680 qpw_voice_set_volume(&PW_VOICE_OUT(hw)->v, vol);
681 }
682
683 static void
684 qpw_volume_in(HWVoiceIn *hw, Volume *vol)
685 {
686 qpw_voice_set_volume(&PW_VOICE_IN(hw)->v, vol);
687 }
688
689 static int wait_resync(pwaudio *pw)
690 {
691 int res;
692 pw->pending_seq = pw_core_sync(pw->core, PW_ID_CORE, pw->pending_seq);
693
694 while (true) {
695 pw_thread_loop_wait(pw->thread_loop);
696
697 res = pw->error;
698 if (res < 0) {
699 pw->error = 0;
700 return res;
701 }
702 if (pw->pending_seq == pw->last_seq) {
703 break;
704 }
705 }
706 return 0;
707 }
708
709 static void
710 on_core_error(void *data, uint32_t id, int seq, int res, const char *message)
711 {
712 pwaudio *pw = data;
713
714 error_report("error id:%u seq:%d res:%d (%s): %s",
715 id, seq, res, spa_strerror(res), message);
716
717 /* stop and exit the thread loop */
718 pw_thread_loop_signal(pw->thread_loop, FALSE);
719 }
720
721 static void
722 on_core_done(void *data, uint32_t id, int seq)
723 {
724 pwaudio *pw = data;
725 assert(id == PW_ID_CORE);
726 pw->last_seq = seq;
727 if (pw->pending_seq == seq) {
728 /* stop and exit the thread loop */
729 pw_thread_loop_signal(pw->thread_loop, FALSE);
730 }
731 }
732
733 static const struct pw_core_events core_events = {
734 PW_VERSION_CORE_EVENTS,
735 .done = on_core_done,
736 .error = on_core_error,
737 };
738
739 static void *
740 qpw_audio_init(Audiodev *dev, Error **errp)
741 {
742 g_autofree pwaudio *pw = g_new0(pwaudio, 1);
743
744 assert(dev->driver == AUDIODEV_DRIVER_PIPEWIRE);
745 trace_pw_audio_init();
746
747 pw_init(NULL, NULL);
748
749 pw->dev = dev;
750 pw->thread_loop = pw_thread_loop_new("PipeWire thread loop", NULL);
751 if (pw->thread_loop == NULL) {
752 error_setg_errno(errp, errno, "Could not create PipeWire loop");
753 goto fail;
754 }
755
756 pw->context =
757 pw_context_new(pw_thread_loop_get_loop(pw->thread_loop), NULL, 0);
758 if (pw->context == NULL) {
759 error_setg_errno(errp, errno, "Could not create PipeWire context");
760 goto fail;
761 }
762
763 if (pw_thread_loop_start(pw->thread_loop) < 0) {
764 error_setg_errno(errp, errno, "Could not start PipeWire loop");
765 goto fail;
766 }
767
768 pw_thread_loop_lock(pw->thread_loop);
769
770 pw->core = pw_context_connect(pw->context, NULL, 0);
771 if (pw->core == NULL) {
772 pw_thread_loop_unlock(pw->thread_loop);
773 goto fail_error;
774 }
775
776 if (pw_core_add_listener(pw->core, &pw->core_listener,
777 &core_events, pw) < 0) {
778 pw_thread_loop_unlock(pw->thread_loop);
779 goto fail_error;
780 }
781 if (wait_resync(pw) < 0) {
782 pw_thread_loop_unlock(pw->thread_loop);
783 }
784
785 pw_thread_loop_unlock(pw->thread_loop);
786
787 return g_steal_pointer(&pw);
788
789 fail_error:
790 error_setg(errp, "Failed to initialize PW context");
791 fail:
792 if (pw->thread_loop) {
793 pw_thread_loop_stop(pw->thread_loop);
794 }
795 g_clear_pointer(&pw->context, pw_context_destroy);
796 g_clear_pointer(&pw->thread_loop, pw_thread_loop_destroy);
797 return NULL;
798 }
799
800 static void
801 qpw_audio_fini(void *opaque)
802 {
803 pwaudio *pw = opaque;
804
805 if (pw->thread_loop) {
806 pw_thread_loop_stop(pw->thread_loop);
807 }
808
809 if (pw->core) {
810 spa_hook_remove(&pw->core_listener);
811 spa_zero(pw->core_listener);
812 pw_core_disconnect(pw->core);
813 }
814
815 if (pw->context) {
816 pw_context_destroy(pw->context);
817 }
818 pw_thread_loop_destroy(pw->thread_loop);
819
820 g_free(pw);
821 }
822
823 static struct audio_pcm_ops qpw_pcm_ops = {
824 .init_out = qpw_init_out,
825 .fini_out = qpw_fini_out,
826 .write = qpw_write,
827 .buffer_get_free = qpw_buffer_get_free,
828 .run_buffer_out = audio_generic_run_buffer_out,
829 .enable_out = qpw_enable_out,
830 .volume_out = qpw_volume_out,
831 .volume_in = qpw_volume_in,
832
833 .init_in = qpw_init_in,
834 .fini_in = qpw_fini_in,
835 .read = qpw_read,
836 .run_buffer_in = audio_generic_run_buffer_in,
837 .enable_in = qpw_enable_in
838 };
839
840 static struct audio_driver pw_audio_driver = {
841 .name = "pipewire",
842 .descr = "http://www.pipewire.org/",
843 .init = qpw_audio_init,
844 .fini = qpw_audio_fini,
845 .pcm_ops = &qpw_pcm_ops,
846 .max_voices_out = INT_MAX,
847 .max_voices_in = INT_MAX,
848 .voice_size_out = sizeof(PWVoiceOut),
849 .voice_size_in = sizeof(PWVoiceIn),
850 };
851
852 static void
853 register_audio_pw(void)
854 {
855 audio_driver_register(&pw_audio_driver);
856 }
857
858 type_init(register_audio_pw);