Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Institute of Technical Acoustics (ITA)
VACore
Commits
6c34e714
Commit
6c34e714
authored
May 27, 2017
by
Dipl.-Ing. Jonas Stienen
Browse files
Moving biquad implementation to ITADSP project
parent
1371d5d4
Changes
4
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
6c34e714
...
...
@@ -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
)
...
...
src/Filtering/VABiquad.h
deleted
100644 → 0
View file @
1371d5d4
/*
*
* 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__
src/Filtering/VAThirdOctaveFilterbankIIR.h
View file @
6c34e714
...
...
@@ -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
<
CV
ABiquad
>
m_vBiquads
;
//!< Biquads, Zugriff: [Band][BiquadNummer]
std
::
vector
<
CIT
ABiquad
>
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
...
...
src/Filtering/_SourceFiles.cmake
View file @
6c34e714
...
...
@@ -8,7 +8,7 @@ set( DirFiles
VAAtmosphere.h
#VAAudiostreamVariableDelayLine.cpp
#VAAudiostreamVariableDelayLine.h
VABiquad.h
#
VABiquad.h
#VAFilter.cpp
#VAFilter.h
#VAFreefieldAudiostreamProcessor.cpp
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment