public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("RIFX") if (fileReader.Read_32bitsBE(offset) != 0x52494658) { return(0); } // Check for Mark ID ("WAVE" + "fmt ") if ((fileReader.Read_32bitsBE(offset + 0x08) == 0x57415645) && (fileReader.Read_32bitsBE(offset + 0x0C) == 0x666D7420)) { for (UInt64 i = 0; i < 0x100; i += 4) { if ((fileReader.Read_32bitsBE(offset + i) == 0x766F7262) || (fileReader.Read_32bitsBE(offset + i) == 0x63756520) || (fileReader.Read_32bitsBE(offset + i) == 0x4A554E4B)) { if (VGM_Utils.CheckSampleRate(fileReader.Read_32bitsBE(offset + 0x18))) { length = fileReader.Read_32bitsBE(offset + 0x04) + 0x8; return(length); } } } } return(0); }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("AUS ") if (fileReader.Read_32bitsBE(offset) != 0x41555320) { return(0); } uint channel_count = fileReader.Read_32bits(offset + 0x0C); uint sample_rate = fileReader.Read_32bits(offset + 0x10); if (!VGM_Utils.CheckChannels(channel_count)) { return(0); } if (!VGM_Utils.CheckSampleRate(sample_rate)) { return(0); } uint fileLength = (fileReader.Read_32bits(offset + 0x08) * 28 / 16) * channel_count; return(fileLength + 0x28); }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID (" KPV") if (fileReader.Read_32bitsBE(offset) != 0x58564147) { return(0); } uint channel_count = fileReader.Read_32bitsBE(offset + 0x28); uint sample_rate = fileReader.Read_32bitsBE(offset + 0x3C); if (!VGM_Utils.CheckChannels(channel_count)) { return(0); } if (!VGM_Utils.CheckSampleRate(sample_rate)) { return(0); } uint fileLength = fileReader.Read_32bitsBE(offset + 0x04) + fileReader.Read_32bitsBE(offset + 0x40); return(fileLength); }
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) { // Check for Mark ID (" KPV") if (fileReader.Read_32bitsBE(offset) != 0x204B5056) { return(0); } uint channel_count = fileReader.Read_32bits(offset + 0x14); uint sample_rate = fileReader.Read_32bits(offset + 0x10); if (!VGM_Utils.CheckChannels(channel_count)) { return(0); } if (!VGM_Utils.CheckSampleRate(sample_rate)) { return(0); } uint fileLength = fileReader.Read_32bits(offset + 0x04); uint interleave = fileReader.Read_32bits(offset + 0x0C) / channel_count; int blockCount = (int)(fileLength / interleave); if ((fileLength % interleave) != 0) { blockCount++; } fileLength = (uint)(blockCount * interleave * channel_count); return(fileLength + fileReader.Read_32bits(offset + 0x08)); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { bool loop_flag = (fileReader.Read_32bits(offset + 0x1C) != 0xFFFFFFFF); int channel_count = (int)fileReader.Read_32bits(offset + 0x10); int sample_rate = (int)fileReader.Read_32bits(offset + 0x0c); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); vgmStream.vgmLoopFlag = loop_flag; vgmStream.vgmChannelCount = channel_count; vgmStream.vgmSampleRate = sample_rate; vgmStream.vgmTotalSamples = (int)fileReader.Read_32bits(offset + 0x24) / 16 * 28 / channel_count; vgmStream.vgmLayout = new Interleave(); vgmStream.vgmInterleaveBlockSize = (int)fileReader.Read_32bits(offset + 0x14); vgmStream.vgmDecoder = new PSX_Decoder(); if (loop_flag) { vgmStream.vgmLoopStartSample = ((int)fileReader.Read_32bits(offset + 0x18) * 0x10) / 16 * 28 / vgmStream.vgmChannelCount; vgmStream.vgmLoopEndSample = ((int)fileReader.Read_32bits(offset + 0x1C) * 0x10) / 16 * 28 / vgmStream.vgmChannelCount; if (vgmStream.vgmLoopEndSample > vgmStream.vgmTotalSamples) { vgmStream.vgmLoopStartSample = ((int)fileReader.Read_32bits(offset + 0x18)) / 16 * 28 / vgmStream.vgmChannelCount; vgmStream.vgmLoopEndSample = ((int)fileReader.Read_32bits(offset + 0x1C)) / 16 * 28 / vgmStream.vgmChannelCount; } } UInt64 start_offset = offset + 0x28; if (!VGM_Utils.IsPS2ADPCM(fileReader, start_offset, start_offset + 0x8000)) { start_offset = offset + 0x800; if (!VGM_Utils.IsPS2ADPCM(fileReader, start_offset, start_offset + 0x8000)) { start_offset = offset + 0x28; vgmStream.vgmDecoder = new PCM16_Decoder(); vgmStream.vgmDecoderType = VGM_Decoder_Type.PCM16BITS; vgmStream.vgmTotalSamples = (int)fileReader.Read_32bits(offset + 0x24) / 2 / channel_count; if (loop_flag) { vgmStream.vgmLoopStartSample = (int)fileReader.Read_32bits(offset + 0x18); vgmStream.vgmLoopEndSample = (int)fileReader.Read_32bits(offset + 0x1C); } } } 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].startOffset = vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(vgmStream.vgmInterleaveBlockSize * i); } } }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("SShd") if (fileReader.Read_32bitsBE(offset) != 0x53536864) { return(0); } // Check for Mark ID ("SSbd") if (fileReader.Read_32bitsBE(offset + 0x20) != 0x53536264) { return(0); } uint channel_count = fileReader.Read_32bits(offset + 0x10); uint sample_rate = fileReader.Read_32bits(offset + 0x0c); if (!VGM_Utils.CheckChannels(channel_count)) { return(0); } if (!VGM_Utils.CheckSampleRate(sample_rate)) { return(0); } uint fileLength = fileReader.Read_32bits(offset + 0x024); return(fileLength + 0x28); }
public void Decode(VGM_Stream vgmStream, VGM_Channel vgmChannel, ref short[] vgmOutput, int vgmChannelSpacing, int vgmFirstSample, int vgmSamplesToDo, int vgmChannelNumber) { int vgmSampleCount, i; int framesin = vgmFirstSample / 32; int scale = vgmChannel.fReader.Read_16bitsBE((vgmChannel.currentOffset + (UInt64)(framesin * 18))) + 1; int vgmSampleHistory1 = vgmChannel.adpcm_history_32bits_1; int vgmSampleHistory2 = vgmChannel.adpcm_history_32bits_2; int coef1 = vgmChannel.adpcm_coef[0]; int coef2 = vgmChannel.adpcm_coef[1]; int vgmSample; vgmFirstSample = vgmFirstSample % 32; for (i = vgmFirstSample, vgmSampleCount = 0; i < vgmFirstSample + vgmSamplesToDo; i++, vgmSampleCount += vgmChannelSpacing) { int sample_byte = vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)((framesin * 18) + 2 + i / 2)); sample_byte = (((i & 1) == 1) ? VGM_Utils.LOWNIBBLE_SIGNED(sample_byte) : VGM_Utils.HINIBBLE_SIGNED(sample_byte)); vgmSample = (sample_byte * scale); vgmSample += (((coef1 * vgmSampleHistory1) + (coef2 * vgmSampleHistory2)) >> 12); vgmOutput[vgmStream.vgmSamplesBlockOffset + vgmSampleCount + vgmChannelNumber] = VGM_Utils.clamp16(vgmSample); vgmSampleHistory2 = vgmSampleHistory1; vgmSampleHistory1 = vgmSample; } vgmChannel.adpcm_history_32bits_1 = vgmSampleHistory1; vgmChannel.adpcm_history_32bits_2 = vgmSampleHistory2; }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("RIFF") if (fileReader.Read_32bitsBE(offset) != 0x52494646) { return(0); } // Check for Mark ID ("WAVE" + "fmt ") if ((fileReader.Read_32bitsBE(offset + 0x08) == 0x57415645) && (fileReader.Read_32bitsBE(offset + 0x0C) == 0x666D7420)) { if (fileReader.Read_16bits(offset + 0x14) == 0xFFFE) { if ((fileReader.Read_32bitsBE(offset + 0x2C) == 0xBFAA23E9) && (fileReader.Read_32bitsBE(offset + 0x30) == 0x58CB7144) && (fileReader.Read_32bitsBE(offset + 0x34) == 0xA119FFFA)) { if (VGM_Utils.CheckSampleRate(fileReader.Read_16bits(offset + 0x18))) { length = fileReader.Read_32bits(offset + 0x04) + 0x8; return(length); } } } } return(0); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { bool loop_flag = (fileReader.Read_32bits(offset + 0x14) == 1); int channel_count = (int)fileReader.Read_32bits(offset + 0x0C); if (fileReader.Read_32bits(offset + 0x30) == 0x45434B2E) { m_Description = "Konami SVAG (KCE-Tokyo)"; } else { m_Description = "Konami SVAG (KONAMITYO)"; } /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); /* fill in the vital statistics */ UInt64 start_offset = offset + 0x800; vgmStream.vgmChannelCount = channel_count; vgmStream.vgmSampleRate = (int)fileReader.Read_32bits(offset + 0x08); vgmStream.vgmDecoder = new PSX_Decoder(); if (vgmStream.vgmChannelCount == 1) { vgmStream.vgmLayout = new NoLayout(); } else { vgmStream.vgmLayout = new Interleave(); } vgmStream.vgmLoopFlag = loop_flag; vgmStream.vgmTotalSamples = (int)((fileReader.Read_32bits(offset + 0x04) * 28 / 16) / channel_count); if (loop_flag) { vgmStream.vgmLoopStartSample = (int)(fileReader.Read_32bits(offset + 0x18) / 16 * 28); vgmStream.vgmLoopEndSample = (int)(fileReader.Read_32bits(offset + 0x04) / 16 * 28 / vgmStream.vgmChannelCount); } vgmStream.vgmInterleaveBlockSize = (int)fileReader.Read_32bits(offset + 0x10); 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].startOffset = vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(vgmStream.vgmInterleaveBlockSize * i); } } }
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 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 int update(ref short[] vgmBuffer, int vgmSampleCount, VGM_Stream vgmStream) { int i; int samples_written = 0; int samples_this_block = vgmStream.vgmTotalSamples; int samples_per_frame = vgmStream.vgmDecoder.SamplesPerFrame(); vgmStream.vgmSamplesBlockOffset = 0; if (vgmStream.vgmDecodedSamples >= vgmStream.vgmTotalSamplesWithLoop) { return(0); } while (samples_written < vgmSampleCount) { int samples_to_do; if (vgmStream.vgmLoopFlag && VGM_Utils.vgmstream_do_loop(vgmStream)) { 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; } for (i = 0; i < vgmStream.vgmChannelCount; i++) { vgmStream.vgmDecoder.Decode(vgmStream, vgmStream.vgmChannel[i], ref vgmBuffer, vgmStream.vgmChannelCount, vgmStream.vgmSamplesIntoBlock, samples_to_do, i); } vgmStream.vgmSamplesBlockOffset += samples_to_do * vgmStream.vgmChannelCount; samples_written += samples_to_do; vgmStream.vgmSamplePlayed += samples_to_do; vgmStream.vgmDecodedSamples += samples_to_do; if (vgmStream.vgmDecodedSamples >= vgmStream.vgmTotalSamplesWithLoop) { return(samples_written); } vgmStream.vgmSamplesIntoBlock += samples_to_do; } return(samples_written); }
public VGM_Decoding(VGM_Stream vgmStream, StreamReader.IReader fileReader) { m_vgmStream = vgmStream; m_fileReader = fileReader; if (m_WavFormat != null) { m_WavFormat = null; } m_WavFormat = new NAudio.Wave.WaveFormat(vgmStream.vgmSampleRate, vgmStream.vgmChannelCount); m_FadeSamples = (int)(m_FadeSeconds * vgmStream.vgmSampleRate); m_vgmStream.vgmDecodedSamples = 0; m_vgmStream.vgmTotalSamplesWithLoop = VGM_Utils.get_vgmstream_play_samples(2, m_FadeSeconds, 0, vgmStream); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { int i; bool loop_flag = (fileReader.Read_32bits(offset + 0x14) != 0); int channel_count = (int)fileReader.Read_32bits(offset + 0x1C); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); /* fill in the vital statistics */ UInt64 start_offset = offset + fileReader.Read_32bits(offset + 0x08); vgmStream.vgmChannelCount = channel_count; vgmStream.vgmSampleRate = (int)fileReader.Read_32bits(offset + 0x18); vgmStream.vgmDecoder = new PSX_Decoder(); if (channel_count == 1) { vgmStream.vgmLayout = new NoLayout(); } else { vgmStream.vgmLayout = new Interleave(); } vgmStream.vgmLoopFlag = loop_flag; vgmStream.vgmTotalSamples = (int)(fileReader.Read_32bits(offset + 0x0C) * 28 / 16 / channel_count); if (loop_flag) { vgmStream.vgmLoopStartSample = (int)((fileReader.Read_32bits(offset + 0x0C) - fileReader.Read_32bits(offset + 0x14)) * 28 / 16 / channel_count); vgmStream.vgmLoopEndSample = (int)(fileReader.Read_32bits(offset + 0x0C) * 28 / 16 / channel_count); } vgmStream.vgmInterleaveBlockSize = (int)fileReader.Read_32bits(offset + 0x24); 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); } } }
public void Decode(VGM_Stream vgmStream, VGM_Channel vgmChannel, ref short[] vgmOutput, int vgmChannelSpacing, int vgmFirstSample, int vgmSamplesToDo, int vgmChannelNumber) { int framesin = vgmFirstSample / 14; vgmFirstSample = vgmFirstSample % 14; byte header = vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)(framesin * 8)); int scale = 1 << (header & 0xf); int coef_index = (header >> 4) & 0xf; int vgmSampleHistory1 = vgmChannel.adpcm_history_32bits_1; int vgmSampleHistory2 = vgmChannel.adpcm_history_32bits_2; try { int coef1 = vgmChannel.adpcm_coef[coef_index * 2]; int coef2 = vgmChannel.adpcm_coef[coef_index * 2 + 1]; int vgmSampleCount, i; int vgmSample; for (i = vgmFirstSample, vgmSampleCount = 0; i < vgmFirstSample + vgmSamplesToDo; i++, vgmSampleCount += vgmChannelSpacing) { int sample_byte = vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)(framesin * 8 + 1 + i / 2)); vgmSample = (((i & 1) == 1) ? VGM_Utils.LOWNIBBLE_SIGNED(sample_byte) : VGM_Utils.HINIBBLE_SIGNED(sample_byte)); vgmSample = ((vgmSample * scale) << 11) + 1024; vgmSample = vgmSample + (coef1 * vgmSampleHistory1 + coef2 * vgmSampleHistory2); vgmSample = vgmSample >> 11; vgmOutput[vgmStream.vgmSamplesBlockOffset + vgmSampleCount + vgmChannelNumber] = VGM_Utils.clamp16(vgmSample); vgmSampleHistory2 = vgmSampleHistory1; vgmSampleHistory1 = vgmSample; } vgmChannel.adpcm_history_32bits_1 = vgmSampleHistory1; vgmChannel.adpcm_history_32bits_2 = vgmSampleHistory2; } catch (Exception e) { Console.Write(e.Message + " in DSP_Decoder"); } }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("Svag") if (fileReader.Read_32bitsBE(offset) != 0x53766167) { return(0); } // Check for Sample Rate if (!VGM_Utils.CheckSampleRate(fileReader.Read_32bits(offset + 0x08))) { return(0); } // Check Channels count if (!VGM_Utils.CheckChannels(fileReader.Read_32bits(offset + 0x0C))) { return(0); } // Values from 0 -> 0x1C are duplicated at offset 0x400 for (UInt64 i = 0; i < 0x1C / 4; i++) { if (fileReader.Read_32bits(offset + i) != fileReader.Read_32bits(offset + 0x400 + i)) { return(0); } } // Try to find file Length UInt64 startOffset = 0x800; UInt64 fileLength = fileReader.Read_32bits(offset + 0x04); //if (!VGM_Utils.IsPS2ADPCM(fileReader, startOffset + offset, startOffset + offset + fileLength)) // return 0; if (fileReader.Read_32bits(offset + 0x30) == 0x45434B2E) { m_Description = "Konami SVAG (KCE-Tokyo)"; } else { m_Description = "Konami SVAG (KONAMITYO)"; } return(fileLength + startOffset); }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("NPSF") if (fileReader.Read_32bitsBE(offset) != 0x4E505346) { return(0); } uint channel_count = fileReader.Read_32bits(offset + 0x0C); uint sample_rate = fileReader.Read_32bits(offset + 0x18); if (!VGM_Utils.CheckChannels(channel_count)) { return(0); } if (!VGM_Utils.CheckSampleRate(sample_rate)) { return(0); } if (fileReader.Read_32bits(offset + 0x10) != 0x800) { return(0); } uint fileLength = fileReader.Read_32bits(offset + 0x08); m_Filename = fileReader.Read_String(offset + 0x34, 0x20); if (channel_count == 1) { return(fileLength + 0x800); } else { uint blockCount = fileLength / 0x800; if ((fileLength % 0x800) != 0) { blockCount++; } fileLength = (blockCount * channel_count * 0x800) + 0x800; } return(fileLength); }
public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length) { // Check for Mark ID ("VAGx") where x can be "p","i","s" if ((fileReader.Read_32bitsBE(offset) & 0xFFFFFF00) != 0x56414700) { return(0); } uint vagLength = fileReader.Read_32bitsBE(offset + 0x0C) + 0x30; if (fileReader.Read_32bitsBE(offset + 0x24) == 0x56414778) { uint k = 0; do { k += 0x10; vagLength += 0x10; }while (fileReader.Read_16bitsBE(offset + fileReader.Read_32bitsBE(offset + 0x0C) + k) != 0x0007); } if ((length != (UInt64)(0xFFFFFFFFF)) && (vagLength != length)) { return(0); } // Check for Sample Rate if (!VGM_Utils.CheckSampleRate(fileReader.Read_32bitsBE(offset + 0x10))) { return(0); } if (!VGM_Utils.IsPS2ADPCM(fileReader, offset + 0x30, offset + vagLength)) { return(0); } // Filename is stored at offset +0x20 m_Filename = fileReader.Read_String(offset + 0x20, 0x10); return(vagLength + 0x30); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { bool loop_flag = (fileReader.Read_32bits(offset + 0x7FC) != 0); int channel_count = (int)fileReader.Read_32bits(offset + 0x14); int sample_rate = (int)fileReader.Read_32bits(offset + 0x10); /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag); vgmStream.vgmLoopFlag = loop_flag; vgmStream.vgmChannelCount = channel_count; vgmStream.vgmSampleRate = sample_rate; vgmStream.vgmTotalSamples = (int)(fileReader.Read_32bits(offset + 0x04) * 28 / 16); vgmStream.vgmLayout = new Interleave(); vgmStream.vgmInterleaveBlockSize = (int)(fileReader.Read_32bits(offset + 0x0C) / 2); vgmStream.vgmDecoder = new PSX_Decoder(); if (loop_flag) { vgmStream.vgmLoopStartSample = (int)fileReader.Read_32bits(offset + 0x7FC) * 28 / 16; vgmStream.vgmLoopEndSample = vgmStream.vgmTotalSamples; } UInt64 start_offset = offset + fileReader.Read_32bits(offset + 08); 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].startOffset = vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(vgmStream.vgmInterleaveBlockSize * i); } } }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { byte[] mibBuffer = new byte[0x10]; byte[] testBuffer = new byte[0x10]; byte[] testBuffer2 = new byte[0x10]; byte[] testBuffer3 = new byte[0x10]; //bool doChannelUpdate=true; //bool bDoUpdateInterleave=true; UInt64 loopStart = 0; UInt64 loopEnd = 0; UInt64 interleave = 0; UInt64 readOffset = offset; UInt64[] loopStartPoints = new UInt64[0x10]; int loopStartPointsCount = 0; UInt64[] loopEndPoints = new UInt64[0x10]; int loopEndPointsCount = 0; byte[] emptyLine = new byte[0x10]; bool loopToEnd = false; bool forceNoLoop = false; bool bolSaveEmptyLine = true; int i, channel_count = 0; bool interleave_found = false; UInt64 tstCount = 0; UInt64[] emptyLineOffset = new UInt64[100]; uint emptyLineCount = 0; uint max_interleave = 0; uint max_interleave_index = 0; // Initialize loop point to 0 for (i = 0; i < 0x10; i++) { loopStartPoints[i] = 0; loopEndPoints[i] = 0; testBuffer[i] = 0; emptyLine[i] = 0; } //if (this.Filename.ToUpper().Contains(".MIB")) /* Search for interleave value & loop points */ /* Get the first 16 values */ mibBuffer = fileReader.Read(offset, 0x10); if (MemoryReader.memcmp(mibBuffer, emptyLine, 0x10, 0)) { tstCount = 0x10; //readOffset += 0x10; } else { tstCount = 0x0e; } do { testBuffer = fileReader.Read(readOffset, 0x10); // be sure to point to an interleave value if (!interleave_found) { if (MemoryReader.memcmp(testBuffer, emptyLine, tstCount, 0x10 - tstCount)) { // don't need to stock all empty lines :P if (emptyLineCount >= 100) { emptyLineCount = 0; } if (emptyLineCount >= 1) { if ((readOffset - offset) > 0x60000) { bolSaveEmptyLine = false; } } if (bolSaveEmptyLine) { emptyLineOffset[emptyLineCount] = readOffset; emptyLineCount++; } } } // Loop Start ... if (testBuffer[0x01] == 0x06) { if (loopStartPointsCount < 0x10) { loopStartPoints[loopStartPointsCount] = readOffset - offset - 0x10; loopStartPointsCount++; } } // Loop End ... if (((testBuffer[0x01] == 0x03) && (testBuffer[0x03] != 0x77)) || (testBuffer[0x01] == 0x01)) { if (loopEndPointsCount < 0x10) { loopEndPoints[loopEndPointsCount] = readOffset - offset; //-0x10; loopEndPointsCount++; } if (testBuffer[0x01] == 0x01) { forceNoLoop = true; } } if (testBuffer[0x01] == 0x04) { // 0x04 loop points flag can't be with a 0x03 loop points flag if (loopStartPointsCount < 0x10) { if ((readOffset - offset) == 0) { loopStartPoints[loopStartPointsCount] = 0; } else { loopStartPoints[loopStartPointsCount] = readOffset - offset; } loopStartPointsCount++; // Loop end value is not set by flags ... // go until end of file loopToEnd = true; } } readOffset += 0x10; } while (readOffset < (offset + fileLength)); // Try to find biggest interleave value if (emptyLineCount > 1) { for (uint count = 1; count < emptyLineCount; count++) { if (((uint)(emptyLineOffset[count] - emptyLineOffset[count - 1])) > max_interleave) { max_interleave = (uint)(emptyLineOffset[count] - emptyLineOffset[count - 1]); max_interleave_index = count; } } if (max_interleave_index != 0) { interleave = (uint)(emptyLineOffset[max_interleave_index] - emptyLineOffset[0]); } } if ((testBuffer[0] == 0x0c) && (testBuffer[1] == 0)) { forceNoLoop = true; } if (channel_count == 0) { channel_count = 1; } // Calc Loop Points & Interleave ... if (loopStartPointsCount >= channel_count) { // can't get more then 0x10 loop point ! // and need at least 2 loop points if ((loopStartPointsCount <= 0x0F) && (loopStartPointsCount >= 2)) { // Always took the first 2 loop points interleave = loopStartPoints[loopStartPointsCount - 1] - loopStartPoints[loopStartPointsCount - 2]; loopStart = loopStartPoints[1]; // Can't be one channel .mib with interleave values if ((interleave > 0) && (channel_count == 1)) { channel_count = 2; } } else { loopStart = 0; } } if (loopEndPointsCount >= channel_count) { // can't get more then 0x10 loop point ! // and need at least 2 loop points if ((loopEndPointsCount <= 0x0F) && (loopEndPointsCount >= 2)) { if (loopEndPointsCount == 4) { if (interleave == 0) { interleave = loopEndPoints[3] - loopEndPoints[1]; } else { interleave = loopEndPoints[loopEndPointsCount - 1] - loopEndPoints[loopEndPointsCount - 2]; } } loopEnd = loopEndPoints[loopEndPointsCount - 1]; if (interleave >= 0x10) { if (channel_count == 1) { channel_count = 2; } } } else { loopToEnd = false; loopEnd = 0; } } if (loopToEnd) { loopEnd = fileLength; } // force no loop if (forceNoLoop) { loopEnd = 0; } if ((interleave > 0x10) && (channel_count == 1)) { channel_count = 2; } if (interleave <= 0) { interleave = 0x10; } /* build the VGMSTREAM */ VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, (loopEnd != 0)); /* fill in the vital statistics */ vgmStream.vgmDecoder = new PSX_Decoder(); if (channel_count == 1) { vgmStream.vgmLayout = new NoLayout(); } else { vgmStream.vgmLayout = new Interleave(); } vgmStream.vgmChannelCount = channel_count; vgmStream.vgmInterleaveBlockSize = (int)interleave; vgmStream.vgmLoopFlag = (loopEnd != 0); if (m_Description == null) { vgmStream.vgmSampleRate = 44100; } else { if (System.IO.Path.GetExtension(m_Description).ToUpper() == ".MIB") { vgmStream.vgmSampleRate = 44100; } } vgmStream.vgmTotalSamples = (int)(fileLength / (UInt64)16 / (UInt64)(channel_count * 28)); if (loopEnd != 0) { if (vgmStream.vgmChannelCount == 1) { vgmStream.vgmLoopStartSample = (int)loopStart / 16 * 18; vgmStream.vgmLoopEndSample = (int)loopEnd / 16 * 28; } else { if (loopStart == 0) { vgmStream.vgmLoopStartSample = 0; } else { vgmStream.vgmLoopStartSample = (int)(((UInt64)(((loopStart / interleave) - 1) * interleave)) / (UInt64)((16 * 14 * channel_count) / channel_count)); if (loopStart % interleave != 0) { vgmStream.vgmLoopStartSample += (int)(((UInt64)((loopStart % interleave) - 1) / (UInt64)(16 * 14 * channel_count))); } } if (loopEnd == fileLength) { vgmStream.vgmLoopEndSample = (int)((UInt64)loopEnd / (UInt64)((16 * 28) / channel_count)); } else { vgmStream.vgmLoopEndSample = (int)((UInt64)(((loopEnd / interleave) - 1) * interleave) / (UInt64)((16 * 14 * channel_count) / channel_count)); if (loopEnd % interleave != 0) { vgmStream.vgmLoopEndSample += (int)((UInt64)((loopEnd % interleave) - 1) / (UInt64)(16 * 14 * channel_count)); } } } } if (InitReader) { for (i = 0; i < channel_count; i++) { vgmStream.vgmChannel[i].currentOffset = offset + (interleave * (UInt64)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()); } } }
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); }
public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength) { UInt64 startOffset = 0; UInt64[] start_offset = new UInt64[2] { 0x140, 0x148 }; if (fileReader.Read_32bitsBE(offset + 0x44) == 0x6461744C) // datL { startOffset = 0x5e; start_offset[0] = fileReader.Read_32bitsBE(offset + 0x48); start_offset[1] = fileReader.Read_32bitsBE(offset + 0x54); } else { startOffset = 0x52; } int channel_count = fileReader.Read_16bitsBE(offset + startOffset); 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_32bitsBE(offset + startOffset + 0x14) / 8 * 14) / channel_count; vgmStream.vgmSampleRate = fileReader.Read_16bitsBE(offset + startOffset + 0x4); 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] = (Int16)fileReader.Read_16bitsBE(offset + startOffset + (UInt64)(0x2C + (i * 2) + (j * 0x60))); } } 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].startOffset = vgmStream.vgmChannel[i].currentOffset = offset + start_offset[i]; } } }
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); } } }
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 Decode(VGM_Stream vgmStream, VGM_Channel vgmChannel, ref short[] vgmOutput, int vgmChannelSpacing, int vgmFirstSample, int vgmSamplesToDo, int vgmChannelNumber) { int i; double vgmSample; int vgmSampleCount; double vgmSampleHistory1 = vgmChannel.adpcm_history_dbl_1; double vgmSampleHistory2 = vgmChannel.adpcm_history_dbl_2; Int16 vgmScale; // Get the offset of the correct frame Int32 vgmFrameNum = vgmFirstSample / 28; Int16 vgmPredictor = (Int16)(vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)(vgmFrameNum * 16)) >> 4); Int16 vgmShiftFactor = (Int16)(vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)(vgmFrameNum * 16)) & 0x0F); byte vgmFlag = vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)((vgmFrameNum * 16) + 1)); vgmFirstSample = vgmFirstSample % 28; for (i = vgmFirstSample, vgmSampleCount = 0; i < vgmFirstSample + vgmSamplesToDo; i++, vgmSampleCount += vgmChannelSpacing) { vgmSample = 0; if (vgmFlag < 0x07) { Int16 sample_byte = vgmChannel.fReader.Read_8Bits(vgmChannel.currentOffset + (UInt64)((vgmFrameNum * 16) + 2 + i / 2)); vgmScale = (Int16)(((((i & 1) == 1) ? sample_byte >> 4 : (sample_byte & 0x0f)) << 12)); if (vgmPredictor < 5) { vgmSample = (((vgmScale >> vgmShiftFactor) + vgmSampleHistory1 * VAG_f[vgmPredictor, 0] + vgmSampleHistory2 * VAG_f[vgmPredictor, 1])); } else { vgmSample = 0; } } vgmOutput[vgmStream.vgmSamplesBlockOffset + vgmSampleCount + vgmChannelNumber] = VGM_Utils.clamp16(vgmSample); vgmSampleHistory2 = vgmSampleHistory1; vgmSampleHistory1 = vgmSample; } vgmChannel.adpcm_history_dbl_1 = vgmSampleHistory1; vgmChannel.adpcm_history_dbl_2 = vgmSampleHistory2; }
public int update(ref short[] vgmBuffer, int vgmSampleCount, VGM_Stream vgmStream) { int samples_written = 0; int i; int frame_size = vgmStream.vgmDecoder.FrameSize(); int samples_per_frame = vgmStream.vgmDecoder.SamplesPerFrame(); int samples_this_block; vgmStream.vgmSamplesBlockOffset = 0; if (vgmStream.vgmDecodedSamples >= vgmStream.vgmTotalSamplesWithLoop) { return(0); } samples_this_block = vgmStream.vgmInterleaveBlockSize / frame_size * samples_per_frame; if ((vgmStream.vgmLayoutType == VGM_Layout_Type.Interleave_With_Shortblock) && (vgmStream.vgmSamplePlayed - vgmStream.vgmSamplesIntoBlock + samples_this_block > vgmStream.vgmTotalSamples)) { frame_size = vgmStream.vgmDecoder.ShortFrameSize(); samples_per_frame = vgmStream.vgmDecoder.SamplesPerShortFrame(); samples_this_block = vgmStream.vgmInterleaveShortBlockSize / frame_size * samples_per_frame; } while (samples_written < vgmSampleCount) { int samples_to_do; if (vgmStream.vgmLoopFlag && VGM_Utils.vgmstream_do_loop(vgmStream)) { /* we assume that the loop is not back into a short block */ if (vgmStream.vgmLayoutType == VGM_Layout_Type.Interleave_With_Shortblock) { frame_size = vgmStream.vgmDecoder.FrameSize(); samples_per_frame = vgmStream.vgmDecoder.SamplesPerFrame(); samples_this_block = vgmStream.vgmInterleaveBlockSize / 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; } 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) { if ((vgmStream.vgmLayoutType == VGM_Layout_Type.Interleave_With_Shortblock) && (vgmStream.vgmSamplePlayed + samples_this_block > vgmStream.vgmTotalSamples)) { frame_size = vgmStream.vgmDecoder.ShortFrameSize(); samples_per_frame = vgmStream.vgmDecoder.SamplesPerShortFrame(); samples_this_block = vgmStream.vgmInterleaveShortBlockSize / frame_size * samples_per_frame; for (i = 0; i < vgmStream.vgmChannelCount; i++) { vgmStream.vgmChannel[i].currentOffset += (UInt64)((vgmStream.vgmInterleaveBlockSize * (vgmStream.vgmChannelCount - i)) + (vgmStream.vgmInterleaveShortBlockSize * i)); } } else { for (i = 0; i < vgmStream.vgmChannelCount; i++) { vgmStream.vgmChannel[i].currentOffset += (UInt64)(vgmStream.vgmInterleaveBlockSize * vgmStream.vgmChannelCount); } } vgmStream.vgmSamplesIntoBlock = 0; } } return(samples_written); }
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); } } }