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 void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { int vgmNumSamples = 0; int loop_start = -1; UInt64 NextBlock; UInt64 currBlock = offset; int i; // Calculate sample length ... uint blockCount = fileReader.Read_32bitsBE(offset + 0x24); for (i = 0; i < blockCount; i++) { NextBlock = fileReader.Read_32bitsBE(currBlock + 0x04); vgmNumSamples += (int)(fileReader.Read_32bitsBE(currBlock + 0x14) / 8 * 14); if (fileReader.Read_32bitsBE(currBlock + 0x20) == fileReader.Read_32bitsBE(currBlock + 0x08)) { loop_start = (int)(vgmNumSamples - fileReader.Read_32bitsBE(currBlock + 0x14) / 8 * 14); } currBlock += NextBlock; } bool loop_flag = (loop_start != -1); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, 2, loop_flag); vgmStream.vgmLoopFlag = loop_flag; vgmStream.vgmChannelCount = 2; vgmStream.vgmSampleRate = 32000; vgmStream.vgmTotalSamples = vgmNumSamples; if (loop_flag) { vgmStream.vgmLoopStartSample = loop_start; vgmStream.vgmLoopEndSample = vgmNumSamples; } vgmStream.vgmDecoder = new DSP_Decoder(); vgmStream.vgmLayout = new Blocked(); vgmStream.vgmLayoutType = VGM_Layout_Type.CAF_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.CAF_Block_Update(offset + 0, ref vgmStream); } }
public int update(ref short[] vgmBuffer, int vgmSampleCount, VGM_Stream vgmStream) { int i; int samples_written = 0; int frame_size = vgmStream.vgmDecoder.FrameSize(); int samples_per_frame = vgmStream.vgmDecoder.SamplesPerFrame(); int samples_this_block; if (vgmStream.vgmDecodedSamples >= vgmStream.vgmTotalSamplesWithLoop) { return(0); } vgmStream.vgmSamplesBlockOffset = 0; if (frame_size == 0) { samples_this_block = vgmStream.vgmCurrentBlockSize * 2 * samples_per_frame; } else { samples_this_block = vgmStream.vgmCurrentBlockSize / frame_size * samples_per_frame; } while (samples_written < vgmSampleCount) { int samples_to_do; if (vgmStream.vgmLoopFlag && VGM_Utils.vgmstream_do_loop(vgmStream)) { if (frame_size == 0) { samples_this_block = vgmStream.vgmCurrentBlockSize * 2 * samples_per_frame; } else { samples_this_block = vgmStream.vgmCurrentBlockSize / frame_size * samples_per_frame; } continue; } samples_to_do = VGM_Utils.vgmstream_samples_to_do(samples_this_block, samples_per_frame, vgmStream); if (samples_written + samples_to_do > vgmSampleCount) { samples_to_do = vgmSampleCount - samples_written; } if (vgmStream.vgmCurrentBlockOffset >= 0) { for (i = 0; i < vgmStream.vgmChannelCount; i++) { vgmStream.vgmDecoder.Decode(vgmStream, vgmStream.vgmChannel[i], ref vgmBuffer, vgmStream.vgmChannelCount, vgmStream.vgmSamplesIntoBlock, samples_to_do, i); } } samples_written += samples_to_do; vgmStream.vgmSamplesBlockOffset += samples_to_do * vgmStream.vgmChannelCount; vgmStream.vgmSamplePlayed += samples_to_do; vgmStream.vgmDecodedSamples += samples_to_do; vgmStream.vgmSamplesIntoBlock += samples_to_do; if (vgmStream.vgmDecodedSamples >= vgmStream.vgmTotalSamplesWithLoop) { return(samples_written); } if (vgmStream.vgmSamplesIntoBlock == samples_this_block) { switch (vgmStream.vgmLayoutType) { case VGM_Layout_Type.CAF_Blocked: BlockedFnts.CAF_Block_Update(vgmStream.vgmNextBlockOffset, ref vgmStream); break; case VGM_Layout_Type.THP_Blocked: BlockedFnts.THP_Block_Update(vgmStream.vgmNextBlockOffset, ref vgmStream); break; default: break; } if (frame_size == 0) { samples_this_block = vgmStream.vgmCurrentBlockSize * 2 * samples_per_frame; } else { samples_this_block = vgmStream.vgmCurrentBlockSize / frame_size * samples_per_frame; } vgmStream.vgmSamplesIntoBlock = 0; } } return(samples_written); }