Пример #1
0
        public static RwavChannelInfo Read(BinaryReader reader, int baseOffset)
        {
            var info = new RwavChannelInfo
            {
                AudioDataOffset  = reader.ReadInt32(),
                AdpcmInfoOffset  = reader.ReadInt32(),
                VolumeFrontRight = reader.ReadInt32(),
                VolumeFrontLeft  = reader.ReadInt32(),
                VolumeBackRight  = reader.ReadInt32(),
                VolumeBackLeft   = reader.ReadInt32()
            };

            reader.BaseStream.Position = baseOffset + info.AdpcmInfoOffset;
            var channel = new GcAdpcmChannelInfo
            {
                Coefs = Enumerable.Range(0, 16).Select(x => reader.ReadInt16()).ToArray(),
                Gain  = reader.ReadInt16(),
                Start = new GcAdpcmContext(reader),
                Loop  = new GcAdpcmContext(reader)
            };

            info.AdpcmInfo = channel;

            return(info);
        }
Пример #2
0
        private static void ReadCoefs(BinaryReader reader, GenhStructure structure, int channelNum)
        {
            using (BinaryReader coefReader = GetBinaryReader(reader.BaseStream, structure.CoefType.Endianness()))
            {
                coefReader.BaseStream.Position = structure.Coefs[channelNum];
                var channel = new GcAdpcmChannelInfo();

                if (structure.CoefType.HasFlag(GenhCoefType.Split))
                {
                    channel.Coefs = new short[16];
                    for (int c = 0; c < 8; c++)
                    {
                        channel.Coefs[c * 2] = coefReader.ReadInt16();
                    }

                    coefReader.BaseStream.Position = structure.CoefsSplit[channelNum];
                    for (int c = 0; c < 8; c++)
                    {
                        channel.Coefs[c * 2 + 1] = coefReader.ReadInt16();
                    }
                }
                else
                {
                    channel.Coefs = Enumerable.Range(0, 16).Select(x => coefReader.ReadInt16()).ToArray();
                }

                structure.Channels.Add(channel);
            }
        }
Пример #3
0
        public static ChannelInfo ReadBfstm(BinaryReader reader)
        {
            var info       = new ChannelInfo();
            int baseOffset = (int)reader.BaseStream.Position;

            var table = new ReferenceTable(reader, baseOffset);

            foreach (Reference channelInfo in table.References)
            {
                reader.BaseStream.Position = channelInfo.AbsoluteOffset;
                if (channelInfo.IsType(ReferenceType.WaveChannelInfo))
                {
                    var audioData = new Reference(reader);
                    info.WaveAudioOffsets.Add(audioData.Offset);
                }

                var adpcmInfo = new Reference(reader, channelInfo.AbsoluteOffset);

                if (adpcmInfo.IsType(ReferenceType.GcAdpcmInfo))
                {
                    reader.BaseStream.Position = adpcmInfo.AbsoluteOffset;

                    var channel = new GcAdpcmChannelInfo
                    {
                        Coefs = Enumerable.Range(0, 16).Select(x => reader.ReadInt16()).ToArray(),
                        Start = new GcAdpcmContext(reader),
                        Loop  = new GcAdpcmContext(reader)
                    };
                    info.Channels.Add(channel);
                }
            }

            return(info);
        }
Пример #4
0
        private static void ReadHeader(BinaryReader reader, DspStructure structure)
        {
            structure.SampleCount    = reader.ReadInt32();
            structure.NibbleCount    = reader.ReadInt32();
            structure.SampleRate     = reader.ReadInt32();
            structure.Looping        = reader.ReadInt16() == 1;
            structure.Format         = reader.ReadInt16();
            structure.StartAddress   = reader.ReadInt32();
            structure.EndAddress     = reader.ReadInt32();
            structure.CurrentAddress = reader.ReadInt32();

            reader.BaseStream.Position    = 0x4a;
            structure.ChannelCount        = reader.ReadInt16();
            structure.FramesPerInterleave = reader.ReadInt16();
            structure.ChannelCount        = structure.ChannelCount == 0 ? 1 : structure.ChannelCount;

            for (int i = 0; i < structure.ChannelCount; i++)
            {
                reader.BaseStream.Position = HeaderSize * i + 0x1c;
                var channel = new GcAdpcmChannelInfo
                {
                    Coefs = Enumerable.Range(0, 16).Select(x => reader.ReadInt16()).ToArray(),
                    Gain  = reader.ReadInt16(),
                    Start = new GcAdpcmContext(reader),
                    Loop  = new GcAdpcmContext(reader)
                };

                structure.Channels.Add(channel);
            }

            if (reader.BaseStream.Length < HeaderSize + SampleCountToByteCount(structure.SampleCount))
            {
                throw new InvalidDataException($"File doesn't contain enough data for {structure.SampleCount} samples");
            }

            if (SampleCountToNibbleCount(structure.SampleCount) != structure.NibbleCount)
            {
                throw new InvalidDataException("Sample count and nibble count do not match");
            }

            if (structure.Format != 0)
            {
                throw new InvalidDataException($"File does not contain ADPCM audio. Specified format is {structure.Format}");
            }
        }
Пример #5
0
        public static void PrintChannelMetadata(GcAdpcmChannelInfo channel, StringBuilder builder, bool printLoopInfo)
        {
            builder.AppendLine("Coefficients:");
            builder.AppendLine($"{CoefficientsToString(channel.Coefs)}");
            builder.AppendLine($"Gain: 0x{channel.Gain:X4}");
            builder.AppendLine($"Pred/Scale: 0x{channel.Start.PredScale:X4}");
            builder.AppendLine($"History sample 1 (n-1): 0x{channel.Start.Hist1:X4}");
            builder.AppendLine($"History sample 2 (n-2): 0x{channel.Start.Hist2:X4}");
            if (!printLoopInfo)
            {
                return;
            }

            builder.AppendLine();
            builder.AppendLine($"Loop Pred/Scale: 0x{channel.Loop.PredScale:X4}");
            builder.AppendLine($"Loop History sample 1: 0x{channel.Loop.Hist1:X4}");
            builder.AppendLine($"Loop History sample 2: 0x{channel.Loop.Hist1:X4}");
        }
Пример #6
0
        public static ChannelInfo ReadBrstm(BinaryReader reader, Reference reference)
        {
            var info = new ChannelInfo();

            int channelCount = reader.ReadByte();

            reader.BaseStream.Position += 3;

            var references = new List <Reference>();

            for (int i = 0; i < channelCount; i++)
            {
                references.Add(new Reference(reader, reference.BaseOffset));
            }

            foreach (Reference channelInfo in references)
            {
                reader.BaseStream.Position = channelInfo.AbsoluteOffset;
                var adpcmInfo = new Reference(reader, reference.BaseOffset);

                if (adpcmInfo.Offset > 0)
                {
                    reader.BaseStream.Position = adpcmInfo.AbsoluteOffset;

                    var channel = new GcAdpcmChannelInfo
                    {
                        Coefs = Enumerable.Range(0, 16).Select(x => reader.ReadInt16()).ToArray(),
                        Gain  = reader.ReadInt16(),
                        Start = new GcAdpcmContext(reader),
                        Loop  = new GcAdpcmContext(reader)
                    };
                    info.Channels.Add(channel);
                }
            }

            return(info);
        }