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