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"
26 #define NAME2 "DirectSoundCapture"
28 #define IFACE IDirectSoundCaptureBuffer
29 #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
30 #define FIELD dsound_capture_buffer
31 #define FIELD2 dsound_capture
32 #define HWVOICE HWVoiceIn
33 #define DSOUNDVOICE DSoundVoiceIn
35 #define NAME "playback buffer"
36 #define NAME2 "DirectSound"
38 #define IFACE IDirectSoundBuffer
39 #define BUFPTR LPDIRECTSOUNDBUFFER
40 #define FIELD dsound_buffer
42 #define HWVOICE HWVoiceOut
43 #define DSOUNDVOICE DSoundVoiceOut
46 static int glue (dsound_unlock_, TYPE) (
56 hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
58 dsound_logerr (hr, "Could not unlock " NAME "\n");
65 static int glue (dsound_lock_, TYPE) (
67 struct audio_pcm_info *info,
82 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
84 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
86 hr = glue(IFACE, _Lock)(buf, pos, len, p1p, blen1p, p2p, blen2p, flag);
90 if (hr == DSERR_BUFFERLOST) {
91 if (glue (dsound_restore_, TYPE) (buf, s)) {
92 dsound_logerr (hr, "Could not lock " NAME "\n");
97 dsound_logerr (hr, "Could not lock " NAME "\n");
101 if ((p1p && *p1p && (*blen1p % info->bytes_per_frame)) ||
102 (p2p && *p2p && (*blen2p % info->bytes_per_frame))) {
103 dolog("DirectSound returned misaligned buffer %ld %ld\n",
105 glue(dsound_unlock_, TYPE)(buf, *p1p, p2p ? *p2p : NULL, *blen1p,
106 blen2p ? *blen2p : 0);
110 if (p1p && !*p1p && *blen1p) {
111 dolog("warning: !p1 && blen1=%ld\n", *blen1p);
115 if (p2p && !*p2p && *blen2p) {
116 dolog("warning: !p2 && blen2=%ld\n", *blen2p);
133 static void dsound_fini_in (HWVoiceIn *hw)
135 static void dsound_fini_out (HWVoiceOut *hw)
140 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
142 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
146 hr = glue (IFACE, _Stop) (ds->FIELD);
148 dsound_logerr (hr, "Could not stop " NAME "\n");
151 hr = glue (IFACE, _Release) (ds->FIELD);
153 dsound_logerr (hr, "Could not release " NAME "\n");
160 static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
163 static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
169 dsound *s = drv_opaque;
171 struct audsettings obt_as;
173 const char *typ = "ADC";
174 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
177 AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
179 const char *typ = "DAC";
180 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
183 AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
187 dolog ("Attempt to initialize voice without " NAME2 " object\n");
191 err = waveformat_from_audio_settings (&wfx, as);
196 memset (&bd, 0, sizeof (bd));
197 bd.dwSize = sizeof (bd);
198 bd.lpwfxFormat = &wfx;
199 bd.dwBufferBytes = audio_buffer_bytes(pdo, as, 92880);
201 hr = IDirectSoundCapture_CreateCaptureBuffer (
204 &ds->dsound_capture_buffer,
208 bd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
209 hr = IDirectSound_CreateSoundBuffer (
218 dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
222 hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
224 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
230 print_wave_format (&wfx);
233 memset (&bc, 0, sizeof (bc));
234 bc.dwSize = sizeof (bc);
236 hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
238 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
242 err = waveformat_to_audio_settings (&wfx, &obt_as);
247 ds->first_time = true;
248 obt_as.endianness = 0;
249 audio_pcm_init_info (&hw->info, &obt_as);
251 if (bc.dwBufferBytes % hw->info.bytes_per_frame) {
253 "GetCaps returned misaligned buffer size %ld, alignment %d\n",
254 bc.dwBufferBytes, hw->info.bytes_per_frame
257 hw->size_emul = bc.dwBufferBytes;
258 hw->samples = bc.dwBufferBytes / hw->info.bytes_per_frame;
262 dolog ("caps %ld, desc %ld\n",
263 bc.dwBufferBytes, bd.dwBufferBytes);
268 glue (dsound_fini_, TYPE) (hw);