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); } }
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]); } }
public CriAdxFormatBuilder WithEncodingType(CriAdxType type) { Type = type; return(this); }