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