public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { UInt64 start_offset; UInt64 i; int thpVersion = fileReader.Read_8Bits(offset + 0x06); /* fill in the vital statistics */ start_offset = fileReader.Read_32bitsBE(offset + 0x28); // Get info from the first block UInt64 componentTypeOffset = offset + fileReader.Read_32bitsBE(offset + 0x20); uint numComponents = fileReader.Read_32bitsBE(componentTypeOffset); UInt64 componentDataOffset = componentTypeOffset + 0x14; componentTypeOffset += 4; for (i = 0; i < numComponents; i++) { if (fileReader.Read_8Bits(componentTypeOffset + i) == 1) // audio block { uint channel_count = fileReader.Read_32bitsBE(componentDataOffset); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, (int)channel_count, false); vgmStream.vgmChannelCount = (int)channel_count; vgmStream.vgmSampleRate = (int)fileReader.Read_32bitsBE(componentDataOffset + 4); vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(componentDataOffset + 8); break; } else { if (thpVersion == 0x10) { componentDataOffset += 0x0c; } else { componentDataOffset += 0x08; } } } vgmStream.vgmTHPNextFrameSize = fileReader.Read_32bitsBE(offset + 0x18); vgmStream.vgmDecoder = new DSP_Decoder(); vgmStream.vgmLayout = new Blocked(); vgmStream.vgmLayoutType = VGM_Layout_Type.THP_Blocked; if (InitReader) { for (i = 0; i < 2; i++) { vgmStream.vgmChannel[i].fReader = (StreamReader.IReader)Activator.CreateInstance(fileReader.GetType());; vgmStream.vgmChannel[i].fReader.Open(fileReader.GetFilename()); vgmStream.vgmChannel[i].fReader.SetSessionID(fileReader.GetSessionID()); } BlockedFnts.THP_Block_Update(offset + start_offset, ref vgmStream); } }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { if (fileReader.Read_32bitsBE(offset + 0) != 0x5253544D) /* "RSTM" */ { return(0); } if ((fileReader.Read_32bitsBE(offset + 0x04) != 0xFEFF0100) && (fileReader.Read_32bitsBE(offset + 0x04) != 0xFEFF0001)) { return(0); } /* get head offset, check */ UInt64 head_offset = fileReader.Read_16bitsBE(offset + 0x0C); if (head_offset == 0x10) { m_Description = "Nintendo RSTM Header v1"; } else { m_Description = "Nintendo RSTM Header v2"; } UInt64 rl_head_offset = head_offset + offset; if (fileReader.Read_32bitsBE(head_offset + offset) != 0x48454144) /* "HEAD" */ { return(0); } /* check type details */ byte codec_number = fileReader.Read_8Bits((head_offset == 0x10) ? rl_head_offset + 0x8 : rl_head_offset + 0x20); bool loop_flag = (fileReader.Read_8Bits((head_offset == 0x10) ? rl_head_offset + 0x19 : rl_head_offset + 0x21) != 0); uint channel_count = fileReader.Read_8Bits((head_offset == 0x10) ? rl_head_offset + 0xa : rl_head_offset + 0x22); uint sample_rate = fileReader.Read_16bitsBE((head_offset == 0x10) ? rl_head_offset + 0xc : rl_head_offset + 0x24); if (!VGM_Utils.CheckChannels(channel_count)) { return(0); } if (!VGM_Utils.CheckSampleRate(sample_rate)) { return(0); } if (codec_number > 2) { return(0); } return(fileReader.Read_32bitsBE(offset + 0x08)); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { Int16[] coef = new Int16[16] { 0x04ab, -0x0313, 0x0789, -0x0121, 0x09a2, -0x051b, 0x0c90, -0x053f, 0x084d, -0x055c, 0x0982, -0x0209, 0x0af6, -0x0506, 0x0be6, -0x040b }; int channel_count = fileReader.Read_8Bits(offset + 0x16); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, false); vgmStream.vgmDecoder = new DSP_Decoder(); vgmStream.vgmLayout = new Interleave(); vgmStream.vgmChannelCount = channel_count; vgmStream.vgmLoopFlag = false; vgmStream.vgmTotalSamples = (int)(fileReader.Read_32bits(offset + 0x42) / 8 * 14) / channel_count; vgmStream.vgmSampleRate = fileReader.Read_16bits(offset + 0x18); if (channel_count == 1) { vgmStream.vgmLayout = new NoLayout(); } else { vgmStream.vgmLayout = new Interleave(); vgmStream.vgmLayoutType = VGM_Layout_Type.Interleave_With_Shortblock; } vgmStream.vgmInterleaveBlockSize = 0x08; int i, j; for (j = 0; j < vgmStream.vgmChannelCount; j++) { for (i = 0; i < 16; i++) { vgmStream.vgmChannel[j].adpcm_coef[i] = coef[i]; } } UInt64 start_offset = offset + 0x46; if (InitReader) { for (i = 0; i < channel_count; i++) { vgmStream.vgmChannel[i].fReader = (StreamReader.IReader)Activator.CreateInstance(fileReader.GetType());; vgmStream.vgmChannel[i].fReader.Open(fileReader.GetFilename()); vgmStream.vgmChannel[i].fReader.SetSessionID(fileReader.GetSessionID()); vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(i * vgmStream.vgmInterleaveBlockSize); } } }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { if (fileReader.Read_16bitsBE(offset) != 0x8000) { return(0); } // Check encoding type ... if (fileReader.Read_8Bits(offset + 4) != 3) { return(0); } // Check Frame Size ... if (fileReader.Read_8Bits(offset + 5) != 18) { return(0); } // Check Bit per Samples ... if (fileReader.Read_8Bits(offset + 6) != 4) { return(0); } // Check for channel count & sample rate uint sampleRate = fileReader.Read_32bitsBE(offset + 0x08); uint channelCount = fileReader.Read_8Bits(offset + 0x07); if (((channelCount <= 0) || (channelCount > 8)) || ((sampleRate < 11025) || (sampleRate > 48000))) { return(0); } // Search for the (c)CRI signature ... UInt64 criOffset = fileReader.Read_16bitsBE(offset + 2); if ((fileReader.Read_32bitsBE(offset + criOffset - 4) != 0x00002863) && (fileReader.Read_32bitsBE(offset + criOffset) != 0x29435249)) { return(0); } // Find file length ... UInt32 totalSamples = fileReader.Read_32bitsBE(offset + 0x0C); UInt64 searchOffset = offset + (totalSamples * channelCount) / 32 * 18 + criOffset + 4; while (fileReader.Read_16bitsBE(searchOffset) != 0x8001) { searchOffset++; if (!fileReader.CanRead()) { break; } } UInt64 fileLength = (searchOffset - offset) + fileReader.Read_16bitsBE(searchOffset + 2) + 4; return(fileLength); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { bool loop_flag = false; UInt32 loop_start_sample = 0; UInt32 loop_start_offset; UInt32 loop_end_sample = 0; UInt32 loop_end_offset; Int16 coef1 = 0; Int16 coef2 = 0; int i; int channel_count = fileReader.Read_8Bits(offset + 0x07); /* check version signature, read loop info */ UInt16 version_signature = fileReader.Read_16bitsBE(offset + 0x12); UInt64 criOffset = (UInt64)fileReader.Read_16bitsBE(offset + 2) + 4; /* encryption */ if (version_signature == 0x0408) { //if (find_key(streamFile, &xor_start, &xor_mult, &xor_add)) //{ // coding_type = coding_CRI_ADX_enc; // version_signature = 0x0400; //} } if (version_signature == 0x0300) { /* type 03 */ if (criOffset - 6 >= 0x2c) { /* enough space for loop info? */ loop_flag = (fileReader.Read_32bitsBE(offset + 0x18) != 0); loop_start_sample = (fileReader.Read_32bitsBE(offset + 0x1c)); loop_start_offset = fileReader.Read_32bitsBE(offset + 0x20); loop_end_sample = fileReader.Read_32bitsBE(offset + 0x24); loop_end_offset = fileReader.Read_32bitsBE(offset + 0x28); } } else if (version_signature == 0x0400) { UInt32 ainf_info_length = 0; if (fileReader.Read_32bitsBE(offset + 0x24) == 0x41494E46) /* AINF Header */ { ainf_info_length = fileReader.Read_32bitsBE(offset + 0x28); } if (criOffset - ainf_info_length - 6 >= 0x38) { /* enough space for loop info? */ loop_flag = (fileReader.Read_32bitsBE(offset + 0x24) != 0); loop_start_sample = (fileReader.Read_32bitsBE(offset + 0x28)); loop_start_offset = fileReader.Read_32bitsBE(offset + 0x2C); loop_end_sample = fileReader.Read_32bitsBE(offset + 0x30); loop_end_offset = fileReader.Read_32bitsBE(offset + 0x34); } } else if (version_signature == 0x0500) { /* found in some SFD : Buggy Heat, appears to have no loop */ } /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); vgmStream.vgmChannelCount = channel_count; vgmStream.vgmSampleRate = (int)fileReader.Read_32bitsBE(offset + 0x08); vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C); vgmStream.vgmDecoder = new ADX_Decoder(); if (channel_count == 1) { vgmStream.vgmLayout = new NoLayout(); } else { vgmStream.vgmLayout = new Interleave(); } vgmStream.vgmLoopFlag = loop_flag; if (loop_flag) { vgmStream.vgmLoopStartSample = (int)loop_start_sample; vgmStream.vgmLoopEndSample = (int)loop_end_sample; } /* high-pass cutoff frequency, always 500 that I've seen */ UInt16 cutoff = fileReader.Read_16bitsBE(offset + 0x10); /* calculate filter coefficients */ { double x, y, z, a, b, c; x = cutoff; y = vgmStream.vgmSampleRate; z = Math.Cos(2.0 * Math.PI * x / y); a = Math.Sqrt(2) - z; b = Math.Sqrt(2) - 1.0; c = (a - Math.Sqrt((a + b) * (a - b))) / b; coef1 = (Int16)Math.Floor(c * 8192); coef2 = (Int16)Math.Floor(c * c * -4096); } vgmStream.vgmInterleaveBlockSize = 18; if (InitReader) { for (i = 0; i < channel_count; i++) { vgmStream.vgmChannel[i].fReader = (StreamReader.IReader)Activator.CreateInstance(fileReader.GetType());; vgmStream.vgmChannel[i].fReader.Open(fileReader.GetFilename()); vgmStream.vgmChannel[i].fReader.SetSessionID(fileReader.GetSessionID()); vgmStream.vgmChannel[i].adpcm_coef[0] = coef1; vgmStream.vgmChannel[i].adpcm_coef[1] = coef2; vgmStream.vgmChannel[i].startOffset = vgmStream.vgmChannel[i].currentOffset = offset + criOffset + (UInt64)(vgmStream.vgmInterleaveBlockSize * i); } } }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { UInt64 head_offset = fileReader.Read_16bitsBE(offset + 0x0C); if (head_offset == 0x10) { m_Description = "Nintendo RSTM Header v1"; } else { m_Description = "Nintendo RSTM Header v2"; } UInt64 rl_head_offset = head_offset + offset; bool loop_flag = (fileReader.Read_8Bits((head_offset == 0x10) ? rl_head_offset + 0x19 : rl_head_offset + 0x21) != 0); bool isDSP = false; int codec_number = fileReader.Read_8Bits((head_offset == 0x10) ? rl_head_offset + 0x8 : rl_head_offset + 0x20); int channel_count = fileReader.Read_8Bits((head_offset == 0x10) ? rl_head_offset + 0xa : rl_head_offset + 0x22); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); switch (codec_number) { case 0: vgmStream.vgmDecoder = new PCM8_Decoder(); break; case 1: vgmStream.vgmDecoder = new PCM16_Decoder(); vgmStream.vgmDecoderType = VGM_Decoder_Type.PCM16BITSBE; break; case 2: isDSP = true; vgmStream.vgmDecoder = new DSP_Decoder(); break; } vgmStream.vgmChannelCount = channel_count; vgmStream.vgmLoopFlag = loop_flag; vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE((head_offset == 0x10) ? rl_head_offset + 0x14 : rl_head_offset + 0x2c); vgmStream.vgmSampleRate = fileReader.Read_16bitsBE((head_offset == 0x10) ? rl_head_offset + 0xC : rl_head_offset + 0x24); if (loop_flag) { vgmStream.vgmLoopStartSample = (int)fileReader.Read_32bitsBE((head_offset == 0x10) ? rl_head_offset + 0x10 : rl_head_offset + 0x28); vgmStream.vgmLoopEndSample = vgmStream.vgmTotalSamples; } if (channel_count == 1) { vgmStream.vgmLayout = new NoLayout(); } else { vgmStream.vgmLayout = new Interleave(); vgmStream.vgmLayoutType = VGM_Layout_Type.Interleave_With_Shortblock; } vgmStream.vgmInterleaveBlockSize = (int)fileReader.Read_32bitsBE((head_offset == 0x10) ? rl_head_offset + 0x20 : rl_head_offset + 0x38); vgmStream.vgmInterleaveShortBlockSize = (int)fileReader.Read_32bitsBE((head_offset == 0x10) ? rl_head_offset + 0x30 : rl_head_offset + 0x48); if (isDSP) { int i, j; int coef_spacing = ((head_offset == 0x10) ? 0x30 : 0x38); UInt64 coef_offset1 = fileReader.Read_32bitsBE(rl_head_offset + 0x1C); UInt64 coef_offset2 = fileReader.Read_32bitsBE(rl_head_offset + 0x10 + coef_offset1); UInt64 coef_offset = ((head_offset == 0x10) ? 0x38 : coef_offset2 + 0x10); for (j = 0; j < vgmStream.vgmChannelCount; j++) { for (i = 0; i < 16; i++) { vgmStream.vgmChannel[j].adpcm_coef[i] = (Int16)fileReader.Read_16bitsBE(rl_head_offset + coef_offset + (UInt64)(j * coef_spacing + i * 2)); } } } UInt64 start_offset = offset + fileReader.Read_32bitsBE((head_offset == 0x10) ? rl_head_offset + 0x18 : rl_head_offset + 0x30); if (InitReader) { for (int i = 0; i < channel_count; i++) { vgmStream.vgmChannel[i].fReader = (StreamReader.IReader)Activator.CreateInstance(fileReader.GetType());; vgmStream.vgmChannel[i].fReader.Open(fileReader.GetFilename()); vgmStream.vgmChannel[i].fReader.SetSessionID(fileReader.GetSessionID()); vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(i * vgmStream.vgmInterleaveBlockSize); } } }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { int i; char vagID = (char)fileReader.Read_8Bits(offset + 0x03); uint fileVagLength = fileReader.Read_32bitsBE(offset + 0x0c); int channel_count = 1; uint interleave = 0; UInt64 loopStart = 0; UInt64 loopEnd = 0; bool loop_flag = false; switch (vagID) { case 'i': channel_count = 2; break; case 'V': if (fileReader.Read_32bitsBE(offset + 0x20) == 0x53746572) // vag Stereo { channel_count = 2; } break; case 'p': if (fileReader.Read_32bitsBE(offset + 0x24) == 0x56414778) { loop_flag = false; channel_count = 2; } else { if (fileReader.Read_32bitsBE(offset + 0x04) <= 0x00000004) { loop_flag = (fileReader.Read_32bitsBE(offset + 0x14) != 0); channel_count = 1; } else { /* Search for loop in VAG */ uint vagfileLength = fileReader.Read_32bitsBE(offset + 0x0c); UInt64 readOffset = offset + 0x20; do { readOffset += 0x10; // Loop Start ... if (fileReader.Read_8Bits(readOffset + 0x01) == 0x06) { if (loopStart == 0) { loopStart = readOffset; } } // Loop End ... if (fileReader.Read_8Bits(readOffset + 0x01) == 0x03) { if (loopEnd == 0) { loopEnd = readOffset; } } // Loop from end to beginning ... if ((fileReader.Read_8Bits(readOffset + 0x01) == 0x01)) { // Check if we have the eof tag after the loop point ... // if so we don't loop, if not present, we loop from end to start ... byte[] vagBuffer = fileReader.Read(readOffset + 0x10, 0x10); if ((vagBuffer[0] != 0) && (vagBuffer[0] != 0x0c)) { if ((vagBuffer[0] == 0x00) && (vagBuffer[0] == 0x07)) { loopStart = 0x40; loopEnd = readOffset; } } } } while (readOffset < offset + 0x20 + vagfileLength); loop_flag = (loopEnd != 0); } } break; default: break; } /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); /* fill in the vital statistics */ UInt64 start_offset = offset + 0x30; vgmStream.vgmChannelCount = channel_count; vgmStream.vgmSampleRate = (int)fileReader.Read_32bitsBE(offset + 0x10); vgmStream.vgmTotalSamples = (int)(fileReader.Read_32bits(offset + 0x04) * 28 / 16); vgmStream.vgmLayout = new NoLayout(); switch (vagID) { case 'i': // VAGi vgmStream.vgmLayout = new Interleave(); vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(0x0C) / 16 * 28; interleave = fileReader.Read_32bitsBE(offset + 0x08); start_offset = offset + 0x800; break; case 'p': // VAGp interleave = 0x10; // used for loop calc if (fileReader.Read_32bitsBE(offset + 0x04) == 0x00000004) { vgmStream.vgmChannelCount = 2; vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C); if (loop_flag) { vgmStream.vgmLoopStartSample = (int)fileReader.Read_32bitsBE(offset + 0x14); vgmStream.vgmLoopEndSample = (int)fileReader.Read_32bitsBE(offset + 0x18); } start_offset = offset + 0x80; vgmStream.vgmLayout = new Interleave(); // Double VAG Header @ 0x0000 & 0x1000 if (fileReader.Read_32bitsBE(offset + 0) == fileReader.Read_32bitsBE(offset + 0x1000)) { vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C) / 16 * 28; interleave = 0x1000; start_offset = offset + 0; } } else { if (fileReader.Read_32bitsBE(offset + 0x24) == 0x56414778) { if (fileReader.Read_16bitsBE(offset + fileReader.Read_32bitsBE(offset + 0x0C) + 0x10) != 0x0007) { interleave = 0x8000; } vgmStream.vgmLayout = new Interleave(); vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C) / 16 * 14; } else { vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C) / 16 * 28; start_offset = offset + 0x30; } } break; case 'V': // pGAV vgmStream.vgmLayout = new Interleave(); interleave = 0x2000; // Jak X hack ... if (fileReader.Read_32bitsBE(offset + 0x1000) == 0x56414770) { interleave = 0x1000; } vgmStream.vgmSampleRate = (int)fileReader.Read_32bits(offset + 0x10); vgmStream.vgmTotalSamples = (int)fileReader.Read_32bits(offset + 0x0C) / 16 * 14; start_offset = offset + 0; break; } vgmStream.vgmDecoder = new PSX_Decoder(); vgmStream.vgmLoopFlag = loop_flag; if (loop_flag) { vgmStream.vgmLoopStartSample = (int)(fileReader.Read_32bits(offset + 0x08) * 28 / 16 / vgmStream.vgmChannelCount); vgmStream.vgmLoopEndSample = (int)(fileReader.Read_32bits(offset + 0x04) * 28 / 16); } vgmStream.vgmInterleaveBlockSize = (int)interleave; if (InitReader) { for (i = 0; i < channel_count; i++) { vgmStream.vgmChannel[i].fReader = (StreamReader.IReader)Activator.CreateInstance(fileReader.GetType());; vgmStream.vgmChannel[i].fReader.Open(fileReader.GetFilename()); vgmStream.vgmChannel[i].startOffset = vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(vgmStream.vgmInterleaveBlockSize * i); } } }