Ejemplo n.º 1
0
        public void Decode(Stream input, Stream output, bool resample)
        {
            int resampleRate = 44100;

            using OggReader reader    = new OggReader(input);
            using BinaryWriter writer = new BinaryWriter(output, System.Text.Encoding.ASCII, true);
            using var decoder         = OpusDecoder.Create(48000, reader.Channels);

            LibResampler resampler = null;

            if (resample)
            {
                resampler = new LibResampler(48000, resampleRate, reader.Channels);
            }

            bool isFirst = true;

            long headerPosition = output.Position;

            output.Position += 44;

            Span <float> inputBuffer = default;

            while (!reader.IsStreamFinished)
            {
                var frame = reader.ReadPacket();

                if (isFirst)
                {
                    inputBuffer = new float[decoder.GetSamples(frame.Span) * decoder.OutputChannels];
                }

                decoder.DecodeFloat(frame.Span, inputBuffer, out int dataLength);

                var outputSamples = inputBuffer.Slice(0, dataLength);

                if (isFirst)
                {
                    //remove preskip
                    outputSamples = outputSamples.Slice(reader.Preskip);

                    isFirst = false;
                }

                Span <float> outputSpan = outputSamples;

                if (resample)
                {
                    float[] resampledSamples = new float[resampler.ResampleUpperBound(outputSamples.Length)];


                    resampler.Resample(outputSamples, resampledSamples, reader.IsStreamFinished, out int outputLength);

                    outputSpan = resampledSamples.AsSpan(0, outputLength);
                }

                foreach (float sample in outputSpan)
                {
                    writer.Write(WaveWriter.ConvertSample(sample));
                }
            }

            long endPosition = output.Position;

            output.Position = headerPosition;

            WaveWriter.WriteWAVHeader(output, reader.Channels, (int)(endPosition - headerPosition), resample ? resampleRate : 48000, 16);

            output.Position = endPosition;
        }