Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
//==============================================================
//		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
}
Exemplo n.º 11
0
//==============================================================
//		ヘッダー情報の取得
//--------------------------------------------------------------
//	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;

}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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
}