/[qemu]/qemu/audio/audio_template.h
ViewVC logotype

Diff of /qemu/audio/audio_template.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by bellard, Sun Oct 30 18:58:22 2005 UTC revision 1.2 by bellard, Sat Nov 5 18:55:27 2005 UTC
# Line 32  Line 32 
32  #define SW glue (SWVoice, In)  #define SW glue (SWVoice, In)
33  #endif  #endif
34    
35    static int glue (audio_pcm_hw_init_, TYPE) (
36        HW *hw,
37        audsettings_t *as
38        )
39    {
40        glue (audio_pcm_hw_free_resources_, TYPE) (hw);
41    
42        if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
43            return -1;
44        }
45    
46        if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
47            dolog ("hw->samples=%d\n", hw->samples);
48            return -1;
49        }
50    
51        LIST_INIT (&hw->sw_head);
52    #ifdef DAC
53        hw->clip =
54            mixeng_clip
55    #else
56        hw->conv =
57            mixeng_conv
58    #endif
59            [hw->info.nchannels == 2]
60            [hw->info.sign]
61            [hw->info.swap_endian]
62            [hw->info.bits == 16];
63    
64        if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
65            glue (hw->pcm_ops->fini_, TYPE) (hw);
66            return -1;
67        }
68    
69        return 0;
70    }
71    
72  static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)  static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
73  {  {
74      glue (audio_pcm_sw_free_resources_, TYPE) (sw);      glue (audio_pcm_sw_free_resources_, TYPE) (sw);
# Line 51  static void glue (audio_pcm_hw_del_sw_, Line 88  static void glue (audio_pcm_hw_del_sw_,
88      LIST_REMOVE (sw, entries);      LIST_REMOVE (sw, entries);
89  }  }
90    
91  static void glue (audio_pcm_hw_fini_, TYPE) (HW *hw)  static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
92  {  {
93      if (hw->active) {      HW *hw = *hwp;
         glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);  
         glue (hw->pcm_ops->fini_, TYPE) (hw);  
         memset (hw, 0, glue (audio_state.drv->voice_size_, TYPE));  
     }  
 }  
94    
 static void glue (audio_pcm_hw_gc_, TYPE) (HW *hw)  
 {  
95      if (!hw->sw_head.lh_first) {      if (!hw->sw_head.lh_first) {
96          glue (audio_pcm_hw_fini_, TYPE) (hw);          LIST_REMOVE (hw, entries);
97            glue (s->nb_hw_voices_, TYPE) += 1;
98            glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
99            glue (hw->pcm_ops->fini_, TYPE) (hw);
100            qemu_free (hw);
101            *hwp = NULL;
102      }      }
103  }  }
104    
105  static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw)  static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
106  {  {
107      return hw ? hw->entries.le_next : glue (hw_head_, TYPE).lh_first;      return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
108  }  }
109    
110  static HW *glue (audio_pcm_hw_find_any_active_, TYPE) (HW *hw)  static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
111  {  {
112      while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {      while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
113          if (hw->active) {          if (hw->enabled) {
114              return hw;              return hw;
115          }          }
116      }      }
117      return NULL;      return NULL;
118  }  }
119    
120  static HW *glue (audio_pcm_hw_find_any_active_enabled_, TYPE) (HW *hw)  static HW *glue (audio_pcm_hw_find_any_passive_, TYPE) (AudioState *s)
121  {  {
122      while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {      if (glue (s->nb_hw_voices_, TYPE)) {
123          if (hw->active && hw->enabled) {          struct audio_driver *drv = s->drv;
124              return hw;  
125            if (audio_bug (AUDIO_FUNC, !drv)) {
126                dolog ("No host audio driver\n");
127                return NULL;
128          }          }
     }  
     return NULL;  
 }  
129    
130  static HW *glue (audio_pcm_hw_find_any_passive_, TYPE) (HW *hw)          HW *hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
131  {          if (!hw) {
132      while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {              dolog ("Can not allocate voice `%s' size %d\n",
133          if (!hw->active) {                     drv->name, glue (drv->voice_size_, TYPE));
             return hw;  
134          }          }
135    
136            LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
137            glue (s->nb_hw_voices_, TYPE) -= 1;
138            return hw;
139      }      }
140    
141      return NULL;      return NULL;
142  }  }
143    
144  static HW *glue (audio_pcm_hw_find_specific_, TYPE) (  static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
145        AudioState *s,
146      HW *hw,      HW *hw,
147      int freq,      audsettings_t *as
     int nchannels,  
     audfmt_e fmt  
148      )      )
149  {  {
150      while ((hw = glue (audio_pcm_hw_find_any_active_, TYPE) (hw))) {      while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
151          if (audio_pcm_info_eq (&hw->info, freq, nchannels, fmt)) {          if (audio_pcm_info_eq (&hw->info, as)) {
152              return hw;              return hw;
153          }          }
154      }      }
155      return NULL;      return NULL;
156  }  }
157    
158  static HW *glue (audio_pcm_hw_add_new_, TYPE) (  static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
     int freq,  
     int nchannels,  
     audfmt_e fmt  
     )  
159  {  {
160      HW *hw;      HW *hw;
161    
162      hw = glue (audio_pcm_hw_find_any_passive_, TYPE) (NULL);      hw = glue (audio_pcm_hw_find_any_passive_, TYPE) (s);
163      if (hw) {      if (hw) {
164          hw->pcm_ops = audio_state.drv->pcm_ops;          hw->pcm_ops = s->drv->pcm_ops;
165          if (!hw->pcm_ops) {          if (!hw->pcm_ops) {
166              return NULL;              return NULL;
167          }          }
168    
169          if (glue (audio_pcm_hw_init_, TYPE) (hw, freq, nchannels, fmt)) {          if (glue (audio_pcm_hw_init_, TYPE) (hw, as)) {
170              glue (audio_pcm_hw_gc_, TYPE) (hw);              glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
171              return NULL;              return NULL;
172          }          }
173          else {          else {
# Line 144  static HW *glue (audio_pcm_hw_add_new_, Line 178  static HW *glue (audio_pcm_hw_add_new_,
178      return NULL;      return NULL;
179  }  }
180    
181  static HW *glue (audio_pcm_hw_add_, TYPE) (  static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
     int freq,  
     int nchannels,  
     audfmt_e fmt  
     )  
182  {  {
183      HW *hw;      HW *hw;
184    
185      if (glue (audio_state.greedy_, TYPE)) {      if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
186          hw = glue (audio_pcm_hw_add_new_, TYPE) (freq, nchannels, fmt);          hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
187          if (hw) {          if (hw) {
188              return hw;              return hw;
189          }          }
190      }      }
191    
192      hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, freq, nchannels, fmt);      hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
193      if (hw) {      if (hw) {
194          return hw;          return hw;
195      }      }
196    
197      hw = glue (audio_pcm_hw_add_new_, TYPE) (freq, nchannels, fmt);      hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
198      if (hw) {      if (hw) {
199          return hw;          return hw;
200      }      }
201    
202      return glue (audio_pcm_hw_find_any_active_, TYPE) (NULL);      return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
203  }  }
204    
205  static SW *glue (audio_pcm_create_voice_pair_, TYPE) (  static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
206      const char *name,      AudioState *s,
207      int freq,      const char *sw_name,
208      int nchannels,      audsettings_t *as
     audfmt_e fmt  
209      )      )
210  {  {
211      SW *sw;      SW *sw;
212      HW *hw;      HW *hw;
213      int hw_freq = freq;      audsettings_t hw_as;
     int hw_nchannels = nchannels;  
     int hw_fmt = fmt;  
214    
215      if (glue (audio_state.fixed_settings_, TYPE)) {      if (glue (conf.fixed_, TYPE).enabled) {
216          hw_freq = glue (audio_state.fixed_freq_, TYPE);          hw_as = glue (conf.fixed_, TYPE).settings;
217          hw_nchannels = glue (audio_state.fixed_channels_, TYPE);      }
218          hw_fmt = glue (audio_state.fixed_fmt_, TYPE);      else {
219            hw_as = *as;
220      }      }
221    
222      sw = qemu_mallocz (sizeof (*sw));      sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
223      if (!sw) {      if (!sw) {
224            dolog ("Could not allocate soft voice `%s' (%d bytes)\n",
225                   sw_name ? sw_name : "unknown", sizeof (*sw));
226          goto err1;          goto err1;
227      }      }
228    
229      hw = glue (audio_pcm_hw_add_, TYPE) (hw_freq, hw_nchannels, hw_fmt);      hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
230      if (!hw) {      if (!hw) {
231          goto err2;          goto err2;
232      }      }
233    
234      glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);      glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
235    
236      if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, freq, nchannels, fmt)) {      if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
237          goto err3;          goto err3;
238      }      }
239    
# Line 211  static SW *glue (audio_pcm_create_voice_ Line 241  static SW *glue (audio_pcm_create_voice_
241    
242  err3:  err3:
243      glue (audio_pcm_hw_del_sw_, TYPE) (sw);      glue (audio_pcm_hw_del_sw_, TYPE) (sw);
244      glue (audio_pcm_hw_gc_, TYPE) (hw);      glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
245  err2:  err2:
246      qemu_free (sw);      qemu_free (sw);
247  err1:  err1:
248      return NULL;      return NULL;
249  }  }
250    
251  void glue (AUD_close_, TYPE) (SW *sw)  static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
252    {
253        glue (audio_pcm_sw_fini_, TYPE) (sw);
254        glue (audio_pcm_hw_del_sw_, TYPE) (sw);
255        glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
256        qemu_free (sw);
257    }
258    void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
259  {  {
260      if (sw) {      if (sw) {
261          glue (audio_pcm_sw_fini_, TYPE) (sw);          if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
262          glue (audio_pcm_hw_del_sw_, TYPE) (sw);              dolog ("card=%p card->audio=%p\n",
263          glue (audio_pcm_hw_gc_, TYPE) (sw->hw);                     card, card ? card->audio : NULL);
264          qemu_free (sw);              return;
265            }
266    
267            glue (audio_close_, TYPE) (card->audio, sw);
268      }      }
269  }  }
270    
271  SW *glue (AUD_open_, TYPE) (  SW *glue (AUD_open_, TYPE) (
272        QEMUSoundCard *card,
273      SW *sw,      SW *sw,
274      const char *name,      const char *name,
275      void *callback_opaque ,      void *callback_opaque ,
276      audio_callback_fn_t callback_fn,      audio_callback_fn_t callback_fn,
277      int freq,      audsettings_t *as
     int nchannels,  
     audfmt_e fmt  
278      )      )
279  {  {
280        AudioState *s;
281  #ifdef DAC  #ifdef DAC
282      int live = 0;      int live = 0;
283      SW *old_sw = NULL;      SW *old_sw = NULL;
284  #endif  #endif
285    
286      if (!callback_fn) {      ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
287          dolog ("No callback specifed for voice `%s'\n", name);              name, as->freq, as->nchannels, as->fmt);
288    
289        if (audio_bug (AUDIO_FUNC,
290                       !card || !card->audio || !name || !callback_fn || !as)) {
291            dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
292                   card, card ? card->audio : NULL, name, callback_fn, as);
293          goto fail;          goto fail;
294      }      }
295    
296      if (nchannels != 1 && nchannels != 2) {      s = card->audio;
297          dolog ("Bogus channel count %d for voice `%s'\n", nchannels, name);  
298        if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
299            audio_print_settings (as);
300          goto fail;          goto fail;
301      }      }
302    
303      if (!audio_state.drv) {      if (audio_bug (AUDIO_FUNC, !s->drv)) {
304          dolog ("No audio driver defined\n");          dolog ("Can not open `%s' (no host audio driver)\n", name);
305          goto fail;          goto fail;
306      }      }
307    
308      if (sw && audio_pcm_info_eq (&sw->info, freq, nchannels, fmt)) {      if (sw && audio_pcm_info_eq (&sw->info, as)) {
309          return sw;          return sw;
310      }      }
311    
312  #ifdef DAC  #ifdef DAC
313      if (audio_state.plive && sw && (!sw->active && !sw->empty)) {      if (conf.plive && sw && (!sw->active && !sw->empty)) {
314          live = sw->total_hw_samples_mixed;          live = sw->total_hw_samples_mixed;
315    
316  #ifdef DEBUG_PLIVE  #ifdef DEBUG_PLIVE
317          dolog ("Replacing voice %s with %d live samples\n", sw->name, live);          dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
318          dolog ("Old %s freq %d, bits %d, channels %d\n",          dolog ("Old %s freq %d, bits %d, channels %d\n",
319                 sw->name, sw->info.freq, sw->info.bits, sw->info.nchannels);                 SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
320          dolog ("New %s freq %d, bits %d, channels %d\n",          dolog ("New %s freq %d, bits %d, channels %d\n",
321                 name, freq, (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,                 name,
322                   freq,
323                   (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
324                 nchannels);                 nchannels);
325  #endif  #endif
326    
# Line 283  SW *glue (AUD_open_, TYPE) ( Line 332  SW *glue (AUD_open_, TYPE) (
332      }      }
333  #endif  #endif
334    
335      if (!glue (audio_state.fixed_settings_, TYPE) && sw) {      if (!glue (conf.fixed_, TYPE).enabled && sw) {
336          glue (AUD_close_, TYPE) (sw);          glue (AUD_close_, TYPE) (card, sw);
337          sw = NULL;          sw = NULL;
338      }      }
339    
# Line 292  SW *glue (AUD_open_, TYPE) ( Line 341  SW *glue (AUD_open_, TYPE) (
341          HW *hw = sw->hw;          HW *hw = sw->hw;
342    
343          if (!hw) {          if (!hw) {
344              dolog ("Internal logic error voice %s has no hardware store\n",              dolog ("Internal logic error voice `%s' has no hardware store\n",
345                     name);                     SW_NAME (sw));
346              goto fail;              goto fail;
347          }          }
348    
349          if (glue (audio_pcm_sw_init_, TYPE) (          if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
                 sw,  
                 hw,  
                 name,  
                 freq,  
                 nchannels,  
                 fmt  
                 )) {  
350              goto fail;              goto fail;
351          }          }
352      }      }
353      else {      else {
354          sw = glue (audio_pcm_create_voice_pair_, TYPE) (          sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
             name,  
             freq,  
             nchannels,  
             fmt);  
355          if (!sw) {          if (!sw) {
356              dolog ("Failed to create voice %s\n", name);              dolog ("Failed to create voice `%s'\n", name);
357              goto fail;              goto fail;
358          }          }
359      }      }
# Line 349  SW *glue (AUD_open_, TYPE) ( Line 387  SW *glue (AUD_open_, TYPE) (
387      return sw;      return sw;
388    
389   fail:   fail:
390      glue (AUD_close_, TYPE) (sw);      glue (AUD_close_, TYPE) (card, sw);
391      return NULL;      return NULL;
392  }  }
393    
# Line 367  void glue (AUD_init_time_stamp_, TYPE) ( Line 405  void glue (AUD_init_time_stamp_, TYPE) (
405      ts->old_ts = sw->hw->ts_helper;      ts->old_ts = sw->hw->ts_helper;
406  }  }
407    
408  uint64_t glue (AUD_time_stamp_get_elapsed_usec_, TYPE) (  uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
     SW *sw,  
     QEMUAudioTimeStamp *ts  
     )  
409  {  {
410      uint64_t delta, cur_ts, old_ts;      uint64_t delta, cur_ts, old_ts;
411    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26