bool HeartBeatSnesSeq::GetHeaderInfo(void) { SetPPQN(SEQ_PPQN); VGMHeader *header = AddHeader(dwOffset, 0); uint32_t curOffset = dwOffset; if (curOffset + 2 > 0x10000) { return false; } header->AddSimpleItem(curOffset, 2, L"Instrument Table Pointer"); curOffset += 2; for (uint8_t trackIndex = 0; trackIndex < MAX_TRACKS; trackIndex++) { uint16_t ofsTrackStart = GetShort(curOffset); if (ofsTrackStart == 0) { // example: Dragon Quest 6 - Brave Fight header->AddSimpleItem(curOffset, 2, L"Track Pointer End"); curOffset += 2; break; } std::wstringstream trackName; trackName << L"Track Pointer " << (trackIndex + 1); header->AddSimpleItem(curOffset, 2, trackName.str().c_str()); curOffset += 2; } return true; }
bool QSoundSeq::GetTrackPointers(void) { // Hack for D&D Shadow over Mystara... if (GetByte(dwOffset) == 0x92) return false; this->AddHeader(dwOffset, 1, L"Sequence Flags"); VGMHeader* header = this->AddHeader(dwOffset+1, GetShortBE(dwOffset+1) - 1, L"Track Pointers"); for (int i=0; i<16; i++) { uint32_t offset = GetShortBE(dwOffset+1+i*2); if (offset == 0) { header->AddSimpleItem(dwOffset+1 + (i*2), 2, L"No Track"); continue; } //if (GetShortBE(offset+dwOffset) == 0xE017) //Rest, EndTrack (used by empty tracks) // continue; QSoundTrack *newTrack = new QSoundTrack(this, offset+dwOffset); aTracks.push_back(newTrack); header->AddSimpleItem(dwOffset+1 + (i*2), 2, L"Track Pointer"); } if (aTracks.size() == 0) return false; return true; }
bool WDInstrSet::GetHeaderInfo() { VGMHeader* header = AddHeader(dwOffset, 0x10, L"Header"); header->AddSimpleItem(dwOffset + 0x2, 2, L"ID"); header->AddSimpleItem(dwOffset + 0x4, 4, L"Sample Section Size"); header->AddSimpleItem(dwOffset + 0x8, 4, L"Number of Instruments"); header->AddSimpleItem(dwOffset + 0xC, 4, L"Number of Regions"); id = GetShort(0x2+dwOffset); dwSampSectSize = GetWord(0x4+dwOffset); dwNumInstrs = GetWord(0x8+dwOffset); dwTotalRegions = GetWord(0xC+dwOffset); if (dwSampSectSize < 0x40) //Some songs in the Bouncer have bizarre values here dwSampSectSize = 0; wostringstream theName; theName << L"WD " << id; name = theName.str(); ULONG sampCollOff = dwOffset + GetWord(dwOffset + 0x20) + (dwTotalRegions * 0x20); //ULONG sampCollOff = (((dwNumInstrs/4)+(dwNumInstrs%4 > 0))* 0x10) + dwTotalRegions * 0x20 + 0x20 + dwOffset; sampColl = new PSXSampColl(SquarePS2Format::name, this, sampCollOff, dwSampSectSize); unLength = sampCollOff+dwSampSectSize - dwOffset; return true; }
bool MP2kSeq::GetHeaderInfo(void) { if (dwOffset + 2 > vgmfile->GetEndOffset()) { return false; } nNumTracks = GetShort(dwOffset); // if there are no tracks or there are more tracks than allowed // return an error; the sequence shall be deleted if (nNumTracks == 0 || nNumTracks > 24) { return false; } if (dwOffset + 8 + nNumTracks * 4 > vgmfile->GetEndOffset()) { return false; } VGMHeader *seqHdr = AddHeader(dwOffset, 8 + nNumTracks * 4, L"Sequence Header"); seqHdr->AddSimpleItem(dwOffset, 1, L"Number of Tracks"); seqHdr->AddSimpleItem(dwOffset + 1, 1, L"Unknown"); seqHdr->AddSimpleItem(dwOffset + 2, 1, L"Priority"); seqHdr->AddSimpleItem(dwOffset + 3, 1, L"Reverb"); uint32_t dwInstPtr = GetWord(dwOffset + 4); seqHdr->AddPointer(dwOffset + 4, 4, dwInstPtr - 0x8000000, true, L"Instrument Pointer"); for (unsigned int i = 0; i < nNumTracks; i++) { uint32_t dwTrackPtrOffset = dwOffset + 8 + i * 4; uint32_t dwTrackPtr = GetWord(dwTrackPtrOffset); seqHdr->AddPointer(dwTrackPtrOffset, 4, dwTrackPtr - 0x8000000, true, L"Track Pointer"); } SetPPQN(0x30); return true; }
bool SonyPS2Seq::GetHeaderInfo(void) { name() = L"Sony PS2 Seq"; uint32_t curOffset = offset(); //read the version chunk GetBytes(curOffset, 0x10, &versCk); VGMHeader* versCkHdr = VGMSeq::AddHeader(curOffset, versCk.chunkSize, L"Version Chunk"); versCkHdr->AddSimpleItem(curOffset, 4, L"Creator"); versCkHdr->AddSimpleItem(curOffset+4, 4, L"Type"); curOffset += versCk.chunkSize; //read the header chunk GetBytes(curOffset, 0x20, &hdrCk); VGMHeader* hdrCkHdr = VGMSeq::AddHeader(curOffset, hdrCk.chunkSize, L"Header Chunk"); hdrCkHdr->AddSimpleItem(curOffset, 4, L"Creator"); hdrCkHdr->AddSimpleItem(curOffset+4, 4, L"Type"); curOffset += hdrCk.chunkSize; //Now we're at the Midi chunk, which starts with the sig "SCEIMidi" (in 32bit little endian) midiChunkSize = GetWord(curOffset+8); maxMidiNumber = GetWord(curOffset+12); //Get the first midi data block addr, which is provided relative to beginning of Midi chunk midiOffsetAddr = GetWord(curOffset+16) + curOffset; curOffset = midiOffsetAddr; //Now we're at the Midi Data Block uint32_t sequenceOffset = GetWord(curOffset); //read sequence offset SetEventsOffset(curOffset + sequenceOffset); SetPPQN(GetShort(curOffset+4)); //read ppqn value if (sequenceOffset != 6) //if a compression mode is being applied { compOption = GetShort(curOffset+6); //read compression mode } //SSEQHdr->AddSimpleItem(dwOffset+8, 4, L"Size"); //SSEQHdr->AddSimpleItem(dwOffset+12, 2, L"Header Size"); //SSEQHdr->AddUnknownItem(dwOffset+14, 2); //TryExpandMidiTracks(16); nNumTracks = 16; channel = 0; SetCurTrack(channel); return true; }
bool NDSInstrSet::GetInstrPointers() { VGMHeader* header = AddHeader(dwOffset, 0x38); uint32_t nInstruments = GetWord(dwOffset + 0x38); VGMHeader* instrptrHdr = AddHeader(dwOffset+0x38, nInstruments*4+4, L"Instrument Pointers"); for (uint32_t i=0; i<nInstruments; i++) { uint32_t instrPtrOff = dwOffset + 0x3C + i*4; uint32_t temp = GetWord(instrPtrOff); if (temp == 0) continue; uint8_t instrType = temp & 0xFF; uint32_t pInstr = temp >> 8; aInstrs.push_back(new NDSInstr(this, pInstr+dwOffset, 0, 0, i, instrType)); VGMHeader* hdr = instrptrHdr->AddHeader(instrPtrOff, 4, L"Pointer"); hdr->AddSimpleItem(instrPtrOff, 1, L"Type"); hdr->AddSimpleItem(instrPtrOff+1, 3, L"Offset"); } return true; }
bool BGMSeq::GetHeaderInfo(void) { VGMHeader *header = AddHeader(dwOffset, 0x20, L"Header"); header->AddSimpleItem(dwOffset, 4, L"Signature"); header->AddSimpleItem(dwOffset + 0x4, 2, L"ID"); header->AddSimpleItem(dwOffset + 0x6, 2, L"Associated WD ID"); header->AddSimpleItem(dwOffset + 0x8, 1, L"Number of Tracks"); header->AddSimpleItem(dwOffset + 0xE, 2, L"PPQN"); header->AddSimpleItem(dwOffset + 0x10, 4, L"File length"); nNumTracks = GetByte(dwOffset + 8); seqID = GetShort(dwOffset + 4); assocWDID = GetShort(dwOffset + 6); SetPPQN(GetShort(dwOffset + 0xE)); unLength = GetWord(dwOffset + 0x10); wostringstream theName; theName << L"BGM " << seqID; if (seqID != assocWDID) theName << L"using WD " << assocWDID; name = theName.str(); return true; }
bool AkaoSeq::GetHeaderInfo(void) { //first do a version check to see if it's older or newer version of AKAO sequence format if (GetWord(dwOffset+0x2C) == 0) { nVersion = VERSION_3; //assoc_ss_id = GetShort(0x14 + dwOffset); id = GetShort(0x14 + dwOffset); seq_id = GetShort(0x4 + dwOffset); } else if (GetWord(dwOffset+0x1C) == 0) { nVersion = VERSION_2; return false; } else { nVersion = VERSION_1; return false; } name = L"Akao Seq"; VGMHeader* hdr = AddHeader(dwOffset, 0x40); hdr->AddSig(dwOffset, 4); hdr->AddSimpleItem(dwOffset+0x4, 2, L"ID"); hdr->AddSimpleItem(dwOffset+0x6, 2, L"Size"); hdr->AddSimpleItem(dwOffset+0x14, 2, L"Associated Sample Set ID"); hdr->AddSimpleItem(dwOffset+0x20, 4, L"Number of Tracks (# of true bits)"); hdr->AddSimpleItem(dwOffset+0x30, 4, L"Instrument Data Pointer"); hdr->AddSimpleItem(dwOffset+0x34, 4, L"Drumkit Data Pointer"); SetPPQN(0x30); nNumTracks = GetNumPositiveBits(GetWord(dwOffset+0x20)); unLength = GetShort(dwOffset+6); //There must be either a melodic instrument section, a drumkit, or both. We determiine //the start of the InstrSet based on whether a melodic instrument section is given. uint32_t instrOff = GetWord(dwOffset + 0x30); uint32_t drumkitOff = GetWord(dwOffset + 0x34); if (instrOff != 0) instrOff += 0x30 + dwOffset; if (drumkitOff != 0) drumkitOff += 0x34 + dwOffset; uint32_t instrSetLength; if (instrOff != 0) instrSetLength = unLength - (instrOff - dwOffset); else instrSetLength = unLength - (drumkitOff - dwOffset); instrset = new AkaoInstrSet(rawfile, instrSetLength, instrOff, drumkitOff, id, L"Akao Instr Set"); if (!instrset->LoadVGMFile()) { delete instrset; instrset = NULL; } return true; //successful }
bool PS1Seq::GetHeaderInfo(void) { name() = L"PS1 SEQ"; SetPPQN(GetShortBE(offset()+8)); nNumTracks = 16; uint8_t numer = GetByte(offset()+0x0D); uint8_t denom = GetByte(offset()+0x0E); if (numer == 0 || numer > 32) //sanity check return false; VGMHeader* seqHeader = VGMSeq::AddHeader(offset(), 11, L"Sequence Header"); seqHeader->AddSimpleItem(offset(), 4, L"ID"); seqHeader->AddSimpleItem(offset()+0x04, 4, L"Version"); seqHeader->AddSimpleItem(offset()+0x08, 2, L"Resolution of quarter note"); seqHeader->AddTempo(offset()+0x0A, 3); seqHeader->AddSig(offset()+0x0D, 2); // Rhythm (Numerator) and Rhythm (Denominator) (2^n) if (GetByte(offset()+0xF) == 0 && GetByte(offset()+0x10) == 0) { SetEventsOffset(offset() + 0x0F + 4); PS1Seq* newPS1Seq = new PS1Seq(rawfile, offset()+GetShortBE(offset()+0x11)+0x13 - 6); if (!newPS1Seq->LoadVGMFile()) { delete newPS1Seq; } //short relOffset = (short)GetShortBE(curOffset); //AddGenericEvent(beginOffset, 4, L"Jump Relative", NULL, BG_CLR_PINK); //curOffset += relOffset; } else { SetEventsOffset(offset() + 0x0F); } return true; }
//============================================================== // Get the information of HOSA header //-------------------------------------------------------------- // Input // Nothing // Output // flag true = successful // false = error // Memo // VGMSeq::LoadMain() から call される。 //============================================================== bool HOSASeq::GetHeaderInfo(void) { name = L"HOSA Seq"; //this object name // About the unLength, if (unLength==0), // "VGMSeq::LoadMain()" will calculate the unLength after "SeqTrack::LoadTrack()". nNumTracks = GetByte(dwOffset+0x06); //BYTE (8bit) assocHOSA_ID = 0x00; // Add the new object "VGMHeader" in this object "HOSASeq"(Super class:"VGMContainerItem") // Delect object is in "VGMContainerItem::~VGMContainerItem()" VGMHeader* hdr = AddHeader(dwOffset, 0x0050); hdr->AddSig(dwOffset, 4); hdr->AddSimpleItem(dwOffset+0x06, 1, L"Quantity of Tracks"); SetPPQN(0x30); //Timebase return true; //successful }
//============================================================== // ヘッダー情報の取得 //-------------------------------------------------------------- // Memo: // VGMInstrSet::Load()関数から呼ばれる //============================================================== bool WdsInstrSet::GetHeaderInfo() { //"hdr"構造体へそのまま転送 GetBytes(dwOffset, sizeof(WdsHdr), &hdr); unLength = hdr.szHeader1 + hdr.szSampColl; //header size + samp coll size id = hdr.iBank; //Bank number. if (hdr.sig == 0x73647764) version = VERSION_DWDS; else if (hdr.sig == 0x20736477) version = VERSION_WDS; //バイナリエディタ表示用 wostringstream theName; theName << L"wds " << id; name = theName.str(); //ヘッダーobjectの生成 VGMHeader* wdsHeader = AddHeader(dwOffset, sizeof(WdsHdr)); wdsHeader->AddSig(dwOffset, sizeof(long)); wdsHeader->AddUnknownItem(dwOffset+0x04, sizeof(long)); wdsHeader->AddSimpleItem(dwOffset+0x08, sizeof(long), L"Header size? (0)"); wdsHeader->AddUnknownItem(dwOffset+0x0C, sizeof(long)); wdsHeader->AddSimpleItem(dwOffset+0x10, sizeof(long), L"Header size? (1)"); wdsHeader->AddSimpleItem(dwOffset+0x14, sizeof(long), L"AD-PCM body(.VB) size"); wdsHeader->AddSimpleItem(dwOffset+0x18, sizeof(long), L"Header size? (2)"); wdsHeader->AddSimpleItem(dwOffset+0x1C, sizeof(long), L"Number of Instruments"); wdsHeader->AddSimpleItem(dwOffset+0x20, sizeof(long), L"Bank number"); wdsHeader->AddUnknownItem(dwOffset+0x24, sizeof(long)); wdsHeader->AddUnknownItem(dwOffset+0x28, sizeof(long)); wdsHeader->AddUnknownItem(dwOffset+0x2C, sizeof(long)); //波形objectの生成 sampColl = new PSXSampColl(FFTFormat::name, this, dwOffset + hdr.szHeader1, hdr.szSampColl); // sampColl->Load(); //VGMInstrSet::Load()関数内でやっている。 // sampColl->UseInstrSet(this); //"WD.cpp"では、同様の事をやっている。 return true; }
bool Vab::GetInstrPointers() { uint32_t nEndOffset = GetEndOffset(); uint32_t nMaxLength = nEndOffset - dwOffset; uint32_t offProgs = dwOffset + 0x20; uint32_t offToneAttrs = offProgs + (16 * 128); uint16_t numPrograms = GetShort(dwOffset + 0x12); uint16_t numVAGs = GetShort(dwOffset + 0x16); uint32_t offVAGOffsets = offToneAttrs + (32 * 16 * numPrograms); VGMHeader* progsHdr = AddHeader(offProgs, 16 * 128, L"Program Table"); VGMHeader* toneAttrsHdr = AddHeader(offToneAttrs, 32 * 16, L"Tone Attributes Table"); if (numPrograms > 128) { return false; } if (numVAGs > 255) { return false; } // Scan all 128 entries regardless of header info. // There could be null instruments that has no tones. // See Clock Tower PSF for example of null instrument. for (uint32_t i = 0; i < 128; i++) { uint32_t offCurrProg = offProgs + (i * 16); uint32_t offCurrToneAttrs = offToneAttrs + (aInstrs.size() * 32 * 16); if (offCurrToneAttrs + (32 * 16) > nEndOffset) { break; } uint8_t numTones = GetByte(offCurrProg); if (numTones > 32) { wchar_t log[512]; wsprintf(log, L"Too many tones (%u) in Program #%u.", numTones, i); pRoot->AddLogItem(new LogItem(log, LOG_LEVEL_WARN, L"Vab")); } else if (numTones != 0) { VabInstr* newInstr = new VabInstr(this, offCurrToneAttrs, 0x20 * 16, 0, i); aInstrs.push_back(newInstr); GetBytes(offCurrProg, 0x10, &newInstr->attr); VGMHeader* hdr = progsHdr->AddHeader(offCurrProg, 0x10, L"Program"); hdr->AddSimpleItem(offCurrProg + 0x00, 1, L"Number of Tones"); hdr->AddSimpleItem(offCurrProg + 0x01, 1, L"Volume"); hdr->AddSimpleItem(offCurrProg + 0x02, 1, L"Priority"); hdr->AddSimpleItem(offCurrProg + 0x03, 1, L"Mode"); hdr->AddSimpleItem(offCurrProg + 0x04, 1, L"Pan"); hdr->AddSimpleItem(offCurrProg + 0x05, 1, L"Reserved"); hdr->AddSimpleItem(offCurrProg + 0x06, 2, L"Attribute"); hdr->AddSimpleItem(offCurrProg + 0x08, 4, L"Reserved"); hdr->AddSimpleItem(offCurrProg + 0x0c, 4, L"Reserved"); newInstr->masterVol = GetByte(offCurrProg + 0x01); toneAttrsHdr->unLength = offCurrToneAttrs + (32 * 16) - offToneAttrs; } } if ((offVAGOffsets + 2 * 256) <= nEndOffset) { wchar_t name[256]; std::vector<SizeOffsetPair> vagLocations; uint32_t totalVAGSize = 0; VGMHeader* vagOffsetHdr = AddHeader(offVAGOffsets, 2 * 256, L"VAG Pointer Table"); uint32_t vagStartOffset = GetShort(offVAGOffsets) * 8; vagOffsetHdr->AddSimpleItem(offVAGOffsets, 2, L"VAG Size /8 #0"); totalVAGSize = vagStartOffset; for (uint32_t i = 0; i < numVAGs; i++) { uint32_t vagOffset; uint32_t vagSize; if (i == 0) { vagOffset = vagStartOffset; vagSize = GetShort(offVAGOffsets + (i + 1) * 2) * 8; } else { vagOffset = vagStartOffset + vagLocations[i - 1].offset + vagLocations[i - 1].size; vagSize = GetShort(offVAGOffsets + (i + 1) * 2) * 8; } wsprintf(name, L"VAG Size /8 #%u", i + 1); vagOffsetHdr->AddSimpleItem(offVAGOffsets + (i + 1) * 2, 2, name); if (vagOffset + vagSize <= nEndOffset) { vagLocations.push_back(SizeOffsetPair(vagOffset, vagSize)); totalVAGSize += vagSize; } else { wchar_t log[512]; wsprintf(log, L"VAG #%u pointer (offset=0x%08X, size=%u) is invalid.", i + 1, vagOffset, vagSize); pRoot->AddLogItem(new LogItem(log, LOG_LEVEL_WARN, L"Vab")); } } unLength = (offVAGOffsets + 2 * 256) - dwOffset; // single VAB file? uint32_t offVAGs = offVAGOffsets + 2 * 256; if (dwOffset == 0 && vagLocations.size() != 0) { // load samples as well PSXSampColl* newSampColl = new PSXSampColl(format, this, offVAGs, totalVAGSize, vagLocations); if (newSampColl->LoadVGMFile()) { pRoot->AddVGMFile(newSampColl); //this->sampColl = newSampColl; } else { delete newSampColl; } } } return true; }
bool Vab::GetHeaderInfo() { uint32_t nEndOffset = GetEndOffset(); uint32_t nMaxLength = nEndOffset - dwOffset; if (nMaxLength < 0x20) { return false; } name = L"VAB"; VGMHeader* vabHdr = AddHeader(dwOffset, 0x20, L"VAB Header"); vabHdr->AddSimpleItem(dwOffset + 0x00, 4, L"ID"); vabHdr->AddSimpleItem(dwOffset + 0x04, 4, L"Version"); vabHdr->AddSimpleItem(dwOffset + 0x08, 4, L"VAB ID"); vabHdr->AddSimpleItem(dwOffset + 0x0c, 4, L"Total Size"); vabHdr->AddSimpleItem(dwOffset + 0x10, 2, L"Reserved"); vabHdr->AddSimpleItem(dwOffset + 0x12, 2, L"Number of Programs"); vabHdr->AddSimpleItem(dwOffset + 0x14, 2, L"Number of Tones"); vabHdr->AddSimpleItem(dwOffset + 0x16, 2, L"Number of VAGs"); vabHdr->AddSimpleItem(dwOffset + 0x18, 1, L"Master Volume"); vabHdr->AddSimpleItem(dwOffset + 0x19, 1, L"Master Pan"); vabHdr->AddSimpleItem(dwOffset + 0x1a, 1, L"Bank Attributes 1"); vabHdr->AddSimpleItem(dwOffset + 0x1b, 1, L"Bank Attributes 2"); vabHdr->AddSimpleItem(dwOffset + 0x1c, 4, L"Reserved"); GetBytes(dwOffset, 0x20, &hdr); // uint32_t sampCollOff = (((dwNumInstrs/4)+(dwNumInstrs%4 > 0))* 0x10) + dwTotalRegions * 0x20 + 0x20; // sampColl = new WDSampColl(this, sampCollOff, dwSampSectSize); // unLength = 0x9000; // uint32_t sampCollOff = dwOffset+0x20 + 128*0x10 + hdr.ps*16*0x20; // sampColl = new VabSampColl(this, sampCollOff, 0, hdr.vs); // sampColl->Load(); return true; }
bool CompileSnesSeq::GetHeaderInfo(void) { SetPPQN(SEQ_PPQN); VGMHeader* header = AddHeader(dwOffset, 0); header->AddSimpleItem(dwOffset, 1, L"Number of Tracks"); nNumTracks = GetByte(dwOffset); if (nNumTracks == 0 || nNumTracks > 8) { return false; } uint32_t curOffset = dwOffset + 1; for (uint8_t trackIndex = 0; trackIndex < nNumTracks; trackIndex++) { std::wstringstream trackName; trackName << L"Track " << (trackIndex + 1); VGMHeader* trackHeader = header->AddHeader(curOffset, 14, trackName.str().c_str()); trackHeader->AddSimpleItem(curOffset, 1, L"Channel"); trackHeader->AddSimpleItem(curOffset + 1, 1, L"Flags"); trackHeader->AddSimpleItem(curOffset + 2, 1, L"Volume"); trackHeader->AddSimpleItem(curOffset + 3, 1, L"Volume Envelope"); trackHeader->AddSimpleItem(curOffset + 4, 1, L"Vibrato"); trackHeader->AddSimpleItem(curOffset + 5, 1, L"Transpose"); trackHeader->AddTempo(curOffset + 6, 1); trackHeader->AddSimpleItem(curOffset + 7, 1, L"Branch ID (Channel #)"); trackHeader->AddSimpleItem(curOffset + 8, 2, L"Score Pointer"); trackHeader->AddSimpleItem(curOffset + 10, 1, L"SRCN"); trackHeader->AddSimpleItem(curOffset + 11, 1, L"ADSR"); trackHeader->AddSimpleItem(curOffset + 12, 1, L"Pan"); trackHeader->AddSimpleItem(curOffset + 13, 1, L"Reserved"); curOffset += 14; } return true; //successful }