Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        public void Open(string name, Stream s)
        {
            Name = name;
            using (BinaryReaderExt r = new BinaryReaderExt(s))
            {
                r.BigEndian = true;

                var headerLength = r.ReadInt32() + 0x10;
                var dataOff      = r.ReadInt32();
                var soundCount   = r.ReadInt32();
                StartIndex = r.ReadInt32();

                Sounds = new DSP[soundCount];

                for (int i = 0; i < soundCount; i++)
                {
                    var sound        = new DSP();
                    var ChannelCount = r.ReadInt32();
                    sound.Frequency = r.ReadInt32();

                    sound.Channels.Clear();
                    for (int j = 0; j < ChannelCount; j++)
                    {
                        var channel = new DSPChannel();

                        channel.LoopFlag = r.ReadInt16();
                        channel.Format   = r.ReadInt16();
                        var LoopStartOffset = r.ReadInt32();
                        var LoopEndOffset   = r.ReadInt32();
                        var CurrentAddress  = r.ReadInt32();
                        for (int k = 0; k < 0x10; k++)
                        {
                            channel.COEF[k] = r.ReadInt16();
                        }
                        channel.Gain = r.ReadInt16();
                        channel.InitialPredictorScale = r.ReadInt16();
                        channel.InitialSampleHistory1 = r.ReadInt16();
                        channel.InitialSampleHistory2 = r.ReadInt16();
                        channel.LoopPredictorScale    = r.ReadInt16();
                        channel.LoopSampleHistory1    = r.ReadInt16();
                        channel.LoopSampleHistory2    = r.ReadInt16();
                        r.ReadInt16(); //  padding

                        channel.NibbleCount = LoopEndOffset - CurrentAddress;
                        channel.LoopStart   = LoopStartOffset - CurrentAddress;

                        sound.Channels.Add(channel);

                        var DataOffset = headerLength + (int)Math.Ceiling(CurrentAddress / 2d) - 1;

                        channel.Data = r.GetSection((uint)DataOffset, (int)Math.Ceiling(channel.NibbleCount / 2d) + 1);
                    }

                    Sounds[i] = sound;
                }
            }
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="channel"></param>
        private void ExportDSPChannel(string filePath, DSPChannel channel)
        {
            using (BinaryWriterExt w = new BinaryWriterExt(new FileStream(filePath, FileMode.Create)))
            {
                w.BigEndian = true;

                var samples = channel.NibbleCount * 7 / 8;

                w.Write(samples);
                w.Write(channel.NibbleCount);
                w.Write(Frequency);

                w.Write(channel.LoopFlag);
                w.Write(channel.Format);
                w.Write(2);
                w.Write(channel.NibbleCount - 2);
                w.Write(2);
                foreach (var v in channel.COEF)
                {
                    w.Write(v);
                }
                w.Write(channel.Gain);
                w.Write(channel.InitialPredictorScale);
                w.Write(channel.InitialSampleHistory1);
                w.Write(channel.InitialSampleHistory2);
                w.Write(channel.LoopPredictorScale);
                w.Write(channel.LoopSampleHistory1);
                w.Write(channel.LoopSampleHistory2);
                w.Write((short)0);

                w.Write(new byte[0x14]);

                w.Write(channel.Data);

                if (w.BaseStream.Position % 0x8 != 0)
                {
                    w.Write(new byte[0x08 - w.BaseStream.Position % 0x08]);
                }

                w.BaseStream.Close();
            }
        }
Пример #3
0
        private void FromDSP(byte[] data)
        {
            Channels.Clear();
            using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(data)))
            {
                r.BigEndian = true;

                r.ReadInt32();
                var nibbleCount = r.ReadInt32();
                Frequency = r.ReadInt32();

                var channel = new DSPChannel();

                channel.LoopFlag = r.ReadInt16();
                channel.Format   = r.ReadInt16();
                var LoopStartOffset = r.ReadInt32();
                var LoopEndOffset   = r.ReadInt32();
                var CurrentAddress  = r.ReadInt32();
                for (int k = 0; k < 0x10; k++)
                {
                    channel.COEF[k] = r.ReadInt16();
                }
                channel.Gain = r.ReadInt16();
                channel.InitialPredictorScale = r.ReadInt16();
                channel.InitialSampleHistory1 = r.ReadInt16();
                channel.InitialSampleHistory2 = r.ReadInt16();
                channel.LoopPredictorScale    = r.ReadInt16();
                channel.LoopSampleHistory1    = r.ReadInt16();
                channel.LoopSampleHistory2    = r.ReadInt16();
                r.ReadInt16(); //  padding

                r.Seek(0x60);
                channel.NibbleCount = nibbleCount;
                channel.LoopStart   = LoopStartOffset - CurrentAddress;
                channel.Data        = r.ReadBytes((int)Math.Ceiling(nibbleCount / 2d));

                Channels.Add(channel);

                r.BaseStream.Close();
            }
        }
Пример #4
0
        /*public void ToHPS()
         * {
         *
         * }*/

        #endregion

        #region WAVE

        private void FromWAVE(byte[] wavFile)
        {
            if (wavFile.Length < 0x2C)
            {
                throw new NotSupportedException("File is not a valid WAVE file");
            }

            Channels.Clear();

            using (BinaryReader r = new BinaryReader(new MemoryStream(wavFile)))
            {
                if (new string(r.ReadChars(4)) != "RIFF")
                {
                    throw new NotSupportedException("File is not a valid WAVE file");
                }

                r.BaseStream.Position = 0x14;
                var comp         = r.ReadInt16();
                var channelCount = r.ReadInt16();
                Frequency = r.ReadInt32();
                r.ReadInt32(); // block rate
                r.ReadInt16(); // block align
                var bpp = r.ReadInt16();

                if (comp != 1)
                {
                    throw new NotSupportedException("Compressed WAVE files not supported");
                }

                if (bpp != 16)
                {
                    throw new NotSupportedException("Only 16 bit WAVE formats accepted");
                }

                while (r.ReadByte() == 0)
                {
                    ;
                }
                r.BaseStream.Seek(-1, SeekOrigin.Current);

                while (new string(r.ReadChars(4)) != "data")
                {
                    var skip = r.ReadInt32();
                    r.BaseStream.Position += skip;
                }

                var channelSizes = r.ReadInt32() / channelCount / 2;

                List <List <short> > channels = new List <List <short> >();

                for (int i = 0; i < channelCount; i++)
                {
                    channels.Add(new List <short>());
                }

                for (int i = 0; i < channelSizes; i++)
                {
                    foreach (var v in channels)
                    {
                        v.Add(r.ReadInt16());
                    }
                }

                Channels.Clear();
                foreach (var data in channels)
                {
                    var c = new DSPChannel();

                    var ss = data.ToArray();

                    c.COEF = GcAdpcmCoefficients.CalculateCoefficients(ss);

                    c.Data = GcAdpcmEncoder.Encode(ss, c.COEF);

                    c.NibbleCount = c.Data.Length * 2;

                    c.InitialPredictorScale = c.Data[0];

                    Channels.Add(c);
                }
            }
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static DSP ToDSP(byte[] data)
        {
            DSP dsp = new DSP();

            dsp.Channels.Clear();
            using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(data)))
            {
                r.BigEndian = true;

                if (new string(r.ReadChars(7)) != " HALPST")
                {
                    throw new NotSupportedException("Invalid HPS file");
                }
                r.ReadByte();

                dsp.Frequency = r.ReadInt32();

                var channelCount = r.ReadInt32();

                if (channelCount != 2)
                {
                    throw new NotSupportedException("Only HPS with 2 channels are currently supported");
                }

                for (int i = 0; i < channelCount; i++)
                {
                    var channel = new DSPChannel();

                    channel.LoopFlag = r.ReadInt16();
                    channel.Format   = r.ReadInt16();
                    var SA = r.ReadInt32();
                    var EA = r.ReadInt32();
                    var CA = r.ReadInt32();
                    for (int k = 0; k < 0x10; k++)
                    {
                        channel.COEF[k] = r.ReadInt16();
                    }
                    channel.Gain = r.ReadInt16();
                    channel.InitialPredictorScale = r.ReadInt16();
                    channel.InitialSampleHistory1 = r.ReadInt16();
                    channel.InitialSampleHistory1 = r.ReadInt16();

                    channel.NibbleCount = EA - CA;
                    channel.LoopStart   = SA - CA;

                    dsp.Channels.Add(channel);
                }

                // read blocks
                r.Position = 0x80;

                Dictionary <int, int> OffsetToLoopPosition = new Dictionary <int, int>();
                List <byte>           channelData1         = new List <byte>();
                List <byte>           channelData2         = new List <byte>();
                while (true)
                {
                    var pos            = r.Position;
                    var length         = r.ReadInt32();
                    var lengthMinusOne = r.ReadInt32();
                    var next           = r.ReadInt32();
                    {
                        var initPS  = r.ReadInt16();
                        var initsh1 = r.ReadInt16();
                        var initsh2 = r.ReadInt16();
                        var gain    = r.ReadInt16();
                    }
                    {
                        var initPS  = r.ReadInt16();
                        var initsh1 = r.ReadInt16();
                        var initsh2 = r.ReadInt16();
                        var gain    = r.ReadInt16();
                    }
                    var extra = r.ReadInt32();

                    OffsetToLoopPosition.Add((int)pos, channelData1.Count * 2);
                    channelData1.AddRange(r.ReadBytes(length / 2));
                    channelData2.AddRange(r.ReadBytes(length / 2));

                    if (next < r.Position || next == -1)
                    {
                        if (next != -1)
                        {
                            foreach (var c in dsp.Channels)
                            {
                                c.LoopStart = OffsetToLoopPosition[next];
                            }
                        }
                        break;
                    }
                    else
                    {
                        r.Position = (uint)next;
                    }
                }

                dsp.Channels[0].Data = channelData1.ToArray();
                dsp.Channels[1].Data = channelData2.ToArray();
            }
            return(dsp);
        }