]> git.proxmox.com Git - mirror_qemu.git/blame - audio/dsound_template.h
hw/s390x/3270-ccw: avoid taking address of fields in packed struct
[mirror_qemu.git] / audio / dsound_template.h
CommitLineData
1d14ffa9
FB
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"
ca9cc28c 26#define NAME2 "DirectSoundCapture"
1d14ffa9
FB
27#define TYPE in
28#define IFACE IDirectSoundCaptureBuffer
29#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
30#define FIELD dsound_capture_buffer
ca9cc28c 31#define FIELD2 dsound_capture
1d14ffa9
FB
32#else
33#define NAME "playback buffer"
ca9cc28c 34#define NAME2 "DirectSound"
1d14ffa9
FB
35#define TYPE out
36#define IFACE IDirectSoundBuffer
37#define BUFPTR LPDIRECTSOUNDBUFFER
38#define FIELD dsound_buffer
ca9cc28c 39#define FIELD2 dsound
1d14ffa9
FB
40#endif
41
42static int glue (dsound_unlock_, TYPE) (
43 BUFPTR buf,
44 LPVOID p1,
45 LPVOID p2,
46 DWORD blen1,
47 DWORD blen2
48 )
49{
50 HRESULT hr;
51
52 hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
53 if (FAILED (hr)) {
c0fe3827 54 dsound_logerr (hr, "Could not unlock " NAME "\n");
1d14ffa9
FB
55 return -1;
56 }
57
58 return 0;
59}
60
61static int glue (dsound_lock_, TYPE) (
62 BUFPTR buf,
63 struct audio_pcm_info *info,
64 DWORD pos,
65 DWORD len,
66 LPVOID *p1p,
67 LPVOID *p2p,
68 DWORD *blen1p,
69 DWORD *blen2p,
191e1f0a
KZ
70 int entire,
71 dsound *s
1d14ffa9
FB
72 )
73{
74 HRESULT hr;
1d14ffa9
FB
75 LPVOID p1 = NULL, p2 = NULL;
76 DWORD blen1 = 0, blen2 = 0;
8ead62cf 77 DWORD flag;
1d14ffa9 78
8ead62cf
FB
79#ifdef DSBTYPE_IN
80 flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
81#else
82 flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
83#endif
2762955f 84 hr = glue(IFACE, _Lock)(buf, pos, len, &p1, &blen1, &p2, &blen2, flag);
1d14ffa9 85
2762955f 86 if (FAILED (hr)) {
1d14ffa9 87#ifndef DSBTYPE_IN
2762955f
KZ
88 if (hr == DSERR_BUFFERLOST) {
89 if (glue (dsound_restore_, TYPE) (buf, s)) {
90 dsound_logerr (hr, "Could not lock " NAME "\n");
1d14ffa9 91 }
1d14ffa9
FB
92 goto fail;
93 }
2762955f
KZ
94#endif
95 dsound_logerr (hr, "Could not lock " NAME "\n");
1d14ffa9
FB
96 goto fail;
97 }
98
99 if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
100 dolog ("DirectSound returned misaligned buffer %ld %ld\n",
101 blen1, blen2);
102 glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
103 goto fail;
104 }
105
106 if (!p1 && blen1) {
107 dolog ("warning: !p1 && blen1=%ld\n", blen1);
108 blen1 = 0;
109 }
110
111 if (!p2 && blen2) {
112 dolog ("warning: !p2 && blen2=%ld\n", blen2);
113 blen2 = 0;
114 }
115
116 *p1p = p1;
117 *p2p = p2;
118 *blen1p = blen1;
119 *blen2p = blen2;
120 return 0;
121
122 fail:
123 *p1p = NULL - 1;
124 *p2p = NULL - 1;
125 *blen1p = -1;
126 *blen2p = -1;
127 return -1;
128}
129
130#ifdef DSBTYPE_IN
131static void dsound_fini_in (HWVoiceIn *hw)
132#else
133static void dsound_fini_out (HWVoiceOut *hw)
134#endif
135{
136 HRESULT hr;
137#ifdef DSBTYPE_IN
138 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
139#else
140 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
141#endif
142
143 if (ds->FIELD) {
144 hr = glue (IFACE, _Stop) (ds->FIELD);
145 if (FAILED (hr)) {
c0fe3827 146 dsound_logerr (hr, "Could not stop " NAME "\n");
1d14ffa9
FB
147 }
148
149 hr = glue (IFACE, _Release) (ds->FIELD);
150 if (FAILED (hr)) {
c0fe3827 151 dsound_logerr (hr, "Could not release " NAME "\n");
1d14ffa9
FB
152 }
153 ds->FIELD = NULL;
154 }
155}
156
157#ifdef DSBTYPE_IN
5706db1d
KZ
158static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
159 void *drv_opaque)
1d14ffa9 160#else
5706db1d
KZ
161static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
162 void *drv_opaque)
1d14ffa9
FB
163#endif
164{
165 int err;
166 HRESULT hr;
191e1f0a 167 dsound *s = drv_opaque;
1d14ffa9 168 WAVEFORMATEX wfx;
1ea879e5 169 struct audsettings obt_as;
1d14ffa9
FB
170#ifdef DSBTYPE_IN
171 const char *typ = "ADC";
172 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
173 DSCBUFFERDESC bd;
174 DSCBCAPS bc;
4a3b8b34 175 AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
1d14ffa9
FB
176#else
177 const char *typ = "DAC";
178 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
179 DSBUFFERDESC bd;
180 DSBCAPS bc;
4a3b8b34 181 AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
1d14ffa9
FB
182#endif
183
ca9cc28c 184 if (!s->FIELD2) {
26463dbc 185 dolog ("Attempt to initialize voice without " NAME2 " object\n");
ca9cc28c
AZ
186 return -1;
187 }
188
c0fe3827 189 err = waveformat_from_audio_settings (&wfx, as);
1d14ffa9
FB
190 if (err) {
191 return -1;
192 }
193
194 memset (&bd, 0, sizeof (bd));
195 bd.dwSize = sizeof (bd);
196 bd.lpwfxFormat = &wfx;
4a3b8b34 197 bd.dwBufferBytes = audio_buffer_bytes(pdo, as, 92880);
1d14ffa9 198#ifdef DSBTYPE_IN
1d14ffa9
FB
199 hr = IDirectSoundCapture_CreateCaptureBuffer (
200 s->dsound_capture,
201 &bd,
202 &ds->dsound_capture_buffer,
203 NULL
204 );
205#else
206 bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
1d14ffa9
FB
207 hr = IDirectSound_CreateSoundBuffer (
208 s->dsound,
209 &bd,
210 &ds->dsound_buffer,
211 NULL
212 );
213#endif
214
215 if (FAILED (hr)) {
c0fe3827 216 dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
1d14ffa9
FB
217 return -1;
218 }
219
c0fe3827 220 hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
1d14ffa9 221 if (FAILED (hr)) {
c0fe3827 222 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
1d14ffa9
FB
223 goto fail0;
224 }
225
226#ifdef DEBUG_DSOUND
227 dolog (NAME "\n");
228 print_wave_format (&wfx);
229#endif
230
231 memset (&bc, 0, sizeof (bc));
232 bc.dwSize = sizeof (bc);
233
234 hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
235 if (FAILED (hr)) {
c0fe3827 236 dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
1d14ffa9
FB
237 goto fail0;
238 }
239
c0fe3827 240 err = waveformat_to_audio_settings (&wfx, &obt_as);
1d14ffa9
FB
241 if (err) {
242 goto fail0;
243 }
244
245 ds->first_time = 1;
d929eba5
FB
246 obt_as.endianness = 0;
247 audio_pcm_init_info (&hw->info, &obt_as);
c0fe3827
FB
248
249 if (bc.dwBufferBytes & hw->info.align) {
250 dolog (
251 "GetCaps returned misaligned buffer size %ld, alignment %d\n",
252 bc.dwBufferBytes, hw->info.align + 1
253 );
254 }
255 hw->samples = bc.dwBufferBytes >> hw->info.shift;
191e1f0a 256 ds->s = s;
1d14ffa9
FB
257
258#ifdef DEBUG_DSOUND
259 dolog ("caps %ld, desc %ld\n",
260 bc.dwBufferBytes, bd.dwBufferBytes);
261
262 dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
c0fe3827 263 hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
1d14ffa9
FB
264#endif
265 return 0;
266
267 fail0:
268 glue (dsound_fini_, TYPE) (hw);
269 return -1;
270}
271
272#undef NAME
832e9079 273#undef NAME2
1d14ffa9
FB
274#undef TYPE
275#undef IFACE
276#undef BUFPTR
277#undef FIELD
832e9079 278#undef FIELD2