1 /* Helper functions for dmusic file handling
3 * Copyright (C) 2003 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "wine/debug.h"
25 #include "wine/unicode.h"
27 #include "dmusic_private.h"
29 /* used while still in testing */
30 WINE_DEFAULT_DEBUG_CHANNEL(dmfile);
31 WINE_DECLARE_DEBUG_CHANNEL(dmfiledat);
33 /******************************************************************************
34 * DMUSIC_FillUNFOFromFileHandle:
35 * - fills a UNFO_List struct (dmusic_private.h) with data from file handle.
36 * - IMPORTANT: it expects a LIST chunk at beginning, so if you are calling it
37 * from another DMUSIC_Fill* function, make sure pointer is at
40 HRESULT WINAPI DMUSIC_FillUNFOFromFileHandle (UNFO_List UNFO, HANDLE fd)
43 DWORD BytesRead, ListCount = 0, ListSize;
45 TRACE("reading 'LIST' chunk...\n");
46 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'LIST' */
47 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'LIST' chunk */
48 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_UNFO_LIST) {
49 TRACE("'UNFO': UNFO list\n");
50 ListSize = chunk.size - sizeof(FOURCC); /* list contents size is same as size of LIST chunk - size of following field ID*/
52 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following field */
53 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of following field */
54 ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
57 case DMUS_FOURCC_UNAM_CHUNK: {
58 TRACE("'UNAM': name\n");
59 UNFO.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
60 ReadFile (fd, UNFO.name, chunk.size, &BytesRead, NULL);
61 TRACE_(dmfiledat)("=> name = %s\n", debugstr_w(UNFO.name));
63 } case DMUS_FOURCC_UART_CHUNK: {
64 TRACE("'UART': artist\n");
65 UNFO.artist = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
66 ReadFile (fd, UNFO.artist, chunk.size, &BytesRead, NULL);
67 TRACE_(dmfiledat)("artist = %s\n", debugstr_w(UNFO.artist));
69 } case DMUS_FOURCC_UCOP_CHUNK: {
70 TRACE("'UCOP': copyright\n");
71 UNFO.copyright = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
72 ReadFile (fd, UNFO.copyright, chunk.size, &BytesRead, NULL);
73 TRACE_(dmfiledat)("=> copyright = %s\n", debugstr_w(UNFO.copyright));
75 } case DMUS_FOURCC_USBJ_CHUNK:{
76 TRACE("'USBJ': subject\n");
77 UNFO.subject = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
78 ReadFile (fd, UNFO.subject, chunk.size, &BytesRead, NULL);
79 TRACE_(dmfiledat)("=> subject = %s\n", debugstr_w(UNFO.subject));
81 } case DMUS_FOURCC_UCMT_CHUNK: {
82 TRACE("'UCMT': comment\n");
83 UNFO.comment = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
84 ReadFile (fd, UNFO.comment, chunk.size, &BytesRead, NULL);
85 TRACE_(dmfiledat)("=> comment = %s\n", debugstr_w(UNFO.comment));
88 WARN("invalid chunk (only 'UNAM', 'UART', 'UCOP', 'USBJ', 'UCMT' allowed)\n");
92 TRACE("ListCount (%ld) < ListSize(%ld)\n", ListCount, ListSize);
93 } while (ListCount < ListSize);
95 WARN("'UNFO' not found: not an UNFO list\n");
100 /******************************************************************************
101 * DMUSIC_FillReferenceFromFileHandle:
102 * - fills a Reference struct (dmusic_private.h) with data from file handle.
103 * - IMPORTANT: it expects a LIST chunk at beginning, so if you are calling it
104 * from another DMUSIC_Fill* function, make sure pointer is at
107 HRESULT WINAPI DMUSIC_FillReferenceFromFileHandle (Reference reference, HANDLE fd)
110 DWORD BytesRead, ListCount = 0, ListSize;
112 TRACE("reading 'LIST' chunk...\n");
113 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'LIST' */
114 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'LIST' chunk */
115 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_REF_LIST) {
116 TRACE("'DMRF': reference list\n");
117 ListSize = chunk.size - sizeof(FOURCC); /* list contents size is same as size of LIST chunk - size of following field ID*/
119 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following field */
120 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of following field */
121 ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
124 case DMUS_FOURCC_REF_CHUNK: {
125 TRACE("'refh': reference header\n");
126 ReadFile (fd, &reference.header, chunk.size, &BytesRead, NULL);
127 TRACE_(dmfiledat)("=> guidClassID = %s; dwValidData = %ld\n", debugstr_guid (&reference.header.guidClassID), reference.header.dwValidData);
129 } case DMUS_FOURCC_GUID_CHUNK: {
130 TRACE("'guid': GUID\n");
131 ReadFile (fd, &reference.guid, chunk.size, &BytesRead, NULL);
132 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid (&reference.guid));
134 } case DMUS_FOURCC_DATE_CHUNK: {
135 TRACE("'date': file date\n");
136 ReadFile (fd, &reference.date, chunk.size, &BytesRead, NULL);
137 TRACE_(dmfiledat)("=> file date = %ld%ld\n", reference.date.dwHighDateTime, reference.date.dwLowDateTime);
139 } case DMUS_FOURCC_NAME_CHUNK: {
140 TRACE("'name': name\n");
141 reference.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
142 ReadFile (fd, reference.name, chunk.size, &BytesRead, NULL);
143 TRACE_(dmfiledat)("=> name = %s\n", debugstr_w (reference.name));
145 } case DMUS_FOURCC_FILE_CHUNK: {
146 TRACE("'file': file name\n");
147 reference.file = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
148 ReadFile (fd, reference.file, chunk.size, &BytesRead, NULL);
149 TRACE_(dmfiledat)("=> file name = %s\n", debugstr_w (reference.file));
151 } case DMUS_FOURCC_CATEGORY_CHUNK: {
152 TRACE("'catg': category\n");
153 reference.category = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
154 ReadFile (fd, reference.category, chunk.size, &BytesRead, NULL);
155 TRACE_(dmfiledat)("=> category = %s\n", debugstr_w (reference.category));
157 } case DMUS_FOURCC_VERSION_CHUNK: {
158 TRACE("'vers': version\n");
159 ReadFile (fd, &reference.version, sizeof(DMUS_IO_VERSION), &BytesRead, NULL);
160 TRACE_(dmfiledat)("=> version = %ld%ld\n", reference.version.dwVersionMS, reference.version.dwVersionLS);
163 WARN("invalid chunk (only 'refh, 'guid', 'date', 'name', 'file', 'catg', 'vers' allowed\n");
167 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
168 } while (ListCount < ListSize);
174 /******************************************************************************
175 * DMUSIC_FillBandFromFileHandle:
176 * - fills a IDirectMusicBandImpl struct with data from file handle.
177 * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it
178 * from another DMUSIC_Fill* function, make sure pointer is at
180 * - TODO: replace data in function with data in IDirectMusicBandImpl
182 HRESULT WINAPI DMUSIC_FillBandFromFileHandle (IDirectMusicBandImpl *band, HANDLE fd)
185 DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
186 /* FIXME: Replace stuff located below with the stuff in band */
188 DMUS_IO_VERSION version;
190 /* only in singular form for time being */
191 DMUS_IO_INSTRUMENT header;
194 TRACE("reading 'RIFF' chunk...\n");
195 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'RIFF' */
196 if (chunk.id == FOURCC_RIFF) {
197 TRACE("'RIFF': RIFF file\n");
198 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
199 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
200 TRACE("reading chunks ...\n");
201 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
202 if (chunk.id == DMUS_FOURCC_BAND_FORM) {
203 TRACE("'DMBD': band form\n");
205 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
206 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
207 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
210 case DMUS_FOURCC_GUID_CHUNK: {
211 TRACE("'guid': GUID\n");
212 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
213 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
215 } case DMUS_FOURCC_VERSION_CHUNK: {
216 TRACE("'vers': version\n");
217 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
218 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
221 TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
222 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
223 ListCount = 0; /* reset */
224 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read list ID */
227 case DMUS_FOURCC_UNFO_LIST: {
228 TRACE("'UNFO': UNFO list (content size = %ld)\n", ListSize);
229 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* set pointer at beginning of list */
230 DMUSIC_FillUNFOFromFileHandle (UNFO, fd); /* forward to DMUSIC_FillUNFOFromFileHandle */
232 } case DMUS_FOURCC_INSTRUMENTS_LIST: {
233 TRACE("'lbil': instrumets list (content size = %ld)\n", ListSize);
235 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
236 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
237 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
238 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_INSTRUMENT_LIST) {
239 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
240 ListCount2 = 0; /* reset */
241 TRACE("'lbin': instrument (size = %ld)\n", ListSize2);
243 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
244 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
245 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
248 case DMUS_FOURCC_INSTRUMENT_CHUNK: {
249 TRACE("'bins': instrument header\n");
250 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
251 TRACE_(dmfiledat)("=> dwPatch = %ld; dwAssignPatch = %ld; dwPChannel = %ld; dwFlags = %ld; bPan = %i; bVolume = %i; nTranspose = %i; dwChannelPriority = %ld; nPitchBendRange = %i", \
252 header.dwPatch, header.dwAssignPatch, header.dwPChannel, header.dwFlags, header.bPan, header.bVolume, header.nTranspose, header.dwChannelPriority, header.nPitchBendRange);
254 } case FOURCC_LIST: {
255 TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
256 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
257 if (chunk.id == DMUS_FOURCC_REF_LIST) {
258 TRACE("'DMRF': reference list (size = %ld)\n", chunk.size - 4); /* set pointer at beginning of list */
259 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT);
260 DMUSIC_FillReferenceFromFileHandle (reference, fd); /* forward to DMUSIC_FillReferenceFromFileHandle */
261 } else WARN("invalid chunk (only 'DMRF' chunk allowed\n");
264 WARN("invalid chunk (only 'bins' and 'LIST' chunks allowed\n");
268 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
269 } while (ListCount2 < ListSize2);
270 } else WARN("invalid chunk (only 'lbin' chunk allowed)\n");
271 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
272 } while (ListCount < ListSize);
275 WARN("invalid chunk (only 'UNFO' and 'lbil' chunks allowed\n");
281 WARN("invalid chunk (only 'guid', 'vers' and 'LIST' chunks allowed)\n");
285 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
286 } while (FileCount < FileSize);
289 WARN("'RIFF' not found: not a RIFF file\n");
295 /******************************************************************************
296 * DMUSIC_FillTrackFromFileHandle:
297 * - fills a IDirectMusicTrack8Impl struct with data from file handle.
298 * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it
299 * from another DMUSIC_Fill* function, make sure pointer is at
301 * - TODO: replace data in function with data in IDirectMusicTrackImpl
302 * implement loading for missing (empty) clauses
303 * fix a problem with tempo track loading (look at code)
305 HRESULT WINAPI DMUSIC_FillTrackFromFileHandle (IDirectMusicTrack8Impl *segment, HANDLE fd)
308 DWORD BytesRead, ListCount = 0, ListCount2 = 0, ListCount3 = 0, ListCount4 = 0, \
309 ListSize, ListSize2, ListSize3, ListSize4, FileCount = 0, FileSize, FileCount2 = 0, FileSize2 /* *2s, *3s and *4s are for various subchunks */;
312 /* general track info */
313 DMUS_IO_TRACK_HEADER header;
314 DMUS_IO_TRACK_EXTRAS_HEADER extheader;
316 DMUS_IO_VERSION version;
318 /* tempo track stuff */
319 DMUS_IO_TEMPO_ITEM tempo;
320 /* chord track stuff */
323 /* command track stuff */
324 DMUS_IO_COMMAND command;
325 /* sytle list stuff (support only 1 while still in parse development mode)*/
328 /* band track stuff */
330 /* wave track stuff (only singular) */
332 /* segment trigger track stuff */
333 SegTriggerTrack segTriggerTrack;
334 /* time signature track stuff */
335 TimeSigTrack timeSigTrack;
336 /* script track list stuff */
339 TRACE("reading 'RIFF' chunk...\n");
340 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
341 if (chunk.id == FOURCC_RIFF) {
342 TRACE ("'RIFF': RIFF file\n");
343 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
344 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
345 TRACE("reading chunks ...\n");
346 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
347 if (chunk.id == DMUS_FOURCC_TRACK_FORM) {
348 TRACE("'DMTK': track form\n");
350 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
351 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
352 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
355 case DMUS_FOURCC_TRACK_CHUNK: {
356 TRACE("'trkh': track header\n");
357 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
358 TRACE_(dmfiledat)("=> track guidClassID = %s; dwPosition = %ld; dwGroup = %ld; ckid = %ld; fccType = %ld\n", \
359 debugstr_guid (&header.guidClassID), header.dwPosition, header.dwGroup, header.ckid, header.fccType);
361 } case DMUS_FOURCC_TRACK_EXTRAS_CHUNK: {
362 TRACE("'trkx': extra track flags\n");
363 ReadFile (fd, &extheader, chunk.size, &BytesRead, NULL);
364 TRACE_(dmfiledat)("=> dwFlags = %ld; dwPriority = %ld\n", extheader.dwFlags,
365 extheader.dwPriority);
367 } case DMUS_FOURCC_GUID_CHUNK: {
368 TRACE("'guid': GUID\n");
369 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
370 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
372 } case DMUS_FOURCC_VERSION_CHUNK: {
373 TRACE("'vers': version\n");
374 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
375 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
378 TRACE("'LIST': list (size = %ld)\n", chunk.size);
379 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
380 ListCount = 0; /* reset */
381 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
384 case DMUS_FOURCC_UNFO_LIST: {
385 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
386 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
387 DMUSIC_FillUNFOFromFileHandle (UNFO, fd); /* forward to DMUSIC_FillUNFOFromFileHandle */
389 } case DMUS_FOURCC_CHORDTRACK_LIST: {
390 TRACE("'cord': chord track list\n");
392 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
393 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
394 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
397 case DMUS_FOURCC_CHORDTRACKHEADER_CHUNK: {
398 TRACE("'crdh': chord header\n");
399 ReadFile (fd, &chordHeader, chunk.size, &BytesRead, NULL);
400 TRACE_(dmfiledat)("=> chord root = %i; scale = %i\n", (chordHeader && 0xFF000000) >> 24, chordHeader && 0x00FFFFFF);
402 } case DMUS_FOURCC_CHORDTRACKBODY_CHUNK: {
403 TRACE("'crdb': chord body\n");
404 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_CHORD) */
405 ReadFile (fd, &chordData.chord, chunk.size, &BytesRead, NULL); /* read DMUS_IO_CHORD */
406 TRACE_(dmfiledat)("=> wszName[16] = %s; mtTime = %li; chord.wMeasure = %d; chord.bBeat = %i; bFlags = %i\n", \
407 debugstr_w (chordData.chord.wszName), chordData.chord.mtTime, chordData.chord.wMeasure, chordData.chord.bBeat, chordData.chord.bFlags);
408 ReadFile (fd, &chordData.nrofsubchords, sizeof(DWORD), &BytesRead, NULL); /* read number of subchords */
409 TRACE_(dmfiledat)("=> number of subchords = %ld\n", chordData.nrofsubchords);
410 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_SUBCHORD) */
411 chordData.subchord = (DMUS_IO_SUBCHORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DMUS_IO_SUBCHORD) * chordData.nrofsubchords); /* allocate space */
412 for (i = 0; i < chordData.nrofsubchords; i++)
414 TRACE_(dmfiledat)("=> subchord[%i]: dwChordPattern = %ld; dwScalePattern = %ld; dwInversionPoints = %ld; dwLevels = %ld; bChordRoot = %i; bScaleRoot = %i\n", \
415 i, chordData.subchord[i].dwChordPattern, chordData.subchord[i].dwScalePattern, chordData.subchord[i].dwInversionPoints, chordData.subchord[i].dwLevels, \
416 chordData.subchord[i].bChordRoot, chordData.subchord[i].bScaleRoot);
418 ReadFile (fd, chordData.subchord, chunk.size*chordData.nrofsubchords, &BytesRead, NULL);
421 WARN("Invalid chunk (only 'crdh' and 'crdb' chunks allowed)\n");
425 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
426 } while (ListCount < ListSize);
428 } case DMUS_FOURCC_STYLE_TRACK_LIST: {
429 TRACE("'sttr': style track list\n");
431 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
432 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
433 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
434 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_STYLE_REF_LIST) {
435 ListSize2 = chunk.size - sizeof(FOURCC);
437 TRACE("'strf': style reference list (size = %ld)\n", ListSize2);
440 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
441 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
442 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
445 case DMUS_FOURCC_TIME_STAMP_CHUNK: {
446 TRACE("'stmp': time stamp\n");
447 ReadFile (fd, ×tamp, chunk.size, &BytesRead, NULL);
448 TRACE_(dmfiledat)("=> time stamp = %ld\n", timestamp);
450 } case FOURCC_LIST: {
451 TRACE("'LIST': list\n");
452 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
453 if (chunk.id == DMUS_FOURCC_REF_LIST){
454 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
455 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
456 DMUSIC_FillReferenceFromFileHandle (reference, fd);
458 WARN("invalid chunk (only 'DMRF' chunk allwed)\n");
462 WARN("invalid chunk (only 'stmp' and 'LIST' chunk allowed)\n");
466 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
467 } while (ListCount2 < ListSize2);
469 WARN("invalid chunk (only 'strf' allowed)\n");
471 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
472 } while (ListCount < ListSize);
474 } case DMUS_FOURCC_PERS_TRACK_LIST: {
475 FIXME("'pftr': chordmap track list: not supported yet\n");
477 } case DMUS_FOURCC_LYRICSTRACK_LIST: {
478 FIXME("'lyrt': lyrics track list: not supported yet\n");
480 } case DMUS_FOURCC_MARKERTRACK_LIST: {
481 FIXME("'MARK': marker track list: not supported yet\n");
483 } case DMUS_FOURCC_MELODYFORM_TRACK_LIST: {
484 FIXME("'mfrm': melody formulation track list: not supported yet\n");
486 } case DMUS_FOURCC_PARAMCONTROLTRACK_TRACK_LIST: {
487 FIXME("'prmt': parameter control track list: not supported yet\n");
489 } case DMUS_FOURCC_SCRIPTTRACK_LIST: {
490 TRACE("'scrt': script track list\n");
492 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
493 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
494 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
495 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SCRIPTTRACKEVENTS_LIST) {
496 TRACE("'scrl': script events list\n");
497 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
500 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
501 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
502 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
503 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SCRIPTTRACKEVENT_LIST) {
504 TRACE("'scre': script event list\n");
505 ListSize3 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
508 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
509 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
510 ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
513 case DMUS_FOURCC_SCRIPTTRACKEVENTHEADER_CHUNK: {
514 TRACE("'scrh': event header\n");
515 ReadFile (fd, &event.header, chunk.size, &BytesRead, NULL);
516 TRACE_(dmfiledat)("=> dwFlags = %ld; lTimeLogical = %li; lTimePhysical = %li\n", \
517 event.header.dwFlags, event.header.lTimeLogical, event.header.lTimePhysical);
519 } case FOURCC_LIST: {
520 TRACE("'LIST': list\n");
521 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
522 if (chunk.id == DMUS_FOURCC_REF_LIST){
523 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
524 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
525 DMUSIC_FillReferenceFromFileHandle (event.reference, fd);
527 WARN("invalid chunk (only 'DMRF' chunk allwed)\n");
530 } case DMUS_FOURCC_SCRIPTTRACKEVENTNAME_CHUNK: {
531 TRACE("'scrn': routine name\n");
532 event.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
533 ReadFile (fd, event.name, chunk.size, &BytesRead, NULL);
534 TRACE_(dmfiledat)("=> routine name = %s\n", debugstr_w (event.name));
537 WARN("invalid chunk (only 'scrh', 'scrn' and 'LIST' chunk allowed)\n");
541 TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3);
542 } while (ListCount3 < ListSize3);
544 WARN("invalid chunk (only 'scre' chunk allowed)\n");
546 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
547 } while (ListCount2 < ListSize2);
549 WARN("invalid chunk (only 'scrl' chunk allowed)\n");
551 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
552 } while (ListCount < ListSize);
554 } case DMUS_FOURCC_SEGTRACK_LIST: {
555 TRACE("'segt': segment trigger track list\n");
557 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
558 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
559 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
562 case DMUS_FOURCC_SEGTRACK_CHUNK: {
563 TRACE("'sgth': segment track header\n");
564 ReadFile (fd, &segTriggerTrack.header, chunk.size, &BytesRead, NULL);
565 TRACE_(dmfiledat)("=> dwFlags = %ld\n", segTriggerTrack.header.dwFlags);
567 } case FOURCC_LIST: {
568 TRACE("'LIST': list\n");
569 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
570 if (chunk.id == DMUS_FOURCC_SEGMENTS_LIST) {
571 TRACE("'lsgl': segment lists list\n");
572 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
575 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
576 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
577 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
578 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SEGMENT_LIST) {
579 ListSize3 = chunk.size - sizeof(FOURCC);
582 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
583 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
584 ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
587 case DMUS_FOURCC_SEGMENTITEM_CHUNK: {
588 TRACE("'sgih': segment item header\n");
589 ReadFile (fd, &segTriggerTrack.itemHeader, chunk.size, &BytesRead, NULL);
590 TRACE_(dmfiledat)("=> lTimeLogical = %li; lTimePhysical = %li; dwPlayFlags = %ld; dwFlags = %ld\n", \
591 segTriggerTrack.itemHeader.lTimeLogical, segTriggerTrack.itemHeader.lTimePhysical, \
592 segTriggerTrack.itemHeader.dwPlayFlags, segTriggerTrack.itemHeader.dwFlags);
594 } case DMUS_FOURCC_SEGMENTITEMNAME_CHUNK: {
595 TRACE("'snam': motif name\n");
596 segTriggerTrack.motifName = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
597 ReadFile (fd, segTriggerTrack.motifName, chunk.size, &BytesRead, NULL);
598 TRACE_(dmfiledat)("=> motif name = %s\n", debugstr_w (segTriggerTrack.motifName));
600 } case FOURCC_LIST: {
601 TRACE("'LIST': list\n");
602 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
603 if (chunk.id == DMUS_FOURCC_REF_LIST) {
604 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
605 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
606 DMUSIC_FillReferenceFromFileHandle (segTriggerTrack.reference, fd);
608 WARN("invalid chunk (only 'DMRF' chunk allowed)\n");
612 WARN("invalid chunk (only 'sgih', 'snam' and 'LIST' chunks allowed)\n");
616 TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3);
617 } while (ListCount3 < ListSize3);
619 WARN("invalid chunk (only 'lseg' chunk allowed)\n");
621 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
622 } while (ListCount2 < ListSize2);
624 WARN("invalid chunk (only 'lsgl' chunk allowed\n");
628 WARN("invalid chunk (only 'sgth' and 'LIST' chunks allowed)\n");
632 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
633 } while (ListCount < ListSize);
635 } case DMUS_FOURCC_TIMESIGTRACK_LIST: {
636 TRACE("'TIMS': time signature track list\n");
637 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
638 if (chunk.id == DMUS_FOURCC_TIMESIGNATURE_TRACK) {
639 TRACE("'tims': time signatures\n");
640 timeSigTrack.nrofitems = chunk.size - sizeof(DWORD);
641 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
642 if (chunk.size != sizeof(DMUS_IO_TIMESIGNATURE_ITEM))
643 WARN("there seem to be a problem: file claims that size of DMUSIC_IO_TEMPO_ITEM is %ld, while real sizeof returns %i\n", chunk.size, sizeof(DMUS_IO_TIMESIGNATURE_ITEM));
644 timeSigTrack.nrofitems /= chunk.size;
645 TRACE_(dmfiledat)("=> number of items = %ld\n", timeSigTrack.nrofitems);
646 timeSigTrack.items = (DMUS_IO_TIMESIGNATURE_ITEM*) HeapAlloc (GetProcessHeap (), 0, chunk.size * timeSigTrack.nrofitems);
647 ReadFile(fd, timeSigTrack.items, chunk.size * timeSigTrack.nrofitems, &BytesRead, NULL);
648 for (i = 0; i < timeSigTrack.nrofitems; i++)
650 TRACE_(dmfiledat)("=> time signature[%i]: lTime = %li; bBeatsPerMeasure = %i; bBeat = %i; wGridsPerBeat = %d\n", \
651 i, timeSigTrack.items[i].lTime, timeSigTrack.items[i].bBeatsPerMeasure, timeSigTrack.items[i].bBeat, timeSigTrack.items[i].wGridsPerBeat);
654 WARN("invalid chunk (only 'tims' chunk allowed)\n");
657 } case DMUS_FOURCC_WAVETRACK_LIST: {
658 TRACE("'wavt': wave track list\n");
660 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
661 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
662 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
665 case DMUS_FOURCC_WAVETRACK_CHUNK: {
666 TRACE("'wath': wave track header\n");
667 ReadFile (fd, &waveTrack.header, chunk.size, &BytesRead, NULL);
668 TRACE_(dmfiledat)("=> lVolume = %li; dwFlags = %ld\n", waveTrack.header.lVolume, waveTrack.header.dwFlags);
670 } case FOURCC_LIST: {
671 TRACE("'LIST': list\n");
672 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
673 if (chunk.id == DMUS_FOURCC_WAVEPART_LIST) {
674 TRACE("'wavp': wave parts list\n");
675 ListSize2 = chunk.size - sizeof(FOURCC);
678 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
679 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
680 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
683 case DMUS_FOURCC_WAVEPART_CHUNK: {
684 TRACE("'waph': wave part header\n");
685 ReadFile (fd, &waveTrack.partHeader, chunk.size, &BytesRead, NULL);
686 TRACE_(dmfiledat)("=> lVolume = %li; dwVariations = %ld; dwPChannel = %ld; dwLockToPart = %ld; dwFlags = %ld; dwIndex = %ld\n", \
687 waveTrack.partHeader.lVolume, waveTrack.partHeader.dwVariations, waveTrack.partHeader.dwPChannel, \
688 waveTrack.partHeader.dwLockToPart, waveTrack.partHeader.dwFlags, waveTrack.partHeader.dwIndex);
690 } case FOURCC_LIST: {
691 TRACE("'LIST': list\n");
692 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
693 if (chunk.id == DMUS_FOURCC_WAVEITEM_LIST) {
694 TRACE("'wavi': wave items list\n");
695 ListSize3 = chunk.size - sizeof(FOURCC);
698 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
699 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
700 ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
701 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_WAVE_LIST) {
702 TRACE("'wave': wave item list\n");
703 ListSize4 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
704 ListCount4 = 0; /* reset */
706 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
707 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
708 ListCount4 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
711 case DMUS_FOURCC_WAVEITEM_CHUNK: {
712 TRACE("'waih': wave item header\n");
713 ReadFile (fd, &waveTrack.itemHeader, chunk.size, &BytesRead, NULL);
714 TRACE_(dmfiledat)("=> lVolume = %li; lPitch = %li; dwVariations = %ld; rtTime = FIXME; rtStartOffset = FIXME; rtReserved = FIXME; rtDuration = FIXME; mtLogicalTime = %li; dwLoopStart = %ld; dwLoopEnd = %ld; dwFlags = %ld\n", \
715 waveTrack.itemHeader.lVolume, waveTrack.itemHeader.lPitch, waveTrack.itemHeader.dwVariations, /*waveTrack.itemHeader.rtTime, \
716 waveTrack.itemHeader.rtStartOffset, waveTrack.itemHeader.rtReserved, waveTrack.itemHeader.rtDuration, */waveTrack.itemHeader.mtLogicalTime, \
717 waveTrack.itemHeader.dwLoopStart, waveTrack.itemHeader.dwLoopEnd, waveTrack.itemHeader.dwFlags);
719 } case mmioFOURCC('w','v','c','u'): {
720 FIXME("'wvcu': undocumented and unknown chunk type (skipping)\n");
721 SetFilePointer (fd, chunk.size, NULL, FILE_CURRENT); /* skip */
723 } case FOURCC_LIST: {
724 TRACE("'LIST': list\n");
725 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
726 if (chunk.id == DMUS_FOURCC_REF_LIST) {
727 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
728 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
729 DMUSIC_FillReferenceFromFileHandle (waveTrack.reference, fd);
731 WARN ("invalid chunk (only 'DMRF' chunk allowed\n");
735 WARN("invalid chunk (only 'waih' and 'LIST' (and undocumented 'wvcu') chunks allowed)\n");
738 TRACE("ListCount4 (%ld) < ListSize4 (%ld)\n", ListCount4, ListSize4);
739 } while (ListCount4 < ListSize4);
741 WARN("invalid chunk (only 'wave' chunk allowed)\n");
743 TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3);
744 } while (ListCount3 < ListSize3);
746 WARN("invalid chunk (only 'wavi' chunk allowed)\n");
750 WARN("invalid chunk (only 'waph' and 'LIST' chunks allowed)\n");
754 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
755 } while (ListCount2 < ListSize2);
757 WARN("invalid chunk (only 'wavp' chunk allwed)\n");
761 WARN("invalid chunk (only 'wath' and 'LIST' chunks allowed)\n");
765 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
766 } while (ListCount < ListSize);
769 WARN ("invalid chunk (only 'UNFO', 'cord', 'sttr', 'pftr', 'lyrt', 'MARK' and 'mfrm' chunks allowed)\n");
774 } case FOURCC_RIFF: {
775 TRACE("'RIFF': embedded RIFF chunk (probably band track form)\n");
776 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
777 if (chunk.id == DMUS_FOURCC_BANDTRACK_FORM) {
778 TRACE("'DMBT': band track form\n");
779 FileSize2 = chunk.size - sizeof(FOURCC);
781 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
782 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
783 FileCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
786 case DMUS_FOURCC_BANDTRACK_CHUNK: {
787 TRACE("'dbth': band track header\n");
788 ReadFile (fd, &bandTrack.header, chunk.size, &BytesRead, NULL);
789 TRACE_(dmfiledat)("=> bAutoDownload = %d\n", bandTrack.header.bAutoDownload);
791 } case DMUS_FOURCC_GUID_CHUNK: {
792 TRACE("'guid': GUID\n");
793 ReadFile (fd, &bandTrack.guid, chunk.size, &BytesRead, NULL);
794 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid (&bandTrack.guid));
796 } case DMUS_FOURCC_VERSION_CHUNK: {
797 TRACE("'vers': version\n");
798 ReadFile (fd, &bandTrack.version, chunk.size, &BytesRead, NULL);
799 TRACE_(dmfiledat)("=> version = %ld%ld\n", bandTrack.version.dwVersionMS, bandTrack.version.dwVersionLS);
801 } case FOURCC_LIST: {
802 TRACE("'LIST': list (content size = %ld)\n", chunk.size);
803 ListSize = chunk.size - sizeof(FOURCC);
805 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
808 case DMUS_FOURCC_UNFO_LIST:{
809 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle)\n");
810 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
811 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
813 } case DMUS_FOURCC_BANDS_LIST: {
814 TRACE("'lbdl': bands list (content size = %ld)\n", ListSize);
816 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
817 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
818 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
819 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_BAND_LIST) {
820 ListSize2 = chunk.size - sizeof(FOURCC);
822 TRACE("'lbnd': band list (content size = %ld)\n", ListSize2);
824 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
825 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
826 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
829 case DMUS_FOURCC_BANDITEM_CHUNK: {
830 TRACE("'bdih': old band header\n");
831 ReadFile (fd, &bandTrack.header1, chunk.size, &BytesRead, NULL);
832 TRACE_(dmfiledat)("=> lBandTime = %li\n", bandTrack.header1.lBandTime);
834 } case DMUS_FOURCC_BANDITEM_CHUNK2: {
835 TRACE("'bd2h': new band header\n");
836 ReadFile (fd, &bandTrack.header2, chunk.size, &BytesRead, NULL);
837 TRACE_(dmfiledat)("=> lBandTimeLogical = %li; lBandTimePhysical = %li\n", \
838 bandTrack.header2.lBandTimeLogical, bandTrack.header2.lBandTimePhysical);
840 } case FOURCC_RIFF: {
841 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
842 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
843 if (chunk.id == DMUS_FOURCC_BAND_FORM) {
844 TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n");
845 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
846 DMUSIC_FillBandFromFileHandle (NULL, fd);
847 } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n");
850 WARN("invalid chunk (only 'bdih', 'bd2h' and 'RIFF' chunks allowed)\n");
854 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
855 } while (ListCount2 < ListSize2);
856 } else WARN("unknown chunk - expect error\n");
858 } while (ListCount < ListSize);
861 WARN("invalid chunk (only 'UNFO' and 'lbdl' chunks allowed)\n");
866 WARN("invalid chunk (only 'dbth', 'guid', 'vers' and 'LIST' chunks allowed)\n");
870 TRACE("FileCount2 (%ld) < FileSize2 (%ld)\n", FileCount2, FileSize2);
871 } while (FileCount2 < FileSize2);
873 WARN("invalid chunk (only 'DMBT' chunk allowed\n");
876 } case DMUS_FOURCC_COMMANDTRACK_CHUNK: {
877 TRACE("'cmnd': command track\n");
878 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof(DMUS_IO_COMMAND) */
879 ReadFile (fd, &command, chunk.size, &BytesRead, NULL); /* read DMUS_IO_COMMAND */
880 TRACE_(dmfiledat)("wMeasure = %d; bBeat = %i; bCommand = %i; bGrooveLevel = %i; bGrooveRange = %i; bRepeatMode = %i\n", \
881 command.wMeasure, command.bBeat, command.bCommand, command.bGrooveLevel, command.bGrooveRange, command.bRepeatMode);
883 } case DMUS_FOURCC_MUTE_CHUNK: {
884 FIXME("'mute': mute track chunk: not supported yet\n");
886 } case DMUS_FOURCC_PATTERN_FORM: {
887 FIXME("'DMPT': pattern track form: not supported yet\n");
889 } case DMUS_FOURCC_SEQ_TRACK: {
890 FIXME("'seqt': sequence track chunk: not supported yet\n");
892 } case DMUS_FOURCC_SIGNPOST_TRACK_CHUNK: {
893 FIXME("'sgnp': signpost track chunk: not supported yet\n");
895 } case DMUS_FOURCC_SYSEX_TRACK: {
896 FIXME("'syex': sysex track chunk: not supported yet\n");
898 } case DMUS_FOURCC_TEMPO_TRACK: {
899 TRACE("'tetr': tempo track chunk\n");
900 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
901 if (chunk.size != sizeof(DMUS_IO_TEMPO_ITEM))
902 WARN("there seem to be a problem: file claims that size of DMUSIC_IO_TEMPO_ITEM is %ld, while real sizeof returns %i\n", \
903 chunk.size, sizeof(DMUS_IO_TEMPO_ITEM));
904 ReadFile (fd, &tempo, chunk.size, &BytesRead, NULL);
905 TRACE_(dmfiledat)("=> lTime = %ld; dblTempo = %f\n", tempo.lTime, tempo.dblTempo);
908 WARN("invalid chunk (too many too list)\n");
912 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
913 } while (FileCount < FileSize);
915 WARN("invalid chunk (only 'DMTK' chunk allowed)\n");
918 WARN("'RIFF' not found: not a RIFF file\n");
924 /******************************************************************************
925 * DMUSIC_FillSegmentFromFileHandle:
926 * - fills a IDirectMusicSegment8Impl struct with data from file handle.
927 * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it
928 * from another DMUSIC_Fill* function, make sure pointer is at
930 * - TODO: replace data in function with data in IDirectMusicSegmentImpl
931 * implement loading for missing (empty) clauses
933 HRESULT WINAPI DMUSIC_FillSegmentFromFileHandle (IDirectMusicSegment8Impl *segment, HANDLE fd)
936 DWORD BytesRead, ListCount = 0, ListSize, FileCount = 0, FileSize;
937 /* FIXME: Replace stuff located below with the stuff in segment */
939 DMUS_IO_SEGMENT_HEADER header;
940 DMUS_IO_VERSION version;
943 TRACE("reading 'RIFF' chunk...\n");
944 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
945 if (chunk.id == FOURCC_RIFF) {
946 TRACE("'RIFF': RIFF file\n");
947 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
948 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
949 TRACE("reading chunks ...\n");
950 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
951 if (chunk.id == DMUS_FOURCC_SEGMENT_FORM) {
952 TRACE("DMSG: segment form\n");
954 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
955 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
956 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
959 case DMUS_FOURCC_SEGMENT_CHUNK: {
960 TRACE("segh: segment header\n");
961 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
962 TRACE_(dmfiledat)("=> dwRepeats = %ld; mtLength = %li; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld; rtLength = FIXME; dwFlags = %ld; dwReserved = %ld\n", \
963 header.dwRepeats, header.mtLength, header.mtPlayStart, header.mtLoopStart, header.mtLoopEnd, header.dwResolution/*, header.rtLength*/, header.dwFlags, header.dwReserved);
965 } case DMUS_FOURCC_GUID_CHUNK: {
966 TRACE("'guid': GUID\n");
967 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
968 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
970 } case DMUS_FOURCC_VERSION_CHUNK: {
971 TRACE("'vers': version\n");
972 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
973 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
976 TRACE("'LIST': list (size) = %ld\n", chunk.size);
977 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
978 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
981 case DMUS_FOURCC_UNFO_LIST: {
982 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
983 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
984 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
986 } case DMUS_FOURCC_TRACK_LIST: {
987 TRACE("'trkl': track list chunk (forward)\n");
989 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read RIFF */
990 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read track size */
991 TRACE("track size = %ld\n", chunk.size);
992 ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
993 SetFilePointer (fd, -(sizeof(DWORD) + sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'RIFF' chunk */
994 DMUSIC_FillTrackFromFileHandle (NULL, fd); /* read encapsulated track as if it was in a track file */
995 TRACE("(Track) List Count = %ld < (Track) List Size = %ld\n", ListCount, ListSize);
996 } while (ListCount < ListSize);
1001 } case FOURCC_RIFF: {
1002 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded container form)\n", chunk.size);
1003 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1004 if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) {
1005 TRACE("'DMCN': embedded container form (forward to DMUSIC_FillContainerFromFileHandle(...))\n");
1006 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1007 DMUSIC_FillContainerFromFileHandle (NULL, fd);
1008 } else WARN("invalid chunk (only 'DMCN' chunk allowed)\n");
1010 } case DMUS_FOURCC_TOOLGRAPH_FORM: {
1011 FIXME("'DMTG': toolgraph chunk: not supported yet\n");
1013 } case DMUS_FOURCC_AUDIOPATH_FORM: {
1014 FIXME("'DMAP': audiopath chunk: not supported yet\n");
1017 WARN("invalid chunk (only 'segh', 'guid', 'vers', 'LIST', 'RIFF', 'DMTG' and 'DMAP' chunks allowed)\n");
1021 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1022 } while (FileCount < FileSize);
1024 WARN("invalid chunk (only 'DMSG' chunk allowed)\n");
1027 WARN("'RIFF' not found: not a RIFF file\n");
1033 /******************************************************************************
1034 * DMUSIC_FillScriptFromFileHandle:
1035 * - fills a IDirectMusicScriptImpl struct with data from file handle.
1036 * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it
1037 * from another DMUSIC_Fill* function, make sure pointer is at
1039 * - TODO: replace data in function with data in IDirectMusicScriptImpl
1042 HRESULT WINAPI DMUSIC_FillScriptFromFileHandle (IDirectMusicScriptImpl *script, HANDLE fd)
1045 DWORD BytesRead/*, ListCount = 0*/, ListSize, FileCount = 0, FileSize;
1046 /* FIXME: Replace stuff located below with the stuff in script */
1048 DMUS_IO_SCRIPT_HEADER header;
1049 DMUS_IO_VERSION version, scriptversion;
1053 Reference scriptsrcref;
1055 TRACE("reading 'RIFF' chunk...\n");
1056 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1057 if (chunk.id == FOURCC_RIFF) {
1058 TRACE("'RIFF': RIFF file\n");
1059 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
1060 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
1061 TRACE("reading chunks ...\n");
1062 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
1063 if (chunk.id == DMUS_FOURCC_SCRIPT_FORM) {
1064 TRACE("'DMSC': script form\n");
1066 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1067 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1068 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
1071 case DMUS_FOURCC_SCRIPT_CHUNK: {
1072 TRACE("'schd': script header\n");
1073 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
1074 TRACE_(dmfiledat)("=> dwFlags = %ld\n", header.dwFlags);
1076 } case DMUS_FOURCC_GUID_CHUNK: {
1077 TRACE("'guid': GUID\n");
1078 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
1079 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
1081 } case DMUS_FOURCC_VERSION_CHUNK: {
1082 TRACE("'vers': version\n");
1083 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
1084 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
1086 } case FOURCC_LIST:{
1087 TRACE("'LIST': list (size) = %ld\n", chunk.size);
1088 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1089 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1092 case DMUS_FOURCC_UNFO_LIST: {
1093 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1094 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1095 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1097 } case DMUS_FOURCC_REF_LIST: {
1098 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
1099 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
1100 DMUSIC_FillReferenceFromFileHandle (scriptsrcref, fd);
1102 WARN("invalid chunk (only 'UNFO' and 'DMRF' chunks allowed)\n");
1106 } case DMUS_FOURCC_SCRIPTVERSION_CHUNK: {
1107 TRACE("'scve': DirectMusic version\n");
1108 ReadFile (fd, &scriptversion, chunk.size, &BytesRead, NULL);
1109 TRACE_(dmfiledat)("=> script version = %ld%ld\n", scriptversion.dwVersionMS, scriptversion.dwVersionLS);
1111 } case FOURCC_RIFF: {
1112 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded container form)\n", chunk.size);
1113 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1114 if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) {
1115 TRACE("'DMCN': embedded container form (forward to DMUSIC_FillContainerFromFileHandle(...))\n");
1116 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1117 DMUSIC_FillContainerFromFileHandle (NULL, fd);
1118 } else WARN("invalid chunk (only 'DMCN' chunk allowed)\n");
1120 } case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: {
1121 TRACE("'scla': scripting language\n");
1122 scriptlang = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
1123 ReadFile (fd, scriptlang, chunk.size, &BytesRead, NULL);
1124 TRACE_(dmfiledat)("script language = %s\n", debugstr_w(scriptlang));
1126 } case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: {
1127 TRACE("'scsr': script source\n");
1128 scriptsrc = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
1129 ReadFile (fd, scriptsrc, chunk.size, &BytesRead, NULL);
1130 TRACE_(dmfiledat)("script source = %s\n", debugstr_w(scriptsrc));
1133 WARN("invalid chunk (only 'schd', 'guid', 'vers', 'LIST', 'scve', 'RIFF' and 'scla' chunks allowed)\n");
1137 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1138 } while (FileCount < FileSize);
1140 WARN("invalid chunk (only 'DMSC' chunk allowed)\n");
1143 WARN("'RIFF' not found: not a RIFF file\n");
1149 /******************************************************************************
1150 * DMUSIC_FillContainerFromFileHandle:
1151 * - fills a IDirectMusicContainerImpl struct with data from file handle.
1152 * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it
1153 * from another DMUSIC_Fill* function, make sure pointer is at
1155 * - TODO: replace data in function with data in IDirectMusicContainerImpl
1157 HRESULT WINAPI DMUSIC_FillContainerFromFileHandle (IDirectMusicContainerImpl *container, HANDLE fd)
1160 DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
1161 /* FIXME: Replace stuff located below with the stuff in container */
1163 DMUS_IO_CONTAINER_HEADER header;
1164 DMUS_IO_VERSION version;
1167 DMUS_IO_CONTAINED_OBJECT_HEADER objheader;
1170 TRACE("reading 'RIFF' chunk...\n");
1171 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1172 if (chunk.id == FOURCC_RIFF) {
1173 TRACE("'RIFF': RIFF file\n");
1174 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
1175 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
1176 TRACE("reading chunks ...\n");
1177 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
1178 if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) {
1179 TRACE("'DMCN': container form\n");
1181 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1182 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1183 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
1186 case DMUS_FOURCC_CONTAINER_CHUNK: {
1187 TRACE("'conh': container header\n");
1188 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
1189 TRACE_(dmfiledat)("=> dwFlags = %ld\n", header.dwFlags);
1191 } case DMUS_FOURCC_GUID_CHUNK: {
1192 TRACE("'guid': GUID\n");
1193 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
1194 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
1196 } case DMUS_FOURCC_VERSION_CHUNK: {
1197 TRACE("'vers': version\n");
1198 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
1199 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
1201 } case FOURCC_LIST:{
1202 TRACE("'LIST': list (size) = %ld\n", chunk.size);
1203 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1204 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1207 case DMUS_FOURCC_UNFO_LIST: {
1208 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1209 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1210 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1212 } case DMUS_FOURCC_CONTAINED_OBJECTS_LIST: {
1213 TRACE("'cosl': objects list (content size = %ld)\n", ListSize);
1215 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1216 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1217 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1218 if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_CONTAINED_OBJECT_LIST) {
1219 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1220 ListCount2 = 0; /* reset */
1221 TRACE("'cobl': object (content size = %ld)\n", ListSize2);
1223 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1224 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1225 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1228 case DMUS_FOURCC_CONTAINED_ALIAS_CHUNK: {
1229 TRACE("'coba': alias (size = %ld)\n", chunk.size);
1230 alias = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
1231 ReadFile (fd, alias, chunk.size, &BytesRead, NULL);
1232 TRACE_(dmfiledat)("=> alias = %s\n", debugstr_w(alias));
1234 } case DMUS_FOURCC_CONTAINED_OBJECT_CHUNK: {
1235 TRACE("'cobh': object header (size = %ld)\n", chunk.size);
1236 ReadFile (fd, &objheader, chunk.size, &BytesRead, NULL);
1237 TRACE_(dmfiledat)("=> guidClassID = %s; dwFlags = %ld; ckid = %ld; fccType = %ld\n", \
1238 debugstr_guid(&objheader.guidClassID), objheader.dwFlags, objheader.ckid, objheader.fccType);
1240 } case FOURCC_LIST: {
1241 TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
1242 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1243 if (chunk.id == DMUS_FOURCC_REF_LIST) {
1244 TRACE("'DMRF': reference list (instead of 'data' chunk: size = %ld)\n", chunk.size - 4); /* set pointer at beginning of list */
1245 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT);
1246 DMUSIC_FillReferenceFromFileHandle (dataref, fd); /* forward to DMUSIC_FillReferenceFromFileHandle */
1247 } else WARN("invalid chunk (only 'DMRF' chunk allowed\n");
1249 } case FOURCC_RIFF: {
1250 TRACE("'RIFF': encapsulated data (can be 'DMSG' or 'DMSG')\n");
1251 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1252 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1255 case DMUS_FOURCC_SEGMENT_FORM: {
1256 TRACE("'DMSG': embedded segment form (forward to DMUSIC_FillSegmentFromFileHandle(...))\n");
1257 DMUSIC_FillSegmentFromFileHandle (NULL, fd);
1259 } case DMUS_FOURCC_STYLE_FORM: {
1260 TRACE("'DMST': embedded style form (forward to DMUSIC_FillStyleFromFileHandle(...))\n");
1261 DMUSIC_FillStyleFromFileHandle (NULL, fd);
1263 } case mmioFOURCC('W','A','V','E'): {
1264 FIXME("'WAVE': not yet supported (skipping)\n");
1265 SetFilePointer (fd, sizeof(FOURCC) + sizeof(DWORD) + chunk.size, NULL, FILE_CURRENT); /* skip */
1268 WARN("invalid chunk (only 'DMSG' and 'DMST' chunks allowed)\n");
1274 WARN("invalid chunk (only 'coba', 'cobh', 'data' and 'LIST' chunks allowed\n");
1278 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
1279 } while (ListCount2 < ListSize2);
1280 } else WARN("invalid chunk (only 'cobl' chunk allowed)\n");
1281 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
1282 } while (ListCount < ListSize);
1285 WARN("invalid chunk (only 'UNFO' and 'cosl' chunks allowed)\n");
1290 WARN("invalid chunk (only 'schd', 'guid', 'vers', 'LIST', 'scve', 'RIFF' and 'scla' chunks allowed)\n");
1294 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1295 } while (FileCount < FileSize);
1297 WARN("invalid chunk (only 'DMSC' chunk allowed)\n");
1300 WARN("'RIFF' not found: not a RIFF file\n");
1306 /******************************************************************************
1307 * DMUSIC_FillStyleFromFileHandle:
1308 * - fills a IDirectMusicStyle8Impl struct with data from file handle.
1309 * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it
1310 * from another DMUSIC_Fill* function, make sure pointer is at
1312 * - TODO: replace data in function with data in IDirectMusicStyleImpl
1314 HRESULT WINAPI DMUSIC_FillStyleFromFileHandle (IDirectMusicStyle8Impl *style, HANDLE fd)
1317 DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
1319 /* FIXME: Replace stuff located below with the stuff in container */
1321 DMUS_IO_STYLE header;
1322 DMUS_IO_VERSION version;
1327 TRACE("reading 'RIFF' chunk...\n");
1328 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1329 if (chunk.id == FOURCC_RIFF) {
1330 TRACE("'RIFF': RIFF file\n");
1331 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
1332 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
1333 TRACE("reading chunks ...\n");
1334 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
1335 if (chunk.id == DMUS_FOURCC_STYLE_FORM) {
1336 TRACE("'DMST': style form\n");
1338 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1339 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1340 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
1344 case DMUS_FOURCC_STYLE_CHUNK: {
1345 TRACE("'styh': style header\n");
1346 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
1347 TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; dblTempo = %f\n", \
1348 header.timeSig.bBeatsPerMeasure, header.timeSig.bBeat, header.timeSig.wGridsPerBeat, header.dblTempo);
1350 } case DMUS_FOURCC_GUID_CHUNK: {
1351 TRACE("'guid': GUID\n");
1352 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
1353 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
1355 } case DMUS_FOURCC_VERSION_CHUNK: {
1356 TRACE("'vers': version\n");
1357 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
1358 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
1360 } case FOURCC_RIFF: {
1361 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
1362 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1363 if (chunk.id == DMUS_FOURCC_BAND_FORM) {
1364 TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n");
1365 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1366 DMUSIC_FillBandFromFileHandle (NULL, fd);
1367 } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n");
1369 } case FOURCC_LIST:{
1370 TRACE("'LIST': list (size) = %ld\n", chunk.size);
1371 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1373 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1376 case DMUS_FOURCC_UNFO_LIST: {
1377 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1378 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1379 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1381 } case DMUS_FOURCC_PART_LIST: {
1382 TRACE("'part': parts list (content size = %ld)\n", ListSize);
1384 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1385 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1386 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1389 case DMUS_FOURCC_PART_CHUNK: {
1390 TRACE("'prth': part header\n");
1391 ReadFile (fd, &part.header, chunk.size, &BytesRead, NULL);
1392 TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; dwVariationChoices = %p; guidPartID = %s; wNbrMeasures = %d; bPlayModeFlags = %i; bInvertUpper = %i; bInvertLower = %i; bPad = %p; dwFlags = %ld\n", \
1393 part.header.timeSig.bBeatsPerMeasure, part.header.timeSig.bBeat, part.header.timeSig.wGridsPerBeat, part.header.dwVariationChoices, \
1394 debugstr_guid (&part.header.guidPartID), part.header.wNbrMeasures, part.header.bPlayModeFlags, part.header.bInvertUpper, part.header.bInvertLower, \
1395 part.header.bPad, part.header.dwFlags);
1397 } case DMUS_FOURCC_NOTE_CHUNK: {
1398 TRACE("'note': notes (size = %ld)\n", chunk.size);
1399 part.nrofnotes = chunk.size - sizeof(DWORD); /* pure contents of 'note' (without first DWORD) */
1400 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLENOTE) */
1401 part.nrofnotes /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLENOTE) */
1402 part.notes = (DMUS_IO_STYLENOTE*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofnotes);
1403 ReadFile (fd, part.notes, chunk.size * part.nrofnotes, &BytesRead, NULL);
1404 TRACE_(dmfiledat)("=> number of notes = %ld\n", part.nrofnotes);
1405 for (i = 0; i < part.nrofnotes; i++)
1407 TRACE_(dmfiledat)("=> note[%i]: mtGridStart = %li; dwVariation = %ld; mtDuration = %li; nTimeOffset = %i; wMusicValue = %d; bVelocity = %i; bTimeRange = %i; bDurRange = %i; bVelRange = %i; bInversionID = %i; bPlayModeFlags = %i; bNoteFlags= %i;\n", \
1408 i, part.notes[i].mtGridStart, part.notes[i].dwVariation, part.notes[i].mtDuration, part.notes[i].nTimeOffset, part.notes[i].wMusicValue, part.notes[i].bVelocity, part.notes[i].bTimeRange, \
1409 part.notes[i].bDurRange, part.notes[i].bVelRange, part.notes[i].bInversionID, part.notes[i].bPlayModeFlags, part.notes[i].bNoteFlags);
1412 } case DMUS_FOURCC_CURVE_CHUNK: {
1413 TRACE("'crve': curves (size = %ld)\n", chunk.size);
1414 part.nrofcurves = chunk.size - sizeof(DWORD); /* pure contents of 'crve' (without first DWORD) */
1415 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLECURVE) */
1416 part.nrofcurves /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLECURVE) */
1417 part.curves = (DMUS_IO_STYLECURVE*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofcurves);
1418 ReadFile (fd, part.curves, chunk.size * part.nrofcurves, &BytesRead, NULL);
1419 TRACE_(dmfiledat)("=> number of curves = %ld\n", part.nrofcurves);
1420 for (i = 0; i < part.nrofcurves; i++)
1422 TRACE_(dmfiledat)("=> curve[%i]: mtGridStart = %li; dwVariation = %ld; mtDuration = %li; mtResetDuration = %li; nTimeOffset = %i; nStartValue = %i; nEndValue = %i; nResetValue = %i; bEventType = %i; bCurveShape = %i; bCCData = %i; bFlags = %i; wParamType = %d;wMergeIndex = %d\n", \
1423 i, part.curves[i].mtGridStart, part.curves[i].dwVariation, part.curves[i].mtDuration, part.curves[i].mtResetDuration, part.curves[i].nTimeOffset, part.curves[i].nStartValue, part.curves[i].nEndValue, \
1424 part.curves[i].nResetValue, part.curves[i].bEventType, part.curves[i].bCurveShape, part.curves[i].bCCData, part.curves[i].bFlags, part.curves[i].wParamType, part.curves[i].wMergeIndex);
1427 } case DMUS_FOURCC_MARKER_CHUNK: {
1428 TRACE("'mrkr': markers (size = %ld)\n", chunk.size);
1429 part.nrofmarkers = chunk.size - sizeof(DWORD); /* pure contents of 'mrkr' (without first DWORD) */
1430 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLEMARKER) */
1431 part.nrofmarkers /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLEMARKER) */
1432 part.markers = (DMUS_IO_STYLEMARKER*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofmarkers);
1433 ReadFile (fd, part.markers, chunk.size * part.nrofmarkers, &BytesRead, NULL);
1434 TRACE_(dmfiledat)("=> number of markers = %ld\n", part.nrofmarkers);
1435 for (i = 0; i < part.nrofmarkers; i++)
1437 TRACE_(dmfiledat)("=> marker[%i]: mtGridStart = %li; dwVariation = %ld; wMarkerFlags = %d\n", \
1438 i, part.markers[i].mtGridStart, part.markers[i].dwVariation, part.markers[i].wMarkerFlags);
1441 } case DMUS_FOURCC_RESOLUTION_CHUNK: {
1442 TRACE("'rsln': resolutions (size = %ld)\n", chunk.size);
1443 part.nrofresolutions = chunk.size - sizeof(DWORD); /* pure contents of 'rsln' (without first DWORD) */
1444 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLERESOLUTION) */
1445 part.nrofresolutions /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLERESOLUTION) */
1446 part.resolutions = (DMUS_IO_STYLERESOLUTION*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofresolutions);
1447 ReadFile (fd, part.resolutions, chunk.size * part.nrofresolutions, &BytesRead, NULL);
1448 TRACE_(dmfiledat)("=> number of resolutions = %ld\n", part.nrofresolutions);
1449 for (i = 0; i < part.nrofresolutions; i++)
1451 TRACE_(dmfiledat)("=> resolution[%i]: dwVariation = %ld; wMusicValue = %d; bInversionID = %i; bPlayModeFlags = %i", \
1452 i, part.resolutions[i].dwVariation, part.resolutions[i].wMusicValue, part.resolutions[i].bInversionID, part.resolutions[i].bPlayModeFlags);
1455 } case DMUS_FOURCC_ANTICIPATION_CHUNK: {
1456 TRACE("'anpn': anticipations (size = %ld)\n", chunk.size);
1457 part.nrofanticipations = chunk.size - sizeof(DWORD); /* pure contents of 'anpn' (without first DWORD) */
1458 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLE_ANTICIPATION) */
1459 part.nrofanticipations /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLE_ANTICIPATION) */
1460 part.anticipations = (DMUS_IO_STYLE_ANTICIPATION*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofanticipations);
1461 ReadFile (fd, part.anticipations, chunk.size * part.nrofanticipations, &BytesRead, NULL);
1462 TRACE_(dmfiledat)("=> number of anticipations = %ld\n", part.nrofanticipations);
1463 for (i = 0; i < part.nrofanticipations; i++)
1465 TRACE_(dmfiledat)("=> anticipation[%i]: mtGridStart = %li; dwVariation = %ld; nTimeOffset = %i; bTimeRange = %i\n", \
1466 i, part.anticipations[i].mtGridStart, part.anticipations[i].dwVariation, part.anticipations[i].nTimeOffset, part.anticipations[i].bTimeRange);
1469 } case FOURCC_LIST: {
1470 TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
1471 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1472 if (chunk.id == DMUS_FOURCC_UNFO_LIST) {
1473 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1474 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* set pointer at beginning of list */
1475 DMUSIC_FillUNFOFromFileHandle (part.UNFO, fd);
1476 } else WARN("invalid chunk (only 'UNFO' chunk allowed\n");
1479 WARN("invalid chunk (only 'prth','note', 'crve', 'mrkr', 'rsln', 'anpn' and 'LIST' chunks allowed\n");
1483 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
1484 } while (ListCount < ListSize);
1486 } case DMUS_FOURCC_PATTERN_LIST: {
1487 TRACE("'pttn': patterns list (content size = %ld)\n", ListSize);
1489 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1490 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1491 ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1494 case DMUS_FOURCC_PATTERN_CHUNK: {
1495 TRACE("'ptnh': pattern header\n");
1496 ReadFile (fd, &pattern.header, chunk.size, &BytesRead, NULL);
1497 TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; bGrooveBottom = %i; bGrooveTop = %i; wEmbellishment = %d; wNbrMeasures = %d; bDestGrooveBottom = %i; bDestGrooveTop = %i; dwFlags = %ld\n", \
1498 pattern.header.timeSig.bBeatsPerMeasure, pattern.header.timeSig.bBeat, pattern.header.timeSig.wGridsPerBeat, pattern.header.bGrooveBottom, pattern.header.bGrooveTop, pattern.header.wEmbellishment, \
1499 pattern.header.wNbrMeasures, pattern.header.bDestGrooveBottom, pattern.header.bDestGrooveTop, pattern.header.dwFlags);
1501 } case DMUS_FOURCC_RHYTHM_CHUNK: {
1502 TRACE("'rhtm': rhytms\n");
1503 pattern.nrofrhytms = chunk.size / sizeof(DWORD);
1504 TRACE_(dmfiledat)("=> number of rhytms = %ld\n", pattern.nrofrhytms);
1505 pattern.rhytms = (DWORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DWORD) * pattern.nrofrhytms);
1506 ReadFile (fd, pattern.rhytms, sizeof(DWORD) * pattern.nrofrhytms, &BytesRead, NULL);
1507 for (i = 0; i < pattern.nrofrhytms; i++)
1509 TRACE_(dmfiledat)("=> rhytm[%i] = %ld\n", i, pattern.rhytms[i]);
1512 } case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: {
1513 TRACE("'mtfs': motif settings\n");
1514 ReadFile (fd, &pattern.motsettings, chunk.size, &BytesRead, NULL);
1515 TRACE_(dmfiledat)("=> dwRepeats = %ld; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld\n", \
1516 pattern.motsettings.dwRepeats, pattern.motsettings.mtPlayStart, pattern.motsettings.mtLoopStart, pattern.motsettings.mtLoopEnd, pattern.motsettings.dwResolution);
1518 } case FOURCC_LIST: {
1519 TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
1520 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1522 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1525 case DMUS_FOURCC_UNFO_LIST: {
1526 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1527 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1528 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1530 } case DMUS_FOURCC_PARTREF_LIST: {
1531 TRACE("'pref': part references list (content size = %ld)\n", ListSize2);
1533 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1534 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1535 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1538 case DMUS_FOURCC_PARTREF_CHUNK: {
1539 TRACE("'prfc': part reference\n");
1540 ReadFile (fd, &pattern.partref, chunk.size, &BytesRead, NULL);
1541 TRACE_(dmfiledat)("=> guidPartID = %s; wLogicalPartID = %d; bVariationLockID = %i; bSubChordLevel = %i; bPriority = %i; bRandomVariation = %i; wPad = %d; dwPChannel = %ld\n", \
1542 debugstr_guid (&pattern.partref.guidPartID), pattern.partref.wLogicalPartID, pattern.partref.bVariationLockID, pattern.partref.bSubChordLevel, \
1543 pattern.partref.bPriority, pattern.partref.bRandomVariation, pattern.partref.wPad, pattern.partref.dwPChannel);
1545 } case FOURCC_LIST: {
1546 TRACE("'LIST': list chunk (MSDN doesn't mention it)\n");
1547 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1548 if (chunk.id == DMUS_FOURCC_UNFO_LIST) {
1549 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1550 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1551 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1553 WARN("invalid chunk (only 'UNFO' chunk allowed)\n");
1557 WARN("invalid chunk (only 'prfc' and 'UNFO'chunk allowed)\n");
1560 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
1561 } while (ListCount2 < ListSize2);
1564 WARN("invalid chunk (only 'UNFO' and 'pref' chunks allowed\n");
1569 } case FOURCC_RIFF: {
1570 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
1571 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1572 if (chunk.id == DMUS_FOURCC_BAND_FORM) {
1573 TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle(...))\n");
1574 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1575 DMUSIC_FillBandFromFileHandle (NULL, fd);
1576 } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n");
1579 WARN("invalid chunk (only 'prnh','rhtm', 'mtfs', 'LIST' and 'RIFF' chunks allowed\n");
1583 TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
1584 } while (ListCount < ListSize);
1587 WARN("invalid chunk (only 'UNFO', 'part', 'pttn' and 'RIFF' chunks allowed)\n");
1592 WARN("invalid chunk (only 'styh', 'guid', 'vers', 'LIST', and 'RIFF' chunks allowed)\n");
1596 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1597 } while (FileCount < FileSize);
1599 WARN("invalid chunk (only 'DMST' chunk allowed)\n");
1602 WARN("'RIFF' not found: not a RIFF file\n");