Beispiel #1
0
        /// <summary>
        /// Melee's sound format
        /// </summary>
        /// <param name="filePath"></param>
        private void OpenSSM(string filePath)
        {
            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
            {
                r.BigEndian = true;

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

                for (int i = 0; i < soundCount; i++)
                {
                    var sound = new DSP();
                    sound.Index = i;
                    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.Add(sound);
                }
            }
        }
Beispiel #2
0
        private DSP ImportDSP(string filePath)
        {
            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
            {
                r.BigEndian = true;

                var dsp = new DSP();

                r.ReadInt32();
                var nibbleCount = r.ReadInt32();
                dsp.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));

                dsp.Channels.Add(channel);

                r.BaseStream.Close();

                return(dsp);
            }
        }
Beispiel #3
0
        private void SaveChannelAsDSP(string filePath, DSPChannel channel, int frequency)
        {
            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();
            }
        }
Beispiel #4
0
        public void FromHPS(byte[] data)
        {
            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();

                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;

                    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();
                        r.ReadInt16();
                    }
                    {
                        var initPS  = r.ReadInt16();
                        var initsh1 = r.ReadInt16();
                        var initsh2 = r.ReadInt16();
                        r.ReadInt16();
                    }
                    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 Channels)
                            {
                                c.LoopStart = OffsetToLoopPosition[next];
                            }
                        }
                        break;
                    }
                    else
                    {
                        r.Position = (uint)next;
                    }
                }

                Channels[0].Data = channelData1.ToArray();
                Channels[1].Data = channelData2.ToArray();
            }
        }
Beispiel #5
0
        /*public void ToHPS()
         * {
         *
         * }*/

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

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

                r.BaseStream.Position = 0x28;
                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>());
                }

                foreach (var v in channels)
                {
                    for (int i = 0; i < channelSizes; i++)
                    {
                        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);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Used in Eighting Engine Games
        /// </summary>
        /// <param name="filePath"></param>
        private void OpenSDI(string filePath)
        {
            var sam = filePath.Replace(".sdi", ".sam");

            if (!File.Exists(sam))
            {
                return;
            }

            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
                using (BinaryReaderExt d = new BinaryReaderExt(new FileStream(sam, FileMode.Open)))
                {
                    r.BigEndian = true;

                    while (true)
                    {
                        var id = r.ReadInt32();
                        if (id == -1)
                        {
                            break;
                        }
                        var dataoffset = r.ReadUInt32();
                        var padding    = r.ReadInt32();
                        var flags      = r.ReadInt16();
                        var frequency  = r.ReadInt16();
                        var value      = r.ReadInt32();
                        r.Skip(8); // unknown
                        uint coefOffset = r.ReadUInt32();

                        DSP dsp = new DSP();
                        dsp.Frequency = frequency;

                        DSPChannel channel = new DSPChannel();
                        channel.NibbleCount = value;

                        var temp = r.Position;
                        var end  = (uint)d.Length;
                        if (r.ReadInt32() != -1)
                        {
                            end = r.ReadUInt32();
                        }

                        r.Seek(coefOffset);
                        r.ReadInt32();
                        r.ReadInt32();

                        for (int i = 0; i < 0x10; i++)
                        {
                            channel.COEF[i] = r.ReadInt16();
                        }

                        r.Seek(temp);

                        d.Seek(dataoffset);
                        byte[] data = d.ReadBytes((int)(end - dataoffset));

                        channel.Data = data;
                        channel.InitialPredictorScale = data[0];
                        dsp.Channels.Add(channel);

                        Sounds.Add(dsp);
                    }
                }
        }