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

Style and comments

parent 984851db
/*
*
* 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 fr Technische Akustik (ITA)
* VVVV AAA RWTH Aachen (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VAThirdOctaveFIRFilterGenerator.cpp
*
* Zweck: Generator FIR-Filter aus Terzband-Betragsspektren
*
* Autor(en): Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*/
// $Id: VAThirdOctaveFIRFilterGenerator.cpp 3629 2014-08-13 12:23:44Z fwefers $
#include "VAThirdOctaveFIRFilterGenerator.h"
#include <ITAFastMath.h>
#include <ITAConstants.h>
#include <ITAFastMath.h>
#include <ITANumericUtils.h>
#include <ITAStringUtils.h>
#include <spline.h>
......@@ -32,121 +11,129 @@
#include <iomanip>
#include <iostream>
#include <fstream>
#include <ITAStringUtils.h>
// Debugging flags
#define DUMP_INTERPOLATED_MAGNITUDES 0
CVAThirdOctaveFIRFilterGenerator::CVAThirdOctaveFIRFilterGenerator(double dSamplerate,
int iFilterLength)
: m_dSamplerate(dSamplerate),
m_iFilterLength(iFilterLength),
m_ypp(nullptr),
m_pfInputFreqs(nullptr),
m_pfInputData(nullptr),
m_pfBuf1(nullptr),
m_pfBuf2(nullptr),
m_bWindow(false)
CVAThirdOctaveFIRFilterGenerator::CVAThirdOctaveFIRFilterGenerator( double dSamplerate, int iFilterLength )
: m_dSamplerate( dSamplerate )
, m_iFilterLength( iFilterLength )
, m_ypp( nullptr )
, m_pfInputFreqs( nullptr )
, m_pfInputData( nullptr )
, m_pfBuf1( nullptr )
, m_pfBuf2( nullptr )
, m_bWindow( false )
{
m_iInputFreqs = CVAThirdOctaveMagnitudes::nBands + 2;
m_pfInputFreqs = fm_falloc( m_iInputFreqs, true );
m_pfInputFreqs[0] = 0; // Left margin
for (int i=0; i<CVAThirdOctaveMagnitudes::nBands; i++)
m_pfInputFreqs[i+1] = CVAThirdOctaveMagnitudes::fCenterFreqs[i];
m_pfInputFreqs[m_iInputFreqs-1] = (float) dSamplerate / 2; // Right margin: Nyquist frequency
m_pfInputFreqs[ 0 ] = 0; // Left margin
for( int i = 0; i < CVAThirdOctaveMagnitudes::nBands; i++ )
m_pfInputFreqs[ i + 1 ] = CVAThirdOctaveMagnitudes::fCenterFreqs[ i ];
m_pfInputFreqs[ m_iInputFreqs - 1 ] = ( float ) dSamplerate / 2; // Right margin: Nyquist frequency
m_pfInputData = fm_falloc( m_iInputFreqs, true );
// DFT frequency bandwidth
m_fDeltaF = (float) dSamplerate / (float) iFilterLength;
m_fDeltaF = ( float ) dSamplerate / ( float ) iFilterLength;
// Number of symetric DFT coefficients;
m_iDFTCoeffs = iFilterLength/2 + 1;
m_iDFTCoeffs = iFilterLength / 2 + 1;
m_pfBuf1 = fm_falloc( 2*m_iDFTCoeffs, false );
m_pfBuf1 = fm_falloc( 2 * m_iDFTCoeffs, false );
m_pfBuf2 = fm_falloc( iFilterLength, false );
m_pfWindow = fm_falloc( iFilterLength, false );
// Windowing function (Hann window)
float c = 2 * ITAConstants::PI_F/(float)(m_iFilterLength-1);
for (int i=0; i<m_iFilterLength; i++) {
m_pfWindow[i] = 0.5F * (1-cos(c*i));
float c = 2 * ITAConstants::PI_F / ( float ) ( m_iFilterLength - 1 );
for( int i = 0; i < m_iFilterLength; i++ )
{
m_pfWindow[ i ] = 0.5F * ( 1 - cos( c*i ) );
}
m_ifft.plan(ITAFFT::IFFT_C2R, iFilterLength, m_pfBuf1, m_pfBuf2);
m_ifft.plan( ITAFFT::IFFT_C2R, iFilterLength, m_pfBuf1, m_pfBuf2 );
m_sDumpFilename = "interpolated_magnitudes.csv";
}
CVAThirdOctaveFIRFilterGenerator::~CVAThirdOctaveFIRFilterGenerator() {
fm_free(m_pfInputFreqs);
fm_free(m_pfInputData);
fm_free(m_pfBuf1);
fm_free(m_pfBuf2);
fm_free(m_pfWindow);
CVAThirdOctaveFIRFilterGenerator::~CVAThirdOctaveFIRFilterGenerator()
{
fm_free( m_pfInputFreqs );
fm_free( m_pfInputData );
fm_free( m_pfBuf1 );
fm_free( m_pfBuf2 );
fm_free( m_pfWindow );
}
int CVAThirdOctaveFIRFilterGenerator::GetFilterLength() const {
int CVAThirdOctaveFIRFilterGenerator::GetFilterLength() const
{
return m_iFilterLength;
}
int CVAThirdOctaveFIRFilterGenerator::GetLatency() const {
int CVAThirdOctaveFIRFilterGenerator::GetLatency() const
{
// Latency = Half DFT period (ceil)
return uprdiv(m_iFilterLength, 2);
return uprdiv( m_iFilterLength, 2 );
}
double CVAThirdOctaveFIRFilterGenerator::GetAverageRuntime() const {
double CVAThirdOctaveFIRFilterGenerator::GetAverageRuntime() const
{
return m_sw.mean();
}
void CVAThirdOctaveFIRFilterGenerator::SetDumpFilename(const std::string& sFilename) {
void CVAThirdOctaveFIRFilterGenerator::SetDumpFilename( const std::string& sFilename )
{
m_sDumpFilename = sFilename;
}
void CVAThirdOctaveFIRFilterGenerator::GenerateFilter(const CVAThirdOctaveMagnitudes& oTOMagnitudes,
float* pfFilterCoeffs) {
void CVAThirdOctaveFIRFilterGenerator::GenerateFilter( const CVAThirdOctaveMagnitudes& oTOMagnitudes, float* pfFilterCoeffs )
{
m_sw.start();
// [fwe] Intermediate bugfix. Wrong filter for identity
const float EPSILON = 0.001F;
bool bZero=true;
bool bIdent=true;
for (int i=0; i<CVAThirdOctaveMagnitudes::nBands; i++) {
bZero &= (oTOMagnitudes[i] > -EPSILON) && (oTOMagnitudes[i] < EPSILON);
bIdent &= (oTOMagnitudes[i] > 1-EPSILON) && (oTOMagnitudes[i] < 1+EPSILON);
bool bZero = true;
bool bIdent = true;
for( int i = 0; i<CVAThirdOctaveMagnitudes::nBands; i++ )
{
bZero &= ( oTOMagnitudes[ i ] > -EPSILON ) && ( oTOMagnitudes[ i ] < EPSILON );
bIdent &= ( oTOMagnitudes[ i ] > 1 - EPSILON ) && ( oTOMagnitudes[ i ] < 1 + EPSILON );
}
if (bZero) {
for (int i=0; i<m_iFilterLength; i++) pfFilterCoeffs[i] = 0;
if( bZero )
{
for( int i = 0; i < m_iFilterLength; i++ )
pfFilterCoeffs[ i ] = 0;
return;
}
if (bIdent) {
for (int i=0; i<m_iFilterLength; i++) pfFilterCoeffs[i] = 0;
pfFilterCoeffs[m_iFilterLength/2] = 1;
if( bIdent )
{
for( int i = 0; i < m_iFilterLength; i++ )
pfFilterCoeffs[ i ] = 0;
pfFilterCoeffs[ m_iFilterLength / 2 ] = 1;
return;
}
// 1st step: Interpolate the magnitudes
m_pfInputData[0] = 1;
memcpy(&m_pfInputData[1], &oTOMagnitudes.fGains, CVAThirdOctaveMagnitudes::nBands*sizeof(float));
m_pfInputData[m_iInputFreqs-1] = 0;
m_pfInputData[ 0 ] = 1;
memcpy( &m_pfInputData[ 1 ], &oTOMagnitudes.fGains, CVAThirdOctaveMagnitudes::nBands*sizeof( float ) );
m_pfInputData[ m_iInputFreqs - 1 ] = 0;
// Initialize cubic spline interpolation
m_ypp = spline_cubic_set( m_iInputFreqs,
m_pfInputFreqs,
m_pfInputData,
1, // Left boundary condition => 1st derivative m=0
0,
1, // Right boundary condition => 1st derivative m=0
0 );
m_pfInputFreqs,
m_pfInputData,
1, // Left boundary condition => 1st derivative m=0
0,
1, // Right boundary condition => 1st derivative m=0
0 );
float fDummy;
float fScale = 1 / (float) m_iFilterLength;
float fScale = 1 / ( float ) m_iFilterLength;
// No DC offset, ever!
m_pfBuf1[0] = 0;
m_pfBuf1[1] = 0;
m_pfBuf1[ 0 ] = 0;
m_pfBuf1[ 1 ] = 0;
#if (DUMP_INTERPOLATED_MAGNITUDES==1)
std::ofstream coeffs_file;
......@@ -156,24 +143,25 @@ void CVAThirdOctaveFIRFilterGenerator::GenerateFilter(const CVAThirdOctaveMagnit
coeffs_file << "# DFT bin bandwidth: " << m_fDeltaF << " Hz" << std::endl << std::endl;
#endif
for (int i=1; i<m_iDFTCoeffs; i++) {
for( int i = 1; i < m_iDFTCoeffs; i++ )
{
float x = spline_cubic_val( m_iInputFreqs,
m_pfInputFreqs,
i*m_fDeltaF,
m_pfInputData,
m_ypp,
&fDummy,
&fDummy );
m_pfInputFreqs,
i*m_fDeltaF,
m_pfInputData,
m_ypp,
&fDummy,
&fDummy );
#if (DUMP_INTERPOLATED_MAGNITUDES==1)
//std::setprecision(12) << std::ios::fixed <<
coeffs_file << (i*m_fDeltaF) << "\t"
<< x << std::endl;
<< x << std::endl;
#endif
// Phase-shift by half the FFT-period: Negate all odd DFT coefficients
m_pfBuf1[2*i] = ((i%2) == 0) ? x*fScale : -x*fScale;
m_pfBuf1[2*i+1] = 0;
m_pfBuf1[ 2 * i ] = ( ( i % 2 ) == 0 ) ? x*fScale : -x*fScale;
m_pfBuf1[ 2 * i + 1 ] = 0;
}
#if (DUMP_INTERPOLATED_MAGNITUDES==1)
......@@ -187,12 +175,15 @@ void CVAThirdOctaveFIRFilterGenerator::GenerateFilter(const CVAThirdOctaveMagnit
m_ifft.execute();
// 3rd (optional) step: Hann window in the time-domain (optional)
if (m_bWindow) {
for (int i=0; i<m_iFilterLength; i++)
pfFilterCoeffs[i] = m_pfBuf2[i] * m_pfWindow[i];
} else {
for (int i=0; i<m_iFilterLength; i++)
pfFilterCoeffs[i] = m_pfBuf2[i];
if( m_bWindow )
{
for( int i = 0; i < m_iFilterLength; i++ )
pfFilterCoeffs[ i ] = m_pfBuf2[ i ] * m_pfWindow[ i ];
}
else
{
for( int i = 0; i < m_iFilterLength; i++ )
pfFilterCoeffs[ i ] = m_pfBuf2[ i ];
}
//writeAudiofile()
......
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA Virtual Acoustics (VA)
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institut fr Technische Akustik (ITA)
* VVVV AAA RWTH Aachen (http://www.akustik.rwth-aachen.de)
* VVVVVV AAA (c) Copyright Institute of Technical Acoustics (ITA), 2015-2017
* VVVV AAA RWTH Aachen University (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VAThirdOctaveFIRFilterGenerator.h
*
* Zweck: Generator FIR-Filter aus Terzband-Betragsspektren
*
* Autor(en): Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
* --------------------------------------------------------------------------------------------
*/
// $Id: VAThirdOctaveFIRFilterGenerator.h 2854 2012-08-06 10:14:43Z fwefers $
#ifndef __VA_THIRDOCTAVE_FIRFILTERGENERATOR__
#define __VA_THIRDOCTAVE_FIRFILTERGENERATOR__
#ifndef IW_VA_THIRDOCTAVE_FIRFILTERGENERATOR
#define IW_VA_THIRDOCTAVE_FIRFILTERGENERATOR
#include "VAThirdOctaveMagnitudes.h"
......@@ -36,17 +27,18 @@
* Hierzu wird ein linear-phasiges FIR-Filter mittels Spline-Interpolation erzeugt.
* Die Filter erzeugen eine Latenz der halben Filterlnge.
*/
class CVAThirdOctaveFIRFilterGenerator {
class CVAThirdOctaveFIRFilterGenerator
{
public:
// Entwurfsmethoden
enum {
// Design methods
enum
{
LINEAR_PHASE = 0,
MINIMUM_PHASE
};
// Konstruktor
CVAThirdOctaveFIRFilterGenerator(double dSamplerate,
int iFilterLength);
CVAThirdOctaveFIRFilterGenerator( double dSamplerate, int iFilterLength );
// Destruktor
~CVAThirdOctaveFIRFilterGenerator();
......@@ -61,11 +53,10 @@ public:
double GetAverageRuntime() const;
// Dateiname fr Debug-Ausgaben setzen
void SetDumpFilename(const std::string& sFilename);
void SetDumpFilename( const std::string& sFilename );
// Filter erzeugen
void GenerateFilter(const CVAThirdOctaveMagnitudes& oTOMagnitudes,
float* pfFilterCoeffs);
void GenerateFilter( const CVAThirdOctaveMagnitudes& oTOMagnitudes, float* pfFilterCoeffs );
private:
double m_dSamplerate; // Abtastrate der Ausgabefilter [Hz]
......@@ -86,4 +77,4 @@ private:
mutable ITAStopWatch m_sw;
};
#endif // __VA_THIRDOCTAVE_FIRFILTERGENERATOR__
#endif // IW_VA_THIRDOCTAVE_FIRFILTERGENERATOR
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA Virtual Acoustics (VA)
* 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)
* VVVVVV AAA (c) Copyright Institute of Technical Acoustics (ITA), 2015-2017
* VVVV AAA RWTH Aachen University (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VAThirdOctaveFilterbankFIR.h
*
* Zweck: FIR-Terzfilterbank
*
* Autor(en): Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
* --------------------------------------------------------------------------------------------
*/
// $Id: VAThirdOctaveFilterbank.h 2729 2012-06-26 13:23:36Z fwefers $
#ifndef __VA_THIRDOCTAVEFILTERBANK_FIR__
#define __VA_THIRDOCTAVEFILTERBANK_FIR__
#ifndef IW_VA_THIRDOCTAVEFILTERBANK_FIR
#define IW_VA_THIRDOCTAVEFILTERBANK_FIR
#include "VAThirdOctaveFilterbank.h"
#include "VAThirdOctaveFIRFilterGenerator.h"
......@@ -33,64 +24,70 @@
#include <cassert>
//! Terzfilterbank mittels Dynamic Single-Channel Blockfalter (FIR Filter)
class CVAThirdOctaveFilterbankFIR : public CVAThirdOctaveFilterbank {
class CVAThirdOctaveFilterbankFIR : public CVAThirdOctaveFilterbank
{
public:
inline CVAThirdOctaveFilterbankFIR(double dSamplerate,
int iBlocklength)
: m_pfFilter(nullptr),
m_pGenerator(nullptr),
m_pConvolver(nullptr)
inline CVAThirdOctaveFilterbankFIR( double dSamplerate, int iBlocklength )
: m_pfFilter( nullptr )
, m_pGenerator( nullptr )
, m_pConvolver( nullptr )
{
m_iBlocklength = iBlocklength;
// [fwe] Hier wird die Filterlänge für Directivities festgelegt
m_iFilterLength = 128;
m_pfFilter = fm_falloc(m_iFilterLength, true );
m_pfFilter = fm_falloc( m_iFilterLength, true );
m_pGenerator = new CVAThirdOctaveFIRFilterGenerator(dSamplerate, m_iFilterLength);
m_pGenerator = new CVAThirdOctaveFIRFilterGenerator( dSamplerate, m_iFilterLength );
m_pConvolver = new DSMBCConvolver(iBlocklength, m_iFilterLength);
m_pConvolver->setFilterExchangeMode(DSMBCConvolver::CROSSFADE_COSINE_SQUARE);
m_pConvolver->setFilterCrossfadeLength(32);
m_pConvolver = new DSMBCConvolver( iBlocklength, m_iFilterLength );
m_pConvolver->setFilterExchangeMode( DSMBCConvolver::CROSSFADE_COSINE_SQUARE );
m_pConvolver->setFilterCrossfadeLength( 32 );
SetIdentity(false);
SetIdentity( false );
}
inline virtual ~CVAThirdOctaveFilterbankFIR() {
fm_free(m_pfFilter);
inline virtual ~CVAThirdOctaveFilterbankFIR()
{
fm_free( m_pfFilter );
delete m_pGenerator;
delete m_pConvolver;
}
inline virtual void SetIdentity( bool bSmoothChangeover ) {
inline virtual void SetIdentity( bool bSmoothChangeover )
{
DSMBCFilter* pFilter = m_pConvolver->requestFilter();
int iLatency = m_pGenerator->GetLatency();
assert( iLatency < m_iFilterLength );
fm_zero(m_pfFilter, m_iFilterLength);
m_pfFilter[iLatency] = 1;
pFilter->load(m_pfFilter, m_iFilterLength);
m_pConvolver->exchangeFilter(pFilter, (bSmoothChangeover ? DSMBCConvolver::AUTO : DSMBCConvolver::SWITCH));
fm_zero( m_pfFilter, m_iFilterLength );
m_pfFilter[ iLatency ] = 1;
pFilter->load( m_pfFilter, m_iFilterLength );
m_pConvolver->exchangeFilter( pFilter, ( bSmoothChangeover ? DSMBCConvolver::AUTO : DSMBCConvolver::SWITCH ) );
pFilter->release(); // Auto-release
}
inline virtual void SetGains( const CVAThirdOctaveMagnitudes& oGains, bool bSmoothChangeover = true ) {
m_pGenerator->GenerateFilter(oGains, m_pfFilter);
inline virtual void SetGains( const CVAThirdOctaveMagnitudes& oGains, bool bSmoothChangeover = true )
{
m_pGenerator->GenerateFilter( oGains, m_pfFilter );
DSMBCFilter* pFilter = m_pConvolver->requestFilter();
pFilter->load(m_pfFilter, m_iFilterLength);
m_pConvolver->exchangeFilter(pFilter, (bSmoothChangeover ? DSMBCConvolver::AUTO : DSMBCConvolver::SWITCH));
pFilter->load( m_pfFilter, m_iFilterLength );
m_pConvolver->exchangeFilter( pFilter, ( bSmoothChangeover ? DSMBCConvolver::AUTO : DSMBCConvolver::SWITCH ) );
pFilter->release(); // Auto-release
}
inline int GetLatency() const {
inline int GetLatency() const
{
return m_pGenerator->GetLatency();
}
inline virtual void Clear() {
inline virtual void Clear()
{
m_pConvolver->clear();
SetIdentity(true);
SetIdentity( true );
}
inline virtual void Process( const float* pfInputSamples, float* pfOutputSamples ) {
m_pConvolver->process(pfInputSamples, m_iBlocklength, pfOutputSamples, m_iBlocklength);
inline virtual void Process( const float* pfInputSamples, float* pfOutputSamples )
{
m_pConvolver->process( pfInputSamples, m_iBlocklength, pfOutputSamples, m_iBlocklength );
}
private:
......@@ -101,4 +98,4 @@ private:
DSMBCConvolver* m_pConvolver;
};
#endif // __VA_THIRDOCTAVEFILTERBANK_FIR__
#endif // IW_VA_THIRDOCTAVEFILTERBANK_FIR
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA Virtual Acoustics (VA)
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institutr Technische Akustik (ITA)
* VVVV AAA RWTH Aachen (http://www.akustik.rwth-aachen.de)
* VVVVVV AAA (c) Copyright Institute of Technical Acoustics (ITA), 2015-2017
* VVVV AAA RWTH Aachen University (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VAVariableDelayLine.h
*
* Zweck: Klasse für variable Verzögerungsglieder (variable delay-lines)
*
* Autor(en): Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
* --------------------------------------------------------------------------------------------
*/
//! $Id: VAVariableDelayLine.h 4303 2015-11-17 21:24:34Z stienen $
#ifndef __VA_VARIABLE_DELAY_LINE__
#define __VA_VARIABLE_DELAY_LINE__
#ifndef IW_VA_VARIABLE_DELAY_LINE
#define IW_VA_VARIABLE_DELAY_LINE
#include <ITAAtomicPrimitives.h>
#include <ITACriticalSection.h>
......@@ -359,4 +350,4 @@ private:
int m_iWindowSize;
};
#endif // __VA_VARIABLE_DELAY_LINE__
#endif // IW_VA_VARIABLE_DELAY_LINE
Supports Markdown
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