Commit 6c34e714 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Moving biquad implementation to ITADSP project

parent 1371d5d4
......@@ -39,6 +39,7 @@ endif( )
vista_use_package( VistaCoreLibs REQUIRED COMPONENTS VistaInterProcComm FIND_DEPENDENCIES )
vista_use_package( VABase REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITABase REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITADSP REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITADataSources REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITAConvolution REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITACTC REQUIRED FIND_DEPENDENCIES )
......
/*
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institut für Technische Akustik (ITA)
* VVVV AAA RWTH Aachen (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VABiquad.h
*
* Zweck: Biquadratisches IIR filter (Biquad, aka SOS-Filter)
*
* Autor(en): Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*/
// $Id: VABiquad.h 3000 2012-12-10 10:19:37Z stienen $
#ifndef __VA_BIQUAD__
#define __VA_BIQUAD__
//! Implementiert ein digitales Biquad IIR Filter
/**
* Diese Klasse realisiert ein Biquad IIR Filter. Es hat einen globalen Verstärkungsfaktor (Gain),
* damit eine Kaskadierung vieler Biquads zur Bandfilterung benutzt werden kann.
* Die Umsetzung erfolgt in Kanonischer Form, um möglichst wenig Multiplizierer/Addierer und
* Verzögerer zu benutzen.
*/
class CVABiquad {
public:
// [stienen] Atomic? Lock? ... cpp Datei?
float g; //!< Verstärkungsfaktor (Gain)
float a1; //!< Nenner-Koeffizient 1
float a2; //!< Nenner-Koeffizient 2
float b0; //!< Zähler-Koeffizient 0
float b1; //!< Zähler-Koeffizient 1
float b2; //!< Zähler-Koeffizient 2
//! Überblendmodus der Ausgabe
enum {
OUTPUT_OVERWRITE = 0, //!< Ausgabe überschreiben
OUTPUT_ADD = 1 //!< Ausgabe addieren
} OutputFadeMode;
//! Standardkonstruktor
/**
* Setzt interne Werte und Koeffizienten für
* einen idealen Übertrager
*/
CVABiquad() : g(1), a1(0), a2(0), b0(1), b1(0), b2(0) {
Clear();
}
//! Initialisierungskonstruktor mit Parametern
/**
* \param params Filterparameter/Koeffizienten, Reihenfolge: g, b0, b1, b2, a1, a2
*
* \note Reihenfolge der Parameter beachten
*/
CVABiquad(const float params[]) {
SetParameters(params);
Clear();
}
//! Destruktor
virtual ~CVABiquad() {};
//! Parameter setzen
/**
* \param params Filterparameter/Koeffizienten, Reihenfolge: g, b0, b1, b2, a1, a2
*
* \note Reihenfolge der Parameter beachten
*/
void SetParameters(const float params[]) {
g = params[0];
b0 = params[1];
b1 = params[2];
b2 = params[3];
a1 = params[4];
a2 = params[5];
}
//! Löscht alle internen Puffer
/**
* Setzt Akkumulatoren auf 0.
*/
void Clear() {
// Akkumulatoren löschen
z[0] = z[1] = 0;
}
//! Filtert Samples, einfache Variante ohne Verstärkungsfaktoren
/**
* Filtert samples gemäß der Direkten Form 2 (Kanonische Form)
*
* \param in Eingabesamples
* \param in Ausgabesamples
* \param in Anzahl der Eingabe- und Ausgabesamples
*
* \note Eingabe- und Ausgabepuffer dürfen gleich sein
*/
void Filter(const float* in, float* out, int nsamples) {
// [fwe] Sehr flotte Implementierung: Statische Fallauflösung und
// statische Referenzen erlauben viel Compileroptimierung! Rockt, Baby!
// Lokale Akkumulatoren erzeugen
float z0, z1, z2; // w[n], w[n-1], w[n-2]
// Lokale Akkumulatoren mit gespeicherten Werten besetzen
z1 = z[0];
z2 = z[1];
for (int i=0; i<nsamples; i++) {
// w[n] = x[n] - a_1*w[n-1] - a_2*w[n-2]
z0 = g*in[i] - a1*z1 - a2*z2;
// y[n] = b_0*w[n] + b_1*w[n-1] + b_2*w[n-2]
out[i] = b0*z0 + b1*z1 + b2*z2;
// Akkumulatoren schieben
z2 = z1;
z1 = z0;
}
/*
// 2-faches loop-unrolling
for (int i=0; i<nsamples; i+=2) {
z0 = g*in[i] - a1*z1 - a2*z2;
out[i] = b0*z0 + b1*z1 + b2*z2;
z2 = z1;
z1 = z0;
z0 = g*in[i+1] - a1*z1 - a2*z2;
out[i+1] = b0*z0 + b1*z1 + b2*z2;
z2 = z1;
z1 = z0;
}
*/
/*
// 4-faches loop-unrolling
for (int i=0; i<nsamples; i+=4) {
z0 = g*in[i] - a1*z1 - a2*z2;
out[i] = b0*z0 + b1*z1 + b2*z2;
z2 = z1;
z1 = z0;
z0 = g*in[i+1] - a1*z1 - a2*z2;
out[i+1] = b0*z0 + b1*z1 + b2*z2;
z2 = z1;
z1 = z0;
z0 = g*in[i+2] - a1*z1 - a2*z2;
out[i+2] = b0*z0 + b1*z1 + b2*z2;
z2 = z1;
z1 = z0;
z0 = g*in[i+3] - a1*z1 - a2*z2;
out[i+3] = b0*z0 + b1*z1 + b2*z2;
z2 = z1;
z1 = z0;
}
*/
// Akkumulatoren für den nächsten Filterprozess speichern
z[0] = z1;
z[1] = z2;
return;
}
//! Filtert Samples, Variante mit Überlenden zu einer vorgegebenen Ausgabeverstärkung
/**
* \param in Eingabesamples
* \param out Ausgabesamples
* \param nsamples Anzahl der Eingabe- und Ausgabesamples
* \param outputGain Ausgabeverstärkung Ausgangsparameter
* \param outputMode Überblendmodus, eines aus #OutputFadeMode
*
* \note Verändern nicht den internen Verstärkungsfaktor #g (Gain)
* \note Eingabe- und Ausgabepuffer dürfen gleich sein
*/
void Filter(const float* in, float* out, int nsamples, float outputGain, int outputMode) {
// Lokale Akkumulatoren
float z0, z1, z2;
z1 = z[0];
z2 = z[1];
if (outputMode == OUTPUT_ADD) {
// Modus: Addieren
for (int i=0; i<nsamples; i++) {
z0 = g*in[i] - a1*z1 - a2*z2;
out[i] += (b0*z0 + b1*z1 + b2*z2) * outputGain;
// Akkumulatoren schieben
z2 = z1;
z1 = z0;
}
} else {
// Modus: Überschreiben
for (int i=0; i<nsamples; i++) {
z0 = g*in[i] - a1*z1 - a2*z2;
out[i] = (b0*z0 + b1*z1 + b2*z2) * outputGain;
// Akkumulatoren schieben
z2 = z1;
z1 = z0;
}
}
// Akkumulatoren global speichern
z[0] = z1;
z[1] = z2;
return;
}
//! Filtert Samples. Fette Variante (Ausgabemodus, Überblendung der Gains)
/**
* Filtert Samples und setzt gleichzeitig eine Verstärkungsänderung um.
* Interpoliert lineare zwischen Gain1 und Gain2 auf allen Samples.
*
* \param in Eingabesamples
* \param out Ausgabesamples
* \param nsamples Anzahl der Eingabe- und Ausgabesamples
* \param outputGain1 Ausgabeverstärkung Ausgangsparameter
* \param outputGain2 Ausgabeverstärkung Zielparameter
* \param outputMode Überblendmodus, eines aus #OutputFadeMode
*
* \note Verändern nicht den internen Verstärkungsfaktor #g (Gain)
* \note Eingabe- und Ausgabepuffer dürfen gleich sein
*/
void Filter(const float* in, float* out, int nsamples,
float outputGain1, float outputGain2,
int outputMode)
{
if (nsamples == 0) return;
// Lokale Akkumulatoren
float z0, z1, z2;
z1 = z[0];
z2 = z[1];
// [fwe] Sehr flotte Implementierung: Statische Fallauflösung und
// statische Referenzen erlauben viel Compileroptimierung! Rockt, Baby!
// Faktor für Linear-Interpolation des Gains
float c = (outputGain2-outputGain1)/nsamples;
if (outputMode == OUTPUT_ADD) {
// Modus: Addieren
for (int i=0; i<nsamples; i++) {
float sampleGain = outputGain1 + i*c;
z0 = g*in[i] - a1*z1 - a2*z2;
out[i] += (b0*z0 + b1*z1 + b2*z2) * sampleGain;
// Akkumulatoren schieben
z2 = z1;
z1 = z0;
}
} else {
// Modus: Überschreiben
for (int i=0; i<nsamples; i++) {
float sampleGain = outputGain1 + i*c;
z0 = g*in[i] - a1*z1 - a2*z2;
out[i] = (b0*z0 + b1*z1 + b2*z2) * sampleGain;
// Akkumulatoren schieben
z2 = z1;
z1 = z0;
}
}
// Akkumulatoren global speichern
z[0] = z1;
z[1] = z2;
}
private:
float z[2]; //!< Akkumulatoren
};
#endif // __VA_BIQUAD__
......@@ -2,14 +2,14 @@
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institut für Technische Akustik (ITA)
* VVVV AAA RWTH Aachen (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VAThirdOctaveFilterbankIIR.h
* Datei: VAThirdOctaveFilterbankIIR.h
*
* Zweck: Terzfilterbanken mittels Biquads (IIR Filter)
*
......@@ -17,14 +17,15 @@
*
* ---------------------------------------------------------------------------------
*/
// $Id: VAThirdOctaveFilterbankIIR.h 2729 2012-06-26 13:23:36Z fwefers $
#ifndef __VA_THIRDOCTAVEFILTERBANK_IIR__
#define __VA_THIRDOCTAVEFILTERBANK_IIR__
#include "VAThirdOctaveFilterbank.h"
#include "VABiquad.h"
#include <ITABiquad.h>
#include <vector>
#include <tbb/concurrent_queue.h>
......@@ -35,14 +36,15 @@
* Biquads (#CVABiquad) für Verstärkungsfaktoren eines Terzbank-Betragsspektrums (#CVAThirdOctaveMagnitudes).
*
*/
class CVAThirdOctaveFilterbankIIR : public CVAThirdOctaveFilterbank {
class CVAThirdOctaveFilterbankIIR : public CVAThirdOctaveFilterbank
{
public:
//! Konstruktor mit Samplerate und Blocklänge
/**
* \param dSamplerate Samplingrate
* \param iBlocklength Blocklänge
*/
CVAThirdOctaveFilterbankIIR(double dSamplerate, int iBlocklength);
CVAThirdOctaveFilterbankIIR( double dSamplerate, int iBlocklength );
//! Destruktor
virtual ~CVAThirdOctaveFilterbankIIR();
......@@ -55,7 +57,7 @@ public:
* \param oGains Verstärkungsfaktoren
* \param bSmoothChangeover Wenn true, dann überblenden (default), sonst sofort internen Gain umschalten
*/
void SetGains(const CVAThirdOctaveMagnitudes& oGains, bool bSmoothChangeover=true);
void SetGains( const CVAThirdOctaveMagnitudes& oGains, bool bSmoothChangeover = true );
//! Alle internen Zustände zurücksetzen (Akkumulatoren der Biquads)
void Clear();
......@@ -65,11 +67,12 @@ public:
* \param pfInputSamples Eingabesamples (Anzahl = Blocklänge)
* \param pfOutputSamples Ausgabesamples (Anzahl = Blocklänge)
*/
void Process(const float* pfInputSamples, float* pfOutputSamples);
void Process( const float* pfInputSamples, float* pfOutputSamples );
private:
//! Interne Datenklasse für das Verarbeiten eines neuen Gain Datensatzes
class GainUpdate {
class GainUpdate
{
public:
CVAThirdOctaveMagnitudes oGains; //!< Gain-Daten
int iBlendSamples; //!< Anzahl Samples zum Überblenden
......@@ -79,7 +82,7 @@ private:
int m_iBlocklength; //!< Blocklänge
int m_nBandsInternal; //!< Anzahl der internen Bänder
int m_nBiquadsPerBand; //!< Anzahl von Biqads pro Band
std::vector<CVABiquad> m_vBiquads; //!< Biquads, Zugriff: [Band][BiquadNummer]
std::vector< CITABiquad > m_vBiquads; //!< Biquads, Zugriff: [Band][BiquadNummer]
tbb::strict_ppl::concurrent_queue<GainUpdate> m_qGains; //!< Liste von neuen Verstärkungsfaktoren
CVAThirdOctaveMagnitudes m_oGainsInternal; //!< Interne Verstärkungsfaktoren
float* m_pfTempFilterBuf; //!< Zwischenpuffer für Filter
......
......@@ -8,7 +8,7 @@ set( DirFiles
VAAtmosphere.h
#VAAudiostreamVariableDelayLine.cpp
#VAAudiostreamVariableDelayLine.h
VABiquad.h
#VABiquad.h
#VAFilter.cpp
#VAFilter.h
#VAFreefieldAudiostreamProcessor.cpp
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment