/// <summary>Instantiates a new <see cref="WaveFormatExtensible"/> structure.</summary>
        /// <param name="waveFormatEx">A <see cref="WaveFormatEx"/> structure.</param>
        /// <param name="samples">Either ValidBitsPerSample, SamplesPerBlock or 0.</param>
        /// <param name="channelMask">Indicates which channels are present in the stream.</param>
        /// <param name="subFormat">Sub format <see cref="Guid"/>.</param>
        public WaveFormatExtensible(WaveFormatEx waveFormatEx, int samples, AudioChannels channelMask, Guid subFormat)
        {
            if (waveFormatEx.FormatTag != (short)WaveFormatTag.Extensible)
            {
                throw new ArgumentException("Invalid wave format: only Extensible is allowed.", "waveFormatEx");
            }

            if (waveFormatEx.ChannelCount == 0 || waveFormatEx.AverageBytesPerSecond == 0 || waveFormatEx.BitsPerSample == 0 || waveFormatEx.BlockAlign == 0 || waveFormatEx.SamplesPerSecond == 0)
            {
                throw new ArgumentException("Invalid wave format.", "waveFormatEx");
            }

            if (waveFormatEx.ExtraInfoSize < ExpectedExtraInfoSize)
            {
                throw new ArgumentException("Invalid wave format: extra info size is too small.", "waveFormatEx");
            }

            if (samples < 0 || samples > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException("samples");
            }

            if (channelMask == AudioChannels.None)
            {
                throw new ArgumentOutOfRangeException("channelMask");
            }

            baseFormat       = waveFormatEx;
            this.samples     = (ushort)samples;
            this.channelMask = channelMask;
            this.subFormat   = subFormat;
        }
        /// <summary>Initializes a new <see cref="WaveFormatExtensible"/> structure.</summary>
        /// <param name="samplesPerSecond">The sample rate, in hertz (Hz).</param>
        /// <param name="averageBytesPerSecond">For buffer estimation.</param>
        /// <param name="blockAlign">The block size of data, in bytes.</param>
        /// <param name="bitsPerSample">The number of bits per sample.</param>
        /// <param name="samples">Either ValidBitsPerSample, SamplesPerBlock or Reserved(0).</param>
        /// <param name="channelMask">Indicates which channels are present in the stream.</param>
        /// <param name="subFormat">Sub format <see cref="Guid"/>.</param>
        /// <exception cref="ArgumentOutOfRangeException"/>
        /// <exception cref="InvalidEnumArgumentException"/>
        public WaveFormatExtensible(int samplesPerSecond, int averageBytesPerSecond, int blockAlign, int bitsPerSample, int samples, AudioChannels channelMask, Guid subFormat)
        {
            if (samples < 0 || samples > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException("samples");
            }

            try
            {
                baseFormat = new WaveFormatEx((short)WaveFormatTag.Extensible, channelMask.GetChannelCount(), samplesPerSecond, averageBytesPerSecond, blockAlign, bitsPerSample, ExpectedExtraInfoSize);
            }
            catch (ArgumentOutOfRangeException)
            {
                throw;
            }

            this.samples     = (ushort)samples;
            this.channelMask = channelMask;
            this.subFormat   = subFormat;
        }
 /// <summary>Returns a value indicating whether this <see cref="WaveFormatExtensible"/> structure is equivalent to a <see cref="WaveFormatEx"/> structure.</summary>
 /// <param name="other">A <see cref="WaveFormatEx"/> structure.</param>
 /// <returns>Returns true if the structures are equivalent, otherwise returns false.</returns>
 public bool Equals(WaveFormatEx other)
 {
     return(baseFormat.Equals(other));
 }