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); 859