/// <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); }
public TransmitForm(MMDevice speaker, MMDevice microphone, bool muteAudio, int bitrate, UdpClient client, IPEndPoint endpoint, byte[] sessionID, KeyPair localKey, byte[] remotePublicKey) { this.speaker = speaker; this.microphone = microphone; this.muteAudio = muteAudio; wasAudioMuted = speaker.AudioEndpointVolume.Mute; speaker.AudioEndpointVolume.Mute = muteAudio ? true : this.wasAudioMuted; this.client = client; this.endpoint = endpoint; this.sessionID = sessionID; this.localKeyPair = localKey; this.remotePublicKey = remotePublicKey; InitializeComponent(); stream = new MemoryStream(); outFormat = new WaveFormat(48000, 2); capture = new WasapiLoopbackCapture(speaker); waveStream = new RawSourceWaveStream(stream, capture.WaveFormat); resampler = new WdlResampler(); resampler.SetMode(true, 0, false); resampler.SetFeedMode(true); resampler.SetRates(capture.WaveFormat.SampleRate, outFormat.SampleRate); output = new WasapiOut(microphone, AudioClientShareMode.Shared, true, 0); waveProvider = new BufferedWaveProvider(new WaveFormat(48000, 2)); waveProvider.BufferLength = 100000; waveProvider.DiscardOnBufferOverflow = true; output.Init(waveProvider); output.Play(); encoder = new OpusEncoder(48000, 2, Concentus.Enums.OpusApplication.OPUS_APPLICATION_AUDIO) { Bitrate = bitrate * 1000 }; decoder = new OpusDecoder(48000, 2); capture.DataAvailable += DataAvailable; capture.StartRecording(); receiverThread = new Thread(new ThreadStart(ReceiverLoop)); receiverThread.Start(); }
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); } }
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); }