xref: /openbmc/qemu/audio/audio_int.h (revision 988717b46b6424907618cb845ace9d69062703af)
1  /*
2   * QEMU Audio subsystem header
3   *
4   * Copyright (c) 2003-2005 Vassili Karpov (malc)
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  #ifndef QEMU_AUDIO_INT_H
26  #define QEMU_AUDIO_INT_H
27  
28  #ifdef CONFIG_AUDIO_COREAUDIO
29  #define FLOAT_MIXENG
30  /* #define RECIPROCAL */
31  #endif
32  #include "mixeng.h"
33  
34  struct audio_pcm_ops;
35  
36  struct audio_callback {
37      void *opaque;
38      audio_callback_fn fn;
39  };
40  
41  struct audio_pcm_info {
42      int bits;
43      bool is_signed;
44      bool is_float;
45      int freq;
46      int nchannels;
47      int bytes_per_frame;
48      int bytes_per_second;
49      int swap_endianness;
50  };
51  
52  typedef struct AudioState AudioState;
53  typedef struct SWVoiceCap SWVoiceCap;
54  
55  typedef struct STSampleBuffer {
56      size_t pos, size;
57      st_sample samples[];
58  } STSampleBuffer;
59  
60  typedef struct HWVoiceOut {
61      AudioState *s;
62      int enabled;
63      int poll_mode;
64      int pending_disable;
65      struct audio_pcm_info info;
66  
67      f_sample *clip;
68      uint64_t ts_helper;
69  
70      STSampleBuffer *mix_buf;
71      void *buf_emul;
72      size_t pos_emul, pending_emul, size_emul;
73  
74      size_t samples;
75      QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
76      QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
77      struct audio_pcm_ops *pcm_ops;
78      QLIST_ENTRY (HWVoiceOut) entries;
79  } HWVoiceOut;
80  
81  typedef struct HWVoiceIn {
82      AudioState *s;
83      int enabled;
84      int poll_mode;
85      struct audio_pcm_info info;
86  
87      t_sample *conv;
88  
89      size_t total_samples_captured;
90      uint64_t ts_helper;
91  
92      STSampleBuffer *conv_buf;
93      void *buf_emul;
94      size_t pos_emul, pending_emul, size_emul;
95  
96      size_t samples;
97      QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
98      struct audio_pcm_ops *pcm_ops;
99      QLIST_ENTRY (HWVoiceIn) entries;
100  } HWVoiceIn;
101  
102  struct SWVoiceOut {
103      QEMUSoundCard *card;
104      AudioState *s;
105      struct audio_pcm_info info;
106      t_sample *conv;
107      int64_t ratio;
108      struct st_sample *buf;
109      void *rate;
110      size_t total_hw_samples_mixed;
111      int active;
112      int empty;
113      HWVoiceOut *hw;
114      char *name;
115      struct mixeng_volume vol;
116      struct audio_callback callback;
117      QLIST_ENTRY (SWVoiceOut) entries;
118  };
119  
120  struct SWVoiceIn {
121      QEMUSoundCard *card;
122      AudioState *s;
123      int active;
124      struct audio_pcm_info info;
125      int64_t ratio;
126      void *rate;
127      size_t total_hw_samples_acquired;
128      struct st_sample *buf;
129      f_sample *clip;
130      HWVoiceIn *hw;
131      char *name;
132      struct mixeng_volume vol;
133      struct audio_callback callback;
134      QLIST_ENTRY (SWVoiceIn) entries;
135  };
136  
137  typedef struct audio_driver audio_driver;
138  struct audio_driver {
139      const char *name;
140      const char *descr;
141      void *(*init) (Audiodev *);
142      void (*fini) (void *);
143      struct audio_pcm_ops *pcm_ops;
144      int can_be_default;
145      int max_voices_out;
146      int max_voices_in;
147      int voice_size_out;
148      int voice_size_in;
149      QLIST_ENTRY(audio_driver) next;
150  };
151  
152  struct audio_pcm_ops {
153      int    (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque);
154      void   (*fini_out)(HWVoiceOut *hw);
155      size_t (*write)   (HWVoiceOut *hw, void *buf, size_t size);
156      void   (*run_buffer_out)(HWVoiceOut *hw);
157      /*
158       * get a buffer that after later can be passed to put_buffer_out; optional
159       * returns the buffer, and writes it's size to size (in bytes)
160       * this is unrelated to the above buffer_size_out function
161       */
162      void  *(*get_buffer_out)(HWVoiceOut *hw, size_t *size);
163      /*
164       * put back the buffer returned by get_buffer_out; optional
165       * buf must be equal the pointer returned by get_buffer_out,
166       * size may be smaller
167       */
168      size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size);
169      void   (*enable_out)(HWVoiceOut *hw, bool enable);
170      void   (*volume_out)(HWVoiceOut *hw, Volume *vol);
171  
172      int    (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque);
173      void   (*fini_in) (HWVoiceIn *hw);
174      size_t (*read)    (HWVoiceIn *hw, void *buf, size_t size);
175      void  *(*get_buffer_in)(HWVoiceIn *hw, size_t *size);
176      void   (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size);
177      void   (*enable_in)(HWVoiceIn *hw, bool enable);
178      void   (*volume_in)(HWVoiceIn *hw, Volume *vol);
179  };
180  
181  void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
182  void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
183  void audio_generic_run_buffer_out(HWVoiceOut *hw);
184  void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
185  size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size);
186  size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size);
187  size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size);
188  
189  struct capture_callback {
190      struct audio_capture_ops ops;
191      void *opaque;
192      QLIST_ENTRY (capture_callback) entries;
193  };
194  
195  struct CaptureVoiceOut {
196      HWVoiceOut hw;
197      void *buf;
198      QLIST_HEAD (cb_listhead, capture_callback) cb_head;
199      QLIST_ENTRY (CaptureVoiceOut) entries;
200  };
201  
202  struct SWVoiceCap {
203      SWVoiceOut sw;
204      CaptureVoiceOut *cap;
205      QLIST_ENTRY (SWVoiceCap) entries;
206  };
207  
208  typedef struct AudioState {
209      struct audio_driver *drv;
210      Audiodev *dev;
211      void *drv_opaque;
212  
213      QEMUTimer *ts;
214      QLIST_HEAD (card_listhead, QEMUSoundCard) card_head;
215      QLIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
216      QLIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
217      QLIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
218      int nb_hw_voices_out;
219      int nb_hw_voices_in;
220      int vm_running;
221      int64_t period_ticks;
222  
223      bool timer_running;
224      uint64_t timer_last;
225  
226      QTAILQ_ENTRY(AudioState) list;
227  } AudioState;
228  
229  extern const struct mixeng_volume nominal_volume;
230  
231  extern const char *audio_prio_list[];
232  
233  void audio_driver_register(audio_driver *drv);
234  audio_driver *audio_driver_lookup(const char *name);
235  
236  void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
237  void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
238  
239  int audio_bug (const char *funcname, int cond);
240  void *audio_calloc (const char *funcname, int nmemb, size_t size);
241  
242  void audio_run(AudioState *s, const char *msg);
243  
244  typedef struct RateCtl {
245      int64_t start_ticks;
246      int64_t bytes_sent;
247  } RateCtl;
248  
249  void audio_rate_start(RateCtl *rate);
250  size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate,
251                              size_t bytes_avail);
252  
253  static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len)
254  {
255      return (dst >= src) ? (dst - src) : (len - src + dst);
256  }
257  
258  #define dolog(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
259  
260  #ifdef DEBUG
261  #define ldebug(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
262  #else
263  #define ldebug(fmt, ...) (void)0
264  #endif
265  
266  #define AUDIO_STRINGIFY_(n) #n
267  #define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n)
268  
269  typedef struct AudiodevListEntry {
270      Audiodev *dev;
271      QSIMPLEQ_ENTRY(AudiodevListEntry) next;
272  } AudiodevListEntry;
273  
274  typedef QSIMPLEQ_HEAD(, AudiodevListEntry) AudiodevListHead;
275  AudiodevListHead audio_handle_legacy_opts(void);
276  
277  void audio_free_audiodev_list(AudiodevListHead *head);
278  
279  void audio_create_pdos(Audiodev *dev);
280  AudiodevPerDirectionOptions *audio_get_pdo_in(Audiodev *dev);
281  AudiodevPerDirectionOptions *audio_get_pdo_out(Audiodev *dev);
282  
283  #endif /* QEMU_AUDIO_INT_H */
284