示例#1
0
        /// <summary>
        /// Parse the MsAdpcm format wav.
        /// </summary>
        private void ParseMsAdpcm()
        {
            int offset = Chunk_fmt_.Offset;

            Sanity.RequiresWave(Chunk_fmt_.Length >= 30, "fmt_ chunk is shorter than expected.");
            switch (SampleRate)
            {
            case 8000:
            case 11025:
                Sanity.RequiresWave(BlockAlign == 256, "MsAdpcm BlockAlign mismatch.");
                break;

            case 22050:
                Sanity.RequiresWave(BlockAlign == 512, "MsAdpcm BlockAlign mismatch.");
                break;

            case 44100:
                Sanity.RequiresWave(BlockAlign == 1024, "MsAdpcm BlockAlign mismatch.");
                break;

            default:
                break;
            }
            CbSize          = BitConverter.ToInt16(WaveBytes, offset + 24);
            SamplesPerBlock = BitConverter.ToInt16(WaveBytes, offset + 26);
            NumCoef         = BitConverter.ToInt16(WaveBytes, offset + 28);
            Sanity.RequiresWave(NumCoef * 4 + 4 == CbSize, "CbSize mismatch.");
            Sanity.RequiresWave(BitsPerSample == 4, "bits/sample should be 4 in MsAdpcm.");
            Sanity.RequiresWave(SampleRate * BlockAlign / SamplesPerBlock == ByteRate, "ByteRate equation error.");
            Sanity.RequiresWave((BlockAlign - 7 * NumChannels) * 8 / (BitsPerSample * NumChannels) + 2 == SamplesPerBlock, "SamplesPerBlock equation error.");
            CoefList = Enumerable.Range(0, NumCoef * 2).Select(x => BitConverter.ToInt16(WaveBytes, offset + 30 + x * 2)).ToList();
            Sanity.RequiresWave(CoefStandardList.SequenceEqual(CoefList.Take(2 * NumCoef)), "Coef list mismatch.");
        }
示例#2
0
 public void ParseData()
 {
     Sanity.Requires(DeepFlag, "Parse data requires deep parse.");
     ParseDataFlag = true;
     AudioBits     = BlockAlign / NumChannels * 8;
     DataValues    = CalcValues().ToArray();
     RMS           = CalculateRms();
 }
示例#3
0
 /// <summary>
 /// Parse the extra parts, typically for alaw and ulaw.
 /// </summary>
 private void ParseWaveFormatEx()
 {
     if (Chunk_fmt_.Length >= 18)
     {
         CbSize = BitConverter.ToInt16(WaveBytes, 24);
     }
     Sanity.RequiresWave(ByteRate == NumChannels * SampleRate * BitsPerSample / 8, "Byte rate equation error.");
     Sanity.RequiresWave(BlockAlign == NumChannels * BitsPerSample / 8, "BlockAlign equation error.");
     Sanity.RequiresWave(CbSize == Chunk_fmt_.Length - 16, "CbSize Error.");
 }
示例#4
0
 public static byte[] ReadBytes(string path, int n)
 {
     Sanity.Requires(File.Exists(path), "The file doesn't exist.");
     Sanity.Requires(n >= 0, "The bytes required cannot be negative.");
     using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
     {
         using (BinaryReader br = new BinaryReader(fs))
         {
             return(br.ReadBytes(n));
         }
     }
 }
示例#5
0
        /// <summary>
        /// Check the chunks after all the parsing are done.
        /// </summary>
        private void PostCheck()
        {
            Sanity.RequiresWave(!string.IsNullOrEmpty(Chunk_fmt_.Name), "Missing fmt_ chunk.");
            Sanity.RequiresWave(!string.IsNullOrEmpty(Chunk_data.Name), "Missing data chunk.");
            if (DeepFlag)
            {
                DataBytes = new byte[Chunk_data.Length];

                DataBytes = WaveBytes.ArraySkip(Chunk_data.Offset + 8);
                //Array.Copy(WaveBytes, Chunk_data.Offset + 8, DataBytes, 0, Chunk_data.Length);
            }
            ParseFormat();
            AudioLength = 1.0 * Chunk_data.Length / ByteRate;
        }
示例#6
0
        /// <summary>
        /// Parse the RIFF chunk.
        /// </summary>
        private void ParseRiff()
        {
            Sanity.RequiresWave(WaveBytes.Length >= 44, "Wave size is less than min requirement(44 bytes).");

            string riffName = Encoding.ASCII.GetString(WaveBytes, 0, 4);

            Sanity.RequiresWave(riffName == "RIFF", "Riff header broken.");

            int length = BitConverter.ToInt32(WaveBytes, 4);

            Sanity.RequiresWave(!DeepFlag || length + 8 == WaveBytes.Length, "Riff length broken.");

            string waveName = Encoding.ASCII.GetString(WaveBytes, 8, 4);

            Sanity.RequiresWave(waveName == "WAVE", "Wave header broken.");

            ParseChunk(12);
        }
示例#7
0
        /// <summary>
        /// Parse the chunk.
        /// </summary>
        /// <param name="offset">The offset of the chunk</param>
        private void ParseChunk(int offset)
        {
            if (offset == WaveBytes.Length)
            {
                return;
            }
            if (offset + 8 > WaveBytes.Length)
            {
                Sanity.RequiresWave(!DeepFlag, "Wave is shorter than expected.");
                return;
            }
            string name   = Encoding.ASCII.GetString(WaveBytes, offset, 4);
            int    length = BitConverter.ToInt32(WaveBytes, offset + 4);

            if ((length & 1) == 1)
            {
                length++;
            }
            switch (name)
            {
            case "fmt ":
                Sanity.RequiresWave(string.IsNullOrEmpty(Chunk_fmt_.Name), "fmt_ chunk duplication.");
                Chunk_fmt_ = new Chunk {
                    Name = name, Length = length, Offset = offset
                };
                break;

            case "data":
                Sanity.RequiresWave(string.IsNullOrEmpty(Chunk_data.Name), "data chunk duplication.");
                Chunk_data = new Chunk {
                    Name = name, Length = length, Offset = offset
                };
                break;

            default:
                Chunks.Add(new Chunk()
                {
                    Name = name, Length = length, Offset = offset
                });
                break;
            }
            ParseChunk(offset + 8 + length);
        }
示例#8
0
 /// <summary>
 /// Calculate the root mean square of the audio.
 /// </summary>
 /// <returns>The RMS value</returns>
 private double CalculateRms()
 {
     Sanity.Requires(ParseDataFlag, "The wave data has to be parsed in order to get RMS.");
     return(Math.Sqrt(DataValues.Sum(x => x * x) / DataValues.Length));
 }
示例#9
0
 public static int ToInt24(byte[] bytes, int offset)
 {
     Sanity.Requires(offset + 3 <= bytes.Length, "Offset exceeds array length.");
     return(ToInt24(bytes[offset], bytes[offset + 1], bytes[offset + 2]));
 }