mirror of
https://github.com/SDRSharpR/SDRSharper.git
synced 2026-01-03 15:09:57 +01:00
115 lines
2.6 KiB
C#
115 lines
2.6 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace SDRSharp.Radio
|
|
{
|
|
[StructLayout(LayoutKind.Sequential, Pack = 16)]
|
|
public struct IirFilter
|
|
{
|
|
private float _a0;
|
|
|
|
private float _a1;
|
|
|
|
private float _a2;
|
|
|
|
private float _b0;
|
|
|
|
private float _b1;
|
|
|
|
private float _b2;
|
|
|
|
private float _x1;
|
|
|
|
private float _x2;
|
|
|
|
private float _y1;
|
|
|
|
private float _y2;
|
|
|
|
public void Init(IirFilterType filterType, double frequency, double sampleRate, int qualityFactor)
|
|
{
|
|
double num = 6.2831853071795862 * frequency / sampleRate;
|
|
double num2 = Math.Sin(num) / (2.0 * (double)qualityFactor);
|
|
switch (filterType)
|
|
{
|
|
case IirFilterType.LowPass:
|
|
this._b0 = (float)((1.0 - Math.Cos(num)) / 2.0);
|
|
this._b1 = (float)(1.0 - Math.Cos(num));
|
|
this._b2 = (float)((1.0 - Math.Cos(num)) / 2.0);
|
|
this._a0 = (float)(1.0 + num2);
|
|
this._a1 = (float)(-2.0 * Math.Cos(num));
|
|
this._a2 = (float)(1.0 - num2);
|
|
break;
|
|
case IirFilterType.HighPass:
|
|
this._b0 = (float)((1.0 + Math.Cos(num)) / 2.0);
|
|
this._b1 = (float)(0.0 - (1.0 + Math.Cos(num)));
|
|
this._b2 = (float)((1.0 + Math.Cos(num)) / 2.0);
|
|
this._a0 = (float)(1.0 + num2);
|
|
this._a1 = (float)(-2.0 * Math.Cos(num));
|
|
this._a2 = (float)(1.0 - num2);
|
|
break;
|
|
default:
|
|
this._b0 = (float)num2;
|
|
this._b1 = 0f;
|
|
this._b2 = (float)(0.0 - num2);
|
|
this._a0 = (float)(1.0 + num2);
|
|
this._a1 = (float)(-2.0 * Math.Cos(num));
|
|
this._a2 = (float)(1.0 - num2);
|
|
break;
|
|
case IirFilterType.Notch:
|
|
this._b0 = 1f;
|
|
this._b1 = (float)(-2.0 * Math.Cos(num));
|
|
this._b2 = 1f;
|
|
this._a0 = (float)(1.0 + num2);
|
|
this._a1 = (float)(-2.0 * Math.Cos(num));
|
|
this._a2 = (float)(1.0 - num2);
|
|
break;
|
|
}
|
|
this._b0 /= this._a0;
|
|
this._b1 /= this._a0;
|
|
this._b2 /= this._a0;
|
|
this._a1 /= this._a0;
|
|
this._a2 /= this._a0;
|
|
this._x1 = 0f;
|
|
this._x2 = 0f;
|
|
this._y1 = 0f;
|
|
this._y2 = 0f;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
this._x1 = 0f;
|
|
this._x2 = 0f;
|
|
this._y1 = 0f;
|
|
this._y2 = 0f;
|
|
}
|
|
|
|
public float Process(float sample)
|
|
{
|
|
float num = this._b0 * sample + this._b1 * this._x1 + this._b2 * this._x2 - this._a1 * this._y1 - this._a2 * this._y2;
|
|
this._x2 = this._x1;
|
|
this._x1 = sample;
|
|
this._y2 = this._y1;
|
|
this._y1 = num;
|
|
return num;
|
|
}
|
|
|
|
public unsafe void Process(float* buffer, int length)
|
|
{
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
buffer[i] = this.Process(buffer[i]);
|
|
}
|
|
}
|
|
|
|
public unsafe void ProcessInterleaved(float* buffer, int length)
|
|
{
|
|
length *= 2;
|
|
for (int i = 0; i < length; i += 2)
|
|
{
|
|
buffer[i] = this.Process(buffer[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|