/[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.3 by bellard, Fri Nov 11 00:03:36 2005 UTC revision 1.4 by bellard, Sun Nov 20 16:24:34 2005 UTC
# Line 23  Line 23 
23   */   */
24    
25  #ifdef DAC  #ifdef DAC
26    #define NAME "playback"
27    #define HWBUF hw->mix_buf
28  #define TYPE out  #define TYPE out
29  #define HW glue (HWVoice, Out)  #define HW HWVoiceOut
30  #define SW glue (SWVoice, Out)  #define SW SWVoiceOut
31  #else  #else
32    #define NAME "capture"
33  #define TYPE in  #define TYPE in
34  #define HW glue (HWVoice, In)  #define HW HWVoiceIn
35  #define SW glue (SWVoice, In)  #define SW SWVoiceIn
36    #define HWBUF hw->conv_buf
37  #endif  #endif
38    
39  static int glue (audio_pcm_hw_init_, TYPE) (  static void glue (audio_init_nb_voices_, TYPE) (
40      HW *hw,      AudioState *s,
41      audsettings_t *as      struct audio_driver *drv
42      )      )
43  {  {
44      glue (audio_pcm_hw_free_resources_, TYPE) (hw);      int max_voices = glue (drv->max_voices_, TYPE);
45        int voice_size = glue (drv->voice_size_, TYPE);
46    
47      if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {      if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
48          return -1;          if (!max_voices) {
49    #ifdef DAC
50                dolog ("Driver `%s' does not support " NAME "\n", drv->name);
51    #endif
52            }
53            else {
54                dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
55                       drv->name,
56                       glue (s->nb_hw_voices_, TYPE),
57                       max_voices);
58            }
59            glue (s->nb_hw_voices_, TYPE) = max_voices;
60      }      }
61    
62      if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {      if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
63          dolog ("hw->samples=%d\n", hw->samples);          dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
64                   drv->name, max_voices);
65            glue (s->nb_hw_voices_, TYPE) = 0;
66        }
67    
68        if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
69            dolog ("drv=`%s' voice_size=%d max_voices=0\n",
70                   drv->name, voice_size);
71        }
72    }
73    
74    static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
75    {
76        if (HWBUF) {
77            qemu_free (HWBUF);
78        }
79    
80        HWBUF = NULL;
81    }
82    
83    static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
84    {
85        HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
86        if (!HWBUF) {
87            dolog ("Could not allocate " NAME " buffer (%d samples)\n",
88                   hw->samples);
89          return -1;          return -1;
90      }      }
91    
92      LIST_INIT (&hw->sw_head);      return 0;
93    }
94    
95    static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
96    {
97        if (sw->buf) {
98            qemu_free (sw->buf);
99        }
100    
101        if (sw->rate) {
102            st_rate_stop (sw->rate);
103        }
104    
105        sw->buf = NULL;
106        sw->rate = NULL;
107    }
108    
109    static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
110    {
111        int samples;
112    
113  #ifdef DAC  #ifdef DAC
114      hw->clip =      samples = sw->hw->samples;
         mixeng_clip  
115  #else  #else
116      hw->conv =      samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
         mixeng_conv  
117  #endif  #endif
         [hw->info.nchannels == 2]  
         [hw->info.sign]  
         [hw->info.swap_endian]  
         [hw->info.bits == 16];  
118    
119      if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {      sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
120          glue (hw->pcm_ops->fini_, TYPE) (hw);      if (!sw->buf) {
121            dolog ("Could not allocate buffer for `%s' (%d samples)\n",
122                   SW_NAME (sw), samples);
123          return -1;          return -1;
124      }      }
125    
126    #ifdef DAC
127        sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
128    #else
129        sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
130    #endif
131        if (!sw->rate) {
132            qemu_free (sw->buf);
133            sw->buf = NULL;
134            return -1;
135        }
136      return 0;      return 0;
137  }  }
138    
139    static int glue (audio_pcm_sw_init_, TYPE) (
140        SW *sw,
141        HW *hw,
142        const char *name,
143        audsettings_t *as,
144        int endian
145        )
146    {
147        int err;
148    
149        audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (endian));
150        sw->hw = hw;
151        sw->active = 0;
152    #ifdef DAC
153        sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
154        sw->total_hw_samples_mixed = 0;
155        sw->empty = 1;
156    #else
157        sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
158    #endif
159    
160    #ifdef DAC
161        sw->conv = mixeng_conv
162    #else
163        sw->clip = mixeng_clip
164    #endif
165            [sw->info.nchannels == 2]
166            [sw->info.sign]
167            [sw->info.swap_endian]
168            [sw->info.bits == 16];
169    
170        sw->name = qemu_strdup (name);
171        err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
172        if (err) {
173            qemu_free (sw->name);
174            sw->name = NULL;
175        }
176        return err;
177    }
178    
179  static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)  static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
180  {  {
181      glue (audio_pcm_sw_free_resources_, TYPE) (sw);      glue (audio_pcm_sw_free_resources_, TYPE) (sw);
# Line 117  static HW *glue (audio_pcm_hw_find_any_e Line 224  static HW *glue (audio_pcm_hw_find_any_e
224      return NULL;      return NULL;
225  }  }
226    
 static HW *glue (audio_pcm_hw_find_any_passive_, TYPE) (AudioState *s)  
 {  
     if (glue (s->nb_hw_voices_, TYPE)) {  
         struct audio_driver *drv = s->drv;  
   
         if (audio_bug (AUDIO_FUNC, !drv)) {  
             dolog ("No host audio driver\n");  
             return NULL;  
         }  
   
         HW *hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));  
         if (!hw) {  
             dolog ("Can not allocate voice `%s' size %d\n",  
                    drv->name, glue (drv->voice_size_, TYPE));  
             return NULL;  
         }  
   
         LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);  
         glue (s->nb_hw_voices_, TYPE) -= 1;  
         return hw;  
     }  
   
     return NULL;  
 }  
   
227  static HW *glue (audio_pcm_hw_find_specific_, TYPE) (  static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
228      AudioState *s,      AudioState *s,
229      HW *hw,      HW *hw,
# Line 159  static HW *glue (audio_pcm_hw_find_speci Line 241  static HW *glue (audio_pcm_hw_find_speci
241  static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)  static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
242  {  {
243      HW *hw;      HW *hw;
244        struct audio_driver *drv = s->drv;
245    
246      hw = glue (audio_pcm_hw_find_any_passive_, TYPE) (s);      if (!glue (s->nb_hw_voices_, TYPE)) {
247      if (hw) {          return NULL;
248          hw->pcm_ops = s->drv->pcm_ops;      }
         if (!hw->pcm_ops) {  
             return NULL;  
         }  
249    
250          if (glue (audio_pcm_hw_init_, TYPE) (hw, as)) {      if (audio_bug (AUDIO_FUNC, !drv)) {
251              glue (audio_pcm_hw_gc_, TYPE) (s, &hw);          dolog ("No host audio driver\n");
252              return NULL;          return NULL;
253          }      }
254          else {  
255              return hw;      if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
256          }          dolog ("Host audio driver without pcm_ops\n");
257            return NULL;
258      }      }
259    
260        hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
261        if (!hw) {
262            dolog ("Can not allocate voice `%s' size %d\n",
263                   drv->name, glue (drv->voice_size_, TYPE));
264            return NULL;
265        }
266    
267        hw->pcm_ops = drv->pcm_ops;
268        LIST_INIT (&hw->sw_head);
269    
270        if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
271            goto err0;
272        }
273    
274        if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
275            dolog ("hw->samples=%d\n", hw->samples);
276            goto err1;
277        }
278    
279    #ifdef DAC
280        hw->clip = mixeng_clip
281    #else
282        hw->conv = mixeng_conv
283    #endif
284            [hw->info.nchannels == 2]
285            [hw->info.sign]
286            [hw->info.swap_endian]
287            [hw->info.bits == 16];
288    
289        if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
290            goto err1;
291        }
292    
293        LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
294        glue (s->nb_hw_voices_, TYPE) -= 1;
295        return hw;
296    
297     err1:
298        glue (hw->pcm_ops->fini_, TYPE) (hw);
299     err0:
300        qemu_free (hw);
301      return NULL;      return NULL;
302  }  }
303    
# Line 206  static HW *glue (audio_pcm_hw_add_, TYPE Line 328  static HW *glue (audio_pcm_hw_add_, TYPE
328  static SW *glue (audio_pcm_create_voice_pair_, TYPE) (  static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
329      AudioState *s,      AudioState *s,
330      const char *sw_name,      const char *sw_name,
331      audsettings_t *as      audsettings_t *as,
332        int sw_endian
333      )      )
334  {  {
335      SW *sw;      SW *sw;
# Line 234  static SW *glue (audio_pcm_create_voice_ Line 357  static SW *glue (audio_pcm_create_voice_
357    
358      glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);      glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
359    
360      if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {      if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
361          goto err3;          goto err3;
362      }      }
363    
# Line 256  static void glue (audio_close_, TYPE) (A Line 379  static void glue (audio_close_, TYPE) (A
379      glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);      glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
380      qemu_free (sw);      qemu_free (sw);
381  }  }
382    
383  void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)  void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
384  {  {
385      if (sw) {      if (sw) {
# Line 275  SW *glue (AUD_open_, TYPE) ( Line 399  SW *glue (AUD_open_, TYPE) (
399      const char *name,      const char *name,
400      void *callback_opaque ,      void *callback_opaque ,
401      audio_callback_fn_t callback_fn,      audio_callback_fn_t callback_fn,
402      audsettings_t *as      audsettings_t *as,
403        int sw_endian
404      )      )
405  {  {
406      AudioState *s;      AudioState *s;
# Line 347  SW *glue (AUD_open_, TYPE) ( Line 472  SW *glue (AUD_open_, TYPE) (
472              goto fail;              goto fail;
473          }          }
474    
475          if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {          glue (audio_pcm_sw_fini_, TYPE) (sw);
476            if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
477              goto fail;              goto fail;
478          }          }
479      }      }
480      else {      else {
481          sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);          sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as, sw_endian);
482          if (!sw) {          if (!sw) {
483              dolog ("Failed to create voice `%s'\n", name);              dolog ("Failed to create voice `%s'\n", name);
484              goto fail;              return NULL;
485          }          }
486      }      }
487    
# Line 435  uint64_t glue (AUD_get_elapsed_usec_, TY Line 561  uint64_t glue (AUD_get_elapsed_usec_, TY
561  #undef TYPE  #undef TYPE
562  #undef HW  #undef HW
563  #undef SW  #undef SW
564    #undef HWBUF
565    #undef NAME

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

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