Exemple #1
0
        /// <summary>
        /// Reads the fmt chunk
        /// </summary>
        /// <param name="data"></param>
        /// <param name="idx"></param>
        /// <returns></returns>
        private static FormatChunkData ParseFmtChunk(byte[] data, int idx)
        {
            var id   = Encoding.ASCII.GetString(data, idx, 4);
            var size = BitConverter.ToInt32(data, idx + 4);

            idx = idx + 8;
            var fmt = new FormatChunkData();

            fmt.AudioFormat    = data[idx];
            fmt.NumChannels    = data[idx + 2];
            fmt.SampleRate     = BitConverter.ToInt32(data, idx + 4);
            fmt.ByteRate       = BitConverter.ToInt32(data, idx + 8);
            fmt.BlockAlign     = BitConverter.ToInt16(data, idx + 12);
            fmt.BitsPerSample  = BitConverter.ToInt16(data, idx + 14);
            fmt.BytesPerSample = fmt.BitsPerSample / 8;

            return(fmt);
        }
Exemple #2
0
        /// <summary>
        /// Reads the fmt chunk
        /// </summary>
        /// <param name="data"></param>
        /// <param name="idx"></param>
        /// <returns></returns>
        private static FormatChunkData ParseFmtChunk(byte[] data, int idx)
        {
            var id = Encoding.ASCII.GetString(data, idx, 4);
            var size = BitConverter.ToInt32(data, idx + 4);

            idx = idx + 8;
            var fmt = new FormatChunkData();
            fmt.AudioFormat = data[idx];
            fmt.NumChannels = data[idx + 2];
            fmt.SampleRate = BitConverter.ToInt32(data, idx + 4);
            fmt.ByteRate = BitConverter.ToInt32(data, idx + 8);
            fmt.BlockAlign = BitConverter.ToInt16(data, idx + 12);
            fmt.BitsPerSample = BitConverter.ToInt16(data, idx + 14);
            fmt.BytesPerSample = fmt.BitsPerSample / 8;

            return fmt;
        }
Exemple #3
0
        /// <summary>
        /// Parses the data chunk, containing the audio data
        /// </summary>
        /// <param name="data">data array to work on</param>
        /// <param name="idx">starting index of the data chunk</param>
        /// <param name="chunkSize">size of the data chunk</param>
        /// <param name="format">the format description, read from the 'fmt ' chunk</param>
        /// <returns></returns>
        private static double[][] ParseDataChunk(byte[] data, int idx, int chunkSize, FormatChunkData format)
        {
            var channels = new List<List<double>>();

            for (int i = 0; i < format.NumChannels; i++)
                channels.Add(new List<double>());

            idx += 8;
            int channel = 0;

            for (int i = idx; i < chunkSize + idx; i += format.BytesPerSample)
            {
                int value = 0;
                if (format.AudioFormat == 3) // audioFormat 3 indicated IEEE 32bit floating point data
                {
                    float val = BitConverter.ToSingle(data, i);
                    channels[channel].Add(val);
                }
                else if (format.BytesPerSample == 1) // 8 bit PCM data
                {
                    value = data[i] - 0x80;
                    channels[channel].Add(value / 128.0);
                }
                else if (format.BytesPerSample == 2) // 16 bit PCM data
                {
                    value = BitConverter.ToInt16(data, i);
                    channels[channel].Add(value / 32768.0);
                }
                else if (format.BytesPerSample == 3) // 24 bit PCM data
                {
                    value = BitConverter.ToInt32(new byte[] { 0, data[i], data[i + 1], data[i + 2] }, 0);
                    channels[channel].Add(value / 2147483648.0);
                }
                else if (format.BytesPerSample == 4) // 32 bit PCM data
                {
                    value = BitConverter.ToInt32(data, i);
                    channels[channel].Add(value / 2147483648.0);
                }

                channel = (channel + 1) % format.NumChannels;
            }

            // convert lists to arrays
            double[][] output = new double[format.NumChannels][];
            for (int i = 0; i < output.Length; i++)
                output[i] = channels[i].ToArray();

            return output;
        }
Exemple #4
0
        /// <summary>
        /// Read a WAVE file. Supports multiple channels, any bitrate.
        /// Supported formats are IEEE 32bit floating point and uncompressed PCM 8/16/24/32 bit
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="clmData">a list to be filled with metadata from the clm chunk</param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static double[][] ReadWaveFile(byte[] data, ref List <byte[]> clmData, out FormatChunkData format)
        {
            format = null;
            var    waveFormat = new byte[] { data[8], data[9], data[10], data[11] };
            string fmt        = Encoding.ASCII.GetString(waveFormat);

            if (fmt != "WAVE")
            {
                return(null);
            }

            int idx = 12;

            double[][] output = null;

            while (idx < data.Length)
            {
                string chunkId   = Encoding.ASCII.GetString(data, idx, 4);
                int    chunkSize = BitConverter.ToInt32(data, idx + 4);

                if (chunkId == "fmt ")
                {
                    format = ParseFmtChunk(data, idx);
                }
                else if (chunkId == "data")
                {
                    if (format == null)                     // format must preced data.
                    {
                        return(null);
                    }

                    output = ParseDataChunk(data, idx, chunkSize, format);
                    break;
                }
                else
                {
                    var dataChunk = data.Skip(idx).Take(8 + chunkSize).ToArray();
                    clmData?.Add(dataChunk);
                }

                idx = idx + 8 + chunkSize;
            }

            return(output);
        }
Exemple #5
0
        /// <summary>
        /// Parses the data chunk, containing the audio data
        /// </summary>
        /// <param name="data">data array to work on</param>
        /// <param name="idx">starting index of the data chunk</param>
        /// <param name="chunkSize">size of the data chunk</param>
        /// <param name="format">the format description, read from the 'fmt ' chunk</param>
        /// <returns></returns>
        private static double[][] ParseDataChunk(byte[] data, int idx, int chunkSize, FormatChunkData format)
        {
            var channels = new List <List <double> >();

            for (int i = 0; i < format.NumChannels; i++)
            {
                channels.Add(new List <double>());
            }

            idx += 8;
            int channel = 0;

            for (int i = idx; i < chunkSize + idx; i += format.BytesPerSample)
            {
                int value = 0;
                if (format.AudioFormat == 3)                 // audioFormat 3 indicated IEEE 32bit floating point data
                {
                    float val = BitConverter.ToSingle(data, i);
                    channels[channel].Add(val);
                }
                else if (format.BytesPerSample == 1)                 // 8 bit PCM data
                {
                    value = data[i] - 0x80;
                    channels[channel].Add(value / 128.0);
                }
                else if (format.BytesPerSample == 2)                 // 16 bit PCM data
                {
                    value = BitConverter.ToInt16(data, i);
                    channels[channel].Add(value / 32768.0);
                }
                else if (format.BytesPerSample == 3)                 // 24 bit PCM data
                {
                    value = BitConverter.ToInt32(new byte[] { 0, data[i], data[i + 1], data[i + 2] }, 0);
                    channels[channel].Add(value / 2147483648.0);
                }
                else if (format.BytesPerSample == 4)                 // 32 bit PCM data
                {
                    value = BitConverter.ToInt32(data, i);
                    channels[channel].Add(value / 2147483648.0);
                }

                channel = (channel + 1) % format.NumChannels;
            }

            // convert lists to arrays
            double[][] output = new double[format.NumChannels][];
            for (int i = 0; i < output.Length; i++)
            {
                output[i] = channels[i].ToArray();
            }

            return(output);
        }