using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace NAudio.Wave { /// /// Microsoft ADPCM /// See http://icculus.org/SDL_sound/downloads/external_documentation/wavecomp.htm /// [StructLayout(LayoutKind.Sequential, Pack=2)] public class AdpcmWaveFormat : WaveFormat { short samplesPerBlock; short numCoeff; // 7 pairs of coefficients [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] short[] coefficients; /// /// Empty constructor needed for marshalling from a pointer /// AdpcmWaveFormat() : this(8000,1) { } /// /// Samples per block /// public int SamplesPerBlock { get { return samplesPerBlock; } } /// /// Number of coefficients /// public int NumCoefficients { get { return numCoeff; } } /// /// Coefficients /// public short[] Coefficients { get { return coefficients; } } /// /// Microsoft ADPCM /// /// Sample Rate /// Channels public AdpcmWaveFormat(int sampleRate, int channels) : base(sampleRate,0,channels) { this.waveFormatTag = WaveFormatEncoding.Adpcm; // TODO: validate sampleRate, bitsPerSample this.extraSize = 32; switch(this.sampleRate) { case 8000: case 11025: blockAlign = 256; break; case 22050: blockAlign = 512; break; case 44100: default: blockAlign = 1024; break; } this.bitsPerSample = 4; this.samplesPerBlock = (short) ((((blockAlign - (7 * channels)) * 8) / (bitsPerSample * channels)) + 2); this.averageBytesPerSecond = ((this.SampleRate * blockAlign) / samplesPerBlock); // samplesPerBlock = blockAlign - (7 * channels)) * (2 / channels) + 2; numCoeff = 7; coefficients = new short[14] { 256,0,512,-256,0,0,192,64,240,0,460,-208,392,-232 }; } /// /// Serializes this wave format /// /// Binary writer public override void Serialize(System.IO.BinaryWriter writer) { base.Serialize(writer); writer.Write(samplesPerBlock); writer.Write(numCoeff); foreach (short coefficient in coefficients) { writer.Write(coefficient); } } /// /// String Description of this WaveFormat /// public override string ToString() { return String.Format("Microsoft ADPCM {0} Hz {1} channels {2} bits per sample {3} samples per block", this.SampleRate, this.channels, this.bitsPerSample, this.samplesPerBlock); } } }