Пример #1
0
        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));
        }
Пример #2
0
        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));
        }
Пример #3
0
        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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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;
        }
Пример #6
0
        /*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);
                }
            }
        }
Пример #7
0
 [Benchmark] public byte[] GenerateCoefsAndEncodeAdpcm() => GcAdpcmEncoder.Encode(_pcm, GcAdpcmCoefficients.CalculateCoefficients(_pcm));
Пример #8
0
 [Benchmark] public short[] GenerateCoefs() => GcAdpcmCoefficients.CalculateCoefficients(_pcm);
Пример #9
0
 public void Setup()
 {
     _pcm   = GenerateAudio.GenerateSineWave((int)(_sampleRate * LengthSeconds), 440, _sampleRate);
     _coefs = GcAdpcmCoefficients.CalculateCoefficients(_pcm);
 }
Пример #10
0
 public short[] DspCorrelateCoefs(short[] pcm)
 {
     return(GcAdpcmCoefficients.CalculateCoefficients(pcm));
 }