private void CreateFilters() { lock (_lockObj) { _filters.Clear(); foreach (var band in _bands) { var filter = new BiQuadFilter[_channels]; for (var n = 0; n < _channels; n++) { filter[n] = BiQuadFilter.PeakingEQ(_sourceProvider.WaveFormat.SampleRate, band.Frequency, band.Bandwidth, band.Gain); } _filters.Add(filter); } } }
/// <summary> /// Create a High pass filter /// </summary> public static BiQuadFilter HighPassFilter(float sampleRate, float cutoffFrequency, float q) { var filter = new BiQuadFilter(); filter.SetHighPassFilter(sampleRate, cutoffFrequency, q); return filter; }
/// <summary> /// Create a Peaking EQ /// </summary> public static BiQuadFilter PeakingEQ(float sampleRate, float centreFrequency, float q, float dbGain) { var filter = new BiQuadFilter(); filter.SetPeakingEq(sampleRate, centreFrequency, q, dbGain); return(filter); }
/// <summary> /// Create a low pass filter /// </summary> // Token: 0x06000344 RID: 836 RVA: 0x0000B03C File Offset: 0x0000923C public static BiQuadFilter LowPassFilter(float sampleRate, float cutoffFrequency, float q) { BiQuadFilter biQuadFilter = new BiQuadFilter(); biQuadFilter.SetLowPassFilter(sampleRate, cutoffFrequency, q); return(biQuadFilter); }
// Trigger this with keystroke, VR input, UI button, etc. // Don't do this every time the person starts/stops sending data, instead, // use this method when the game starts up, or when you want to make the mic // available. Audio won't actually go through unless the code in Update() // can successfully give the networking system an AudioPacket. Interrupt // it before it delivers the packet, and no data will be sent. VoipReceivers // on the other side will intelligently interpret this as packet loss and // wait for new data. public void StartTransmitting() { if (isTransmitting) { return; } Debug.Log("Voip Test Transmit"); Debug.Log("Beginning VOIP transmit"); lastSamplePosition = 0; lastSampleTime = 0; int maxFreq = 0; int minFreq = 0; string deviceName = Microphone.devices[0]; Microphone.GetDeviceCaps(deviceName, out minFreq, out maxFreq); //Record at lowest frequency possible. //This makes the downsampling process a little less painful. SOURCE_FREQUENCY = minFreq; DEVICE = deviceName; lastClip = Microphone.Start(deviceName, true, 60, SOURCE_FREQUENCY); Debug.Log("Mic name: " + deviceName + ", freq: " + SOURCE_FREQUENCY); downsampler = new NAudio.Wave.Compression.AcmStream(new NAudio.Wave.WaveFormat(SOURCE_FREQUENCY, 16, 1), new NAudio.Wave.WaveFormat(TRANSMIT_FREQUENCY, 16, 1)); bitreduce = new NAudio.Wave.Compression.AcmStream(new NAudio.Wave.WaveFormat(TRANSMIT_FREQUENCY, 16, 1), new NAudio.Wave.WaveFormat(TRANSMIT_FREQUENCY, 8, 1)); lowPassFilter = NAudio.Dsp.BiQuadFilter.LowPassFilter(SOURCE_FREQUENCY, TRANSMIT_FREQUENCY * 0.5f, lowPassQuality); Debug.Log("Channels: " + lastClip.channels); Debug.Log("Bitconvert is little endian? " + BitConverter.IsLittleEndian); isTransmitting = true; }
/// <summary> /// Create a High pass filter /// </summary> public static BiQuadFilter HighPassFilter(float sampleRate, float cutoffFrequency, float q) { var filter = new BiQuadFilter(); filter.SetHighPassFilter(sampleRate, cutoffFrequency, q); return(filter); }
/// <summary> /// H(s) = (s/Q) / (s^2 + s/Q + 1) (constant 0 dB peak gain) /// </summary> public static BiQuadFilter BandPassFilterConstantPeakGain(float sampleRate, float centreFrequency, float q) { double w0 = 2 * Math.PI * centreFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double alpha = sinw0 / (2 * q); BiQuadFilter filter = new BiQuadFilter(); filter.b0 = alpha; filter.b1 = 0; filter.b2 = -alpha; filter.a0 = 1 + alpha; filter.a1 = -2 * cosw0; filter.a2 = 1 - alpha; return filter; }
/// <summary> /// H(s) = s^2 / (s^2 + s/Q + 1) /// </summary> public static BiQuadFilter HighPassFilter(float sampleRate, float cutoffFrequency, float q) { double w0 = 2 * Math.PI * cutoffFrequency / sampleRate; double cosw0 = Math.Cos(w0); double alpha = Math.Sin(w0) / (2 * q); BiQuadFilter filter = new BiQuadFilter(); filter.b0 = (1 + Math.Cos(w0))/2; filter.b1 = -(1 + Math.Cos(w0)); filter.b2 = (1 + Math.Cos(w0))/2; filter.a0 = 1 + alpha; filter.a1 = -2*Math.Cos(w0); filter.a2 = 1 - alpha; return filter; }
/// <summary> /// H(s) = s^2 / (s^2 + s/Q + 1) /// </summary> public static BiQuadFilter HighPassFilter(float sampleRate, float cutoffFrequency, float q) { double w0 = 2 * Math.PI * cutoffFrequency / sampleRate; double cosw0 = Math.Cos(w0); double alpha = Math.Sin(w0) / (2 * q); var filter = new BiQuadFilter(); filter.b0 = (1 + Math.Cos(w0)) / 2; filter.b1 = -(1 + Math.Cos(w0)); filter.b2 = (1 + Math.Cos(w0)) / 2; filter.a0 = 1 + alpha; filter.a1 = -2 * Math.Cos(w0); filter.a2 = 1 - alpha; return(filter); }
/// <summary> /// H(s) = (s/Q) / (s^2 + s/Q + 1) (constant 0 dB peak gain) /// </summary> public static BiQuadFilter BandPassFilterConstantPeakGain(float sampleRate, float centreFrequency, float q) { double w0 = 2 * Math.PI * centreFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double alpha = sinw0 / (2 * q); var filter = new BiQuadFilter(); filter.b0 = alpha; filter.b1 = 0; filter.b2 = -alpha; filter.a0 = 1 + alpha; filter.a1 = -2 * cosw0; filter.a2 = 1 - alpha; return(filter); }
/// <summary> /// H(s) = (s^2 + 1) / (s^2 + s/Q + 1) /// </summary> public static BiQuadFilter NotchFilter(float sampleRate, float centreFrequency, float q) { double w0 = 2 * Math.PI * centreFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double alpha = sinw0 / (2 * q); BiQuadFilter filter = new BiQuadFilter(); filter.b0 = 1; filter.b1 = -2 * cosw0; filter.b2 = 1; filter.a0 = 1 + alpha; filter.a1 = -2 * cosw0; filter.a2 = 1 - alpha; return(filter); }
/// <summary> /// H(s) = A * (s^2 + (sqrt(A)/Q)*s + A)/(A*s^2 + (sqrt(A)/Q)*s + 1) /// </summary> /// <param name="sampleRate"></param> /// <param name="cutoffFrequency"></param> /// <param name="shelfSlope">a "shelf slope" parameter (for shelving EQ only). /// When S = 1, the shelf slope is as steep as it can be and remain monotonically /// increasing or decreasing gain with frequency. The shelf slope, in dB/octave, /// remains proportional to S for all other values for a fixed f0/Fs and dBgain.</param> /// <param name="dbGain">Gain in decibels</param> public static BiQuadFilter LowShelf(float sampleRate, float cutoffFrequency, float shelfSlope, float dbGain) { double w0 = 2 * Math.PI * cutoffFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double A = Math.Pow(10, dbGain / 40); // TODO: should we square root this value? double alpha = sinw0 / 2 * Math.Sqrt((A + 1 / A) * (1 / shelfSlope - 1) + 2); double temp = 2 * Math.Sqrt(A) * alpha; var filter = new BiQuadFilter(); filter.b0 = A * ((A + 1) - (A - 1) * cosw0 + temp); filter.b1 = 2 * A * ((A - 1) - (A + 1) * cosw0); filter.b2 = A * ((A + 1) - (A - 1) * cosw0 - temp); filter.a0 = (A + 1) + (A - 1) * cosw0 + temp; filter.a1 = -2 * ((A - 1) + (A + 1) * cosw0); filter.a2 = (A + 1) + (A - 1) * cosw0 - temp; return(filter); }
/// <summary> /// H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) /// </summary> public static BiQuadFilter PeakingEQ(float sampleRate, float centreFrequency, float q, float dbGain) { double w0 = 2 * Math.PI * centreFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double alpha = sinw0 / (2 * q); double A = Math.Pow(10, dbGain / 40); // TODO: should we square root this value? var filter = new BiQuadFilter(); filter.b0 = 1 + alpha * A; filter.b1 = -2 * cosw0; filter.b2 = 1 - alpha * A; filter.a0 = 1 + alpha / A; filter.a1 = -2 * cosw0; filter.a2 = 1 - alpha / A; return(filter); }
/// <summary> /// H(s) = (s^2 + 1) / (s^2 + s/Q + 1) /// </summary> public static BiQuadFilter NotchFilter(float sampleRate, float centreFrequency, float q) { double w0 = 2*Math.PI*centreFrequency/sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double alpha = sinw0/(2*q); var filter = new BiQuadFilter(); filter.b0 = 1; filter.b1 = -2*cosw0; filter.b2 = 1; filter.a0 = 1 + alpha; filter.a1 = -2*cosw0; filter.a2 = 1 - alpha; return filter; }
/// <summary> /// H(s) = A * (A*s^2 + (sqrt(A)/Q)*s + 1)/(s^2 + (sqrt(A)/Q)*s + A) /// </summary> /// <param name="sampleRate"></param> /// <param name="cutoffFrequency"></param> /// <param name="shelfSlope"></param> /// <param name="dbGain"></param> /// <returns></returns> public static BiQuadFilter HighShelf(float sampleRate, float cutoffFrequency, float shelfSlope, float dbGain) { double w0 = 2 * Math.PI * cutoffFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double A = Math.Pow(10, dbGain / 40); // TODO: should we square root this value? double alpha = sinw0 / 2 * Math.Sqrt((A + 1 / A) * (1 / shelfSlope - 1) + 2); double temp = 2 * Math.Sqrt(A) * alpha; BiQuadFilter filter = new BiQuadFilter(); filter.b0 = A*( (A+1) + (A-1)*cosw0 + temp ); filter.b1 = -2*A*( (A-1) + (A+1)*cosw0 ); filter.b2 = A*( (A+1) + (A-1)*cosw0 - temp ); filter.a0 = (A+1) - (A-1)*cosw0 + temp; filter.a1 = 2*( (A-1) - (A+1)*cosw0 ); filter.a2 = (A+1) - (A-1)*cosw0 - temp; return filter; }
/// <summary> /// H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) /// </summary> public static BiQuadFilter PeakingEQ(float sampleRate, float centreFrequency, float q, float dbGain) { double w0 = 2 * Math.PI * centreFrequency / sampleRate; double cosw0 = Math.Cos(w0); double sinw0 = Math.Sin(w0); double alpha = sinw0 / (2 * q); double A = Math.Pow(10, dbGain / 40); // TODO: should we square root this value? BiQuadFilter filter = new BiQuadFilter(); filter.b0 = 1 + alpha*A; filter.b1 = -2*cosw0; filter.b2 = 1 - alpha*A; filter.a0 = 1 + alpha/A; filter.a1 = -2*cosw0; filter.a2 = 1 - alpha/A; return filter; }
/// <summary> /// Creating a new MixingSampleProvider with a collection of sources /// </summary> /// <param name="sources"></param> public MyMixingSampleProvider(IEnumerable<ISampleProvider> sources) { env.AttackRate = 44100f; env.DecayRate = 44100f; env.SustainLevel = .8f; env.ReleaseRate = 44100f; filter = BiQuadFilter.LowPassFilter(44100f, cutoffFrq, 1); this.sources = new List<ISampleProvider>(); foreach (var source in sources) { AddMixerInput(source); } if (this.sources.Count == 0) { throw new ArgumentException("Must provide at least one input in this constructor"); } }
/// <summary> /// Create a Peaking EQ /// </summary> public static BiQuadFilter PeakingEQ(float sampleRate, float centreFrequency, float q, float dbGain) { var filter = new BiQuadFilter(); filter.SetPeakingEq(sampleRate, centreFrequency, q, dbGain); return filter; }