Exemplo n.º 1
0
        public static byte[] Encode(short[] pcm, short[] coefs, GcAdpcmParameters config = null)
        {
            config = config ?? new GcAdpcmParameters();
            int sampleCount = config.SampleCount == -1 ? pcm.Length : config.SampleCount;
            var adpcm       = new byte[SampleCountToByteCount(sampleCount)];

            /* Execute encoding-predictor for each frame */
            var pcmBuffer   = new short[2 + SamplesPerFrame];
            var adpcmBuffer = new byte[BytesPerFrame];

            pcmBuffer[0] = config.History2;
            pcmBuffer[1] = config.History1;

            int frameCount = sampleCount.DivideByRoundUp(SamplesPerFrame);
            var buffers    = new AdpcmEncodeBuffers();

            for (int frame = 0; frame < frameCount; frame++)
            {
                int samplesToCopy = Math.Min(sampleCount - frame * SamplesPerFrame, SamplesPerFrame);
                Array.Copy(pcm, frame * SamplesPerFrame, pcmBuffer, 2, samplesToCopy);
                Array.Clear(pcmBuffer, 2 + samplesToCopy, SamplesPerFrame - samplesToCopy);

                DspEncodeFrame(pcmBuffer, SamplesPerFrame, adpcmBuffer, coefs, buffers);

                Array.Copy(adpcmBuffer, 0, adpcm, frame * BytesPerFrame, SampleCountToByteCount(samplesToCopy));

                pcmBuffer[0] = pcmBuffer[14];
                pcmBuffer[1] = pcmBuffer[15];
                config.Progress?.ReportAdd(1);
            }

            return(adpcm);
        }
Exemplo n.º 2
0
        public static void DspEncodeFrame(short[] pcmInOut, int sampleCount, byte[] adpcmOut, short[] coefsIn,
                                          AdpcmEncodeBuffers b = null)
        {
            b = b ?? new AdpcmEncodeBuffers();

            for (int i = 0; i < 8; i++)
            {
                b.Coefs[i][0] = coefsIn[i * 2];
                b.Coefs[i][1] = coefsIn[i * 2 + 1];
            }

            /* Iterate through each coef set, finding the set with the smallest error */
            for (int i = 0; i < 8; i++)
            {
                DspEncodeCoef(pcmInOut, sampleCount, b.Coefs[i], b.PcmOut[i], b.AdpcmOut[i], out b.Scale[i],
                              out b.TotalDistance[i]);
            }

            int bestCoef = 0;

            double min = double.MaxValue;

            for (int i = 0; i < 8; i++)
            {
                if (b.TotalDistance[i] < min)
                {
                    min      = b.TotalDistance[i];
                    bestCoef = i;
                }
            }

            /* Write converted samples */
            for (int s = 0; s < sampleCount; s++)
            {
                pcmInOut[s + 2] = (short)b.PcmOut[bestCoef][s + 2];
            }

            /* Write predictor and scale */
            adpcmOut[0] = CombineNibbles(bestCoef, b.Scale[bestCoef]);

            /* Zero remaining samples */
            for (int s = sampleCount; s < 14; s++)
            {
                b.AdpcmOut[bestCoef][s] = 0;
            }

            /* Write output samples */
            for (int i = 0; i < 7; i++)
            {
                adpcmOut[i + 1] = CombineNibbles(b.AdpcmOut[bestCoef][i * 2], b.AdpcmOut[bestCoef][i * 2 + 1]);
            }
        }