Replace tabs by 8 spaces. No code change, by Herve Poussineau.
[qemu/dscho.git] / audio / dsound_template.h
blob0896b04a03d89936af2060281e50d92c6f53f3f8
1 /*
2 * QEMU DirectSound audio driver header
4 * Copyright (c) 2005 Vassili Karpov (malc)
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #ifdef DSBTYPE_IN
25 #define NAME "capture buffer"
26 #define TYPE in
27 #define IFACE IDirectSoundCaptureBuffer
28 #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
29 #define FIELD dsound_capture_buffer
30 #else
31 #define NAME "playback buffer"
32 #define TYPE out
33 #define IFACE IDirectSoundBuffer
34 #define BUFPTR LPDIRECTSOUNDBUFFER
35 #define FIELD dsound_buffer
36 #endif
38 static int glue (dsound_unlock_, TYPE) (
39 BUFPTR buf,
40 LPVOID p1,
41 LPVOID p2,
42 DWORD blen1,
43 DWORD blen2
46 HRESULT hr;
48 hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
49 if (FAILED (hr)) {
50 dsound_logerr (hr, "Could not unlock " NAME "\n");
51 return -1;
54 return 0;
57 static int glue (dsound_lock_, TYPE) (
58 BUFPTR buf,
59 struct audio_pcm_info *info,
60 DWORD pos,
61 DWORD len,
62 LPVOID *p1p,
63 LPVOID *p2p,
64 DWORD *blen1p,
65 DWORD *blen2p,
66 int entire
69 HRESULT hr;
70 int i;
71 LPVOID p1 = NULL, p2 = NULL;
72 DWORD blen1 = 0, blen2 = 0;
73 DWORD flag;
75 #ifdef DSBTYPE_IN
76 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
77 #else
78 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
79 #endif
80 for (i = 0; i < conf.lock_retries; ++i) {
81 hr = glue (IFACE, _Lock) (
82 buf,
83 pos,
84 len,
85 &p1,
86 &blen1,
87 &p2,
88 &blen2,
89 flag
92 if (FAILED (hr)) {
93 #ifndef DSBTYPE_IN
94 if (hr == DSERR_BUFFERLOST) {
95 if (glue (dsound_restore_, TYPE) (buf)) {
96 dsound_logerr (hr, "Could not lock " NAME "\n");
97 goto fail;
99 continue;
101 #endif
102 dsound_logerr (hr, "Could not lock " NAME "\n");
103 goto fail;
106 break;
109 if (i == conf.lock_retries) {
110 dolog ("%d attempts to lock " NAME " failed\n", i);
111 goto fail;
114 if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
115 dolog ("DirectSound returned misaligned buffer %ld %ld\n",
116 blen1, blen2);
117 glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
118 goto fail;
121 if (!p1 && blen1) {
122 dolog ("warning: !p1 && blen1=%ld\n", blen1);
123 blen1 = 0;
126 if (!p2 && blen2) {
127 dolog ("warning: !p2 && blen2=%ld\n", blen2);
128 blen2 = 0;
131 *p1p = p1;
132 *p2p = p2;
133 *blen1p = blen1;
134 *blen2p = blen2;
135 return 0;
137 fail:
138 *p1p = NULL - 1;
139 *p2p = NULL - 1;
140 *blen1p = -1;
141 *blen2p = -1;
142 return -1;
145 #ifdef DSBTYPE_IN
146 static void dsound_fini_in (HWVoiceIn *hw)
147 #else
148 static void dsound_fini_out (HWVoiceOut *hw)
149 #endif
151 HRESULT hr;
152 #ifdef DSBTYPE_IN
153 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
154 #else
155 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
156 #endif
158 if (ds->FIELD) {
159 hr = glue (IFACE, _Stop) (ds->FIELD);
160 if (FAILED (hr)) {
161 dsound_logerr (hr, "Could not stop " NAME "\n");
164 hr = glue (IFACE, _Release) (ds->FIELD);
165 if (FAILED (hr)) {
166 dsound_logerr (hr, "Could not release " NAME "\n");
168 ds->FIELD = NULL;
172 #ifdef DSBTYPE_IN
173 static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
174 #else
175 static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
176 #endif
178 int err;
179 HRESULT hr;
180 dsound *s = &glob_dsound;
181 WAVEFORMATEX wfx;
182 audsettings_t obt_as;
183 #ifdef DSBTYPE_IN
184 const char *typ = "ADC";
185 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
186 DSCBUFFERDESC bd;
187 DSCBCAPS bc;
188 #else
189 const char *typ = "DAC";
190 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
191 DSBUFFERDESC bd;
192 DSBCAPS bc;
193 #endif
195 err = waveformat_from_audio_settings (&wfx, as);
196 if (err) {
197 return -1;
200 memset (&bd, 0, sizeof (bd));
201 bd.dwSize = sizeof (bd);
202 bd.lpwfxFormat = &wfx;
203 #ifdef DSBTYPE_IN
204 bd.dwBufferBytes = conf.bufsize_in;
205 hr = IDirectSoundCapture_CreateCaptureBuffer (
206 s->dsound_capture,
207 &bd,
208 &ds->dsound_capture_buffer,
209 NULL
211 #else
212 bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
213 bd.dwBufferBytes = conf.bufsize_out;
214 hr = IDirectSound_CreateSoundBuffer (
215 s->dsound,
216 &bd,
217 &ds->dsound_buffer,
218 NULL
220 #endif
222 if (FAILED (hr)) {
223 dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
224 return -1;
227 hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
228 if (FAILED (hr)) {
229 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
230 goto fail0;
233 #ifdef DEBUG_DSOUND
234 dolog (NAME "\n");
235 print_wave_format (&wfx);
236 #endif
238 memset (&bc, 0, sizeof (bc));
239 bc.dwSize = sizeof (bc);
241 hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
242 if (FAILED (hr)) {
243 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
244 goto fail0;
247 err = waveformat_to_audio_settings (&wfx, &obt_as);
248 if (err) {
249 goto fail0;
252 ds->first_time = 1;
253 obt_as.endianness = 0;
254 audio_pcm_init_info (&hw->info, &obt_as);
256 if (bc.dwBufferBytes & hw->info.align) {
257 dolog (
258 "GetCaps returned misaligned buffer size %ld, alignment %d\n",
259 bc.dwBufferBytes, hw->info.align + 1
262 hw->samples = bc.dwBufferBytes >> hw->info.shift;
264 #ifdef DEBUG_DSOUND
265 dolog ("caps %ld, desc %ld\n",
266 bc.dwBufferBytes, bd.dwBufferBytes);
268 dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
269 hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
270 #endif
271 return 0;
273 fail0:
274 glue (dsound_fini_, TYPE) (hw);
275 return -1;
278 #undef NAME
279 #undef TYPE
280 #undef IFACE
281 #undef BUFPTR
282 #undef FIELD