Client LuaCsForBarotrauma
SoundFilters.cs
1 using System;
2 
3 namespace Barotrauma.Sounds
4 {
5  /* This code is adapted from CSCore (.NET Audio Library) which is under a Microsoft Public License (Ms-PL) license.*/
6 
7  /*
8  Microsoft Public License (Ms-PL)
9 
10  This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
11 
12  1. Definitions
13  The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
14 
15  A "contribution" is the original software, or any additions or changes to the software.
16 
17  A "contributor" is any person that distributes its contribution under this license.
18 
19  "Licensed patents" are a contributor's patent claims that read directly on its contribution.
20 
21  2. Grant of Rights
22  (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
23 
24  (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
25 
26  3. Conditions and Limitations
27  (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
28 
29  (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
30 
31  (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
32 
33  (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
34 
35  (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
36  */
37 
38  /*
39  * These implementations are based on http://www.earlevel.com/main/2011/01/02/biquad-formulas/
40  */
41 
45  public abstract class BiQuad
46  {
50  protected double A0;
54  protected double A1;
58  protected double A2;
62  protected double B1;
66  protected double B2;
67 
71  protected readonly double _q;
75  protected readonly double _gainDB;
79  protected double Z1;
83  protected double Z2;
84 
85  protected readonly double _frequency;
86 
90  protected readonly int _sampleRate;
91 
92  protected static readonly double DefaultQ = 1.0 / Math.Sqrt(2);
93  protected const double DefaultGainDb = 6.0;
94 
108  protected BiQuad(int sampleRate, double frequency, double q, double gainDb)
109  {
110  if (sampleRate <= 0)
111  {
112  throw new ArgumentOutOfRangeException("sampleRate");
113  }
114  if (frequency <= 0)
115  {
116  throw new ArgumentOutOfRangeException("frequency");
117  }
118  if (q <= 0)
119  {
120  throw new ArgumentOutOfRangeException("q");
121  }
122  if (sampleRate < frequency * 2)
123  {
124  throw new ArgumentOutOfRangeException("sampleRate", "The sample rate has to be greater than or equal to 2 * frequency.");
125  }
126  _sampleRate = sampleRate;
127  _frequency = frequency;
128  _q = q;
129  _gainDB = gainDb;
131  }
132 
138  public float Process(float input)
139  {
140  double o = input * A0 + Z1;
141  Z1 = input * A1 + Z2 - B1 * o;
142  Z2 = input * A2 - B2 * o;
143  return (float)o;
144  }
145 
151  public void Process(float[] input)
152  {
153  for (int i = 0; i < input.Length; i++)
154  {
155  input[i] = Process(input[i]);
156  }
157  }
158 
162  protected abstract void CalculateBiQuadCoefficients();
163  }
164 
168  public sealed class LowpassFilter : BiQuad
169  {
175  public LowpassFilter(int sampleRate, double frequency)
176  : base(sampleRate, frequency, DefaultQ, DefaultGainDb)
177  {
178  }
179 
183  protected override void CalculateBiQuadCoefficients()
184  {
185  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
186  var norm = 1 / (1 + k / _q + k * k);
187  A0 = k * k * norm;
188  A1 = 2 * A0;
189  A2 = A0;
190  B1 = 2 * (k * k - 1) * norm;
191  B2 = (1 - k / _q + k * k) * norm;
192  }
193  }
194 
198  public sealed class HighpassFilter : BiQuad
199  {
205  public HighpassFilter(int sampleRate, double frequency)
206  : base(sampleRate, frequency, DefaultQ, DefaultGainDb)
207  {
208  }
209 
213  protected override void CalculateBiQuadCoefficients()
214  {
215  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
216  var norm = 1 / (1 + k / _q + k * k);
217  A0 = 1 * norm;
218  A1 = -2 * A0;
219  A2 = A0;
220  B1 = 2 * (k * k - 1) * norm;
221  B2 = (1 - k / _q + k * k) * norm;
222  }
223  }
224 
228  public sealed class BandpassFilter : BiQuad
229  {
235  public BandpassFilter(int sampleRate, double frequency)
236  : base(sampleRate, frequency, DefaultQ, DefaultGainDb)
237  {
238  }
239 
243  protected override void CalculateBiQuadCoefficients()
244  {
245  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
246  double norm = 1 / (1 + k / _q + k * k);
247  A0 = k / _q * norm;
248  A1 = 0;
249  A2 = -A0;
250  B1 = 2 * (k * k - 1) * norm;
251  B2 = (1 - k / _q + k * k) * norm;
252  }
253  }
254 
258  public sealed class NotchFilter : BiQuad
259  {
265  public NotchFilter(int sampleRate, double frequency)
266  : base(sampleRate, frequency, DefaultQ, DefaultGainDb)
267  {
268  }
269 
273  protected override void CalculateBiQuadCoefficients()
274  {
275  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
276  double norm = 1 / (1 + k / _q + k * k);
277  A0 = (1 + k * k) * norm;
278  A1 = 2 * (k * k - 1) * norm;
279  A2 = A0;
280  B1 = A1;
281  B2 = (1 - k / _q + k * k) * norm;
282  }
283  }
284 
288  public sealed class LowShelfFilter : BiQuad
289  {
296  public LowShelfFilter(int sampleRate, double frequency, double gainDB)
297  : base(sampleRate, frequency, DefaultQ, gainDB)
298  { }
299 
303  protected override void CalculateBiQuadCoefficients()
304  {
305  const double sqrt2 = 1.4142135623730951;
306  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
307  double v = Math.Pow(10, Math.Abs(_gainDB) / 20.0);
308  double norm;
309  if (_gainDB >= 0)
310  { // boost
311  norm = 1 / (1 + sqrt2 * k + k * k);
312  A0 = (1 + Math.Sqrt(2 * v) * k + v * k * k) * norm;
313  A1 = 2 * (v * k * k - 1) * norm;
314  A2 = (1 - Math.Sqrt(2 * v) * k + v * k * k) * norm;
315  B1 = 2 * (k * k - 1) * norm;
316  B2 = (1 - sqrt2 * k + k * k) * norm;
317  }
318  else
319  { // cut
320  norm = 1 / (1 + Math.Sqrt(2 * v) * k + v * k * k);
321  A0 = (1 + sqrt2 * k + k * k) * norm;
322  A1 = 2 * (k * k - 1) * norm;
323  A2 = (1 - sqrt2 * k + k * k) * norm;
324  B1 = 2 * (v * k * k - 1) * norm;
325  B2 = (1 - Math.Sqrt(2 * v) * k + v * k * k) * norm;
326  }
327  }
328  }
329 
333  public sealed class HighShelfFilter : BiQuad
334  {
341  public HighShelfFilter(int sampleRate, double frequency, double gainDB)
342  : base(sampleRate, frequency, DefaultQ, gainDB)
343  { }
344 
348  protected override void CalculateBiQuadCoefficients()
349  {
350  const double sqrt2 = 1.4142135623730951;
351  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
352  double v = Math.Pow(10, Math.Abs(_gainDB) / 20.0);
353  double norm;
354  if (_gainDB >= 0)
355  { // boost
356  norm = 1 / (1 + sqrt2 * k + k * k);
357  A0 = (v + Math.Sqrt(2 * v) * k + k * k) * norm;
358  A1 = 2 * (k * k - v) * norm;
359  A2 = (v - Math.Sqrt(2 * v) * k + k * k) * norm;
360  B1 = 2 * (k * k - 1) * norm;
361  B2 = (1 - sqrt2 * k + k * k) * norm;
362  }
363  else
364  { // cut
365  norm = 1 / (v + Math.Sqrt(2 * v) * k + k * k);
366  A0 = (1 + sqrt2 * k + k * k) * norm;
367  A1 = 2 * (k * k - 1) * norm;
368  A2 = (1 - sqrt2 * k + k * k) * norm;
369  B1 = 2 * (k * k - v) * norm;
370  B2 = (v - Math.Sqrt(2 * v) * k + k * k) * norm;
371  }
372  }
373  }
374 
378  public sealed class PeakFilter : BiQuad
379  {
387  public PeakFilter(int sampleRate, double frequency, double bandWidth, double peakGainDB)
388  : base(sampleRate, frequency, bandWidth, peakGainDB)
389  { }
390 
394  protected override void CalculateBiQuadCoefficients()
395  {
396  double norm;
397  double v = Math.Pow(10, Math.Abs(_gainDB) / 20.0);
398  double k = Math.Tan(Math.PI * _frequency / _sampleRate);
399  double q = _q;
400 
401  if (_gainDB >= 0) //boost
402  {
403  norm = 1 / (1 + 1 / q * k + k * k);
404  A0 = (1 + v / q * k + k * k) * norm;
405  A1 = 2 * (k * k - 1) * norm;
406  A2 = (1 - v / q * k + k * k) * norm;
407  B1 = A1;
408  B2 = (1 - 1 / q * k + k * k) * norm;
409  }
410  else //cut
411  {
412  norm = 1 / (1 + v / q * k + k * k);
413  A0 = (1 + 1 / q * k + k * k) * norm;
414  A1 = 2 * (k * k - 1) * norm;
415  A2 = (1 - 1 / q * k + k * k) * norm;
416  B1 = A1;
417  B2 = (1 - v / q * k + k * k) * norm;
418  }
419  }
420  }
421 
422 }
Used to apply a bandpass-filter to a signal.
BandpassFilter(int sampleRate, double frequency)
Initializes a new instance of the BandpassFilter class.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.
Represents a biquad-filter.
Definition: SoundFilters.cs:46
double A2
The a2 value.
Definition: SoundFilters.cs:58
double Z2
The z2 value.
Definition: SoundFilters.cs:83
double B1
The b1 value.
Definition: SoundFilters.cs:62
const double DefaultGainDb
Definition: SoundFilters.cs:93
void Process(float[] input)
Processes multiple input samples.
readonly double _frequency
Definition: SoundFilters.cs:85
readonly double _q
The q value.
Definition: SoundFilters.cs:71
double B2
The b2 value.
Definition: SoundFilters.cs:66
readonly double _gainDB
The gain value in dB.
Definition: SoundFilters.cs:75
float Process(float input)
Processes a single input sample and returns the result.
double A0
The a0 value.
Definition: SoundFilters.cs:50
readonly int _sampleRate
Gets the sample rate.
Definition: SoundFilters.cs:90
double A1
The a1 value.
Definition: SoundFilters.cs:54
BiQuad(int sampleRate, double frequency, double q, double gainDb)
Initializes a new instance of the BiQuad class.
static readonly double DefaultQ
Definition: SoundFilters.cs:92
abstract void CalculateBiQuadCoefficients()
Calculates all coefficients.
double Z1
The z1 value.
Definition: SoundFilters.cs:79
Used to apply a highshelf-filter to a signal.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.
HighShelfFilter(int sampleRate, double frequency, double gainDB)
Initializes a new instance of the HighShelfFilter class.
Used to apply a highpass-filter to a signal.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.
HighpassFilter(int sampleRate, double frequency)
Initializes a new instance of the HighpassFilter class.
Used to apply a lowshelf-filter to a signal.
LowShelfFilter(int sampleRate, double frequency, double gainDB)
Initializes a new instance of the LowShelfFilter class.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.
Used to apply a lowpass-filter to a signal.
LowpassFilter(int sampleRate, double frequency)
Initializes a new instance of the LowpassFilter class.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.
Used to apply a notch-filter to a signal.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.
NotchFilter(int sampleRate, double frequency)
Initializes a new instance of the NotchFilter class.
Used to apply an peak-filter to a signal.
PeakFilter(int sampleRate, double frequency, double bandWidth, double peakGainDB)
Initializes a new instance of the PeakFilter class.
override void CalculateBiQuadCoefficients()
Calculates all coefficients.