jackaudio.c (17146B)
1/* 2 * QEMU JACK Audio Connection Kit Client 3 * 4 * Copyright (c) 2020 Geoffrey McRae (gnif) 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25#include "qemu/osdep.h" 26#include "qemu/module.h" 27#include "qemu/atomic.h" 28#include "qemu/main-loop.h" 29#include "audio.h" 30 31#define AUDIO_CAP "jack" 32#include "audio_int.h" 33 34#include <jack/jack.h> 35#include <jack/thread.h> 36 37struct QJack; 38 39typedef enum QJackState { 40 QJACK_STATE_DISCONNECTED, 41 QJACK_STATE_RUNNING, 42 QJACK_STATE_SHUTDOWN 43} 44QJackState; 45 46typedef struct QJackBuffer { 47 int channels; 48 int frames; 49 uint32_t used; 50 int rptr, wptr; 51 float **data; 52} 53QJackBuffer; 54 55typedef struct QJackClient { 56 AudiodevJackPerDirectionOptions *opt; 57 58 bool out; 59 bool enabled; 60 bool connect_ports; 61 int packets; 62 63 QJackState state; 64 jack_client_t *client; 65 jack_nframes_t freq; 66 QEMUBH *shutdown_bh; 67 68 struct QJack *j; 69 int nchannels; 70 int buffersize; 71 jack_port_t **port; 72 QJackBuffer fifo; 73} 74QJackClient; 75 76typedef struct QJackOut { 77 HWVoiceOut hw; 78 QJackClient c; 79} 80QJackOut; 81 82typedef struct QJackIn { 83 HWVoiceIn hw; 84 QJackClient c; 85} 86QJackIn; 87 88static int qjack_client_init(QJackClient *c); 89static void qjack_client_connect_ports(QJackClient *c); 90static void qjack_client_fini(QJackClient *c); 91static QemuMutex qjack_shutdown_lock; 92 93static void qjack_buffer_create(QJackBuffer *buffer, int channels, int frames) 94{ 95 buffer->channels = channels; 96 buffer->frames = frames; 97 buffer->used = 0; 98 buffer->rptr = 0; 99 buffer->wptr = 0; 100 buffer->data = g_malloc(channels * sizeof(float *)); 101 for (int i = 0; i < channels; ++i) { 102 buffer->data[i] = g_malloc(frames * sizeof(float)); 103 } 104} 105 106static void qjack_buffer_clear(QJackBuffer *buffer) 107{ 108 assert(buffer->data); 109 qatomic_store_release(&buffer->used, 0); 110 buffer->rptr = 0; 111 buffer->wptr = 0; 112} 113 114static void qjack_buffer_free(QJackBuffer *buffer) 115{ 116 if (!buffer->data) { 117 return; 118 } 119 120 for (int i = 0; i < buffer->channels; ++i) { 121 g_free(buffer->data[i]); 122 } 123 124 g_free(buffer->data); 125 buffer->data = NULL; 126} 127 128/* write PCM interleaved */ 129static int qjack_buffer_write(QJackBuffer *buffer, float *data, int size) 130{ 131 assert(buffer->data); 132 const int samples = size / sizeof(float); 133 int frames = samples / buffer->channels; 134 const int avail = buffer->frames - qatomic_load_acquire(&buffer->used); 135 136 if (frames > avail) { 137 frames = avail; 138 } 139 140 int copy = frames; 141 int wptr = buffer->wptr; 142 143 while (copy) { 144 145 for (int c = 0; c < buffer->channels; ++c) { 146 buffer->data[c][wptr] = *data++; 147 } 148 149 if (++wptr == buffer->frames) { 150 wptr = 0; 151 } 152 153 --copy; 154 } 155 156 buffer->wptr = wptr; 157 158 qatomic_add(&buffer->used, frames); 159 return frames * buffer->channels * sizeof(float); 160}; 161 162/* write PCM linear */ 163static int qjack_buffer_write_l(QJackBuffer *buffer, float **dest, int frames) 164{ 165 assert(buffer->data); 166 const int avail = buffer->frames - qatomic_load_acquire(&buffer->used); 167 int wptr = buffer->wptr; 168 169 if (frames > avail) { 170 frames = avail; 171 } 172 173 int right = buffer->frames - wptr; 174 if (right > frames) { 175 right = frames; 176 } 177 178 const int left = frames - right; 179 for (int c = 0; c < buffer->channels; ++c) { 180 memcpy(buffer->data[c] + wptr, dest[c] , right * sizeof(float)); 181 memcpy(buffer->data[c] , dest[c] + right, left * sizeof(float)); 182 } 183 184 wptr += frames; 185 if (wptr >= buffer->frames) { 186 wptr -= buffer->frames; 187 } 188 buffer->wptr = wptr; 189 190 qatomic_add(&buffer->used, frames); 191 return frames; 192} 193 194/* read PCM interleaved */ 195static int qjack_buffer_read(QJackBuffer *buffer, float *dest, int size) 196{ 197 assert(buffer->data); 198 const int samples = size / sizeof(float); 199 int frames = samples / buffer->channels; 200 const int avail = qatomic_load_acquire(&buffer->used); 201 202 if (frames > avail) { 203 frames = avail; 204 } 205 206 int copy = frames; 207 int rptr = buffer->rptr; 208 209 while (copy) { 210 211 for (int c = 0; c < buffer->channels; ++c) { 212 *dest++ = buffer->data[c][rptr]; 213 } 214 215 if (++rptr == buffer->frames) { 216 rptr = 0; 217 } 218 219 --copy; 220 } 221 222 buffer->rptr = rptr; 223 224 qatomic_sub(&buffer->used, frames); 225 return frames * buffer->channels * sizeof(float); 226} 227 228/* read PCM linear */ 229static int qjack_buffer_read_l(QJackBuffer *buffer, float **dest, int frames) 230{ 231 assert(buffer->data); 232 int copy = frames; 233 const int used = qatomic_load_acquire(&buffer->used); 234 int rptr = buffer->rptr; 235 236 if (copy > used) { 237 copy = used; 238 } 239 240 int right = buffer->frames - rptr; 241 if (right > copy) { 242 right = copy; 243 } 244 245 const int left = copy - right; 246 for (int c = 0; c < buffer->channels; ++c) { 247 memcpy(dest[c] , buffer->data[c] + rptr, right * sizeof(float)); 248 memcpy(dest[c] + right, buffer->data[c] , left * sizeof(float)); 249 } 250 251 rptr += copy; 252 if (rptr >= buffer->frames) { 253 rptr -= buffer->frames; 254 } 255 buffer->rptr = rptr; 256 257 qatomic_sub(&buffer->used, copy); 258 return copy; 259} 260 261static int qjack_process(jack_nframes_t nframes, void *arg) 262{ 263 QJackClient *c = (QJackClient *)arg; 264 265 if (c->state != QJACK_STATE_RUNNING) { 266 return 0; 267 } 268 269 /* get the buffers for the ports */ 270 float *buffers[c->nchannels]; 271 for (int i = 0; i < c->nchannels; ++i) { 272 buffers[i] = jack_port_get_buffer(c->port[i], nframes); 273 } 274 275 if (c->out) { 276 if (likely(c->enabled)) { 277 qjack_buffer_read_l(&c->fifo, buffers, nframes); 278 } else { 279 for (int i = 0; i < c->nchannels; ++i) { 280 memset(buffers[i], 0, nframes * sizeof(float)); 281 } 282 } 283 } else { 284 if (likely(c->enabled)) { 285 qjack_buffer_write_l(&c->fifo, buffers, nframes); 286 } 287 } 288 289 return 0; 290} 291 292static void qjack_port_registration(jack_port_id_t port, int reg, void *arg) 293{ 294 if (reg) { 295 QJackClient *c = (QJackClient *)arg; 296 c->connect_ports = true; 297 } 298} 299 300static int qjack_xrun(void *arg) 301{ 302 QJackClient *c = (QJackClient *)arg; 303 if (c->state != QJACK_STATE_RUNNING) { 304 return 0; 305 } 306 307 qjack_buffer_clear(&c->fifo); 308 return 0; 309} 310 311static void qjack_shutdown_bh(void *opaque) 312{ 313 QJackClient *c = (QJackClient *)opaque; 314 qjack_client_fini(c); 315} 316 317static void qjack_shutdown(void *arg) 318{ 319 QJackClient *c = (QJackClient *)arg; 320 c->state = QJACK_STATE_SHUTDOWN; 321 qemu_bh_schedule(c->shutdown_bh); 322} 323 324static void qjack_client_recover(QJackClient *c) 325{ 326 if (c->state != QJACK_STATE_DISCONNECTED) { 327 return; 328 } 329 330 /* packets is used simply to throttle this */ 331 if (c->packets % 100 == 0) { 332 333 /* if enabled then attempt to recover */ 334 if (c->enabled) { 335 dolog("attempting to reconnect to server\n"); 336 qjack_client_init(c); 337 } 338 } 339} 340 341static size_t qjack_write(HWVoiceOut *hw, void *buf, size_t len) 342{ 343 QJackOut *jo = (QJackOut *)hw; 344 ++jo->c.packets; 345 346 if (jo->c.state != QJACK_STATE_RUNNING) { 347 qjack_client_recover(&jo->c); 348 return len; 349 } 350 351 qjack_client_connect_ports(&jo->c); 352 return qjack_buffer_write(&jo->c.fifo, buf, len); 353} 354 355static size_t qjack_read(HWVoiceIn *hw, void *buf, size_t len) 356{ 357 QJackIn *ji = (QJackIn *)hw; 358 ++ji->c.packets; 359 360 if (ji->c.state != QJACK_STATE_RUNNING) { 361 qjack_client_recover(&ji->c); 362 return len; 363 } 364 365 qjack_client_connect_ports(&ji->c); 366 return qjack_buffer_read(&ji->c.fifo, buf, len); 367} 368 369static void qjack_client_connect_ports(QJackClient *c) 370{ 371 if (!c->connect_ports || !c->opt->connect_ports) { 372 return; 373 } 374 375 c->connect_ports = false; 376 const char **ports; 377 ports = jack_get_ports(c->client, c->opt->connect_ports, NULL, 378 c->out ? JackPortIsInput : JackPortIsOutput); 379 380 if (!ports) { 381 return; 382 } 383 384 for (int i = 0; i < c->nchannels && ports[i]; ++i) { 385 const char *p = jack_port_name(c->port[i]); 386 if (jack_port_connected_to(c->port[i], ports[i])) { 387 continue; 388 } 389 390 if (c->out) { 391 dolog("connect %s -> %s\n", p, ports[i]); 392 jack_connect(c->client, p, ports[i]); 393 } else { 394 dolog("connect %s -> %s\n", ports[i], p); 395 jack_connect(c->client, ports[i], p); 396 } 397 } 398} 399 400static int qjack_client_init(QJackClient *c) 401{ 402 jack_status_t status; 403 char client_name[jack_client_name_size()]; 404 jack_options_t options = JackNullOption; 405 406 if (c->state == QJACK_STATE_RUNNING) { 407 return 0; 408 } 409 410 c->connect_ports = true; 411 412 snprintf(client_name, sizeof(client_name), "%s-%s", 413 c->out ? "out" : "in", 414 c->opt->client_name ? c->opt->client_name : audio_application_name()); 415 416 if (c->opt->exact_name) { 417 options |= JackUseExactName; 418 } 419 420 if (!c->opt->start_server) { 421 options |= JackNoStartServer; 422 } 423 424 if (c->opt->server_name) { 425 options |= JackServerName; 426 } 427 428 c->client = jack_client_open(client_name, options, &status, 429 c->opt->server_name); 430 431 if (c->client == NULL) { 432 dolog("jack_client_open failed: status = 0x%2.0x\n", status); 433 if (status & JackServerFailed) { 434 dolog("unable to connect to JACK server\n"); 435 } 436 return -1; 437 } 438 439 c->freq = jack_get_sample_rate(c->client); 440 441 if (status & JackServerStarted) { 442 dolog("JACK server started\n"); 443 } 444 445 if (status & JackNameNotUnique) { 446 dolog("JACK unique name assigned %s\n", 447 jack_get_client_name(c->client)); 448 } 449 450 jack_set_process_callback(c->client, qjack_process , c); 451 jack_set_port_registration_callback(c->client, qjack_port_registration, c); 452 jack_set_xrun_callback(c->client, qjack_xrun, c); 453 jack_on_shutdown(c->client, qjack_shutdown, c); 454 455 /* allocate and register the ports */ 456 c->port = g_malloc(sizeof(jack_port_t *) * c->nchannels); 457 for (int i = 0; i < c->nchannels; ++i) { 458 459 char port_name[16]; 460 snprintf( 461 port_name, 462 sizeof(port_name), 463 c->out ? "output %d" : "input %d", 464 i); 465 466 c->port[i] = jack_port_register( 467 c->client, 468 port_name, 469 JACK_DEFAULT_AUDIO_TYPE, 470 c->out ? JackPortIsOutput : JackPortIsInput, 471 0); 472 } 473 474 /* activate the session */ 475 jack_activate(c->client); 476 c->buffersize = jack_get_buffer_size(c->client); 477 478 /* 479 * ensure the buffersize is no smaller then 512 samples, some (all?) qemu 480 * virtual devices do not work correctly otherwise 481 */ 482 if (c->buffersize < 512) { 483 c->buffersize = 512; 484 } 485 486 /* create a 2 period buffer */ 487 qjack_buffer_create(&c->fifo, c->nchannels, c->buffersize * 2); 488 489 qjack_client_connect_ports(c); 490 c->state = QJACK_STATE_RUNNING; 491 return 0; 492} 493 494static int qjack_init_out(HWVoiceOut *hw, struct audsettings *as, 495 void *drv_opaque) 496{ 497 QJackOut *jo = (QJackOut *)hw; 498 Audiodev *dev = (Audiodev *)drv_opaque; 499 500 jo->c.out = true; 501 jo->c.enabled = false; 502 jo->c.nchannels = as->nchannels; 503 jo->c.opt = dev->u.jack.out; 504 505 jo->c.shutdown_bh = qemu_bh_new(qjack_shutdown_bh, &jo->c); 506 507 int ret = qjack_client_init(&jo->c); 508 if (ret != 0) { 509 qemu_bh_delete(jo->c.shutdown_bh); 510 return ret; 511 } 512 513 /* report the buffer size to qemu */ 514 hw->samples = jo->c.buffersize; 515 516 /* report the audio format we support */ 517 struct audsettings os = { 518 .freq = jo->c.freq, 519 .nchannels = jo->c.nchannels, 520 .fmt = AUDIO_FORMAT_F32, 521 .endianness = 0 522 }; 523 audio_pcm_init_info(&hw->info, &os); 524 525 dolog("JACK output configured for %dHz (%d samples)\n", 526 jo->c.freq, jo->c.buffersize); 527 528 return 0; 529} 530 531static int qjack_init_in(HWVoiceIn *hw, struct audsettings *as, 532 void *drv_opaque) 533{ 534 QJackIn *ji = (QJackIn *)hw; 535 Audiodev *dev = (Audiodev *)drv_opaque; 536 537 ji->c.out = false; 538 ji->c.enabled = false; 539 ji->c.nchannels = as->nchannels; 540 ji->c.opt = dev->u.jack.in; 541 542 ji->c.shutdown_bh = qemu_bh_new(qjack_shutdown_bh, &ji->c); 543 544 int ret = qjack_client_init(&ji->c); 545 if (ret != 0) { 546 qemu_bh_delete(ji->c.shutdown_bh); 547 return ret; 548 } 549 550 /* report the buffer size to qemu */ 551 hw->samples = ji->c.buffersize; 552 553 /* report the audio format we support */ 554 struct audsettings is = { 555 .freq = ji->c.freq, 556 .nchannels = ji->c.nchannels, 557 .fmt = AUDIO_FORMAT_F32, 558 .endianness = 0 559 }; 560 audio_pcm_init_info(&hw->info, &is); 561 562 dolog("JACK input configured for %dHz (%d samples)\n", 563 ji->c.freq, ji->c.buffersize); 564 565 return 0; 566} 567 568static void qjack_client_fini_locked(QJackClient *c) 569{ 570 switch (c->state) { 571 case QJACK_STATE_RUNNING: 572 jack_deactivate(c->client); 573 /* fallthrough */ 574 575 case QJACK_STATE_SHUTDOWN: 576 jack_client_close(c->client); 577 c->client = NULL; 578 579 qjack_buffer_free(&c->fifo); 580 g_free(c->port); 581 582 c->state = QJACK_STATE_DISCONNECTED; 583 /* fallthrough */ 584 585 case QJACK_STATE_DISCONNECTED: 586 break; 587 } 588} 589 590static void qjack_client_fini(QJackClient *c) 591{ 592 qemu_mutex_lock(&qjack_shutdown_lock); 593 qjack_client_fini_locked(c); 594 qemu_mutex_unlock(&qjack_shutdown_lock); 595} 596 597static void qjack_fini_out(HWVoiceOut *hw) 598{ 599 QJackOut *jo = (QJackOut *)hw; 600 qjack_client_fini(&jo->c); 601 602 qemu_bh_delete(jo->c.shutdown_bh); 603} 604 605static void qjack_fini_in(HWVoiceIn *hw) 606{ 607 QJackIn *ji = (QJackIn *)hw; 608 qjack_client_fini(&ji->c); 609 610 qemu_bh_delete(ji->c.shutdown_bh); 611} 612 613static void qjack_enable_out(HWVoiceOut *hw, bool enable) 614{ 615 QJackOut *jo = (QJackOut *)hw; 616 jo->c.enabled = enable; 617} 618 619static void qjack_enable_in(HWVoiceIn *hw, bool enable) 620{ 621 QJackIn *ji = (QJackIn *)hw; 622 ji->c.enabled = enable; 623} 624 625static int qjack_thread_creator(jack_native_thread_t *thread, 626 const pthread_attr_t *attr, void *(*function)(void *), void *arg) 627{ 628 int ret = pthread_create(thread, attr, function, arg); 629 if (ret != 0) { 630 return ret; 631 } 632 633 /* set the name of the thread */ 634 pthread_setname_np(*thread, "jack-client"); 635 636 return ret; 637} 638 639static void *qjack_init(Audiodev *dev) 640{ 641 assert(dev->driver == AUDIODEV_DRIVER_JACK); 642 return dev; 643} 644 645static void qjack_fini(void *opaque) 646{ 647} 648 649static struct audio_pcm_ops jack_pcm_ops = { 650 .init_out = qjack_init_out, 651 .fini_out = qjack_fini_out, 652 .write = qjack_write, 653 .run_buffer_out = audio_generic_run_buffer_out, 654 .enable_out = qjack_enable_out, 655 656 .init_in = qjack_init_in, 657 .fini_in = qjack_fini_in, 658 .read = qjack_read, 659 .run_buffer_in = audio_generic_run_buffer_in, 660 .enable_in = qjack_enable_in 661}; 662 663static struct audio_driver jack_driver = { 664 .name = "jack", 665 .descr = "JACK Audio Connection Kit Client", 666 .init = qjack_init, 667 .fini = qjack_fini, 668 .pcm_ops = &jack_pcm_ops, 669 .can_be_default = 1, 670 .max_voices_out = INT_MAX, 671 .max_voices_in = INT_MAX, 672 .voice_size_out = sizeof(QJackOut), 673 .voice_size_in = sizeof(QJackIn) 674}; 675 676static void qjack_error(const char *msg) 677{ 678 dolog("E: %s\n", msg); 679} 680 681static void qjack_info(const char *msg) 682{ 683 dolog("I: %s\n", msg); 684} 685 686static void register_audio_jack(void) 687{ 688 qemu_mutex_init(&qjack_shutdown_lock); 689 audio_driver_register(&jack_driver); 690 jack_set_thread_creator(qjack_thread_creator); 691 jack_set_error_function(qjack_error); 692 jack_set_info_function(qjack_info); 693} 694type_init(register_audio_jack);