コード例 #1
0
        private static void VerifyData(HpsStructure structure)
        {
            structure.SampleCount = structure.Channels.First().SampleCount;
            if (structure.Channels.Any(x => x.SampleCount != structure.SampleCount))
            {
                throw new InvalidDataException("Channels have differing sample counts");
            }

            int startOffset = structure.Blocks.Last().NextOffset;

            if (startOffset == -1)
            {
                return;
            }

            int currentNibble = 0;

            //Find the loop start block
            foreach (HpsBlock block in structure.Blocks)
            {
                if (block.Offset == startOffset)
                {
                    structure.Looping   = true;
                    structure.LoopStart = GcAdpcmMath.NibbleCountToSampleCount(currentNibble);

                    for (int i = 0; i < structure.Channels.Count; i++)
                    {
                        structure.Channels[i].Loop = block.Channels[i].Context;
                    }
                }
                currentNibble += block.FinalNibble + 1;
            }
        }
コード例 #2
0
        public static (byte[] adpcm, short[] coefs) GenerateAdpcmEmpty(int sampleCount)
        {
            var adpcm = new byte[GcAdpcmMath.SampleCountToByteCount(sampleCount)];
            var coefs = new short[16];

            return(adpcm, coefs);
        }
コード例 #3
0
ファイル: GcAdpcmChannel.cs プロジェクト: soneek/VGAudio
        internal GcAdpcmChannel(GcAdpcmChannelBuilder b)
        {
            if (b.AlignedAdpcm.Length < GcAdpcmMath.SampleCountToByteCount(b.SampleCount))
            {
                throw new ArgumentException("Audio array length is too short for the specified number of samples.");
            }

            UnalignedSampleCount = b.SampleCount;
            Adpcm = b.Adpcm;
            Pcm   = b.Pcm;

            Coefs        = b.Coefs;
            Gain         = b.Gain;
            StartContext = new GcAdpcmContext(Adpcm[0], b.StartContext.Hist1, b.StartContext.Hist2);

            Alignment     = b.GetAlignment();
            LoopContextEx = b.GetLoopContext();
            SeekTable     = b.GetSeekTable();

            //Grab the PCM data in case it was generated for the loop context or seek table
            if (!AlignmentNeeded)
            {
                Pcm = b.AlignedPcm;
            }
        }
コード例 #4
0
        public void AdpcmLengthIsCorrectAfterRealignment()
        {
            GcAdpcmChannel channel  = GetBuilder(100).WithLoop(true, 10, 100).WithLoopAlignment(15).Build();
            GcAdpcmChannel channel2 = channel.GetCloneBuilder().WithLoopAlignment(20).Build();

            Assert.Equal(GcAdpcmMath.SampleCountToByteCount(110), channel2.GetAdpcmAudio().Length);
        }
コード例 #5
0
        private static GcAdpcmChannelBuilder GetBuilder(int sampleCount = 100)
        {
            var adpcm = new byte[GcAdpcmMath.SampleCountToByteCount(sampleCount)];
            var coefs = new short[16];

            return(new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount));
        }
コード例 #6
0
ファイル: RwavWaveInfo.cs プロジェクト: soneek/VGAudio
        public static RwavWaveInfo ReadBrwav(BinaryReader reader)
        {
            int baseOffset = (int)reader.BaseStream.Position;
            var info       = new RwavWaveInfo();

            info.Codec        = (NwCodec)reader.ReadByte();
            info.Looping      = reader.ReadBoolean();
            info.ChannelCount = reader.ReadByte();
            reader.BaseStream.Position++;
            info.SampleRate             = reader.ReadUInt16();
            reader.BaseStream.Position += 2;
            info.LoopStart              = GcAdpcmMath.NibbleToSample(reader.ReadInt32());
            info.SampleCount            = GcAdpcmMath.NibbleToSample(reader.ReadInt32());
            info.ChannelInfoOffset      = reader.ReadInt32();
            info.InfoStructureLength    = reader.ReadInt32();

            var channelInfoOffsets = new int[info.ChannelCount];

            reader.BaseStream.Position = baseOffset + info.ChannelInfoOffset;

            for (int i = 0; i < info.ChannelCount; i++)
            {
                channelInfoOffsets[i] = reader.ReadInt32();
            }

            for (int i = 0; i < info.ChannelCount; i++)
            {
                reader.BaseStream.Position = baseOffset + channelInfoOffsets[i];
                RwavChannelInfo channel = RwavChannelInfo.Read(reader, baseOffset);
                info.Channels.Add(channel);
            }

            return(info);
        }
コード例 #7
0
        public void ConstructorAssignmentWorks(int sampleCount)
        {
            var adpcm   = new byte[GcAdpcmMath.SampleCountToByteCount(sampleCount)];
            var coefs   = new short[16];
            var builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount);

            Assert.Equal(adpcm, builder.Adpcm);
            Assert.Equal(coefs, builder.Coefs);
            Assert.Equal(sampleCount, builder.SampleCount);
        }
コード例 #8
0
        public void ReturnsSameDataAfterCreation()
        {
            var            adpcm   = new byte[GcAdpcmMath.SampleCountToByteCount(100)];
            var            coefs   = new short[16];
            GcAdpcmChannel channel = new GcAdpcmChannelBuilder(adpcm, coefs, 100).Build();

            Assert.Equal(100, channel.SampleCount);
            Assert.Same(adpcm, channel.Adpcm);
            Assert.Same(coefs, channel.Coefs);
        }
コード例 #9
0
        public static GcAdpcmChannel[] GenerateAdpcmChannelsEmpty(int sampleCount, int channelCount)
        {
            var channels = new GcAdpcmChannel[channelCount];

            for (int i = 0; i < channelCount; i++)
            {
                var adpcm = new byte[GcAdpcmMath.SampleCountToByteCount(sampleCount)];
                var coefs = new short[16];
                channels[i] = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount).Build();
            }
            return(channels);
        }
コード例 #10
0
ファイル: GenerateAudio.cs プロジェクト: soneek/VGAudio
        public static GcAdpcmFormat GenerateAdpcmEmpty(int sampleCount, int channelCount, int sampleRate, int samplesPerSeekTableEntry = 0x3800)
        {
            var channels = new GcAdpcmChannel[channelCount];

            for (int i = 0; i < channelCount; i++)
            {
                var builder = new GcAdpcmChannelBuilder(new byte[GcAdpcmMath.SampleCountToByteCount(sampleCount)], new short[16], sampleCount);
                builder.WithSeekTable(new short[sampleCount.DivideByRoundUp(samplesPerSeekTableEntry) * 2], samplesPerSeekTableEntry, true);
                channels[i] = builder.Build();
            }

            var adpcm = new GcAdpcmFormat(channels, sampleRate);

            return(adpcm);
        }
コード例 #11
0
ファイル: Common.cs プロジェクト: LazyBone152/XV2-Tools
        public static int BytesToSamples(int byteCount, NwCodec codec)
        {
            switch (codec)
            {
            case NwCodec.GcAdpcm:
                return(GcAdpcmMath.ByteCountToSampleCount(byteCount));

            case NwCodec.Pcm16Bit:
                return(byteCount / 2);

            case NwCodec.Pcm8Bit:
                return(byteCount);

            default:
                return(0);
            }
        }
コード例 #12
0
ファイル: Common.cs プロジェクト: LazyBone152/XV2-Tools
        public static int SamplesToBytes(int sampleCount, NwCodec codec)
        {
            switch (codec)
            {
            case NwCodec.GcAdpcm:
                return(GcAdpcmMath.SampleCountToByteCount(sampleCount));

            case NwCodec.Pcm16Bit:
                return(sampleCount * 2);

            case NwCodec.Pcm8Bit:
                return(sampleCount);

            default:
                return(0);
            }
        }
コード例 #13
0
ファイル: DspToolDll.cs プロジェクト: soneek/VGAudio
        public unsafe GcAdpcmChannel EncodeChannel(short[] pcm)
        {
            int sampleCount = pcm.Length;
            var adpcm       = new byte[GcAdpcmMath.SampleCountToByteCount(sampleCount)];
            var info        = new ADPCMINFO();

            Encode(pcm, adpcm, ref info, (uint)sampleCount);

            var coefs = new short[16];

            for (int i = 0; i < 16; i++)
            {
                coefs[i] = info.coef[i];
            }

            return(new GcAdpcmChannel(adpcm, coefs, sampleCount));
        }
コード例 #14
0
ファイル: Bxstm.cs プロジェクト: LazyBone152/XV2-Tools
        public static void PrintSpecificMetadata(object structure, StringBuilder builder)
        {
            var bxstm = structure as BxstmStructure;

            if (bxstm == null)
            {
                throw new InvalidDataException("Could not parse file metadata.");
            }
            StreamInfo info = bxstm.StreamInfo;

            builder.AppendLine();

            int calculatedSamples = (info.InterleaveCount - 1) * info.SamplesPerInterleave +
                                    GcAdpcmMath.ByteCountToSampleCount(info.LastBlockSizeWithoutPadding);

            builder.AppendLine($"Interleave Count: {info.InterleaveCount}");
            builder.AppendLine($"Interleave Size: 0x{info.InterleaveSize:X}");
            builder.AppendLine($"Samples per interleave: {info.SamplesPerInterleave}");
            builder.AppendLine($"Last interleave size without padding: 0x{info.LastBlockSizeWithoutPadding:X}");
            builder.AppendLine($"Last interleave size: 0x{info.LastBlockSize:X}");
            builder.AppendLine($"Samples in last interleave block: {info.LastBlockSamples}");
            builder.AppendLine($"Sample count from data size: {calculatedSamples}");
            builder.AppendLine();

            builder.AppendLine($"Samples per seek table entry: {info.SamplesPerSeekTableEntry}");

            for (int i = 0; i < bxstm.TrackInfo?.Tracks.Count; i++)
            {
                builder.AppendLine();
                builder.AppendLine($"Track {i}");
                builder.AppendLine(new string('-', 25));
                PrintTrackMetadata(bxstm.TrackInfo?.Tracks[i], builder);
            }

            if (info.Codec != NwCodec.GcAdpcm)
            {
                return;
            }
            GcAdpcm.PrintAdpcmMetadata(bxstm.ChannelInfo.Channels, builder);
        }
コード例 #15
0
        public void AdpcmLengthIsCorrectAfterBuilding()
        {
            GcAdpcmChannel channel = GetBuilder(100).WithLoop(true, 10, 100).Build();

            Assert.Equal(GcAdpcmMath.SampleCountToByteCount(100), channel.GetAdpcmAudio().Length);
        }
コード例 #16
0
        public void AdpcmLengthIsCorrectAfterAlignment()
        {
            var channel = GetBuilder(100).WithLoop(true, 10, 100).WithLoopAlignment(15).Build();

            Assert.Equal(GcAdpcmMath.SampleCountToByteCount(105), channel.GetAdpcmAudio().Length);
        }