public void AlignedAdpcmIsCorrect(int multiple, int loopStart, int sineCycles, int tolerance) { int loopEnd = sineCycles * 4 * SamplesPerFrame + loopStart; short[] pcm = GenerateSineWave(GetNextMultiple(loopEnd, SamplesPerFrame), 1, SamplesPerFrame * 4); short[] coefs = GcAdpcmCoefficients.CalculateCoefficients(pcm); byte[] adpcm = GcAdpcmEncoder.Encode(pcm, coefs); var alignment = new GcAdpcmAlignment(multiple, loopStart, loopEnd, adpcm, coefs); short[] pcmAligned = GcAdpcmDecoder.Decode(alignment.AdpcmAligned, coefs, new GcAdpcmParameters { SampleCount = alignment.SampleCountAligned }); short[] pcmExpected = GenerateSineWave(alignment.SampleCountAligned, 1, SamplesPerFrame * 4); var diff = new double[alignment.SampleCountAligned]; //Skip the first sine cycle and last ADPCM frame due to history samples int end = GetNextMultiple(alignment.SampleCountAligned, SamplesPerFrame) - SamplesPerFrame; for (int i = SamplesPerFrame * 4; i < end; i++) { double dist = Math.Abs(pcmExpected[i] - pcmAligned[i]); diff[i] = dist; } Assert.All(diff, x => Assert.InRange(x, 0, tolerance)); }
public GcAdpcmChannel EncodeChannel(short[] pcm) { int sampleCount = pcm.Length; short[] coefs = GcAdpcmCoefficients.CalculateCoefficients(pcm); byte[] adpcm = GcAdpcmEncoder.Encode(pcm, coefs); return(new GcAdpcmChannel(adpcm, coefs, sampleCount)); }
public void AlignedPcmIsCorrect(int multiple, int loopStart, int sineCycles) { int loopEnd = sineCycles * 4 * SamplesPerFrame + loopStart; var pcm = GenerateSineWave(GetNextMultiple(loopEnd, SamplesPerFrame), 1, SamplesPerFrame * 4); var coefs = GcAdpcmCoefficients.CalculateCoefficients(pcm); var adpcm = GcAdpcmEncoder.Encode(pcm, coefs); var alignment = new GcAdpcmAlignment(multiple, loopStart, loopEnd, adpcm, coefs); var pcmAligned = alignment.PcmAligned; var pcmExpected = GcAdpcmDecoder.Decode(alignment.AdpcmAligned, coefs, new GcAdpcmParameters { SampleCount = alignment.SampleCountAligned }); Assert.Equal(pcmExpected, pcmAligned); }
/// <summary> /// Encodes the samples. /// </summary> /// <returns>The samples.</returns> /// <param name="samples">Samples.</param> public static byte[] EncodeSamples(short[] samples, out DspAdpcmInfo info, uint loopStart) { //Encod data. short[] coeffs = GcAdpcmCoefficients.CalculateCoefficients(samples); byte[] dspAdpcm = GcAdpcmEncoder.Encode(samples, coeffs); info = new DspAdpcmInfo(); info.coefs = new short[8][]; info.coefs[0] = new short[2]; info.coefs[1] = new short[2]; info.coefs[2] = new short[2]; info.coefs[3] = new short[2]; info.coefs[4] = new short[2]; info.coefs[5] = new short[2]; info.coefs[6] = new short[2]; info.coefs[7] = new short[2]; info.coefs[0][0] = coeffs[0]; info.coefs[0][1] = coeffs[1]; info.coefs[1][0] = coeffs[2]; info.coefs[1][1] = coeffs[3]; info.coefs[2][0] = coeffs[4]; info.coefs[2][1] = coeffs[5]; info.coefs[3][0] = coeffs[6]; info.coefs[3][1] = coeffs[7]; info.coefs[4][0] = coeffs[8]; info.coefs[4][1] = coeffs[9]; info.coefs[5][0] = coeffs[10]; info.coefs[5][1] = coeffs[11]; info.coefs[6][0] = coeffs[12]; info.coefs[6][1] = coeffs[13]; info.coefs[7][0] = coeffs[14]; info.coefs[7][1] = coeffs[15]; //Loop stuff. if (loopStart > 0) { info.loop_yn1 = samples[loopStart - 1]; } if (loopStart > 1) { info.loop_yn2 = samples[loopStart - 2]; } return(dspAdpcm); }
/// <summary> /// Convert from floating point PCM to the data. /// </summary> /// <param name="pcm">PCM data.</param> /// <param name="encodingData">Encoding data.</param> /// <param name="loopStart">Loop start.</param> /// <param name="loopEnd">Loop end.</param> public void FromFloatPCM(float[] pcm, object encodingData = null, int loopStart = -1, int loopEnd = -1) { //Convert data. short[] s = pcm.Select(x => ConvertFloat(x)).ToArray(); //Get context. DspAdpcmContext context = null; if (encodingData != null) { context = encodingData as DspAdpcmContext; } if (context == null) { context = new DspAdpcmContext(); context.LoadCoeffs(GcAdpcmCoefficients.CalculateCoefficients(s)); } //Encode data. Data = DspAdpcmEncoder.EncodeSamples(s, context, loopStart); //Set pointers. encodingData = Context = context; }
/*public void ToHPS() * { * * }*/ #endregion #region WAVE private void FromWAVE(byte[] wavFile) { if (wavFile.Length < 0x2C) { throw new NotSupportedException("File is not a valid WAVE file"); } Channels.Clear(); using (BinaryReader r = new BinaryReader(new MemoryStream(wavFile))) { if (new string(r.ReadChars(4)) != "RIFF") { throw new NotSupportedException("File is not a valid WAVE file"); } r.BaseStream.Position = 0x14; var comp = r.ReadInt16(); var channelCount = r.ReadInt16(); Frequency = r.ReadInt32(); r.ReadInt32(); // block rate r.ReadInt16(); // block align var bpp = r.ReadInt16(); if (comp != 1) { throw new NotSupportedException("Compressed WAVE files not supported"); } if (bpp != 16) { throw new NotSupportedException("Only 16 bit WAVE formats accepted"); } while (new string(r.ReadChars(4)) != "data") { var skip = r.ReadInt32(); r.BaseStream.Position += skip; } var channelSizes = r.ReadInt32() / channelCount / 2; List <List <short> > channels = new List <List <short> >(); for (int i = 0; i < channelCount; i++) { channels.Add(new List <short>()); } for (int i = 0; i < channelSizes; i++) { foreach (var v in channels) { v.Add(r.ReadInt16()); } } Channels.Clear(); foreach (var data in channels) { var c = new DSPChannel(); var ss = data.ToArray(); c.COEF = GcAdpcmCoefficients.CalculateCoefficients(ss); c.Data = GcAdpcmEncoder.Encode(ss, c.COEF); c.NibbleCount = c.Data.Length * 2; c.InitialPredictorScale = c.Data[0]; Channels.Add(c); } } }
[Benchmark] public byte[] GenerateCoefsAndEncodeAdpcm() => GcAdpcmEncoder.Encode(_pcm, GcAdpcmCoefficients.CalculateCoefficients(_pcm));
[Benchmark] public short[] GenerateCoefs() => GcAdpcmCoefficients.CalculateCoefficients(_pcm);
public void Setup() { _pcm = GenerateAudio.GenerateSineWave((int)(_sampleRate * LengthSeconds), 440, _sampleRate); _coefs = GcAdpcmCoefficients.CalculateCoefficients(_pcm); }
public short[] DspCorrelateCoefs(short[] pcm) { return(GcAdpcmCoefficients.CalculateCoefficients(pcm)); }