Пример #1
0
        /// <summary>
        /// VorbisFileWriter that actually writes to a stream
        /// </summary>
        /// <param name="outStream">Stream to be written to</param>
        /// <param name="sampleRate">The sample rate to use</param>
        /// <param name="channels">The number of channels to use</param>
        /// <param name="quality">The base quality for Vorbis encoding</param>
        public VorbisFileWriter(Stream outStream, int sampleRate, int channels, float quality = 0.5f)
        {
            this.outStream = outStream;
            SampleRate     = sampleRate;
            Channels       = channels;

            if (!startBuffers.ContainsKey(sampleRate))
            {
                throw new InvalidOperationException($"Vorbis writer does not support {sampleRate} sample rate.");
            }

            // Stores all the static vorbis bitstream settings
            Console.WriteLine($"Initiating variable bit rate: {channels} channels, {sampleRate} sample rate, {quality} quality");
            var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, quality);

            // set up our packet->stream encoder
            var serial = MainWindow.MainRandom.Next();

            oggStream = new OggStream(serial);

            // =========================================================
            // HEADER
            // =========================================================
            // Vorbis streams begin with three headers; the initial header (with
            // most of the codec setup parameters) which is mandated by the Ogg
            // bitstream spec.  The second header holds any comment fields.  The
            // third header holds the bitstream codebook.
            var headerBuilder = new HeaderPacketBuilder();

            var comments = new Comments();

            var infoPacket     = headerBuilder.BuildInfoPacket(info);
            var commentsPacket = headerBuilder.BuildCommentsPacket(comments);
            var booksPacket    = headerBuilder.BuildBooksPacket(info);

            oggStream.PacketIn(infoPacket);
            oggStream.PacketIn(commentsPacket);
            oggStream.PacketIn(booksPacket);

            // Flush to force audio data onto its own page per the spec
            FlushPages(oggStream, outStream, true);

            // =========================================================
            // BODY (Audio Data)
            // =========================================================
            processingState = ProcessingState.Create(info);

            // Append some zeros at the start so the result has the same length as the input
            int bufferSize = startBuffers[sampleRate];

            float[][] outSamples = new float[channels][];
            for (int ch = 0; ch < channels; ch++)
            {
                outSamples[ch] = new float[bufferSize];
            }

            processingState.WriteData(outSamples, bufferSize);
        }
    private static void ProcessChunk(float[][] floatSamples, ProcessingState processingState, OggStream oggStream, int writeBufferSize)
    {
        processingState.WriteData(floatSamples, writeBufferSize, 0);

        while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet))
        {
            oggStream.PacketIn(packet);
        }
    }
Пример #3
0
        /// <summary>
        /// Encodes and writes a number of float samples
        /// </summary>
        /// <param name="floatSamples">The samples. The array shape is [channel][sample]</param>
        /// <param name="count">The number of samples to write.</param>
        public void WriteFloatSamples(float[][] floatSamples, int count)
        {
            //Console.WriteLine($"Writing {count} samples!");
            processingState.WriteData(floatSamples, count);

            while (!oggStream.Finished && processingState.PacketOut(out var packet))
            {
                //Console.WriteLine($"Got packet with {packet.PacketData.Length} bytes of data");
                oggStream.PacketIn(packet);

                FlushPages(oggStream, outStream, false);
            }
        }