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