예제 #1
0
        /// <summary>
        /// Engages the specified source floats. This doc was autogenerated so it's weird.
        /// </summary>
        /// <param name="sourceFloats">The source floats.</param>
        /// <param name="sourceLength">Length of the source -- how many floats to use from the provided buffer.</param>
        /// <param name="resampledResult">The resampled result.</param>
        /// <param name="sampleRateIn">The sample rate in.</param>
        /// <param name="sampleRateOut">The sample rate out.</param>
        /// <returns>
        /// the number of samples processed
        /// </returns>
        public int Engage(float[] sourceFloats,
                          int sourceLength,
                          out float[] resampledResult,
                          int sampleRateIn,
                          int sampleRateOut)
        {
            // The resampler code is very delicate. I don't recommend messing with it unless you have a week to
            // spend on it.
            // See https://gist.github.com/markheath/dc41131fefb84b93b041f1dde8a08209 for more info
            _resampler.SetMode(false, 0, false);
            _resampler.SetFilterParms();
            _resampler.SetRates(sampleRateIn, sampleRateOut);
            _resampler.SetFeedMode(true); // input driven

            float[] inData;
            int     inBufferOffset;
            int     inputFrameCount = sourceLength / _channels;
            int     framesExpected  = _resampler.ResamplePrepare(inputFrameCount, _channels, out inData, out inBufferOffset);

            // Feed the samples into the resampler's byte array.
            Array.Copy(sourceFloats, 0, inData, inBufferOffset, framesExpected * _channels);
            var ratio = (double)sampleRateIn / sampleRateOut;

            double expected = (double)framesExpected * _channels / ratio;

            // round upward to nearest complete frame to prevent data loss
            int roundedSamples = (int)Math.Ceiling(expected / _channels) * _channels;

            resampledResult = new float[roundedSamples];

            // the return value is the Inverse of what would actually be helpful
            int framesProcessed = _resampler.ResampleOut(resampledResult, 0, framesExpected, roundedSamples, _channels);

            return(framesProcessed * 2);
        }
        /// <summary>
        /// Constructs a new resampler
        /// </summary>
        /// <param name="source">Source to resample</param>
        /// <param name="newSampleRate">Desired output sample rate</param>
        public WdlResamplingSampleProvider(ISampleProvider source, int newSampleRate)
        {
            channels    = source.WaveFormat.Channels;
            outFormat   = WaveFormat.CreateIeeeFloatWaveFormat(newSampleRate, channels);
            this.source = source;

            resampler = new WdlResampler();
            resampler.SetMode(true, 2, false);
            resampler.SetFilterParms();
            resampler.SetFeedMode(false); // output driven
            resampler.SetRates(source.WaveFormat.SampleRate, newSampleRate);
        }
예제 #3
0
        public Resampler(ISampleSource source, IRateProvider rate)
        {
            _source = source;
            _rate   = rate;

            AudioSettings.OnAudioConfigurationChanged += OnAudioConfigurationChanged;
            OnAudioConfigurationChanged(false);

            _resampler = new WdlResampler();
            _resampler.SetMode(true, 2, false);
            _resampler.SetFilterParms();
            _resampler.SetFeedMode(false);
        }
예제 #4
0
        public Resampler([NotNull] ISampleProvider source, int newSampleRate)
        {
            _source = source;
            _format = new WaveFormat(source.WaveFormat.Channels, newSampleRate);

            if (source.WaveFormat.SampleRate != newSampleRate)
            {
                _resampler = new WdlResampler();
                _resampler.SetMode(true, 2, false);
                _resampler.SetFilterParms();
                _resampler.SetFeedMode(false); // output driven
                _resampler.SetRates(source.WaveFormat.SampleRate, newSampleRate);
            }
        }
예제 #5
0
        public bool Read(ArraySegment <float> samples)
        {
            var inFormat  = _source.WaveFormat;
            var outFormat = _outputFormat;

            if (outFormat.SampleRate == inFormat.SampleRate)
            {
                return(_source.Read(samples));
            }

            if (_resampler == null || outFormat.SampleRate != (int)_resampler.OutputSampleRate)
            {
                Log.Debug("Initializing resampler to resample {0}Hz source to {1}Hz output", inFormat.SampleRate, outFormat.SampleRate);

                _resampler = new WdlResampler();
                _resampler.SetMode(true, 2, false);
                _resampler.SetFilterParms();
                _resampler.SetFeedMode(false); // output driven
                _resampler.SetRates(inFormat.SampleRate, outFormat.SampleRate);
            }

            var channels = inFormat.Channels;

            // prepare buffers
            float[] inBuffer;
            int     inBufferOffset;
            var     samplesPerChannelRequested = samples.Count / channels;
            var     samplesPerChannelRequired  = _resampler.ResamplePrepare(samplesPerChannelRequested, channels, out inBuffer, out inBufferOffset);
            var     sourceBuffer = new ArraySegment <float>(inBuffer, inBufferOffset, samplesPerChannelRequired * channels);

            // read source
            var complete = _source.Read(sourceBuffer);

            // resample
            Log.Trace("Resampling {0}Hz -> {1}Hz", inFormat.SampleRate, outFormat.SampleRate);
            _resampler.ResampleOut(samples.Array, samples.Offset, samplesPerChannelRequired, samplesPerChannelRequested, channels);

            return(complete);
        }