VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/dsound_template.h@ 33000

Last change on this file since 33000 was 32936, checked in by vboxsync, 14 years ago

dsound: Use global focus (instead of sticky).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
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 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
37
38static int glue (dsound_unlock_, TYPE) (
39 BUFPTR buf,
40 LPVOID p1,
41 LPVOID p2,
42 DWORD blen1,
43 DWORD blen2
44 )
45{
46 HRESULT hr;
47
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;
52 }
53
54 return 0;
55}
56
57static 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
67 )
68{
69 HRESULT hr;
70 int i;
71 LPVOID p1 = NULL, p2 = NULL;
72 DWORD blen1 = 0, blen2 = 0;
73 DWORD flag;
74
75#ifdef DSBTYPE_IN
76 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
77#else
78 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
79#endif
80
81 for (i = 0; i < conf.lock_retries; ++i) {
82 hr = glue (IFACE, _Lock) (
83 buf,
84 pos,
85 len,
86 &p1,
87 &blen1,
88 &p2,
89 &blen2,
90 flag
91 );
92
93 if (FAILED (hr)) {
94#ifndef DSBTYPE_IN
95 if (hr == DSERR_BUFFERLOST) {
96 if (glue (dsound_restore_, TYPE) (buf)) {
97 dsound_logerr (hr, "Could not lock " NAME "\n");
98 goto fail;
99 }
100 continue;
101 }
102#endif
103 dsound_logerr (hr, "Could not lock " NAME "\n");
104 goto fail;
105 }
106
107 break;
108 }
109
110 if (i == conf.lock_retries) {
111 dolog ("%d attempts to lock " NAME " failed\n", i);
112 goto fail;
113 }
114
115 if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
116 dolog ("DirectSound returned misaligned buffer %ld %ld\n",
117 blen1, blen2);
118 glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
119 goto fail;
120 }
121
122 if (!p1 && blen1) {
123 dolog ("warning: !p1 && blen1=%ld\n", blen1);
124 blen1 = 0;
125 }
126
127 if (!p2 && blen2) {
128 dolog ("warning: !p2 && blen2=%ld\n", blen2);
129 blen2 = 0;
130 }
131
132 *p1p = p1;
133 *p2p = p2;
134 *blen1p = blen1;
135 *blen2p = blen2;
136 return 0;
137
138 fail:
139 *p1p = NULL;
140 *p2p = NULL;
141 *blen1p = -1;
142 *blen2p = -1;
143 return -1;
144}
145
146#ifdef DSBTYPE_IN
147static void dsound_fini_in (HWVoiceIn *hw)
148#else
149static void dsound_fini_out (HWVoiceOut *hw)
150#endif
151{
152 HRESULT hr;
153#ifdef DSBTYPE_IN
154 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
155#else
156 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
157#endif
158
159 if (ds->FIELD) {
160 hr = glue (IFACE, _Stop) (ds->FIELD);
161 if (FAILED (hr)) {
162 dsound_logerr (hr, "Could not stop " NAME "\n");
163 }
164
165 hr = glue (IFACE, _Release) (ds->FIELD);
166 if (FAILED (hr)) {
167 dsound_logerr (hr, "Could not release " NAME "\n");
168 }
169 ds->FIELD = NULL;
170 }
171}
172
173#ifdef DSBTYPE_IN
174static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
175#else
176static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
177#endif
178{
179 int err;
180 HRESULT hr;
181 dsound *s = &glob_dsound;
182 WAVEFORMATEX wfx;
183 audsettings_t obt_as;
184#ifdef DSBTYPE_IN
185 const char *typ = "ADC";
186 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
187 DSCBUFFERDESC bd;
188 DSCBCAPS bc;
189#else
190 const char *typ = "DAC";
191 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
192 DSBUFFERDESC bd;
193 DSBCAPS bc;
194#endif
195
196 err = waveformat_from_audio_settings (&wfx, as);
197 if (err) {
198 return -1;
199 }
200
201#ifdef DSBTYPE_IN
202 if (!s->dsound_capture)
203 return -1;
204#endif
205
206 memset (&bd, 0, sizeof (bd));
207 bd.dwSize = sizeof (bd);
208 bd.lpwfxFormat = &wfx;
209#ifdef DSBTYPE_IN
210 bd.dwBufferBytes = conf.bufsize_in;
211 hr = IDirectSoundCapture_CreateCaptureBuffer (
212 s->dsound_capture,
213 &bd,
214 &ds->dsound_capture_buffer,
215 NULL
216 );
217#else
218 bd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
219 bd.dwBufferBytes = conf.bufsize_out;
220 hr = IDirectSound_CreateSoundBuffer (
221 s->dsound,
222 &bd,
223 &ds->dsound_buffer,
224 NULL
225 );
226#endif
227
228 if (FAILED (hr)) {
229 dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
230 return -1;
231 }
232
233 hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
234 if (FAILED (hr)) {
235 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
236 goto fail0;
237 }
238
239#ifdef DEBUG_DSOUND
240 dolog (NAME "\n");
241 print_wave_format (&wfx);
242#endif
243
244 memset (&bc, 0, sizeof (bc));
245 bc.dwSize = sizeof (bc);
246
247 hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
248 if (FAILED (hr)) {
249 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
250 goto fail0;
251 }
252
253 err = waveformat_to_audio_settings (&wfx, &obt_as);
254 if (err) {
255 goto fail0;
256 }
257
258 ds->first_time = 1;
259 obt_as.endianness = 0;
260 audio_pcm_init_info (&hw->info, &obt_as);
261
262 if (bc.dwBufferBytes & hw->info.align) {
263 dolog (
264 "GetCaps returned misaligned buffer size %ld, alignment %d\n",
265 bc.dwBufferBytes, hw->info.align + 1
266 );
267 }
268 hw->samples = bc.dwBufferBytes >> hw->info.shift;
269
270#ifdef DEBUG_DSOUND
271 dolog ("caps %ld, desc %ld\n",
272 bc.dwBufferBytes, bd.dwBufferBytes);
273
274 dolog ("bufsize %d, freq %d, chan %d, bits %d, sign %d\n",
275 hw->samples << hw->info.shift,
276 hw->info.freq,
277 hw->info.nchannels,
278 hw->info.bits,
279 hw->info.sign);
280#endif
281 return 0;
282
283 fail0:
284 glue (dsound_fini_, TYPE) (hw);
285 return -1;
286}
287
288#undef NAME
289#undef TYPE
290#undef IFACE
291#undef BUFPTR
292#undef FIELD
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use