public int Read(float[] buffer, int offset, int count) { //If the resampler is null just read from upstream if (_resampler == null) { return(_source.Read(buffer, offset, count)); } //Early exit if no data is needed if (count == 0) { return(0); } var channels = _source.WaveFormat.Channels; float[] inBuffer; int inBufferOffset; var framesRequested = count / channels; var inNeeded = _resampler.ResamplePrepare(framesRequested, channels, out inBuffer, out inBufferOffset); var inAvailable = _source.Read(inBuffer, inBufferOffset, inNeeded * channels) / channels; //Resampler does not handle zero samples well! If we read nothing, return nothing if (inAvailable == 0) { return(0); } var outAvailable = _resampler.ResampleOut(buffer, offset, inAvailable, framesRequested, channels); return(outAvailable * channels); }
/// <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> /// Reads from this sample provider /// </summary> public int Read(float[] buffer, int offset, int count) { float[] inBuffer; int inBufferOffset; int framesRequested = count / channels; int inNeeded = resampler.ResamplePrepare(framesRequested, outFormat.Channels, out inBuffer, out inBufferOffset); int inAvailable = source.Read(inBuffer, inBufferOffset, inNeeded * channels) / channels; int outAvailable = resampler.ResampleOut(buffer, offset, inAvailable, framesRequested, channels); return(outAvailable * channels); }
private void DataAvailable(object sender, WaveInEventArgs e) { // WaveBuffer is broken. //var buffer = new WaveBuffer(e.Buffer); var buffer = new float[e.BytesRecorded / 4]; for (int i = 0; i < e.BytesRecorded; i += 4) { buffer[i / 4] = BitConverter.ToSingle(e.Buffer, i) * SpeakersVolumeSlider.Volume; } // This peak detection doesn't work correctly { float peakL = 0, peakR = 0; for (int i = 0; i < buffer.Length; i += 2) { peakL += Math.Abs(buffer[i]); } for (int i = 1; i < buffer.Length; i += 2) { peakR += Math.Abs(buffer[i]); } SpeakersLeftChannel.Amplitude = peakL / (buffer.Length / 2); SpeakersRightChannel.Amplitude = peakR / (buffer.Length / 2); } int framesAvailable = e.BytesRecorded * 8 / capture.WaveFormat.BitsPerSample / 2; //Console.WriteLine("Got {0} samples per channel", framesAvailable); float[] inBuffer; int inBufferOffset; int inNeeded = resampler.ResamplePrepare(framesAvailable, capture.WaveFormat.Channels, out inBuffer, out inBufferOffset); Array.Copy(buffer, 0, inBuffer, inBufferOffset, inNeeded * 2); float[] outBuffer = new float[framesAvailable * 4]; int outAvailable = resampler.ResampleOut(outBuffer, 0, inNeeded, framesAvailable * 2, outFormat.Channels); //Console.WriteLine("Got {0} samples after resample", outAvailable); for (int i = 0; i < framesAvailable * 2; i += 960) { var resampledDataTemp = outBuffer.Skip(i).Take(Math.Min(960, (outAvailable * 2 - i))).ToArray(); var resampledPaddedData = new float[960]; var output = new byte[1276]; Array.Copy(resampledDataTemp, resampledPaddedData, resampledDataTemp.Length); int encoded = encoder.Encode(resampledPaddedData, 0, 480, output, 0, 1276); SendData(output.Take(encoded).ToArray()); //Console.WriteLine("Encoded packet of {0} bytes", encoded); // TODO: Send encoded data to the client } }
public bool Read(ArraySegment <float> samples) { var inFormat = _source.WaveFormat; var outFormat = _outputFormat; // Configure the rate of the resampler based on the requested playback rate. // If rate adjustment is very small (<1%) play back at the base rate, this means // in the normal case (rate=1) the rate won't be changing every frame var outputRate = (double)outFormat.SampleRate; if (Mathf.Abs(_rate.PlaybackRate - 1) > 0.01f) { outputRate = outFormat.SampleRate * (1 / _rate.PlaybackRate); } // ReSharper disable once CompareOfFloatsByEqualityOperator (justification: we want exact comparison) if (outputRate != _resampler.OutputSampleRate) { Log.Trace("Changing resampler rate to {0}Hz", outputRate); _resampler.SetRates(inFormat.SampleRate, outputRate); } 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); }
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); }