]> Git Repo - qemu.git/blob - audio/dsound_template.h
audio: remove LOG_TO_MONITOR along with default_mon
[qemu.git] / audio / dsound_template.h
1 /*
2  * QEMU DirectSound audio driver header
3  *
4  * Copyright (c) 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 #ifdef DSBTYPE_IN
25 #define NAME "capture buffer"
26 #define NAME2 "DirectSoundCapture"
27 #define TYPE in
28 #define IFACE IDirectSoundCaptureBuffer
29 #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
30 #define FIELD dsound_capture_buffer
31 #define FIELD2 dsound_capture
32 #else
33 #define NAME "playback buffer"
34 #define NAME2 "DirectSound"
35 #define TYPE out
36 #define IFACE IDirectSoundBuffer
37 #define BUFPTR LPDIRECTSOUNDBUFFER
38 #define FIELD dsound_buffer
39 #define FIELD2 dsound
40 #endif
41
42 static int glue (dsound_unlock_, TYPE) (
43     BUFPTR buf,
44     LPVOID p1,
45     LPVOID p2,
46     DWORD blen1,
47     DWORD blen2
48     )
49 {
50     HRESULT hr;
51
52     hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
53     if (FAILED (hr)) {
54         dsound_logerr (hr, "Could not unlock " NAME "\n");
55         return -1;
56     }
57
58     return 0;
59 }
60
61 static int glue (dsound_lock_, TYPE) (
62     BUFPTR buf,
63     struct audio_pcm_info *info,
64     DWORD pos,
65     DWORD len,
66     LPVOID *p1p,
67     LPVOID *p2p,
68     DWORD *blen1p,
69     DWORD *blen2p,
70     int entire,
71     dsound *s
72     )
73 {
74     HRESULT hr;
75     int i;
76     LPVOID p1 = NULL, p2 = NULL;
77     DWORD blen1 = 0, blen2 = 0;
78     DWORD flag;
79     DSoundConf *conf = &s->conf;
80
81 #ifdef DSBTYPE_IN
82     flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
83 #else
84     flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
85 #endif
86     for (i = 0; i < conf->lock_retries; ++i) {
87         hr = glue (IFACE, _Lock) (
88             buf,
89             pos,
90             len,
91             &p1,
92             &blen1,
93             &p2,
94             &blen2,
95             flag
96             );
97
98         if (FAILED (hr)) {
99 #ifndef DSBTYPE_IN
100             if (hr == DSERR_BUFFERLOST) {
101                 if (glue (dsound_restore_, TYPE) (buf, s)) {
102                     dsound_logerr (hr, "Could not lock " NAME "\n");
103                     goto fail;
104                 }
105                 continue;
106             }
107 #endif
108             dsound_logerr (hr, "Could not lock " NAME "\n");
109             goto fail;
110         }
111
112         break;
113     }
114
115     if (i == conf->lock_retries) {
116         dolog ("%d attempts to lock " NAME " failed\n", i);
117         goto fail;
118     }
119
120     if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
121         dolog ("DirectSound returned misaligned buffer %ld %ld\n",
122                blen1, blen2);
123         glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
124         goto fail;
125     }
126
127     if (!p1 && blen1) {
128         dolog ("warning: !p1 && blen1=%ld\n", blen1);
129         blen1 = 0;
130     }
131
132     if (!p2 && blen2) {
133         dolog ("warning: !p2 && blen2=%ld\n", blen2);
134         blen2 = 0;
135     }
136
137     *p1p = p1;
138     *p2p = p2;
139     *blen1p = blen1;
140     *blen2p = blen2;
141     return 0;
142
143  fail:
144     *p1p = NULL - 1;
145     *p2p = NULL - 1;
146     *blen1p = -1;
147     *blen2p = -1;
148     return -1;
149 }
150
151 #ifdef DSBTYPE_IN
152 static void dsound_fini_in (HWVoiceIn *hw)
153 #else
154 static void dsound_fini_out (HWVoiceOut *hw)
155 #endif
156 {
157     HRESULT hr;
158 #ifdef DSBTYPE_IN
159     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
160 #else
161     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
162 #endif
163
164     if (ds->FIELD) {
165         hr = glue (IFACE, _Stop) (ds->FIELD);
166         if (FAILED (hr)) {
167             dsound_logerr (hr, "Could not stop " NAME "\n");
168         }
169
170         hr = glue (IFACE, _Release) (ds->FIELD);
171         if (FAILED (hr)) {
172             dsound_logerr (hr, "Could not release " NAME "\n");
173         }
174         ds->FIELD = NULL;
175     }
176 }
177
178 #ifdef DSBTYPE_IN
179 static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
180                           void *drv_opaque)
181 #else
182 static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
183                            void *drv_opaque)
184 #endif
185 {
186     int err;
187     HRESULT hr;
188     dsound *s = drv_opaque;
189     WAVEFORMATEX wfx;
190     struct audsettings obt_as;
191     DSoundConf *conf = &s->conf;
192 #ifdef DSBTYPE_IN
193     const char *typ = "ADC";
194     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
195     DSCBUFFERDESC bd;
196     DSCBCAPS bc;
197 #else
198     const char *typ = "DAC";
199     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
200     DSBUFFERDESC bd;
201     DSBCAPS bc;
202 #endif
203
204     if (!s->FIELD2) {
205         dolog ("Attempt to initialize voice without " NAME2 " object\n");
206         return -1;
207     }
208
209     err = waveformat_from_audio_settings (&wfx, as);
210     if (err) {
211         return -1;
212     }
213
214     memset (&bd, 0, sizeof (bd));
215     bd.dwSize = sizeof (bd);
216     bd.lpwfxFormat = &wfx;
217 #ifdef DSBTYPE_IN
218     bd.dwBufferBytes = conf->bufsize_in;
219     hr = IDirectSoundCapture_CreateCaptureBuffer (
220         s->dsound_capture,
221         &bd,
222         &ds->dsound_capture_buffer,
223         NULL
224         );
225 #else
226     bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
227     bd.dwBufferBytes = conf->bufsize_out;
228     hr = IDirectSound_CreateSoundBuffer (
229         s->dsound,
230         &bd,
231         &ds->dsound_buffer,
232         NULL
233         );
234 #endif
235
236     if (FAILED (hr)) {
237         dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
238         return -1;
239     }
240
241     hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
242     if (FAILED (hr)) {
243         dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
244         goto fail0;
245     }
246
247 #ifdef DEBUG_DSOUND
248     dolog (NAME "\n");
249     print_wave_format (&wfx);
250 #endif
251
252     memset (&bc, 0, sizeof (bc));
253     bc.dwSize = sizeof (bc);
254
255     hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
256     if (FAILED (hr)) {
257         dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
258         goto fail0;
259     }
260
261     err = waveformat_to_audio_settings (&wfx, &obt_as);
262     if (err) {
263         goto fail0;
264     }
265
266     ds->first_time = 1;
267     obt_as.endianness = 0;
268     audio_pcm_init_info (&hw->info, &obt_as);
269
270     if (bc.dwBufferBytes & hw->info.align) {
271         dolog (
272             "GetCaps returned misaligned buffer size %ld, alignment %d\n",
273             bc.dwBufferBytes, hw->info.align + 1
274             );
275     }
276     hw->samples = bc.dwBufferBytes >> hw->info.shift;
277     ds->s = s;
278
279 #ifdef DEBUG_DSOUND
280     dolog ("caps %ld, desc %ld\n",
281            bc.dwBufferBytes, bd.dwBufferBytes);
282
283     dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
284            hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
285 #endif
286     return 0;
287
288  fail0:
289     glue (dsound_fini_, TYPE) (hw);
290     return -1;
291 }
292
293 #undef NAME
294 #undef NAME2
295 #undef TYPE
296 #undef IFACE
297 #undef BUFPTR
298 #undef FIELD
299 #undef FIELD2
This page took 0.043835 seconds and 4 git commands to generate.