public GcAdpcmAlignment(int multiple, int loopStart, int loopEnd, byte[] adpcm, short[] coefs) { AlignmentMultiple = multiple; LoopStart = loopStart; LoopEnd = loopEnd; AlignmentNeeded = !Helpers.LoopPointsAreAligned(loopStart, multiple); if (!AlignmentNeeded) { return; } int loopLength = loopEnd - loopStart; LoopStartAligned = Helpers.GetNextMultiple(loopStart, multiple); SampleCountAligned = loopEnd + (LoopStartAligned - loopStart); AdpcmAligned = new byte[SampleCountToByteCount(SampleCountAligned)]; PcmAligned = new short[SampleCountAligned]; int framesToKeep = loopEnd / SamplesPerFrame; int bytesToKeep = framesToKeep * BytesPerFrame; int samplesToKeep = framesToKeep * SamplesPerFrame; int samplesToEncode = SampleCountAligned - samplesToKeep; var param = new GcAdpcmParameters { SampleCount = loopEnd }; short[] oldPcm = GcAdpcmDecoder.Decode(adpcm, coefs, param); Array.Copy(oldPcm, 0, PcmAligned, 0, loopEnd); var newPcm = new short[samplesToEncode]; Array.Copy(oldPcm, samplesToKeep, newPcm, 0, loopEnd - samplesToKeep); for (int currentSample = loopEnd - samplesToKeep; currentSample < samplesToEncode; currentSample += loopLength) { Array.Copy(PcmAligned, loopStart, newPcm, currentSample, Math.Min(loopLength, samplesToEncode - currentSample)); } param.SampleCount = samplesToEncode; param.History1 = samplesToKeep < 1 ? (short)0 : oldPcm[samplesToKeep - 1]; param.History2 = samplesToKeep < 2 ? (short)0 : oldPcm[samplesToKeep - 2]; byte[] newAdpcm = GcAdpcmEncoder.Encode(newPcm, coefs, param); Array.Copy(adpcm, 0, AdpcmAligned, 0, bytesToKeep); Array.Copy(newAdpcm, 0, AdpcmAligned, bytesToKeep, newAdpcm.Length); short[] decodedPcm = GcAdpcmDecoder.Decode(newAdpcm, coefs, param); Array.Copy(decodedPcm, 0, PcmAligned, samplesToKeep, samplesToEncode); }
protected override void SetupWriter(AudioData audio) { var parameters = new GcAdpcmParameters { Progress = Configuration.Progress }; if (Codec == NwCodec.GcAdpcm) { Adpcm = audio.GetFormat <GcAdpcmFormat>(parameters); AudioFormat = Adpcm; } else if (Codec == NwCodec.Pcm16Bit) { Pcm16 = audio.GetFormat <Pcm16Format>(parameters); AudioFormat = Pcm16; } }
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; } }