示例#1
0
        protected override IAudioFormat ToAudioStream(HpsStructure structure)
        {
            var channels = new GcAdpcmChannel[structure.ChannelCount];

            for (int c = 0; c < structure.ChannelCount; c++)
            {
                int audioLength     = structure.Blocks.Sum(x => x.Channels[c].AudioData.Length);
                var audio           = new byte[audioLength];
                int currentPosition = 0;

                foreach (HpsBlock block in structure.Blocks)
                {
                    byte[] source = block.Channels[c].AudioData;
                    Array.Copy(source, 0, audio, currentPosition, source.Length);
                    currentPosition += source.Length;
                }

                var channelBuilder = new GcAdpcmChannelBuilder(audio, structure.Channels[c].Coefs, structure.Channels[c].SampleCount)
                {
                    Gain         = structure.Channels[c].Gain,
                    StartContext = structure.Channels[c].Start
                };

                channelBuilder.WithLoop(structure.Looping, structure.LoopStart, structure.SampleCount)
                .WithLoopContext(structure.LoopStart, structure.Channels[c].Loop?.PredScale ?? 0,
                                 structure.Channels[c].Loop?.Hist1 ?? 0, structure.Channels[c].Loop?.Hist2 ?? 0);

                channels[c] = channelBuilder.Build();
            }

            return(new GcAdpcmFormatBuilder(channels, structure.SampleRate)
                   .WithLoop(structure.Looping, structure.LoopStart, structure.SampleCount)
                   .Build());
        }
示例#2
0
        private static GcAdpcmFormat ToAdpcmStream(BxstmStructure structure)
        {
            StreamInfo streamInfo = structure.StreamInfo;
            List <GcAdpcmChannelInfo> channelInfo = structure.ChannelInfo.Channels;
            var channels = new GcAdpcmChannel[streamInfo.ChannelCount];

            for (int c = 0; c < channels.Length; c++)
            {
                var channelBuilder = new GcAdpcmChannelBuilder(structure.AudioData[c], channelInfo[c].Coefs, streamInfo.SampleCount)
                {
                    Gain         = channelInfo[c].Gain,
                    StartContext = channelInfo[c].Start
                };

                channelBuilder.WithLoop(streamInfo.Looping, streamInfo.LoopStart, streamInfo.SampleCount)
                .WithLoopContext(streamInfo.LoopStart, channelInfo[c].Loop.PredScale,
                                 channelInfo[c].Loop.Hist1, channelInfo[c].Loop.Hist2);

                if (structure.SeekTable != null)
                {
                    channelBuilder.WithSeekTable(structure.SeekTable[c], streamInfo.SamplesPerSeekTableEntry);
                }

                channels[c] = channelBuilder.Build();
            }

            return(new GcAdpcmFormatBuilder(channels, streamInfo.SampleRate)
                   .WithTracks(structure.TrackInfo?.Tracks)
                   .WithLoop(streamInfo.Looping, streamInfo.LoopStart, streamInfo.SampleCount)
                   .Build());
        }
示例#3
0
        protected override void SetupWriter(AudioData audio)
        {
            Adpcm = audio.GetFormat <GcAdpcmFormat>(new GcAdpcmParameters {
                Progress = Configuration.Progress
            });
            int channelSize = GetNextMultiple(MaxBlockSize / ChannelCount - 0x20, 0x20);

            MaxBlockSizeActual = channelSize * ChannelCount;
            int alignment = ByteCountToSampleCount(channelSize);

            if (!LoopPointsAreAligned(Adpcm.LoopStart, alignment))
            {
                Adpcm = Adpcm.GetCloneBuilder().WithAlignment(alignment).Build();
            }

            Parallel.For(0, ChannelCount, i =>
            {
                GcAdpcmChannelBuilder builder = Adpcm.Channels[i].GetCloneBuilder();

                builder.LoopAlignmentMultiple             = alignment;
                builder.EnsureLoopContextIsSelfCalculated = true;
                Adpcm.Channels[i] = builder.Build();
            });

            BlockMap = CreateBlockMap(Adpcm.SampleCount, Adpcm.Looping, Adpcm.LoopStart, Adpcm.ChannelCount, MaxBlockSizeActual);
        }
        public void SetLoopAssignsProperlyBoolOnlyWhenLooping()
        {
            GcAdpcmChannelBuilder builder = GetBuilder(200).WithLoop(true);

            Assert.True(builder.Looping);
            Assert.Equal(0, builder.LoopStart);
            Assert.Equal(200, builder.LoopEnd);
        }
        public void SetLoopAssignsProperlyWhenLooping()
        {
            GcAdpcmChannelBuilder builder = GetBuilder().WithLoop(true, 30, 50);

            Assert.True(builder.Looping);
            Assert.Equal(30, builder.LoopStart);
            Assert.Equal(50, builder.LoopEnd);
        }
        public void SetLoopAssignsProperlyWhenNotLooping()
        {
            GcAdpcmChannelBuilder builder = GetBuilder().WithLoop(false, 30, 50);

            Assert.False(builder.Looping);
            Assert.Equal(0, builder.LoopStart);
            Assert.Equal(0, builder.LoopEnd);
        }
        public void SetSeekTableSamplesOnlyReplacesOldTable()
        {
            GcAdpcmChannelBuilder builder = GetBuilder().WithSeekTable(new short[100], 100, true);

            builder.WithSamplesPerSeekTableEntry(10);
            Assert.Null(builder.SeekTable);
            Assert.False(builder.SeekTableIsSelfCalculated);
            Assert.Equal(10, builder.SamplesPerSeekTableEntry);
        }
        public void SetSeekTablePrebuiltSelfCalculated(int sampleCount, int samplesPerEntry, bool isSelfCalculated)
        {
            var seekTable = new short[100];
            GcAdpcmChannelBuilder builder = GetBuilder(sampleCount).WithSeekTable(seekTable, samplesPerEntry, isSelfCalculated);

            Assert.Equal(seekTable, builder.SeekTable);
            Assert.Equal(samplesPerEntry, builder.SamplesPerSeekTableEntry);
            Assert.Equal(isSelfCalculated, builder.SeekTableIsSelfCalculated);
        }
示例#9
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);
        }
        public void SetLoopContextAssignsVariables(int loopStart, short predScale, short loopHist1, short loopHist2, bool isSelfCalculated)
        {
            GcAdpcmChannelBuilder builder = GetBuilder().WithLoopContext(loopStart, predScale, loopHist1, loopHist2, isSelfCalculated);

            Assert.Equal(loopStart, builder.LoopContextStart);
            Assert.Equal(predScale, builder.LoopContext.PredScale);
            Assert.Equal(loopHist1, builder.LoopContext.Hist1);
            Assert.Equal(loopHist2, builder.LoopContext.Hist2);
            Assert.Equal(isSelfCalculated, builder.LoopContextIsSelfCalculated);
        }
        public void SetSeekTableSamplesDoesntReplaceOldTable()
        {
            var seekTable = new short[100];
            GcAdpcmChannelBuilder builder = GetBuilder().WithSeekTable(seekTable, 100, true);

            builder.WithSamplesPerSeekTableEntry(100);
            Assert.Equal(seekTable, builder.SeekTable);
            Assert.True(builder.SeekTableIsSelfCalculated);
            Assert.Equal(100, builder.SamplesPerSeekTableEntry);
        }
        public void CurrentSeekTableIsValidTest(bool isSelfCalculated, bool ensureSelfCalculated, int samplesPerEntry, bool expected)
        {
            GcAdpcmChannelBuilder builder = GetBuilder()
                                            .WithSeekTable(new short[0], 20, isSelfCalculated)
                                            .WithSamplesPerSeekTableEntry(samplesPerEntry);

            builder.EnsureSeekTableIsSelfCalculated = ensureSelfCalculated;

            Assert.Equal(expected, builder.CurrentSeekTableIsValid());
        }
示例#13
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);
        }
        public void SetPreviousAssignsProperly()
        {
            var seekTable   = new GcAdpcmSeekTable(new short[10], 2);
            var loopContext = new GcAdpcmLoopContext(1, 2, 3, 4, true);
            var alignment   = new GcAdpcmAlignment(0, 0, 10, new byte[10], new short[16]);
            GcAdpcmChannelBuilder builder = GetBuilder().WithPrevious(seekTable, loopContext, alignment);

            Assert.Equal(seekTable, builder.PreviousSeekTable);
            Assert.Equal(loopContext, builder.PreviousLoopContext);
            Assert.Equal(alignment, builder.PreviousAlignment);
        }
        public void PreviousSeekTableIsValidTest(bool isSelfCalculated, bool ensureSelfCalculated, int samplesPerEntry, bool expected)
        {
            var previous = new GcAdpcmSeekTable(new short[0], 20, isSelfCalculated);
            GcAdpcmChannelBuilder builder = GetBuilder()
                                            .WithPrevious(previous, null, null)
                                            .WithSamplesPerSeekTableEntry(samplesPerEntry);

            builder.EnsureSeekTableIsSelfCalculated = ensureSelfCalculated;

            Assert.Equal(expected, builder.PreviousSeekTableIsValid());
        }
        public void PreviousAlignmentIsValidTest(bool looping, int multiple, int loopStart, int loopEnd, bool expected)
        {
            var previous = new GcAdpcmAlignment(10, 20, 30, new byte[20], new short[16]);
            GcAdpcmChannelBuilder builder = GetBuilder()
                                            .WithPrevious(null, null, previous)
                                            .WithLoop(looping, loopStart, loopEnd);

            builder.LoopAlignmentMultiple = multiple;

            Assert.Equal(expected, builder.PreviousAlignmentIsValid());
        }
示例#17
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);
        }
        public void LoopContextIsValidTest(bool isSelfCalculated, bool ensureSelfCalculated, int loopStart, bool expected)
        {
            var previous = new GcAdpcmLoopContext(0, 0, 0, 20, isSelfCalculated);
            GcAdpcmChannelBuilder builder = GetBuilder()
                                            .WithPrevious(null, previous, null)
                                            .WithLoopContext(20, 0, 0, 0, isSelfCalculated);

            builder.EnsureLoopContextIsSelfCalculated = ensureSelfCalculated;

            Assert.Equal(expected, builder.PreviousLoopContextIsValid(loopStart));
            Assert.Equal(expected, builder.CurrentLoopContextIsValid(loopStart));
        }
示例#19
0
        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);
        }
示例#20
0
        public void CreateAlignmentReplacePreviousWhenLoopChanges(int multiple, int loopStart, int loopEnd)
        {
            var sampleCount = 100;

            var(adpcm, coefs) = GenerateAudio.GenerateAdpcmEmpty(sampleCount);
            var previous = new GcAdpcmAlignment(multiple, loopStart, loopEnd, adpcm, coefs);

            var builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount)
                          .WithLoop(true, loopStart + 1, loopEnd + 1)
                          .WithPrevious(null, null, previous);

            builder.LoopAlignmentMultiple = multiple;
            var alignment = builder.GetAlignment();

            Assert.NotEqual(previous, alignment);
        }
        public void CreateAlignmentWithPrevious(int multiple, int loopStart, int loopEnd)
        {
            int sampleCount = 100;

            (byte[] adpcm, short[] coefs) = GenerateAudio.GenerateAdpcmEmpty(sampleCount);
            var previous = new GcAdpcmAlignment(multiple, loopStart, loopEnd, adpcm, coefs);

            GcAdpcmChannelBuilder builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount)
                                            .WithLoop(true, loopStart, loopEnd)
                                            .WithPrevious(null, null, previous);

            builder.LoopAlignmentMultiple = multiple;
            GcAdpcmAlignment alignment = builder.GetAlignment();

            Assert.Equal(previous, alignment);
        }
示例#22
0
        public void CreateAlignmentWithNoPrevious(int multiple, int loopStart, int loopEnd)
        {
            var sampleCount = 100;

            var(adpcm, coefs) = GenerateAudio.GenerateAdpcmEmpty(sampleCount);

            var builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount)
                          .WithLoop(true, loopStart, loopEnd);

            builder.LoopAlignmentMultiple = multiple;
            var alignment = builder.GetAlignment();

            Assert.Equal(multiple, alignment.AlignmentMultiple);
            Assert.Equal(loopStart, alignment.LoopStart);
            Assert.Equal(loopEnd, alignment.LoopEnd);
        }
示例#23
0
        protected override IAudioFormat ToAudioStream(GenhStructure structure)
        {
            var channels = new GcAdpcmChannel[structure.ChannelCount];

            for (int c = 0; c < structure.ChannelCount; c++)
            {
                GcAdpcmChannel channel =
                    new GcAdpcmChannelBuilder(structure.AudioData[c], structure.Channels[c].Coefs, structure.SampleCount)
                    .WithLoop(structure.Looping, structure.LoopStart, structure.LoopEnd)
                    .Build();

                channels[c] = channel;
            }

            return(new GcAdpcmFormatBuilder(channels, structure.SampleRate)
                   .WithLoop(structure.Looping, structure.LoopStart, structure.LoopEnd)
                   .Build());
        }
示例#24
0
        public void GetLoopContextWithPrevious(bool isSelfCalculated, bool ensureSelfCalculated)
        {
            short num         = 20;
            var   sampleCount = 100;

            var(adpcm, coefs) = GenerateAudio.GenerateAdpcmEmpty(sampleCount);
            var previous = new GcAdpcmLoopContext(num, num, num, num, isSelfCalculated);

            var builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount)
                          .WithLoop(true, num, sampleCount)
                          .WithPrevious(null, previous, null)
                          .PrepareForBuild();

            builder.EnsureLoopContextIsSelfCalculated = ensureSelfCalculated;
            var context = builder.GetLoopContext();

            Assert.Equal(previous, context);
        }
示例#25
0
        protected override void SetupWriter(AudioData audio)
        {
            var parameters = new GcAdpcmParameters {
                Progress = Configuration.Progress
            };

            if (Codec == NwCodec.GcAdpcm)
            {
                Adpcm = audio.GetFormat <GcAdpcmFormat>(parameters);

                if (!LoopPointsAreAligned(Adpcm.LoopStart, Configuration.LoopPointAlignment))
                {
                    Adpcm = Adpcm.GetCloneBuilder().WithAlignment(Configuration.LoopPointAlignment).Build();
                }

                Parallel.For(0, Adpcm.ChannelCount, i =>
                {
                    GcAdpcmChannelBuilder builder = Adpcm.Channels[i].GetCloneBuilder()
                                                    .WithSamplesPerSeekTableEntry(SamplesPerSeekTableEntry)
                                                    .WithLoop(Adpcm.Looping, Adpcm.UnalignedLoopStart, Adpcm.UnalignedLoopEnd);

                    builder.LoopAlignmentMultiple             = Configuration.LoopPointAlignment;
                    builder.EnsureLoopContextIsSelfCalculated = Configuration.RecalculateLoopContext;
                    builder.EnsureSeekTableIsSelfCalculated   = Configuration.RecalculateSeekTable;
                    Adpcm.Channels[i] = builder.Build();
                });

                AudioFormat = Adpcm;
                Tracks      = Adpcm.Tracks;
            }
            else if (Codec == NwCodec.Pcm16Bit)
            {
                Pcm16       = audio.GetFormat <Pcm16Format>(parameters);
                AudioFormat = Pcm16;
                Tracks      = Pcm16.Tracks;
            }
            else if (Codec == NwCodec.Pcm8Bit)
            {
                Pcm8        = audio.GetFormat <Pcm8SignedFormat>(parameters);
                AudioFormat = Pcm8;
                Tracks      = Pcm8.Tracks;
            }
        }
示例#26
0
        public void CreateLoopContextWithNoPrevious(short predScale, short hist1, short hist2, int loopStart, bool isSelfCalculated)
        {
            var sampleCount = 100;

            var(adpcm, coefs) = GenerateAudio.GenerateAdpcmEmpty(sampleCount);

            var builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount)
                          .WithLoop(true, loopStart, sampleCount)
                          .WithLoopContext(loopStart, predScale, hist1, hist2, isSelfCalculated);

            builder.AlignedLoopStart = loopStart;

            var context = builder.GetLoopContext();

            Assert.Equal(predScale, context.PredScale);
            Assert.Equal(hist1, context.Hist1);
            Assert.Equal(hist2, context.Hist2);
            Assert.Equal(loopStart, context.LoopStart);
            Assert.Equal(isSelfCalculated, context.IsSelfCalculated);
        }
示例#27
0
        protected override IAudioFormat ToAudioStream(DspStructure structure)
        {
            var channels = new GcAdpcmChannel[structure.ChannelCount];

            for (int c = 0; c < structure.ChannelCount; c++)
            {
                var channelBuilder = new GcAdpcmChannelBuilder(structure.AudioData[c], structure.Channels[c].Coefs, structure.SampleCount)
                {
                    Gain         = structure.Channels[c].Gain,
                    StartContext = structure.Channels[c].Start
                };

                channelBuilder.WithLoop(structure.Looping, structure.LoopStart, structure.LoopEnd)
                .WithLoopContext(structure.LoopStart, structure.Channels[c].Loop.PredScale,
                                 structure.Channels[c].Loop.Hist1, structure.Channels[c].Loop.Hist2);

                channels[c] = channelBuilder.Build();
            }

            return(new GcAdpcmFormatBuilder(channels, structure.SampleRate)
                   .WithLoop(structure.Looping, structure.LoopStart, structure.LoopEnd)
                   .Build());
        }
示例#28
0
        public void GetLoopContextReplacePrevious(short expected, int loopStart, bool isSelfCalculated, bool ensureSelfCalculated)
        {
            short num         = 20;
            short numLarge    = 25;
            var   sampleCount = 100;

            var(adpcm, coefs) = GenerateAudio.GenerateAdpcmEmpty(sampleCount);
            var previous = new GcAdpcmLoopContext(num, num, num, num, isSelfCalculated);

            var builder = new GcAdpcmChannelBuilder(adpcm, coefs, sampleCount)
                          .WithPrevious(null, previous, null)
                          .WithLoop(true, loopStart, sampleCount)
                          .WithLoopContext(numLarge, numLarge, numLarge, numLarge, isSelfCalculated)
                          .PrepareForBuild();

            builder.EnsureLoopContextIsSelfCalculated = ensureSelfCalculated;
            var context = builder.GetLoopContext();

            Assert.Equal(expected, context.PredScale);
            Assert.Equal(expected, context.Hist1);
            Assert.Equal(expected, context.Hist2);
            Assert.Equal(loopStart, context.LoopStart);
        }