예제 #1
0
파일: Adx.cs 프로젝트: soneek/VGAudio
        private static AudioFormat FromAdx(CriAdxType codec)
        {
            switch (codec)
            {
            case CriAdxType.Fixed:
                return(AudioFormat.CriAdxFixed);

            case CriAdxType.Linear:
                return(AudioFormat.CriAdx);

            case CriAdxType.Exponential:
                return(AudioFormat.CriAdxExp);

            default:
                throw new ArgumentOutOfRangeException(nameof(codec), codec, null);
            }
        }
예제 #2
0
        public static void EncodeFrame(short[] pcm, byte[] adpcmOut, short[] coefs, int samplesPerFrame, CriAdxType type, int version)
        {
            int maxDistance = 0;

            int[] adpcm = new int[samplesPerFrame];

            for (int i = 0; i < samplesPerFrame; i++)
            {
                int predictedSample = (pcm[i + 1] * coefs[0] >> 12) + (pcm[i] * coefs[1] >> 12);
                int distance        = pcm[i + 2] - predictedSample;
                distance = Math.Abs((int)Clamp16(distance));
                if (distance > maxDistance)
                {
                    maxDistance = distance;
                }
            }

            int scale = CalculateScale(maxDistance, out double gain, out int scaleOut, type == CriAdxType.Exponential);

            for (int i = 0; i < samplesPerFrame; i++)
            {
                int predictedSample = (pcm[i + 1] * coefs[0] >> 12) + (pcm[i] * coefs[1] >> 12);
                int rawDistance     = pcm[i + 2] - predictedSample;
                int scaledDistance  = Clamp16((int)(rawDistance * gain));

                int adpcmSample = ScaleShortToNibble(scaledDistance);
                adpcm[i] = adpcmSample;

                short decodedDistance = Clamp16(scale * adpcmSample);
                if (version == 4)
                {
                    predictedSample = (pcm[i + 1] * coefs[0] + pcm[i] * coefs[1]) >> 12;
                }
                int decodedSample = decodedDistance + predictedSample;
                pcm[i + 2] = Clamp16(decodedSample);
            }

            adpcmOut[0] = (byte)((scaleOut >> 8) & 0x1f);
            adpcmOut[1] = (byte)scaleOut;

            for (int i = 0; i < samplesPerFrame / 2; i++)
            {
                adpcmOut[i + 2] = CombineNibbles(adpcm[i * 2], adpcm[i * 2 + 1]);
            }
        }
예제 #3
0
 public CriAdxFormatBuilder WithEncodingType(CriAdxType type)
 {
     Type = type;
     return(this);
 }