/// <summary>
        /// Constructs a stream that will accept PCM audio input, and automatically encode it to Opus and packetize it using Ogg,
        /// writing the output pages to an underlying stream (usually a file stream).
        /// You are allowed to change the encoding parameters mid-stream using the properties of the OpusEncoder; the only thing you
        /// cannot change is the sample rate and num# of channels.
        /// </summary>
        /// <param name="encoder">An opus encoder to use for output</param>
        /// <param name="outputStream">A base stream to accept the encoded ogg file output</param>
        /// <param name="fileTags">(optional) A set of tags to include in the encoded file</param>
        /// <param name="inputSampleRate">The actual real sample rate of your input data (NOT the encoder's sample rate).
        /// The opus encoder usually requires 48Khz input, but most MP3s and such will give you 44.1Khz. To get the
        /// sample rates to line up properly in this case, set the encoder to 48000 and pass inputSampleRate = 44100,
        /// and the write stream will perform resampling for you automatically (Note that resampling will slow down
        /// the encoding).</param>
        public OpusOggWriteStream(OpusEncoder encoder, Stream outputStream, OpusTags fileTags = null, int inputSampleRate = 0, int logicalStreamId = 0)
        {
            _encoder = encoder;

            if (_encoder.UseDTX)
            {
                throw new ArgumentException("DTX is not currently supported in Ogg streams");
            }

            _inputSampleRate = inputSampleRate;
            if (_inputSampleRate == 0)
            {
                _inputSampleRate = _encoder.SampleRate;
            }

            if (logicalStreamId == 0)
            {
                logicalStreamId = new Random().Next();
            }

            _logicalStreamId   = logicalStreamId;
            _encoderSampleRate = encoder.SampleRate;
            _inputChannels     = encoder.NumChannels;
            _outputStream      = outputStream;
            _opusFrameIndex    = 0;
            _granulePosition   = 0;
            _opusFrameSamples  = (int)((long)_encoderSampleRate * FRAME_SIZE_MS / 1000);
            _opusFrame         = new short[_opusFrameSamples * _inputChannels];
            _crc       = new Crc();
            _resampler = SpeexResampler.Create(_inputChannels, _inputSampleRate, _encoderSampleRate, 5);

            BeginNewPage();
            WriteOpusHeadPage();
            WriteOpusTagsPage(fileTags);
        }
        /// <summary>
        /// Constructs a stream that will accept PCM audio input, and automatically encode it to Opus and packetize it using Ogg,
        /// writing the output pages to an underlying stream (usually a file stream).
        /// You are allowed to change the encoding parameters mid-stream using the properties of the OpusEncoder; the only thing you
        /// cannot change is the sample rate and num# of channels.
        /// </summary>
        /// <param name="outputStream">A base stream to accept the encoded ogg file output</param>
        /// <param name="sampleRate"></param>
        /// <param name="channelCount"></param>
        /// <param name="preSkip"></param>
        /// <param name="sampleCount"></param>
        /// <param name="fileTags">(optional) A set of tags to include in the encoded file</param>
        /// <param name="inputSampleRate">The actual real sample rate of your input data (NOT the encoder's sample rate).
        /// The opus encoder usually requires 48Khz input, but most MP3s and such will give you 44.1Khz. To get the
        /// sample rates to line up properly in this case, set the encoder to 48000 and pass inputSampleRate = 44100,
        /// and the write stream will perform resampling for you automatically (Note that resampling will slow down
        /// the encoding).</param>
        public OpusOggWriteStream(Stream outputStream, int sampleRate, int channelCount, int preSkip, int sampleCount = -1, OpusTags fileTags = null, int inputSampleRate = 0)
        {
            _inputSampleRate = inputSampleRate;
            if (_inputSampleRate == 0)
            {
                _inputSampleRate = sampleRate;
            }

            _logicalStreamId   = new Random().Next();
            _encoderSampleRate = sampleRate;
            _inputChannels     = channelCount;
            _outputStream      = outputStream;
            //_opusFrameIndex = 0;
            _granulePosition  = 0;
            _opusFrameSamples = (int)((long)_encoderSampleRate * FRAME_SIZE_MS / 1000);
            _opusFrame        = new short[_opusFrameSamples * _inputChannels];
            _crc       = new Crc();
            _resampler = SpeexResampler.Create(_inputChannels, _inputSampleRate, _encoderSampleRate, 5);

            _preSkipSamples = preSkip;
            _sampleCount    = sampleCount == -1 ? int.MaxValue : preSkip + sampleCount;

            BeginNewPage();
            WriteOpusHeadPage();
            WriteOpusTagsPage(fileTags);
        }