Well, trying to run AudioScript.exe from DX SDK and read both script files results in this patch. It can now parse files containing scripts, tracks (some parts are still missing), containers, bands and others. More support will be added (I'm now officially on holidays =)). Anyway, I have some questions: - at some points in file, chunk size, which should be same as sizeof(some_dmus_struct) actually differs from sizeof (tests show that it's 4 bytes bigger). Functions for now read whole chunk (with chunk size given in file), although it may corrupt data within struct. Any suggestions? - do we need routines for reading of WAVE files (which are sometimes embedded within container)? or is there existing function in winmm/dsound code? (dsound docs say app is responsible for loading WAVEs, but just to make sure...). The patch applies cleanly to today's CVS (but isn't based on Raphael's latest patch since it doesn't apply cleanly (btw: I'll clean dmusic/dmusic8 interfaces when I'm finished with framework (it isn't trivial right now)). -- Rok Mandeljc <rok.mandeljc@gimb.org> "All that is gold does not glitter, Not all those who wander are lost; The old that is strong does not wither, Deep roots are not reached by the frost. From the ashes a fire shall be woken, A light from the shadows shall spring; Renewed shall be blade that was broken, The crownless again shall be king." -- J.R.R. Tolkien
diff -Nru Original/wine/dlls/dmusic/dmusic_loader.c wine/dlls/dmusic/dmusic_loader.c --- Original/wine/dlls/dmusic/dmusic_loader.c 2003-06-27 14:34:52.000000000 +0200 +++ wine/dlls/dmusic/dmusic_loader.c 2003-06-27 14:41:15.000000000 +0200 @@ -312,12 +312,12 @@ WCHAR* pwzFilePath, void** ppObject) { - HANDLE fd; - ICOM_THIS(IDirectMusicLoader8Impl,iface); FIXME("(%p, %s, %s, %s, %p): stub\n", This, debugstr_guid(rguidClassID), debugstr_guid(iidInterfaceID), debugstr_w(pwzFilePath), ppObject); + HANDLE *fd; + fd = CreateFileW (pwzFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (!fd) { WARN ("could not load file\n"); @@ -331,6 +331,7 @@ DMUSIC_FillBandFromFileHandle (NULL, fd); } else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicContainer)) { FIXME("wanted 'con'\n"); + DMUSIC_FillContainerFromFileHandle (NULL, fd); } else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicCollection)) { FIXME("wanted 'dls'\n"); } else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicChordMap)) { @@ -340,6 +341,7 @@ DMUSIC_FillSegmentFromFileHandle (NULL, fd); } else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicScript)) { FIXME("wanted 'spt'\n"); + DMUSIC_FillScriptFromFileHandle (NULL, fd); } else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicSong)) { FIXME("wanted 'sng'\n"); } else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicStyle)) { @@ -369,6 +371,13 @@ container->ref = 1; *ppObject = container; return S_OK; + } else if (IsEqualGUID(iidInterfaceID, &IID_IDirectMusicScript)) { + IDirectMusicScriptImpl* script; + script = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectMusicScriptImpl)); + script->lpVtbl = &DirectMusicScript_Vtbl; + script->ref = 1; + *ppObject = script; + return S_OK; } else { FIXME("bad iid\n"); } diff -Nru Original/wine/dlls/dmusic/dmusic_private.h wine/dlls/dmusic/dmusic_private.h --- Original/wine/dlls/dmusic/dmusic_private.h 2003-06-27 14:34:52.000000000 +0200 +++ wine/dlls/dmusic/dmusic_private.h 2003-06-27 15:06:01.000000000 +0200 @@ -157,7 +157,7 @@ { FOURCC id; /* FOURCC */ DWORD size; /* size of chunk_riff */ - /* BYTE* data; */ /* chunk_riff data */ + // BYTE* data; /* chunk_riff data */ } rawChunk; /* struct in which UNFO data is stored */ @@ -203,6 +203,66 @@ } BandTrack; + +typedef struct _Part +{ + DMUS_IO_STYLEPART header; + UNFO_List UNFO; + DWORD nrofnotes; + DMUS_IO_STYLENOTE* notes; + DWORD nrofcurves; + DMUS_IO_STYLECURVE* curves; + DWORD nrofmarkers; + DMUS_IO_STYLEMARKER* markers; + DWORD nrofresolutions; + DMUS_IO_STYLERESOLUTION* resolutions; + DWORD nrofanticipations; + DMUS_IO_STYLE_ANTICIPATION* anticipations; +} Part; + +typedef struct _Pattern +{ + DMUS_IO_PATTERN header; + DWORD nrofrhytms; + DWORD* rhytms; + UNFO_List UNFO; + DMUS_IO_MOTIFSETTINGS motsettings; + /* IDirectMusicBandImpl band */ + DWORD nrofpartrefs; + /* FIXME: only in singular form for now */ + UNFO_List partrefUNFO; + DMUS_IO_PARTREF partref; +} Pattern; + +typedef struct _WaveTrack +{ + DMUS_IO_WAVE_TRACK_HEADER header; + /* FIXME: only in singular form now */ + DMUS_IO_WAVE_PART_HEADER partHeader; + DMUS_IO_WAVE_ITEM_HEADER itemHeader; + Reference reference; +} WaveTrack; + +typedef struct _SegTriggerTrack +{ + DMUS_IO_SEGMENT_TRACK_HEADER header; + /* FIXME: only in singular form now */ + DMUS_IO_SEGMENT_ITEM_HEADER itemHeader; + Reference reference; + WCHAR* motifName; +} SegTriggerTrack; + +typedef struct _TimeSigTrack { + DWORD nrofitems; + DMUS_IO_TIMESIGNATURE_ITEM* items; +} TimeSigTrack; + +typedef struct _ScriptEvent { + DMUS_IO_SCRIPTTRACK_EVENTHEADER header; + Reference reference; + WCHAR* name; +} ScriptEvent; + /***************************************************************************** * IDirectMusicImpl implementation structure */ @@ -1379,5 +1439,8 @@ HRESULT WINAPI DMUSIC_FillReferenceFromFileHandle (Reference reference, HANDLE fd); HRESULT WINAPI DMUSIC_FillUNFOFromFileHandle (UNFO_List UNFO, HANDLE fd); HRESULT WINAPI DMUSIC_FillBandFromFileHandle (IDirectMusicBandImpl *band, HANDLE fd); +HRESULT WINAPI DMUSIC_FillScriptFromFileHandle (IDirectMusicScriptImpl *script, HANDLE fd); +HRESULT WINAPI DMUSIC_FillContainerFromFileHandle (IDirectMusicContainerImpl *container, HANDLE fd); +HRESULT WINAPI DMUSIC_FillStyleFromFileHandle (IDirectMusicStyleImpl *style, HANDLE fd); #endif /* __WINE_DMUSIC_PRIVATE_H */ diff -Nru Original/wine/dlls/dmusic/helper.c wine/dlls/dmusic/helper.c --- Original/wine/dlls/dmusic/helper.c 2003-06-27 14:34:52.000000000 +0200 +++ wine/dlls/dmusic/helper.c 2003-06-27 15:07:15.000000000 +0200 @@ -56,31 +56,31 @@ { case DMUS_FOURCC_UNAM_CHUNK: { TRACE("'UNAM': name\n"); - UNFO.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */ + UNFO.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ ReadFile (fd, UNFO.name, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> name = %s\n", debugstr_w(UNFO.name)); break; } case DMUS_FOURCC_UART_CHUNK: { TRACE("'UART': artist\n"); - UNFO.artist = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */ + UNFO.artist = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ ReadFile (fd, UNFO.artist, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("artist = %s\n", debugstr_w(UNFO.artist)); break; } case DMUS_FOURCC_UCOP_CHUNK: { TRACE("'UCOP': copyright\n"); - UNFO.copyright = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */ + UNFO.copyright = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ ReadFile (fd, UNFO.copyright, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> copyright = %s\n", debugstr_w(UNFO.copyright)); break; } case DMUS_FOURCC_USBJ_CHUNK:{ TRACE("'USBJ': subject\n"); - UNFO.subject = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */ + UNFO.subject = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ ReadFile (fd, UNFO.subject, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> subject = %s\n", debugstr_w(UNFO.subject)); break; } case DMUS_FOURCC_UCMT_CHUNK: { TRACE("'UCMT': comment\n"); - UNFO.comment = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */ + UNFO.comment = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ ReadFile (fd, UNFO.comment, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> comment = %s\n", debugstr_w(UNFO.comment)); break; @@ -138,19 +138,19 @@ break; } case DMUS_FOURCC_NAME_CHUNK: { TRACE("'name': name\n"); - reference.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); + reference.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); ReadFile (fd, reference.name, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> name = %s\n", debugstr_w (reference.name)); break; } case DMUS_FOURCC_FILE_CHUNK: { TRACE("'file': file name\n"); - reference.file = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); + reference.file = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); ReadFile (fd, reference.file, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> file name = %s\n", debugstr_w (reference.file)); break; } case DMUS_FOURCC_CATEGORY_CHUNK: { TRACE("'catg': category\n"); - reference.category = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); + reference.category = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); ReadFile (fd, reference.category, chunk.size, &BytesRead, NULL); TRACE_(dmfiledat)("=> category = %s\n", debugstr_w (reference.category)); break; @@ -267,7 +267,6 @@ } TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2); } while (ListCount2 < ListSize2); - } else WARN("invalid chunk (only 'lbin' chunk allowed)\n"); TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); } while (ListCount < ListSize); @@ -306,7 +305,9 @@ HRESULT WINAPI DMUSIC_FillTrackFromFileHandle (IDirectMusicTrackImpl *segment, HANDLE fd) { rawChunk chunk; - DWORD BytesRead, ListCount = 0, ListCount2 = 0, ListSize, ListSize2, FileCount = 0, FileSize, FileCount2 = 0, FileSize2 /* *2s are for various subchunks */; + DWORD BytesRead, ListCount = 0, ListCount2 = 0, ListCount3 = 0, ListCount4 = 0, \ + ListSize, ListSize2, ListSize3, ListSize4, FileCount = 0, FileSize, FileCount2 = 0, FileSize2 /* *2s, *3s and *4s are for various subchunks */; + int i; /* general track info */ DMUS_IO_TRACK_HEADER header; @@ -326,7 +327,15 @@ Reference reference; /* band track stuff */ BandTrack bandTrack; - + /* wave track stuff (only singular) */ + WaveTrack waveTrack; + /* segment trigger track stuff */ + SegTriggerTrack segTriggerTrack; + /* time signature track stuff */ + TimeSigTrack timeSigTrack; + /* script track list stuff */ + ScriptEvent event; + TRACE("reading 'RIFF' chunk...\n"); ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); if (chunk.id == FOURCC_RIFF) { @@ -391,7 +400,6 @@ TRACE_(dmfiledat)("=> chord root = %i; scale = %i\n", (chordHeader && 0xFF000000) >> 24, chordHeader && 0x00FFFFFF); break; } case DMUS_FOURCC_CHORDTRACKBODY_CHUNK: { - int i; TRACE("'crdb': chord body\n"); ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_CHORD) */ ReadFile (fd, &chordData.chord, chunk.size, &BytesRead, NULL); /* read DMUS_IO_CHORD */ @@ -401,6 +409,7 @@ TRACE_(dmfiledat)("=> number of subchords = %ld\n", chordData.nrofsubchords); ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_SUBCHORD) */ chordData.subchord = (DMUS_IO_SUBCHORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DMUS_IO_SUBCHORD) * chordData.nrofsubchords); /* allocate space */ + int i; for (i = 0; i < chordData.nrofsubchords; i++) { TRACE_(dmfiledat)("=> subchord[%i]: dwChordPattern = %ld; dwScalePattern = %ld; dwInversionPoints = %ld; dwLevels = %ld; bChordRoot = %i; bScaleRoot = %i\n", \ @@ -425,6 +434,7 @@ ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_STYLE_REF_LIST) { ListSize2 = chunk.size - sizeof(FOURCC); + ListCount2 = 0; TRACE("'strf': style reference list (size = %ld)\n", ListSize2); do { @@ -462,7 +472,304 @@ TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); } while (ListCount < ListSize); break; - } + } case DMUS_FOURCC_PERS_TRACK_LIST: { + FIXME("'pftr': chordmap track list: not supported yet\n"); + break; + } case DMUS_FOURCC_LYRICSTRACK_LIST: { + FIXME("'lyrt': lyrics track list: not supported yet\n"); + break; + } case DMUS_FOURCC_MARKERTRACK_LIST: { + FIXME("'MARK': marker track list: not supported yet\n"); + break; + } case DMUS_FOURCC_MELODYFORM_TRACK_LIST: { + FIXME("'mfrm': melody formulation track list: not supported yet\n"); + break; + } case DMUS_FOURCC_PARAMCONTROLTRACK_TRACK_LIST: { + FIXME("'prmt': parameter control track list: not supported yet\n"); + break; + } case DMUS_FOURCC_SCRIPTTRACK_LIST: { + TRACE("'scrt': script track list\n"); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SCRIPTTRACKEVENTS_LIST) { + TRACE("'scrl': script events list\n"); + ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount2 = 0; + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SCRIPTTRACKEVENT_LIST) { + TRACE("'scre': script event list\n"); + ListSize3 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount3 = 0; + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_SCRIPTTRACKEVENTHEADER_CHUNK: { + TRACE("'scrh': event header\n"); + ReadFile (fd, &event.header, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> dwFlags = %ld; lTimeLogical = %li; lTimePhysical = %li\n", \ + event.header.dwFlags, event.header.lTimeLogical, event.header.lTimePhysical); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_REF_LIST){ + TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */ + DMUSIC_FillReferenceFromFileHandle (event.reference, fd); + } else { + WARN("invalid chunk (only 'DMRF' chunk allwed)\n"); + } + break; + } case DMUS_FOURCC_SCRIPTTRACKEVENTNAME_CHUNK: { + TRACE("'scrn': routine name\n"); + event.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); + ReadFile (fd, event.name, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> routine name = %s\n", debugstr_w (event.name)); + break; + } default: { + WARN("invalid chunk (only 'scrh', 'scrn' and 'LIST' chunk allowed)\n"); + break; + } + } + TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3); + } while (ListCount3 < ListSize3); + } else { + WARN("invalid chunk (only 'scre' chunk allowed)\n"); + } + TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2); + } while (ListCount2 < ListSize2); + } else { + WARN("invalid chunk (only 'scrl' chunk allowed)\n"); + } + TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); + } while (ListCount < ListSize); + break; + } case DMUS_FOURCC_SEGTRACK_LIST: { + TRACE("'segt': segment trigger track list\n"); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_SEGTRACK_CHUNK: { + TRACE("'sgth': segment track header\n"); + ReadFile (fd, &segTriggerTrack.header, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> dwFlags = %ld\n", segTriggerTrack.header.dwFlags); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_SEGMENTS_LIST) { + TRACE("'lsgl': segment lists list\n"); + ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount2 = 0; + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SEGMENT_LIST) { + ListSize3 = chunk.size - sizeof(FOURCC); + ListCount3 = 0; + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_SEGMENTITEM_CHUNK: { + TRACE("'sgih': segment item header\n"); + ReadFile (fd, &segTriggerTrack.itemHeader, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> lTimeLogical = %li; lTimePhysical = %li; dwPlayFlags = %ld; dwFlags = %ld\n", \ + segTriggerTrack.itemHeader.lTimeLogical, segTriggerTrack.itemHeader.lTimePhysical, \ + segTriggerTrack.itemHeader.dwPlayFlags, segTriggerTrack.itemHeader.dwFlags); + break; + } case DMUS_FOURCC_SEGMENTITEMNAME_CHUNK: { + TRACE("'snam': motif name\n"); + segTriggerTrack.motifName = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); + ReadFile (fd, segTriggerTrack.motifName, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> motif name = %s\n", debugstr_w (segTriggerTrack.motifName)); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_REF_LIST) { + TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */ + DMUSIC_FillReferenceFromFileHandle (segTriggerTrack.reference, fd); + } else { + WARN("invalid chunk (only 'DMRF' chunk allowed)\n"); + } + break; + } default: { + WARN("invalid chunk (only 'sgih', 'snam' and 'LIST' chunks allowed)\n"); + break; + } + } + TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3); + } while (ListCount3 < ListSize3); + } else { + WARN("invalid chunk (only 'lseg' chunk allowed)\n"); + } + TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2); + } while (ListCount2 < ListSize2); + } else { + WARN("invalid chunk (only 'lsgl' chunk allowed\n"); + } + break; + } default: { + WARN("invalid chunk (only 'sgth' and 'LIST' chunks allowed)\n"); + break; + } + } + TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); + } while (ListCount < ListSize); + break; + } case DMUS_FOURCC_TIMESIGTRACK_LIST: { + TRACE("'TIMS': time signature track list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_TIMESIGNATURE_TRACK) { + TRACE("'tims': time signatures\n"); + timeSigTrack.nrofitems = chunk.size - sizeof(DWORD); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + if (chunk.size != sizeof(DMUS_IO_TIMESIGNATURE_ITEM)) + 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)); + timeSigTrack.nrofitems /= chunk.size; + TRACE_(dmfiledat)("=> number of items = %ld\n", timeSigTrack.nrofitems); + timeSigTrack.items = (DMUS_IO_TIMESIGNATURE_ITEM*) HeapAlloc (GetProcessHeap (), 0, chunk.size * timeSigTrack.nrofitems); + ReadFile(fd, timeSigTrack.items, chunk.size * timeSigTrack.nrofitems, &BytesRead, NULL); + for (i = 0; i < timeSigTrack.nrofitems; i++) + { + TRACE_(dmfiledat)("=> time signature[%i]: lTime = %li; bBeatsPerMeasure = %i; bBeat = %i; wGridsPerBeat = %d\n", \ + i, timeSigTrack.items[i].lTime, timeSigTrack.items[i].bBeatsPerMeasure, timeSigTrack.items[i].bBeat, timeSigTrack.items[i].wGridsPerBeat); + } + } else { + WARN("invalid chunk (only 'tims' chunk allowed)\n"); + } + break; + } case DMUS_FOURCC_WAVETRACK_LIST: { + TRACE("'wavt': wave track list\n"); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_WAVETRACK_CHUNK: { + TRACE("'wath': wave track header\n"); + ReadFile (fd, &waveTrack.header, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> lVolume = %li; dwFlags = %ld\n", waveTrack.header.lVolume, waveTrack.header.dwFlags); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_WAVEPART_LIST) { + TRACE("'wavp': wave parts list\n"); + ListSize2 = chunk.size - sizeof(FOURCC); + ListCount2 = 0; + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_WAVEPART_CHUNK: { + TRACE("'waph': wave part header\n"); + ReadFile (fd, &waveTrack.partHeader, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> lVolume = %li; dwVariations = %ld; dwPChannel = %ld; dwLockToPart = %ld; dwFlags = %ld; dwIndex = %ld\n", \ + waveTrack.partHeader.lVolume, waveTrack.partHeader.dwVariations, waveTrack.partHeader.dwPChannel, \ + waveTrack.partHeader.dwLockToPart, waveTrack.partHeader.dwFlags, waveTrack.partHeader.dwIndex); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_WAVEITEM_LIST) { + TRACE("'wavi': wave items list\n"); + ListSize3 = chunk.size - sizeof(FOURCC); + ListCount3 = 0; + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_WAVE_LIST) { + TRACE("'wave': wave item list\n"); + ListSize4 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount4 = 0; /* reset */ + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount4 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_WAVEITEM_CHUNK: { + TRACE("'waih': wave item header\n"); + ReadFile (fd, &waveTrack.itemHeader, chunk.size, &BytesRead, NULL); + 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", \ + waveTrack.itemHeader.lVolume, waveTrack.itemHeader.lPitch, waveTrack.itemHeader.dwVariations, /*waveTrack.itemHeader.rtTime, \ + waveTrack.itemHeader.rtStartOffset, waveTrack.itemHeader.rtReserved, waveTrack.itemHeader.rtDuration, */waveTrack.itemHeader.mtLogicalTime, \ + waveTrack.itemHeader.dwLoopStart, waveTrack.itemHeader.dwLoopEnd, waveTrack.itemHeader.dwFlags); + break; + } case mmioFOURCC('w','v','c','u'): { + FIXME("'wvcu': undocumented and unknown chunk type (skipping)\n"); + SetFilePointer (fd, chunk.size, NULL, FILE_CURRENT); /* skip */ + break; + } case FOURCC_LIST: { + TRACE("'LIST': list\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_REF_LIST) { + TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */ + DMUSIC_FillReferenceFromFileHandle (waveTrack.reference, fd); + } else { + WARN ("invalid chunk (only 'DMRF' chunk allowed\n"); + } + break; + } default: { + WARN("invalid chunk (only 'waih' and 'LIST' (and undocumented 'wvcu') chunks allowed)\n"); + } + } + TRACE("ListCount4 (%ld) < ListSize4 (%ld)\n", ListCount4, ListSize4); + } while (ListCount4 < ListSize4); + } else { + WARN("invalid chunk (only 'wave' chunk allowed)\n"); + } + TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3); + } while (ListCount3 < ListSize3); + } else { + WARN("invalid chunk (only 'wavi' chunk allowed)\n"); + } + break; + } default: { + WARN("invalid chunk (only 'waph' and 'LIST' chunks allowed)\n"); + break; + } + } + TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2); + } while (ListCount2 < ListSize2); + } else { + WARN("invalid chunk (only 'wavp' chunk allwed)\n"); + } + break; + } default: { + WARN("invalid chunk (only 'wath' and 'LIST' chunks allowed)\n"); + break; + } + } + TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); + } while (ListCount < ListSize); + break; + } default: { + WARN ("invalid chunk (only 'UNFO', 'cord', 'sttr', 'pftr', 'lyrt', 'MARK' and 'mfrm' chunks allowed)\n"); + break; + } } break; } case FOURCC_RIFF: { @@ -538,7 +845,7 @@ TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n"); SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */ DMUSIC_FillBandFromFileHandle (NULL, fd); - } else WARN("invalid chunk (only 'RIFF' chunk allowed)\n"); + } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n"); break; } default: { WARN("invalid chunk (only 'bdih', 'bd2h' and 'RIFF' chunks allowed)\n"); @@ -567,9 +874,6 @@ WARN("invalid chunk (only 'DMBT' chunk allowed\n"); } break; - } case DMUS_FOURCC_PERS_TRACK_LIST: { - FIXME("'pftr': chordmap track list: not supported yet\n"); - break; } case DMUS_FOURCC_COMMANDTRACK_CHUNK: { TRACE("'cmnd': command track\n"); ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof(DMUS_IO_COMMAND) */ @@ -577,30 +881,12 @@ TRACE_(dmfiledat)("wMeasure = %d; bBeat = %i; bCommand = %i; bGrooveLevel = %i; bGrooveRange = %i; bRepeatMode = %i\n", \ command.wMeasure, command.bBeat, command.bCommand, command.bGrooveLevel, command.bGrooveRange, command.bRepeatMode); break; - } case DMUS_FOURCC_LYRICSTRACK_LIST: { - FIXME("'lyrt': lyrics track list: not supported yet\n"); - break; - } case DMUS_FOURCC_MARKERTRACK_LIST: { - FIXME("'MARK': marker track list: not supported yet\n"); - break; - } case DMUS_FOURCC_MELODYFORM_TRACK_LIST: { - FIXME("'mfrm': melody formulation track list: not supported yet\n"); - break; } case DMUS_FOURCC_MUTE_CHUNK: { FIXME("'mute': mute track chunk: not supported yet\n"); break; - } case DMUS_FOURCC_PARAMCONTROLTRACK_TRACK_LIST: { - FIXME("'prmt': parameter control track list: not supported yet\n"); - break; } case DMUS_FOURCC_PATTERN_FORM: { FIXME("'DMPT': pattern track form: not supported yet\n"); break; - } case DMUS_FOURCC_SCRIPTTRACK_LIST: { - FIXME("'scrt': script track list: not supported yet\n"); - break; - } case DMUS_FOURCC_SEGTRACK_LIST: { - FIXME("'segt': segment trigger track list: not supported yet\n"); - break; } case DMUS_FOURCC_SEQ_TRACK: { FIXME("'seqt': sequence track chunk: not supported yet\n"); break; @@ -614,16 +900,10 @@ TRACE("'tetr': tempo track chunk\n"); ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); if (chunk.size != sizeof(DMUS_IO_TEMPO_ITEM)) - WARN("there seem so te ba problem: file claims that size of DMUSIC_IO_TEMPO_ITEM is %ld, while real sizeof returns %i", \ + 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_TEMPO_ITEM)); ReadFile (fd, &tempo, chunk.size, &BytesRead, NULL); - TRACE_(dmfiledat)("lTime = %ld; dblTempo = %f\n", tempo.lTime, tempo.dblTempo); - break; - } case DMUS_FOURCC_TIMESIGNATURE_TRACK: { - FIXME("'tims': time signature track list: not supported yet\n"); - break; - } case DMUS_FOURCC_WAVETRACK_LIST: { - FIXME("'wavt': wave track list not supported yet\n"); + TRACE_(dmfiledat)("lTime = %ld; dblTempo = %lf\n", tempo.lTime, tempo.dblTempo); break; } default: { WARN("invalid chunk (too many too list)\n"); @@ -642,6 +922,15 @@ return S_OK; } +/****************************************************************************** + * DMUSIC_FillSegmentFromFileHandle: + * - fills a IDirectMusicSegmentImpl struct with data from file handle. + * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it + * from another DMUSIC_Fill* function, make sure pointer is at + * correct place! + * - TODO: replace data in function with data in IDirectMusicSegmentImpl + * implement loading for missing (empty) clauses + */ HRESULT WINAPI DMUSIC_FillSegmentFromFileHandle (IDirectMusicSegmentImpl *segment, HANDLE fd) { rawChunk chunk; @@ -671,7 +960,7 @@ case DMUS_FOURCC_SEGMENT_CHUNK: { TRACE("segh: segment header\n"); ReadFile (fd, &header, chunk.size, &BytesRead, NULL); - TRACE_(dmfiledat)("dwRepeats = %ld; mtLength = %li; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld; rtLenght = FIXME; dwFlags = %ld; dwReserved = %ld\n", \ + TRACE_(dmfiledat)("=> dwRepeats = %ld; mtLength = %li; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld; rtLenght = FIXME; dwFlags = %ld; dwReserved = %ld\n", \ header.dwRepeats, header.mtLength, header.mtPlayStart, header.mtLoopStart, header.mtLoopEnd, header.dwResolution/*, header.rtLenght*/, header.dwFlags, header.dwReserved); break; } case DMUS_FOURCC_GUID_CHUNK: { @@ -710,9 +999,15 @@ } } break; - } case DMUS_FOURCC_CONTAINER_FORM: { - FIXME("'DMCN': container form chunk: not supported yet\n"); - break; + } case FOURCC_RIFF: { + TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded container form)\n", chunk.size); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) { + TRACE("'DMCN': embedded container form (forward to DMUSIC_FillContainerFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */ + DMUSIC_FillContainerFromFileHandle (NULL, fd); + } else WARN("invalid chunk (only 'DMCN' chunk allowed)\n"); + break; } case DMUS_FOURCC_TOOLGRAPH_FORM: { FIXME("'DMTG': toolgraph chunk: not supported yet\n"); break; @@ -720,12 +1015,589 @@ FIXME("'DMAP': audiopath chunk: not supported yet\n"); break; } default: { - FIXME("invalid chunk (only 'segh', 'guid', 'vers', 'LIST', 'DMCN', 'DMTG' and 'DMAP' chunks allowed)\n"); + WARN("invalid chunk (only 'segh', 'guid', 'vers', 'LIST', 'RIFF', 'DMTG' and 'DMAP' chunks allowed)\n"); break; } } TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize); } while (FileCount < FileSize); + } else { + WARN("invalid chunk (only 'DMSG' chunk allowed)\n"); + } + } else { + WARN("'RIFF' not found: not a RIFF file\n"); + } + + return S_OK; +} + +/****************************************************************************** + * DMUSIC_FillScriptFromFileHandle: + * - fills a IDirectMusicScriptImpl struct with data from file handle. + * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it + * from another DMUSIC_Fill* function, make sure pointer is at + * correct place! + * - TODO: replace data in function with data in IDirectMusicScriptImpl + */ +HRESULT WINAPI DMUSIC_FillScriptFromFileHandle (IDirectMusicScriptImpl *script, HANDLE fd) +{ + rawChunk chunk; + DWORD BytesRead/*, ListCount = 0*/, ListSize, FileCount = 0, FileSize; + /* FIXME: Replace stuff located below with the stuff in script */ + UNFO_List UNFO; + DMUS_IO_SCRIPT_HEADER header; + DMUS_IO_VERSION version, scriptversion; + GUID guid; + WCHAR* scriptlang; + WCHAR* scriptsrc; + Reference scriptsrcref; + + TRACE("reading 'RIFF' chunk...\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == FOURCC_RIFF) { + TRACE("'RIFF': RIFF file\n"); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */ + FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */ + TRACE("reading chunks ...\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */ + if (chunk.id == DMUS_FOURCC_SCRIPT_FORM) { + TRACE("'DMSC': script form\n"); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC); + switch (chunk.id) + { + case DMUS_FOURCC_SCRIPT_CHUNK: { + TRACE("'schd': script header\n"); + ReadFile (fd, &header, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> dwFlags = %ld\n", header.dwFlags); + break; + } case DMUS_FOURCC_GUID_CHUNK: { + TRACE("'guid': GUID\n"); + ReadFile (fd, &guid, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid)); + break; + } case DMUS_FOURCC_VERSION_CHUNK: { + TRACE("'vers': version\n"); + ReadFile (fd, &version, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS); + break; + } case FOURCC_LIST:{ + TRACE("'LIST': list (size) = %ld\n", chunk.size); + ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + switch (chunk.id) + { + case DMUS_FOURCC_UNFO_LIST: { + TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */ + DMUSIC_FillUNFOFromFileHandle (UNFO, fd); + break; + } case DMUS_FOURCC_REF_LIST: { + TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */ + DMUSIC_FillReferenceFromFileHandle (scriptsrcref, fd); + } default: { + WARN("invalid chunk (only 'UNFO' and 'DMRF' chunks allowed)\n"); + } + } + break; + } case DMUS_FOURCC_SCRIPTVERSION_CHUNK: { + TRACE("'scve': DirectMusic version\n"); + ReadFile (fd, &scriptversion, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> script version = %ld%ld\n", scriptversion.dwVersionMS, scriptversion.dwVersionLS); + break; + } case FOURCC_RIFF: { + TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded container form)\n", chunk.size); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) { + TRACE("'DMCN': embedded container form (forward to DMUSIC_FillContainerFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */ + DMUSIC_FillContainerFromFileHandle (NULL, fd); + } else WARN("invalid chunk (only 'DMCN' chunk allowed)\n"); + break; + } case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: { + TRACE("'scla': scripting language\n"); + scriptlang = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ + ReadFile (fd, scriptlang, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("script language = %s\n", debugstr_w(scriptlang)); + break; + } case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: { + TRACE("'scsr': script source\n"); + scriptsrc = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ + ReadFile (fd, scriptsrc, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("script source = %s\n", debugstr_w(scriptsrc)); + break; + } default: { + WARN("invalid chunk (only 'schd', 'guid', 'vers', 'LIST', 'scve', 'RIFF' and 'scla' chunks allowed)\n"); + break; + } + } + TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize); + } while (FileCount < FileSize); + } else { + WARN("invalid chunk (only 'DMSC' chunk allowed)\n"); + } + } else { + WARN("'RIFF' not found: not a RIFF file\n"); + } + + return S_OK; +} + +/****************************************************************************** + * DMUSIC_FillContainerFromFileHandle: + * - fills a IDirectMusicContainerImpl struct with data from file handle. + * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it + * from another DMUSIC_Fill* function, make sure pointer is at + * correct place! + * - TODO: replace data in function with data in IDirectMusicContainerImpl + */ +HRESULT WINAPI DMUSIC_FillContainerFromFileHandle (IDirectMusicContainerImpl *container, HANDLE fd) +{ + rawChunk chunk; + DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize; + /* FIXME: Replace stuff located below with the stuff in container */ + UNFO_List UNFO; + DMUS_IO_CONTAINER_HEADER header; + DMUS_IO_VERSION version; + GUID guid; + WCHAR* alias; + DMUS_IO_CONTAINED_OBJECT_HEADER objheader; + Reference dataref; + + TRACE("reading 'RIFF' chunk...\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == FOURCC_RIFF) { + TRACE("'RIFF': RIFF file\n"); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */ + FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */ + TRACE("reading chunks ...\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */ + if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) { + TRACE("'DMCN': container form\n"); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC); + switch (chunk.id) + { + case DMUS_FOURCC_CONTAINER_CHUNK: { + TRACE("'conh': container header\n"); + ReadFile (fd, &header, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> dwFlags = %ld\n", header.dwFlags); + break; + } case DMUS_FOURCC_GUID_CHUNK: { + TRACE("'guid': GUID\n"); + ReadFile (fd, &guid, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid)); + break; + } case DMUS_FOURCC_VERSION_CHUNK: { + TRACE("'vers': version\n"); + ReadFile (fd, &version, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS); + break; + } case FOURCC_LIST:{ + TRACE("'LIST': list (size) = %ld\n", chunk.size); + ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + switch (chunk.id) + { + case DMUS_FOURCC_UNFO_LIST: { + TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */ + DMUSIC_FillUNFOFromFileHandle (UNFO, fd); + break; + } case DMUS_FOURCC_CONTAINED_OBJECTS_LIST: { + TRACE("'cosl': objects list (content size = %ld)\n", ListSize); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_CONTAINED_OBJECT_LIST) { + ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount2 = 0; /* reset */ + TRACE("'cobl': object (content size = %ld)\n", ListSize2); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_CONTAINED_ALIAS_CHUNK: { + TRACE("'coba': alias (size = %ld)\n", chunk.size); + alias = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */ + ReadFile (fd, alias, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> alias = %s\n", debugstr_w(alias)); + break; + } case DMUS_FOURCC_CONTAINED_OBJECT_CHUNK: { + TRACE("'cobh': object header (size = %ld)\n", chunk.size); + ReadFile (fd, &objheader, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> guidClassID = %s; dwFlags = %ld; ckid = %ld; fccType = %ld\n", \ + debugstr_guid(&objheader.guidClassID), objheader.dwFlags, objheader.ckid, objheader.fccType); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list chunk (size = %ld)\n", chunk.size); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_REF_LIST) { + TRACE("'DMRF': reference list (instead of 'data' chunk: size = %ld)\n", chunk.size - 4); /* set pointer at beginning of list */ + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); + DMUSIC_FillReferenceFromFileHandle (dataref, fd); /* forward to DMUSIC_FillReferenceFromFileHandle */ + } else WARN("invalid chunk (only 'DMRF' chunk allowed\n"); + break; + } case FOURCC_RIFF: { + TRACE("'RIFF': encapsulated data (can be 'DMSG' or 'DMSG')\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */ + switch (chunk.id) + { + case DMUS_FOURCC_SEGMENT_FORM: { + TRACE("'DMSG': embedded segment form (forward to DMUSIC_FillSegmentFromFileHandle(...))\n"); + DMUSIC_FillSegmentFromFileHandle (NULL, fd); + break; + } case DMUS_FOURCC_STYLE_FORM: { + TRACE("'DMST': embedded style form (forward to DMUSIC_FillStyleFromFileHandle(...))\n"); + DMUSIC_FillStyleFromFileHandle (NULL, fd); + break; + } case mmioFOURCC('W','A','V','E'): { + FIXME("'WAVE': not yet supported (skipping)\n"); + SetFilePointer (fd, sizeof(FOURCC) + sizeof(DWORD) + chunk.size, NULL, FILE_CURRENT); /* skip */ + break; + } default: { + WARN("invalid chunk (only 'DMSG' and 'DMST' chunks allowed)\n"); + break; + } + } + break; + } default: { + WARN("invalid chunk (only 'coba', 'cobh', 'data' and 'LIST' chunks allowed\n"); + break; + } + } + TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2); + } while (ListCount2 < ListSize2); + } else WARN("invalid chunk (only 'cobl' chunk allowed)\n"); + TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); + } while (ListCount < ListSize); + break; + } default: { + WARN("invalid chunk (only 'UNFO' and 'cosl' chunks allowed)\n"); + } + } + break; + } default: { + WARN("invalid chunk (only 'schd', 'guid', 'vers', 'LIST', 'scve', 'RIFF' and 'scla' chunks allowed)\n"); + break; + } + } + TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize); + } while (FileCount < FileSize); + } else { + WARN("invalid chunk (only 'DMSC' chunk allowed)\n"); + } + } else { + WARN("'RIFF' not found: not a RIFF file\n"); + } + + return S_OK; +} + +/****************************************************************************** + * DMUSIC_FillStyleFromFileHandle: + * - fills a IDirectMusicStyleImpl struct with data from file handle. + * - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it + * from another DMUSIC_Fill* function, make sure pointer is at + * correct place! + * - TODO: replace data in function with data in IDirectMusicStyleImpl + */ +HRESULT WINAPI DMUSIC_FillStyleFromFileHandle (IDirectMusicStyleImpl *style, HANDLE fd) +{ + rawChunk chunk; + DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize; + int i; + /* FIXME: Replace stuff located below with the stuff in container */ + UNFO_List UNFO; + DMUS_IO_STYLE header; + DMUS_IO_VERSION version; + GUID guid; + Part part; + Pattern pattern; + + TRACE("reading 'RIFF' chunk...\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == FOURCC_RIFF) { + TRACE("'RIFF': RIFF file\n"); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */ + FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */ + TRACE("reading chunks ...\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */ + if (chunk.id == DMUS_FOURCC_STYLE_FORM) { + TRACE("'DMST': style form\n"); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC); + + switch (chunk.id) + { + case DMUS_FOURCC_STYLE_CHUNK: { + TRACE("'styh': style header\n"); + ReadFile (fd, &header, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; dblTempo = %lf\n", \ + header.timeSig.bBeatsPerMeasure, header.timeSig.bBeat, header.timeSig.wGridsPerBeat, header.dblTempo); + break; + } case DMUS_FOURCC_GUID_CHUNK: { + TRACE("'guid': GUID\n"); + ReadFile (fd, &guid, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid)); + break; + } case DMUS_FOURCC_VERSION_CHUNK: { + TRACE("'vers': version\n"); + ReadFile (fd, &version, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS); + break; + } case FOURCC_RIFF: { + TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_BAND_FORM) { + TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */ + DMUSIC_FillBandFromFileHandle (NULL, fd); + } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n"); + break; + } case FOURCC_LIST:{ + TRACE("'LIST': list (size) = %ld\n", chunk.size); + ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount = 0; + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + switch (chunk.id) + { + case DMUS_FOURCC_UNFO_LIST: { + TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */ + DMUSIC_FillUNFOFromFileHandle (UNFO, fd); + break; + } case DMUS_FOURCC_PART_LIST: { + TRACE("'part': parts list (content size = %ld)\n", ListSize); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_PART_CHUNK: { + TRACE("'prth': part header\n"); + ReadFile (fd, &part.header, chunk.size, &BytesRead, NULL); + 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", \ + part.header.timeSig.bBeatsPerMeasure, part.header.timeSig.bBeat, part.header.timeSig.wGridsPerBeat, part.header.dwVariationChoices, \ + debugstr_guid (&part.header.guidPartID), part.header.wNbrMeasures, part.header.bPlayModeFlags, part.header.bInvertUpper, part.header.bInvertLower, \ + part.header.bPad, part.header.dwFlags); + break; + } case DMUS_FOURCC_NOTE_CHUNK: { + TRACE("'note': notes (size = %ld)\n", chunk.size); + part.nrofnotes = chunk.size - sizeof(DWORD); /* pure contents of 'note' (without first DWORD) */ + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLENOTE) */ + part.nrofnotes /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLENOTE) */ + part.notes = (DMUS_IO_STYLENOTE*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofnotes); + ReadFile (fd, part.notes, chunk.size * part.nrofnotes, &BytesRead, NULL); + TRACE_(dmfiledat)("=> number of notes = %ld\n", part.nrofnotes); + for (i = 0; i < part.nrofnotes; i++) + { + 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", \ + 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, \ + part.notes[i].bDurRange, part.notes[i].bVelRange, part.notes[i].bInversionID, part.notes[i].bPlayModeFlags, part.notes[i].bNoteFlags); + } + break; + } case DMUS_FOURCC_CURVE_CHUNK: { + TRACE("'crve': curves (size = %ld)\n", chunk.size); + part.nrofcurves = chunk.size - sizeof(DWORD); /* pure contents of 'crve' (without first DWORD) */ + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLECURVE) */ + part.nrofcurves /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLECURVE) */ + part.curves = (DMUS_IO_STYLECURVE*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofcurves); + ReadFile (fd, part.curves, chunk.size * part.nrofcurves, &BytesRead, NULL); + TRACE_(dmfiledat)("=> number of curves = %ld\n", part.nrofcurves); + for (i = 0; i < part.nrofcurves; i++) + { + 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", \ + 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, \ + 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); + } + break; + } case DMUS_FOURCC_MARKER_CHUNK: { + TRACE("'mrkr': markers (size = %ld)\n", chunk.size); + part.nrofmarkers = chunk.size - sizeof(DWORD); /* pure contents of 'mrkr' (without first DWORD) */ + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLEMARKER) */ + part.nrofmarkers /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLEMARKER) */ + part.markers = (DMUS_IO_STYLEMARKER*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofmarkers); + ReadFile (fd, part.markers, chunk.size * part.nrofmarkers, &BytesRead, NULL); + TRACE_(dmfiledat)("=> number of markers = %ld\n", part.nrofmarkers); + for (i = 0; i < part.nrofmarkers; i++) + { + TRACE_(dmfiledat)("=> marker[%i]: mtGridStart = %li; dwVariation = %ld; wMarkerFlags = %d\n", \ + i, part.markers[i].mtGridStart, part.markers[i].dwVariation, part.markers[i].wMarkerFlags); + } + break; + } case DMUS_FOURCC_RESOLUTION_CHUNK: { + TRACE("'rsln': resolutions (size = %ld)\n", chunk.size); + part.nrofresolutions = chunk.size - sizeof(DWORD); /* pure contents of 'rsln' (without first DWORD) */ + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLERESOLUTION) */ + part.nrofresolutions /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLERESOLUTION) */ + part.resolutions = (DMUS_IO_STYLERESOLUTION*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofresolutions); + ReadFile (fd, part.resolutions, chunk.size * part.nrofresolutions, &BytesRead, NULL); + TRACE_(dmfiledat)("=> number of resolutions = %ld\n", part.nrofresolutions); + for (i = 0; i < part.nrofresolutions; i++) + { + TRACE_(dmfiledat)("=> resolution[%i]: dwVariation = %ld; wMusicValue = %d; bInversionID = %i; bPlayModeFlags = %i", \ + i, part.resolutions[i].dwVariation, part.resolutions[i].wMusicValue, part.resolutions[i].bInversionID, part.resolutions[i].bPlayModeFlags); + } + break; + } case DMUS_FOURCC_ANTICIPATION_CHUNK: { + TRACE("'anpn': anticipations (size = %ld)\n", chunk.size); + part.nrofanticipations = chunk.size - sizeof(DWORD); /* pure contents of 'anpn' (without first DWORD) */ + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLE_ANTICIPATION) */ + part.nrofanticipations /= chunk.size; /* nrofnotes = pure contents / sizeof (DMUS_IO_STYLE_ANTICIPATION) */ + part.anticipations = (DMUS_IO_STYLE_ANTICIPATION*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofanticipations); + ReadFile (fd, part.anticipations, chunk.size * part.nrofanticipations, &BytesRead, NULL); + TRACE_(dmfiledat)("=> number of anticipations = %ld\n", part.nrofanticipations); + for (i = 0; i < part.nrofanticipations; i++) + { + TRACE_(dmfiledat)("=> anticipation[%i]: mtGridStart = %li; dwVariation = %ld; nTimeOffset = %i; bTimeRange = %i\n", \ + i, part.anticipations[i].mtGridStart, part.anticipations[i].dwVariation, part.anticipations[i].nTimeOffset, part.anticipations[i].bTimeRange); + } + break; + } case FOURCC_LIST: { + TRACE("'LIST': list chunk (size = %ld)\n", chunk.size); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_UNFO_LIST) { + TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* set pointer at beginning of list */ + DMUSIC_FillUNFOFromFileHandle (part.UNFO, fd); + } else WARN("invalid chunk (only 'UNFO' chunk allowed\n"); + break; + } default: { + WARN("invalid chunk (only 'prth','note', 'crve', 'mrkr', 'rsln', 'anpn' and 'LIST' chunks allowed\n"); + break; + } + } + TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); + } while (ListCount < ListSize); + break; + } case DMUS_FOURCC_PATTERN_LIST: { + TRACE("'pttn': patterns list (content size = %ld)\n", ListSize); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_PATTERN_CHUNK: { + TRACE("'ptnh': pattern header\n"); + ReadFile (fd, &pattern.header, chunk.size, &BytesRead, NULL); + 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", \ + pattern.header.timeSig.bBeatsPerMeasure, pattern.header.timeSig.bBeat, pattern.header.timeSig.wGridsPerBeat, pattern.header.bGrooveBottom, pattern.header.bGrooveTop, pattern.header.wEmbellishment, \ + pattern.header.wNbrMeasures, pattern.header.bDestGrooveBottom, pattern.header.bDestGrooveTop, pattern.header.dwFlags); + break; + } case DMUS_FOURCC_RHYTHM_CHUNK: { + TRACE("'rhtm': rhytms\n"); + pattern.nrofrhytms = chunk.size / sizeof(DWORD); + TRACE_(dmfiledat)("=> number of rhytms = %ld\n", pattern.nrofrhytms); + pattern.rhytms = (DWORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DWORD) * pattern.nrofrhytms); + ReadFile (fd, pattern.rhytms, sizeof(DWORD) * pattern.nrofrhytms, &BytesRead, NULL); + for (i = 0; i < pattern.nrofrhytms; i++) + { + TRACE_(dmfiledat)("=> rhytm[%i] = %ld\n", i, pattern.rhytms[i]); + } + break; + } case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: { + TRACE("'mtfs': motif settings\n"); + ReadFile (fd, &pattern.motsettings, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> dwRepeats = %ld; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld\n", \ + pattern.motsettings.dwRepeats, pattern.motsettings.mtPlayStart, pattern.motsettings.mtLoopStart, pattern.motsettings.mtLoopEnd, pattern.motsettings.dwResolution); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list chunk (size = %ld)\n", chunk.size); + ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */ + ListCount2 = 0; + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + switch (chunk.id) + { + case DMUS_FOURCC_UNFO_LIST: { + TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */ + DMUSIC_FillUNFOFromFileHandle (UNFO, fd); + break; + } case DMUS_FOURCC_PARTREF_LIST: { + TRACE("'pref': part references list (content size = %ld)\n", ListSize2); + do { + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); + ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size; + switch (chunk.id) + { + case DMUS_FOURCC_PARTREF_CHUNK: { + TRACE("'prfc': part reference\n"); + ReadFile (fd, &pattern.partref, chunk.size, &BytesRead, NULL); + TRACE_(dmfiledat)("=> guidPartID = %s; wLogicalPartID = %d; bVariationLockID = %i; bSubChordLevel = %i; bPriority = %i; bRandomVariation = %i; wPad = %d; dwPChannel = %ld\n", \ + debugstr_guid (&pattern.partref.guidPartID), pattern.partref.wLogicalPartID, pattern.partref.bVariationLockID, pattern.partref.bSubChordLevel, \ + pattern.partref.bPriority, pattern.partref.bRandomVariation, pattern.partref.wPad, pattern.partref.dwPChannel); + break; + } case FOURCC_LIST: { + TRACE("'LIST': list chunk (MSDN doesn't mention it)\n"); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_UNFO_LIST) { + TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */ + DMUSIC_FillUNFOFromFileHandle (UNFO, fd); + } else { + WARN("invalid chunk (only 'UNFO' chunk allowed)\n"); + } + break; + } default: { + WARN("invalid chunk (only 'prfc' and 'UNFO'chunk allowed)\n"); + } + } + TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2); + } while (ListCount2 < ListSize2); + break; + } default: { + WARN("invalid chunk (only 'UNFO' and 'pref' chunks allowed\n"); + break; + } + } + break; + } case FOURCC_RIFF: { + TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size); + ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); + if (chunk.id == DMUS_FOURCC_BAND_FORM) { + TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle(...))\n"); + SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */ + DMUSIC_FillBandFromFileHandle (NULL, fd); + } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n"); + break; + } default: { + WARN("invalid chunk (only 'prnh','rhtm', 'mtfs', 'LIST' and 'RIFF' chunks allowed\n"); + break; + } + + } + TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize); + } while (ListCount < ListSize); + break; + } default: { + WARN("invalid chunk (only 'UNFO', 'part', 'pttn' and 'RIFF' chunks allowed)\n"); + } + } + break; + } default: { + WARN("invalid chunk (only 'styh', 'guid', 'vers', 'LIST', and 'RIFF' chunks allowed)\n"); + break; + } + } + TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize); + } while (FileCount < FileSize); + } else { + WARN("invalid chunk (only 'DMST' chunk allowed)\n"); } } else { WARN("'RIFF' not found: not a RIFF file\n");
Attachment:
signature.asc
Description: To je digitalno podpisan del=?iso-8859-2?Q?sporo=E8ila?=