/// <summary> /// Encode audio data. /// </summary> /// <returns>Encoded audio data.</returns> public byte[] Encode() { byte[] data = new byte[Data.Length / 2 + (Data.Length % 2 != 0 ? 1 : 0)]; bool secondNibble = false; int dataPtr = 0; for (int i = 0; i < Data.Length; i++) { int config = GetBestConfig(Index, ConvertFloat(Data[i]) - Sample); Sample = ImaAdpcmMath.ClampSample(Sample + (ImaAdpcmMath.StepTable[Index] / 8 + ImaAdpcmMath.StepTable[Index] / 4 * (config & 1) + ImaAdpcmMath.StepTable[Index] / 2 * (config >> 1 & 1) + ImaAdpcmMath.StepTable[Index] * (config >> 2 & 1)) * ((config >> 3 & 1) == 1 ? -1 : 1)); Index = ImaAdpcmMath.ClampIndex(this.Index + ImaAdpcmMath.IndexTable[config & 7]); if (!secondNibble) { data[dataPtr] |= (byte)((config & 0xF) << 0); } else { data[dataPtr] |= (byte)((config & 0xF) << 4); dataPtr++; } secondNibble = !secondNibble; } return(data); }
/// <summary> /// Get a sample from a nibble. /// </summary> /// <param name="nibble">Nibble to decode.</param> /// <returns>Decoded sample.</returns> private short GetSample(byte nibble) { Sample = ImaAdpcmMath.ClampSample(Sample + (ImaAdpcmMath.StepTable[Index] / 8 + ImaAdpcmMath.StepTable[Index] / 4 * ((int)nibble & 1) + ImaAdpcmMath.StepTable[Index] / 2 * ((int)nibble >> 1 & 1) + ImaAdpcmMath.StepTable[Index] * ((int)nibble >> 2 & 1)) * (((int)nibble >> 3 & 1) == 1 ? -1 : 1)); Index = ImaAdpcmMath.ClampIndex(Index + ImaAdpcmMath.IndexTable[(int)nibble & 7]); return((short)Sample); }