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