ReactOS 0.4.15-dev-7942-gd23573b
instrument.c
Go to the documentation of this file.
1/*
2 * IDirectMusicInstrument Implementation
3 *
4 * Copyright (C) 2003-2004 Rok Mandeljc
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "dmusic_private.h"
22
24
25static const GUID IID_IDirectMusicInstrumentPRIVATE = { 0xbcb20080, 0xa40c, 0x11d1, { 0x86, 0xbc, 0x00, 0xc0, 0x4f, 0xbf, 0x8f, 0xef } };
26
27/* IDirectMusicInstrument IUnknown part: */
29{
30 TRACE("(%p)->(%s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
31
33 IsEqualIID(riid, &IID_IDirectMusicInstrument))
34 {
35 *ret_iface = iface;
37 return S_OK;
38 }
40 {
41 /* it seems to me that this interface is only basic IUnknown, without any
42 * other inherited functions... *sigh* this is the worst scenario, since it means
43 * that whoever calls it knows the layout of original implementation table and therefore
44 * tries to get data by direct access... expect crashes
45 */
46 FIXME("*sigh*... requested private/unspecified interface\n");
47
48 *ret_iface = iface;
50 return S_OK;
51 }
52
53 WARN("(%p)->(%s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
54
55 return E_NOINTERFACE;
56}
57
59{
62
63 TRACE("(%p)->(): new ref = %u\n", iface, ref);
64
65 return ref;
66}
67
69{
72
73 TRACE("(%p)->(): new ref = %u\n", iface, ref);
74
75 if (!ref)
76 {
77 ULONG i;
78
79 HeapFree(GetProcessHeap(), 0, This->regions);
80 for (i = 0; i < This->nb_articulations; i++)
81 HeapFree(GetProcessHeap(), 0, This->articulations->connections);
82 HeapFree(GetProcessHeap(), 0, This->articulations);
85 }
86
87 return ref;
88}
89
90/* IDirectMusicInstrumentImpl IDirectMusicInstrument part: */
92{
94
95 TRACE("(%p)->(%p)\n", This, pdwPatch);
96
97 *pdwPatch = MIDILOCALE2Patch(&This->header.Locale);
98
99 return S_OK;
100}
101
103{
105
106 TRACE("(%p)->(%d): stub\n", This, dwPatch);
107
108 Patch2MIDILOCALE(dwPatch, &This->header.Locale);
109
110 return S_OK;
111}
112
113static const IDirectMusicInstrumentVtbl DirectMusicInstrument_Vtbl =
114{
120};
121
122/* for ClassFactory */
125 HRESULT hr;
126
128 if (NULL == dminst) {
129 *ppobj = NULL;
130 return E_OUTOFMEMORY;
131 }
133 dminst->ref = 1;
134
137 ppobj);
139
140 return hr;
141}
142
144{
145 ULONG bytes_read;
146 HRESULT hr;
147
148 hr = IStream_Read(stream, data, size, &bytes_read);
149 if(FAILED(hr)){
150 TRACE("IStream_Read failed: %08x\n", hr);
151 return hr;
152 }
153 if (bytes_read < size) {
154 TRACE("Didn't read full chunk: %u < %u\n", bytes_read, size);
155 return E_FAIL;
156 }
157
158 return S_OK;
159}
160
162{
163 if(bytes > len){
164 TRACE("Apparent mismatch in chunk lengths? %u bytes remaining, %u bytes read\n", len, bytes);
165 return 0;
166 }
167 return len - bytes;
168}
169
171{
172 LARGE_INTEGER move;
173 HRESULT ret;
174
175 move.QuadPart = bytes;
176
177 ret = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
178 if (FAILED(ret))
179 WARN("IStream_Seek failed: %08x\n", ret);
180
181 return ret;
182}
183
185{
186 HRESULT ret;
188
189 TRACE("(%p, %p, %p, %u)\n", This, stream, region, length);
190
191 while (length)
192 {
193 ret = read_from_stream(stream, &chunk, sizeof(chunk));
194 if (FAILED(ret))
195 return ret;
196
197 length = subtract_bytes(length, sizeof(chunk));
198
199 switch (chunk.fccID)
200 {
201 case FOURCC_RGNH:
202 TRACE("RGNH chunk (region header): %u bytes\n", chunk.dwSize);
203
204 ret = read_from_stream(stream, &region->header, sizeof(region->header));
205 if (FAILED(ret))
206 return ret;
207
208 length = subtract_bytes(length, sizeof(region->header));
209 break;
210
211 case FOURCC_WSMP:
212 TRACE("WSMP chunk (wave sample): %u bytes\n", chunk.dwSize);
213
214 ret = read_from_stream(stream, &region->wave_sample, sizeof(region->wave_sample));
215 if (FAILED(ret))
216 return ret;
217 length = subtract_bytes(length, sizeof(region->wave_sample));
218
219 if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample))))
220 break;
221
222 ret = read_from_stream(stream, &region->wave_loop, sizeof(region->wave_loop));
223 if (FAILED(ret))
224 return ret;
225
226 length = subtract_bytes(length, sizeof(region->wave_loop));
227 break;
228
229 case FOURCC_WLNK:
230 TRACE("WLNK chunk (wave link): %u bytes\n", chunk.dwSize);
231
232 ret = read_from_stream(stream, &region->wave_link, sizeof(region->wave_link));
233 if (FAILED(ret))
234 return ret;
235
236 length = subtract_bytes(length, sizeof(region->wave_link));
237 break;
238
239 default:
240 TRACE("Unknown chunk %s (skipping): %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
241
242 ret = advance_stream(stream, chunk.dwSize);
243 if (FAILED(ret))
244 return ret;
245
247 break;
248 }
249 }
250
251 return S_OK;
252}
253
255{
256 HRESULT ret;
257 instrument_articulation *articulation;
258
259 if (!This->articulations)
260 This->articulations = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->articulations));
261 else
262 This->articulations = HeapReAlloc(GetProcessHeap(), 0, This->articulations, sizeof(*This->articulations) * (This->nb_articulations + 1));
263 if (!This->articulations)
264 return E_OUTOFMEMORY;
265
266 articulation = &This->articulations[This->nb_articulations];
267
268 ret = read_from_stream(stream, &articulation->connections_list, sizeof(CONNECTIONLIST));
269 if (FAILED(ret))
270 return ret;
271
272 articulation->connections = HeapAlloc(GetProcessHeap(), 0, sizeof(CONNECTION) * articulation->connections_list.cConnections);
273 if (!articulation->connections)
274 return E_OUTOFMEMORY;
275
276 ret = read_from_stream(stream, articulation->connections, sizeof(CONNECTION) * articulation->connections_list.cConnections);
277 if (FAILED(ret))
278 {
279 HeapFree(GetProcessHeap(), 0, articulation->connections);
280 return ret;
281 }
282
284
285 This->nb_articulations++;
286
287 return S_OK;
288}
289
290/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
292{
294 HRESULT hr;
296 ULONG i = 0;
297 ULONG length = This->length;
298
299 TRACE("(%p, %p): offset = 0x%s, length = %u)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);
300
301 if (This->loaded)
302 return S_OK;
303
304 hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL);
305 if (FAILED(hr))
306 {
307 WARN("IStream_Seek failed: %08x\n", hr);
309 }
310
311 This->regions = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->regions) * This->header.cRegions);
312 if (!This->regions)
313 return E_OUTOFMEMORY;
314
315 while (length)
316 {
317 hr = read_from_stream(stream, &chunk, sizeof(chunk));
318 if (FAILED(hr))
319 goto error;
320
321 length = subtract_bytes(length, sizeof(chunk) + chunk.dwSize);
322
323 switch (chunk.fccID)
324 {
325 case FOURCC_INSH:
326 case FOURCC_DLID:
327 TRACE("Chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
328
329 /* Instrument header and id are already set so just skip */
330 hr = advance_stream(stream, chunk.dwSize);
331 if (FAILED(hr))
332 goto error;
333
334 break;
335
336 case FOURCC_LIST: {
337 DWORD size = chunk.dwSize;
338
339 TRACE("LIST chunk: %u bytes\n", chunk.dwSize);
340
341 hr = read_from_stream(stream, &chunk.fccID, sizeof(chunk.fccID));
342 if (FAILED(hr))
343 goto error;
344
345 size = subtract_bytes(size, sizeof(chunk.fccID));
346
347 switch (chunk.fccID)
348 {
349 case FOURCC_LRGN:
350 TRACE("LRGN chunk (regions list): %u bytes\n", size);
351
352 while (size)
353 {
354 hr = read_from_stream(stream, &chunk, sizeof(chunk));
355 if (FAILED(hr))
356 goto error;
357
358 if (chunk.fccID != FOURCC_LIST)
359 {
360 TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
361 goto error;
362 }
363
364 hr = read_from_stream(stream, &chunk.fccID, sizeof(chunk.fccID));
365 if (FAILED(hr))
366 goto error;
367
368 if (chunk.fccID == FOURCC_RGN)
369 {
370 TRACE("RGN chunk (region): %u bytes\n", chunk.dwSize);
371 hr = load_region(This, stream, &This->regions[i++], chunk.dwSize - sizeof(chunk.fccID));
372 }
373 else
374 {
375 TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
376 hr = advance_stream(stream, chunk.dwSize - sizeof(chunk.fccID));
377 }
378 if (FAILED(hr))
379 goto error;
380
381 size = subtract_bytes(size, chunk.dwSize + sizeof(chunk));
382 }
383 break;
384
385 case FOURCC_LART:
386 TRACE("LART chunk (articulations list): %u bytes\n", size);
387
388 while (size)
389 {
390 hr = read_from_stream(stream, &chunk, sizeof(chunk));
391 if (FAILED(hr))
392 goto error;
393
394 if (chunk.fccID == FOURCC_ART1)
395 {
396 TRACE("ART1 chunk (level 1 articulation): %u bytes\n", chunk.dwSize);
398 }
399 else
400 {
401 TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
402 hr = advance_stream(stream, chunk.dwSize);
403 }
404 if (FAILED(hr))
405 goto error;
406
407 size = subtract_bytes(size, chunk.dwSize + sizeof(chunk));
408 }
409 break;
410
411 default:
412 TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
413
414 hr = advance_stream(stream, chunk.dwSize - sizeof(chunk.fccID));
415 if (FAILED(hr))
416 goto error;
417
418 size = subtract_bytes(size, chunk.dwSize - sizeof(chunk.fccID));
419 break;
420 }
421 break;
422 }
423
424 default:
425 TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
426
427 hr = advance_stream(stream, chunk.dwSize);
428 if (FAILED(hr))
429 goto error;
430
431 break;
432 }
433 }
434
435 This->loaded = TRUE;
436
437 return S_OK;
438
439error:
440 HeapFree(GetProcessHeap(), 0, This->regions);
441 This->regions = NULL;
442
444}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define FOURCC_RGN
Definition: dls1.h:44
#define FOURCC_WSMP
Definition: dls1.h:49
#define FOURCC_LART
Definition: dls1.h:46
#define FOURCC_LRGN
Definition: dls1.h:43
#define FOURCC_DLID
Definition: dls1.h:34
#define FOURCC_RGNH
Definition: dls1.h:45
#define FOURCC_INSH
Definition: dls1.h:42
#define FOURCC_ART1
Definition: dls1.h:47
#define FOURCC_WLNK
Definition: dls1.h:48
#define DMUS_E_UNSUPPORTED_STREAM
Definition: dmerror.h:101
void Patch2MIDILOCALE(DWORD dwPatch, LPMIDILOCALE pLocale)
Definition: dmusic_main.c:205
DWORD MIDILOCALE2Patch(const MIDILOCALE *pLocale)
Definition: dmusic_main.c:195
const char * debugstr_dmguid(const GUID *id)
Definition: dmusic_main.c:237
static void DMUSIC_UnlockModule(void)
static IDirectMusicInstrumentImpl * impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface)
static void DMUSIC_LockModule(void)
#define IDirectMusicInstrument_AddRef(p)
Definition: dmusicc.h:525
#define IDirectMusicInstrument_QueryInterface(p, a, b)
Definition: dmusicc.h:524
struct IDirectMusicInstrument * LPDIRECTMUSICINSTRUMENT
Definition: dmusicc.h:99
#define IDirectMusicInstrument_Release(p)
Definition: dmusicc.h:526
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
static DWORD subtract_bytes(DWORD len, DWORD bytes)
Definition: instrument.c:161
static ULONG WINAPI IDirectMusicInstrumentImpl_AddRef(LPDIRECTMUSICINSTRUMENT iface)
Definition: instrument.c:58
static HRESULT advance_stream(IStream *stream, ULONG bytes)
Definition: instrument.c:170
HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream)
Definition: instrument.c:291
static ULONG WINAPI IDirectMusicInstrumentImpl_Release(LPDIRECTMUSICINSTRUMENT iface)
Definition: instrument.c:68
HRESULT DMUSIC_CreateDirectMusicInstrumentImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter)
Definition: instrument.c:123
static HRESULT WINAPI IDirectMusicInstrumentImpl_SetPatch(LPDIRECTMUSICINSTRUMENT iface, DWORD dwPatch)
Definition: instrument.c:102
static const IDirectMusicInstrumentVtbl DirectMusicInstrument_Vtbl
Definition: instrument.c:113
static HRESULT load_articulation(IDirectMusicInstrumentImpl *This, IStream *stream, ULONG length)
Definition: instrument.c:254
static HRESULT WINAPI IDirectMusicInstrumentImpl_GetPatch(LPDIRECTMUSICINSTRUMENT iface, DWORD *pdwPatch)
Definition: instrument.c:91
static HRESULT load_region(IDirectMusicInstrumentImpl *This, IStream *stream, instrument_region *region, ULONG length)
Definition: instrument.c:184
static const GUID IID_IDirectMusicInstrumentPRIVATE
Definition: instrument.c:25
static HRESULT read_from_stream(IStream *stream, void *data, ULONG size)
Definition: instrument.c:143
static HRESULT WINAPI IDirectMusicInstrumentImpl_QueryInterface(LPDIRECTMUSICINSTRUMENT iface, REFIID riid, LPVOID *ret_iface)
Definition: instrument.c:28
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define error(str)
Definition: mkdosfs.c:1605
#define FOURCC_LIST
Definition: mmsystem.h:565
static LPUNKNOWN
Definition: ndr_ole.c:49
static const char * debugstr_fourcc(DWORD fourcc)
Definition: parsing.c:85
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
IDirectMusicInstrument IDirectMusicInstrument_iface
ULONG cConnections
Definition: dls1.h:73
CONNECTIONLIST connections_list
Definition: send.c:48
Definition: parse.h:23
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
int ret
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364