Пример #1
0
        /// <summary>
        /// Converts a RIFF WAVE bitstream with header to raw samples.
        /// </summary>
        public RIFFWaveDecoder(BinaryReader reader)
        {
            // RIFF header
            if (reader.ReadInt32() != RIFFWave.syncWord1)
            {
                throw new SyncException();
            }
            stream           = reader.BaseStream;
            stream.Position += 4; // File length

            // Format header
            if (reader.ReadInt64() != RIFFWave.syncWord2)
            {
                throw new SyncException();
            }
            stream.Position += 4;                    // Format header length
            short sampleFormat = reader.ReadInt16(); // 1 = int, 3 = float, -2 = WAVE EX

            channelCount     = reader.ReadInt16();
            sampleRate       = reader.ReadInt32();
            stream.Position += 4; // Bytes/sec
            stream.Position += 2; // Block size in bytes
            short bitDepth = reader.ReadInt16();

            if (sampleFormat == -2)
            {
                // Extension size (22) - 2 bytes, valid bits per sample - 2 bytes, channel mask - 4 bytes
                stream.Position += 8;
                sampleFormat     = reader.ReadInt16();
                stream.Position += 15; // Skip the rest of the sub format GUID
            }
            if (sampleFormat == 1)
            {
                Bits = bitDepth switch {
                    8 => BitDepth.Int8,
                    16 => BitDepth.Int16,
                    24 => BitDepth.Int24,
                    _ => throw new IOException($"Unsupported bit depth for signed little endian integer: {bitDepth}.")
                };
            }
            else if (sampleFormat == 3 && bitDepth == 32)
            {
                Bits = BitDepth.Float32;
            }
            else
            {
                throw new IOException($"Unsupported bit depth ({bitDepth}) for sample format {sampleFormat}.");
            }

            // Data header
            int header = 0;

            do
            {
                header = (header << 8) | reader.ReadByte();
            }while (header != RIFFWave.syncWord3BE && stream.Position < stream.Length);
            length      = reader.ReadUInt32() * 8L / (long)Bits / ChannelCount;
            dataStart   = stream.Position;
            this.reader = BlockBuffer <byte> .Create(reader, FormatConsts.blockSize);
        }