コード例 #1
0
        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);
        }
コード例 #2
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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        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);
                }
            }
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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;
        }
コード例 #9
0
        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);
        }
コード例 #10
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);
                }
            }
        }
コード例 #11
0
        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);
            }
        }
コード例 #12
0
        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));
        }
コード例 #13
0
        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);
                }
            }
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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);
                }
            }
        }
コード例 #17
0
        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");
            }
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        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);
        }
コード例 #21
0
        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);
                }
            }
        }
コード例 #22
0
        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());
                }
            }
        }
コード例 #23
0
        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);
        }
コード例 #24
0
        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];
                }
            }
        }
コード例 #25
0
        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);
                }
            }
        }
コード例 #26
0
        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);
                }
            }
        }
コード例 #27
0
        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;
        }
コード例 #28
0
        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);
        }
コード例 #29
0
        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);
                }
            }
        }