示例#1
0
        public UInt64 IsFormat(StreamReader.IReader fileReader, UInt64 offset, UInt64 length)
        {
            if (fileReader.Read_16bitsBE(offset) != 0x8000)
            {
                return(0);
            }

            // Check encoding type ...
            if (fileReader.Read_8Bits(offset + 4) != 3)
            {
                return(0);
            }

            // Check Frame Size ...
            if (fileReader.Read_8Bits(offset + 5) != 18)
            {
                return(0);
            }

            // Check Bit per Samples ...
            if (fileReader.Read_8Bits(offset + 6) != 4)
            {
                return(0);
            }

            // Check for channel count & sample rate
            uint sampleRate   = fileReader.Read_32bitsBE(offset + 0x08);
            uint channelCount = fileReader.Read_8Bits(offset + 0x07);

            if (((channelCount <= 0) || (channelCount > 8)) ||
                ((sampleRate < 11025) || (sampleRate > 48000)))
            {
                return(0);
            }

            // Search for the (c)CRI signature ...
            UInt64 criOffset = fileReader.Read_16bitsBE(offset + 2);

            if ((fileReader.Read_32bitsBE(offset + criOffset - 4) != 0x00002863) &&
                (fileReader.Read_32bitsBE(offset + criOffset) != 0x29435249))
            {
                return(0);
            }

            // Find file length ...
            UInt32 totalSamples = fileReader.Read_32bitsBE(offset + 0x0C);
            UInt64 searchOffset = offset + (totalSamples * channelCount) / 32 * 18 + criOffset + 4;

            while (fileReader.Read_16bitsBE(searchOffset) != 0x8001)
            {
                searchOffset++;
                if (!fileReader.CanRead())
                {
                    break;
                }
            }

            UInt64 fileLength = (searchOffset - offset) + fileReader.Read_16bitsBE(searchOffset + 2) + 4;

            return(fileLength);
        }
示例#2
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;

            UInt16 xor_start = 0;
            UInt16 xor_mult  = 0;
            UInt16 xor_add   = 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(fileReader, offset, ref xor_start, ref xor_mult, ref xor_add))
                {
                    return;
                }
            }

            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);
            }

            /* 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 ADXENC_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));

                    int j;
                    vgmStream.vgmChannel[i].adx_channels = channel_count;
                    vgmStream.vgmChannel[i].adx_xor      = xor_start;
                    vgmStream.vgmChannel[i].adx_mult     = xor_mult;
                    vgmStream.vgmChannel[i].adx_add      = xor_add;

                    for (j = 0; j < i; j++)
                    {
                        VGM_Utils.adx_next_key(ref vgmStream.vgmChannel[i]);
                    }
                }
            }
        }