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, "Can 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;
74 for (i = 0; i < conf.lock_retries; ++i) {
75 hr = glue (IFACE, _Lock) (
85 ? DSCBLOCK_ENTIREBUFFER
87 ? DSBLOCK_ENTIREBUFFER
94 if (hr == DSERR_BUFFERLOST) {
95 if (glue (dsound_restore_, TYPE) (buf)) {
96 dsound_logerr (hr, "Can not lock " NAME "\n");
102 dsound_logerr (hr, "Can 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, "Can not stop " NAME "\n");
164 hr = glue (IFACE, _Release) (ds->FIELD);
166 dsound_logerr (hr, "Can not release " NAME "\n");
173 static int dsound_init_in (
180 static int dsound_init_out (
190 dsound *s = &glob_dsound;
192 struct full_fmt full_fmt;
194 const char *typ = "ADC";
195 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
199 const char *typ = "DAC";
200 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
205 full_fmt.freq = freq;
206 full_fmt.nchannels = nchannels;
208 err = waveformat_from_full_fmt (&wfx, &full_fmt);
213 memset (&bd, 0, sizeof (bd));
214 bd.dwSize = sizeof (bd);
215 bd.lpwfxFormat = &wfx;
217 bd.dwBufferBytes = conf.bufsize_in;
218 hr = IDirectSoundCapture_CreateCaptureBuffer (
221 &ds->dsound_capture_buffer,
225 bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
226 bd.dwBufferBytes = conf.bufsize_out;
227 hr = IDirectSound_CreateSoundBuffer (
236 dsound_logerr2 (hr, typ, "Can not create " NAME "\n");
240 hr = glue (IFACE, _GetFormat) (
247 dsound_logerr2 (hr, typ, "Can not get " NAME " format\n");
253 print_wave_format (&wfx);
256 memset (&bc, 0, sizeof (bc));
257 bc.dwSize = sizeof (bc);
259 hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
261 dsound_logerr2 (hr, typ, "Can not get " NAME " format\n");
265 err = waveformat_to_full_fmt (&wfx, &full_fmt);
271 hw->bufsize = bc.dwBufferBytes;
272 audio_pcm_init_info (
277 audio_need_to_swap_endian (0)
281 dolog ("caps %ld, desc %ld\n",
282 bc.dwBufferBytes, bd.dwBufferBytes);
284 dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
285 hw->bufsize, full_fmt.freq, full_fmt.nchannels, full_fmt.fmt);
290 glue (dsound_fini_, TYPE) (hw);