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
25 #define NAME "capture buffer"
27 #define IFACE IDirectSoundCaptureBuffer
28 #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
29 #define FIELD dsound_capture_buffer
31 #define NAME "playback buffer"
33 #define IFACE IDirectSoundBuffer
34 #define BUFPTR LPDIRECTSOUNDBUFFER
35 #define FIELD dsound_buffer
38 static int glue (dsound_unlock_
, TYPE
) (
48 hr
= glue (IFACE
, _Unlock
) (buf
, p1
, blen1
, p2
, blen2
);
50 dsound_logerr (hr
, "Could not unlock " NAME
"\n");
57 static int glue (dsound_lock_
, TYPE
) (
59 struct audio_pcm_info
*info
,
71 LPVOID p1
= NULL
, p2
= NULL
;
72 DWORD blen1
= 0, blen2
= 0;
76 flag
= entire
? DSCBLOCK_ENTIREBUFFER
: 0;
78 flag
= entire
? DSBLOCK_ENTIREBUFFER
: 0;
80 for (i
= 0; i
< conf
.lock_retries
; ++i
) {
81 hr
= glue (IFACE
, _Lock
) (
94 if (hr
== DSERR_BUFFERLOST
) {
95 if (glue (dsound_restore_
, TYPE
) (buf
)) {
96 dsound_logerr (hr
, "Could not lock " NAME
"\n");
102 dsound_logerr (hr
, "Could not lock " NAME
"\n");
109 if (i
== conf
.lock_retries
) {
110 dolog ("%d attempts to lock " NAME
" failed\n", i
);
114 if ((p1
&& (blen1
& info
->align
)) || (p2
&& (blen2
& info
->align
))) {
115 dolog ("DirectSound returned misaligned buffer %ld %ld\n",
117 glue (dsound_unlock_
, TYPE
) (buf
, p1
, p2
, blen1
, blen2
);
122 dolog ("warning: !p1 && blen1=%ld\n", blen1
);
127 dolog ("warning: !p2 && blen2=%ld\n", blen2
);
146 static void dsound_fini_in (HWVoiceIn
*hw
)
148 static void dsound_fini_out (HWVoiceOut
*hw
)
153 DSoundVoiceIn
*ds
= (DSoundVoiceIn
*) hw
;
155 DSoundVoiceOut
*ds
= (DSoundVoiceOut
*) hw
;
159 hr
= glue (IFACE
, _Stop
) (ds
->FIELD
);
161 dsound_logerr (hr
, "Could not stop " NAME
"\n");
164 hr
= glue (IFACE
, _Release
) (ds
->FIELD
);
166 dsound_logerr (hr
, "Could not release " NAME
"\n");
173 static int dsound_init_in (HWVoiceIn
*hw
, audsettings_t
*as
)
175 static int dsound_init_out (HWVoiceOut
*hw
, audsettings_t
*as
)
180 dsound
*s
= &glob_dsound
;
182 audsettings_t obt_as
;
184 const char *typ
= "ADC";
185 DSoundVoiceIn
*ds
= (DSoundVoiceIn
*) hw
;
189 const char *typ
= "DAC";
190 DSoundVoiceOut
*ds
= (DSoundVoiceOut
*) hw
;
195 err
= waveformat_from_audio_settings (&wfx
, as
);
200 memset (&bd
, 0, sizeof (bd
));
201 bd
.dwSize
= sizeof (bd
);
202 bd
.lpwfxFormat
= &wfx
;
204 bd
.dwBufferBytes
= conf
.bufsize_in
;
205 hr
= IDirectSoundCapture_CreateCaptureBuffer (
208 &ds
->dsound_capture_buffer
,
212 bd
.dwFlags
= DSBCAPS_STICKYFOCUS
| DSBCAPS_GETCURRENTPOSITION2
;
213 bd
.dwBufferBytes
= conf
.bufsize_out
;
214 hr
= IDirectSound_CreateSoundBuffer (
223 dsound_logerr2 (hr
, typ
, "Could not create " NAME
"\n");
227 hr
= glue (IFACE
, _GetFormat
) (ds
->FIELD
, &wfx
, sizeof (wfx
), NULL
);
229 dsound_logerr2 (hr
, typ
, "Could not get " NAME
" format\n");
235 print_wave_format (&wfx
);
238 memset (&bc
, 0, sizeof (bc
));
239 bc
.dwSize
= sizeof (bc
);
241 hr
= glue (IFACE
, _GetCaps
) (ds
->FIELD
, &bc
);
243 dsound_logerr2 (hr
, typ
, "Could not get " NAME
" format\n");
247 err
= waveformat_to_audio_settings (&wfx
, &obt_as
);
253 obt_as
.endianness
= 0;
254 audio_pcm_init_info (&hw
->info
, &obt_as
);
256 if (bc
.dwBufferBytes
& hw
->info
.align
) {
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
;
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
);
274 glue (dsound_fini_
, TYPE
) (hw
);