Commit 13feac68 authored by Jonas Stienen's avatar Jonas Stienen

Initial project checkin

parents
cmake_minimum_required( VERSION 2.8 )
project( ITAConvolution )
list( APPEND CMAKE_MODULE_PATH "$ENV{VISTA_CMAKE_COMMON}" )
include( VistaCommon )
# dependencies
vista_use_package( ITABASE REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITAFFT REQUIRED FIND_DEPENDENCIES )
vista_use_package( TBB REQUIRED )
# includes
include_directories( "include" )
# sources
set( ITAConvolutionHeader
include/DSMBCConvolver.h
include/DSMBCFilter.h
include/DSMBCFilterPool.h
include/DSMBCTrigger.h
include/ITAConvolution.h
include/ITAConvolutionDefinitions.h
)
set( ITAConvolutionSources
src/DSMBCConvolver.cpp
src/DSMBCFilter.cpp
src/DSMBCFilterPool.cpp
src/ITAConvolution.cpp
src/ITAConvolutionImpl.cpp
src/ITAConvolutionImpl.h
)
# compiler
add_definitions( -DITA_BASE_DLL -DITA_FFT_DLL -DITA_CONVOLUTION_DLL -DITA_CONVOLUTION_EXPORT )
# linker
add_library( ITAConvolution SHARED ${ITAConvolutionHeader} ${ITAConvolutionSources} )
target_link_libraries( ITAConvolution ${VISTA_USE_PACKAGE_LIBRARIES} )
# configure
vista_configure_lib( ITAConvolution )
vista_install( ITAConvolution )
set( ITACONVOLUTION_INCLUDE_OUTDIR "${CMAKE_CURRENT_SOURCE_DIR}/include" )
vista_create_cmake_configs( ITAConvolution )
vista_create_default_info_file( ITAConvolution )
set_property( TARGET ITAConvolution PROPERTY FOLDER "ITACoreLibs" )
# tests
set( ITACONVOLUTION_COMMON_BUILD TRUE )
add_subdirectory( "${CMAKE_CURRENT_SOURCE_DIR}/tests" )
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: DSMBCConvolver.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_DSMBC_CONVOLVER
#define INCLUDE_WATCHER_DSMBC_CONVOLVER
#include <ITAConvolutionDefinitions.h>
#include <ITACriticalSection.h>
#include <ITAUncopyable.h>
#include <vector>
#include <tbb/concurrent_queue.h>
#include <DSMBCTrigger.h>
#include <atomic>
// Vorwürtsdeklarationen
class DSMBCFilter;
class DSMBCFilterPool;
class ITAFFT;
/**
* Diese Klasse realisiert einen schnellen (einkanaligen) Falter (dynamic single-channel multi-block convolver),
* welcher die effiziente Overlap-Save Blockfaltung zusammen mit einer frequency-domain delay-line (FDL)
* benutzt um eine Impulsantwortet zu falten, welche in mehrere gleichlange Teile zerlegt wird.
* Dieser Ansatz ermüglicht eine wesentlich grüüere Leistung als ein einfacher Blockfaltungsansatz,
* bei welchem die komplette Impulsantwort mit einem Block gefaltet werden. Der Falter ist dynamisch,
* d.h. er erlaubt den Austausch der Filter zur Laufzeit bzw. Streamingzeit. Der Austausch der Filter
* geschieht entweder durch hartes Umschalten oder überblendung im Zeitbereich.
*
* Nebenlüufigkeit & Synchronisation:
*
* Folgende Methoden sind synchronisiert:
*
* - getFilterPool, setFilterPool, requestFilter, releaseFilter => Blocking aber leichtgewichtig, reentrant
* - getFilterExchangeMode, setFilterExchangeMode, getFilterCrossfadeLength, setFilterCrossfadeLength,
* getActiveFilter, exchangeFilter => Non-blocking und wait-free, reentrant
* - process => Non-blocking, wait-free aber NICHT REENTRANT (!!)
*
* Alle anderen Methoden sind nicht synchronisiert.
*
* Müchtest Du mehr zu den Details wissen? Frag mich! -> Frank.Wefers@akustik.rwth-aachen.de
*/
class ITA_CONVOLUTION_API DSMBCConvolver : public ITAUncopyable {
public:
//! Austausch-Modi
enum {
SWITCH = 0, //!< Hartes Umschalten
CROSSFADE_LINEAR, //!< Lineare Kreuzblende
CROSSFADE_COSINE_SQUARE //!< Cosinus-Quadrat Kreuzblende
};
//! Ausgabe-Modi
enum {
OUTPUT_OVERWRITE = 0, //!< Daten im Ausgabepuffer mit neuen Daten überschreiben
OUTPUT_MIX, //!< Neue Daten in den Ausgabepuffer einmischen
};
static const int AUTO=-1;
//! Standard-Konstruktor
/**
* Erzeugt einen Falter der seinen eigenen Filterpool betreibt
*/
DSMBCConvolver();
//! Initialierungs-Konstruktor
/**
* Erzeugt einen Falter.
*
* \param iBlocklength Blocklänge [in Samples]
* \param iMaxFilterlength Maximale Filterlänge [Anzahl Filterkoeffizienten]
*/
DSMBCConvolver(int iBlocklength, int iMaxFilterlength, DSMBCFilterPool* pFilterPool=NULL);
//! Destruktor
virtual ~DSMBCConvolver();
//! Initialisieren
/**
* Initialisiert einen Falter.
*
* \param iBlocklength Blocklänge [in Samples]
* \param iMaxFilterlength Maximale Filterlänge [Anzahl Filterkoeffizienten]
*/
void init(int iBlocklength, int iFilterLength);
//! Blocklänge zurückgeben
int getBlocklength() const;
//! Maximale Filterlänge [Anzahl Filterkoeffizienten] zurückgeben
int getMaxFilterlength() const;
//! Trigger für den Filteraustausch zurückgeben (NULL falls keiner zugeordnet)
const DSMBCTrigger* getFilterExchangeTrigger() const;
//! Trigger für den Filteraustausch setzen
void setFilterExchangeTrigger(const DSMBCTrigger* pTrigger);
//! Filteraustausch-Modus zurückgeben
int getFilterExchangeMode();
//! Filteraustausch-Modus setzen
void setFilterExchangeMode(int iMode);
//! überblendlänge [Samples] des Filteraustauschs zurückgeben
int getFilterCrossfadeLength();
//! überblendlänge [Samples] für den Filteraustausch setzen
void setFilterCrossfadeLength(int iLength);
//! Verstärkung zurückgeben
float getGain() const;
//! Verstärkung setzen
// Hinweis: Falls bSetImmediately==true gesetzt, wird die Verstärkung nicht
// dynamisch angepasst, sondern hart auf den angegebenen Wert gesetzt.
void setGain(float fGain, bool bSetImmediately=false);
//! Filterpool zurückgeben
DSMBCFilterPool* getFilterPool() const;
//! Filterpool setzen
/**
* NULL => Falter-eigenen Pool benutzen
*/
void setFilterPool(DSMBCFilterPool* pFilterPool);
//! Freies Filter anfordern
DSMBCFilter* requestFilter();
//! Filter wieder zur anderweitigen Benutzung freigeben
void releaseFilter(DSMBCFilter* pFilter);
//! Aktives Filter zurückgeben
/**
* Das aktive Filter ist jenes, welches der Falter momentan benutzt.
*/
DSMBCFilter* getActiveFilter();
//! Filter austauschen
/**
* Hinweis: Nullzeiger => Aktives Filter entfernen
*/
void exchangeFilter(DSMBCFilter* pNewFilter, int iExchangeMode=AUTO, int iCrossfadeLength=AUTO);
//! Löscht alle internen Samplepuffer
void clear();
//! Faltungsmethode
/**
* Nimmt einen neuen Block Eingangsdaten entgegen und faltet ihn mit der Impulsantwortet.
* Das (partielle) Ausgangssignal wird als Block im Zielarray gespeichert.
*
* \param pfInputData Array der Eingangsdaten (Exakt soviele Elemente wie die Blocklänge ist)
* \param pfOutputData Array der Ausgangsdaten (Exakt soviele Elemente wie die Blocklänge ist)
* \param iOutputMode Ausgabemodus (überschreiben oder Einmischen)
*/
// TODO: Hier wird Austausch durchgeführt!
void process(const float* pfInputData,
float* pfOutputData,
int iOutputMode=OUTPUT_OVERWRITE);
//! Faltungsmethode (Erweitert)
/**
* Nimmt einen neuen Block Eingangsdaten entgegen und faltet ihn mit der Impulsantwortet.
* Das (partielle) Ausgangssignal wird als Block im Zielarray gespeichert.
*
* \param pfInputData Array der Eingangsdaten
* \param iInputLength Anzahl der Samples in den Eingangsdaten
* \param pfOutputData Array der Ausgangsdaten (Exakt soviele Elemente wie die Blocklänge ist)
* \param iOutputLength Anzahl der Samples in den Ausgabedaten
* \param iOutputMode Ausgabemodus (überschreiben oder Einmischen)
*/
// TODO: Hier wird Austausch durchgeführt!
void process(const float* pfInputData,
int iInputLength,
float* pfOutputData,
int iOutputLength,
int iOutputMode=OUTPUT_OVERWRITE);
private:
typedef struct {
DSMBCFilter* pFilter;
int iExchangeMode;
int iCrossfadeLength;
} FilterUpdate;
int m_iBlocklength;
int m_iMaxFilterlength;
std::atomic< int > m_iExchangeMode; // Austauschmodus
std::atomic< int > m_iCrossfadeLength; // überblendlänge
std::atomic< float > m_fCurrentGain; // Aktuelle Verstärkung
std::atomic< float > m_fNewGain; // Gewünschte Verstärkung
std::atomic< DSMBCFilter* > m_pCurrentFilter; // Aktives Filter
tbb::strict_ppl::concurrent_queue<FilterUpdate> m_qExchangeFilters; // Queue: Nächste Filter zum Austausch
float *m_pfTimeInputBuffer; // Eingangspuffer (Zeitbereich)
float *m_pfTimeOutputBuffer1; // Ausgangspuffer (Zeitbereich)
float *m_pfTimeOutputBuffer2; // Ausgangspuffer (Zeitbereich)
float *m_pfFreqAuxBuffer; // Hilfspuffer (Frequenz-bereich)
float *m_pfFreqMixdownBuffer; // Mischpuffer (Frequenz-bereich)
int m_iFreqCoeffs; // Anzahl DFT-Koeffizienten (Symetrien eingerechnet)
std::vector<float*> m_vpfFreqDelayLine; // Frequency-domain delay line (FDL)
ITAFFT *m_pFFT, *m_pIFFT; // FFT, IFFT der Daten
ITACriticalSection m_csPool; // Exklusiver Zugriff auf den Filterpool
DSMBCFilterPool* m_pCurrentPool; // Gesetzer Filterpool
DSMBCFilterPool* m_pOwnPool; // Falter-eigener Filterpool
DSMBCTriggerWatch m_oTriggerWatch; // TriggerWatch für den Filteraustausch
void copyOutputApplyGain1(float* pfDest, const float* pfSrc, int iNumSamples, int iOutputMode);
void copyOutputApplyGain2(float* pfDest, const float* pfSrc1, const float* pfSrc2, int iOutputLength, int iCrossfadeLength, int iOutputMode);
};
#endif // INCLUDE_WATCHER_DSMBC_CONVOLVER
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: DSMBCFilter.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_DSMBC_FILTER
#define INCLUDE_WATCHER_DSMBC_FILTER
#include <ITAConvolutionDefinitions.h>
#include <ITACriticalSection.h>
#include <ITATypes.h>
#include <ITAUncopyable.h>
#include <atomic>
#include <vector>
// Vorwärtsdeklarationen
class DSMBCFilterPool;
class ITAFFT;
/**
* Diese Klasse realisiert Filter (d.h. Representationen von Impulsantworten im Frequenzbereich)
* für DSMBCConvolver. Solche Filter haben einen Zustand: 1) unbenutzt oder 2) momentan in einem
* Falter in Benutzung. Generell kann 1 Filter in beliebig vielen Faltern verwendet werden.
* Seine Daten dürfen aber nur modifiziert werden, wenn es nicht in Benutzung ist.
*
* Eine neue Impulsantwort wird mittels der Methode load geladen und intern transformiert.
*
* Nebenläufigkeit & Synchronisation:
*
* Instanzen der Klasse sollen nur von einem Thread zu einer Zeit benutzt werden
* (üblicherweise der Thread der die Filterdaten generiert hat). Im Sinne der Anwendung
* macht es keinen Sinn das mehrere Threads um beispielsweise die load-Methode konkurrieren.
* Deshalb unternimmt die Klasse keine Maßnahmen zur Synchronisation.
*/
class ITA_CONVOLUTION_API DSMBCFilter : public ITAUncopyable {
public:
//! Konstruktor
DSMBCFilter(int iBlocklength, int iMaxFilterLength);
//! Destruktor
/**
* Hinweis: Das Objekt kann nur freigegeben werden, wenn es nicht mehr benutzt wird!
*/
virtual ~DSMBCFilter();
//! Gibt zurück ob der Filter aktuell in Benutzung ist
bool isInUse() const;
//! übergeordneten Filterpool zurückgeben (falls nicht vorhanden NULL)
DSMBCFilterPool* getParentFilterPool() const;
//! Filter übergeordneten Filterpool freigeben (falls Teil eines Filterpools)
void release();
//! Filterdaten laden
/**
* \param pfFilterData Array mit den Filterkoeffizienten
* \param iFilterLength Anzahl Filterkoeffizienten in pfFilterData (maximal iMaxFilterLength)
*
* \note Falls das Filter in Benutzung ist wird eine ITAException geworfen!
*/
void load(const float* pfFilterData, int iFilterLength);
//! Nullen setzen
void zeros();
//! Einheitsimpuls (Dirac) setzen
void identity();
//private:
// Interne Zustandklasse, welche Referenzzähler enthält.
// Es werden immer zwei Zähler benötigt: Prep und Use.
class State {
public:
State(DSMBCFilter* pParent);
bool isInUse() const;
void addPrep();
void removePrep();
void xchangePrep2Use();
void removeUse();
//private:
// Damit auf älteren Windows-System, welche keine DCAS-Operationen bereistellen,
// dieser zwei-elementige Zustand atomar verändert werden kann,
// muss eine Datenstruktur von 32-Bit realisiert werden.
// 16-Bit für die Zähler ist immer noch ausreichend
typedef struct
{
std::atomic< int16_t > iPrepRefCount;
std::atomic< int16_t > iUseRefCount;
} StateStruct;
DSMBCFilter* m_pParent;
StateStruct m_oState;
void modifyState(int16_t iPrepDelta, int16_t iUseDelta);
};
DSMBCFilterPool* m_pParent; // Übergeordneter Filterpool
int m_iBlocklength; // Blocklänge (Zeitbereich)
int m_iNumFilterParts; // Anzahl Filterteile
int m_iNumEffectiveFilterParts; // Anzahl effektiver Filterteile mit Filterkoeff. != 0
std::vector<float*> m_vpfFreqData; // Filterdaten im Frequenzbereich (DFT-Spektren der Teile)
ITAFFT* m_pFFT;
ITACriticalSection m_csReentrance; // Reentrance-Lock für die Load-Methode
State m_oState; // Zustand
friend class DSMBCConvolver;
friend class DSMBCFilterPool;
};
#endif // INCLUDE_WATCHER_DSMBC_FILTER
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: DSMBCFilterPool.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_DSMBC_FILTER_POOL
#define INCLUDE_WATCHER_DSMBC_FILTER_POOL
#include <ITAConvolutionDefinitions.h>
#include <ITACriticalSection.h>
#include <ITAFFT.h>
#include <list>
// Vorwärtsdeklarationen
class DSMBCFilter;
/**
* Diese Klasse realisiert eine Verwalter für Filterobjekte und
* ermöglicht ein effizientes Filter-Management mit geringem Speicherverbrauch,
* durch die automatische Wiederverwendung von Filtern.
*
* Nebenläufigkeit & Synchronisation:
*
* Instanzen der Klasse können von beliebig vielen Threads gleichzeitig benutzt werden.
* Alle Methoden mittels synchronisiert und dürfen auch mehrfach parallel aufgerufen
* werden (reentrant). Die Synchronisation ist blocking, aber die Wartezeiten sind
* gering, da innerhalb des exklusiven Zugriffs nur kurze Operationen durchgeführt werden.
*
*/
class ITA_CONVOLUTION_API DSMBCFilterPool
{
public:
//! Konstruktor
DSMBCFilterPool(int iBlocklength, int iMaxFilterLength, int iInitialSize);
//! Destruktor
/**
* Hinweis: Das Objekt kann nur freigegeben werden, wenn es nicht mehr benutzt wird!
*/
virtual ~DSMBCFilterPool();
//! Blocklänge zurückgeben
int getBlocklength() const;
//! Maximale Filterlänge [Anzahl Filterkoeffizienten] zurückgeben
int getMaxFilterlength() const;
//! Anzahl freier Filter zurückgeben
int getNumFreeFilters() const;
//! Anzahl freier Filter zurückgeben
int getNumUsedFilters() const;
//! Anzahl freier Filter zurückgeben
int getNumTotalFilters() const;
//! Freies Filter anfordern
DSMBCFilter* requestFilter();
//! Filter wieder zur anderweitigen Benutzung freigeben
/**
* Ist das Filter nicht in Benutzung, so kann es sofort weiterbenutzt werden.
* Ist das Filter in Benutzung, so wird es für die Weiterbenutzung freigebenen,
* sobald es in einem Falter (DSMBCConvolver) nicht mehr in Benutzung ist
*/
void releaseFilter(DSMBCFilter* pFilter);
private:
int m_iBlocklength;
int m_iMaxFilterLength;
std::list<DSMBCFilter*> m_lpFreeFilters; // Unbenutzte (freie) Filter im Pool
std::list<DSMBCFilter*> m_lpUsedFilters; // Benutzte Filter im Pool
std::list<DSMBCFilter*> m_lpAutoFilters; // Filter welche nicht mehr seitens den Benutzers
// gebraucht werden, aber noch in einem Falter benutzt werden
ITACriticalSection m_csFilters; // Exklusiver Zugriff auf die Listen
};
#endif // INCLUDE_WATCHER_DSMBC_FILTER_POOL
\ No newline at end of file
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: ITAConvolution.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_DSMBC_TRIGGER
#define INCLUDE_WATCHER_DSMBC_TRIGGER
#include <ITAConvolutionDefinitions.h>
#include <ITAUncopyable.h>
// Lightweight atomic trigger for synchronized filter exchanges
class ITA_CONVOLUTION_API DSMBCTrigger : public ITAUncopyable
{
public:
DSMBCTrigger() : m_iState(0) {};
// Returns the current state
int getState() const { return m_iState; };
// Pull the trigger. Update/alter the state.
void trigger() { ++m_iState; };
private:
volatile int m_iState;
};
// Simple watcher class, realization update checks on a trigger
class ITA_CONVOLUTION_API DSMBCTriggerWatch
{
public:
DSMBCTriggerWatch() : m_pTrigger(0), bFirst(true), m_iPrevTriggerState(0) {};
const DSMBCTrigger* getWatchedTrigger() const { return m_pTrigger; };
void setWatchedTrigger(const DSMBCTrigger* pNewTrigger) {
m_pTrigger = pNewTrigger;
bFirst = true;
};
// Logic: We always fire, if there is no trigger associated. This is needed in the convolver.
bool fire() {
if (!m_pTrigger) return true;
int iNewTriggerState = m_pTrigger->getState();
if ((iNewTriggerState != m_iPrevTriggerState) || bFirst) {
m_iPrevTriggerState = iNewTriggerState;
bFirst = false;
return true;
}
return false;
};
private:
const DSMBCTrigger* m_pTrigger;
bool bFirst;
int m_iPrevTriggerState;
};
#endif // INCLUDE_WATCHER_DSMBC_TRIGGER
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: ITAConvolution.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_ITA_CONVOLUTION
#define INCLUDE_WATCHER_ITA_CONVOLUTION
#include <ITAConvolutionDefinitions.h>
#include <ITASampleBuffer.h>
#include <ITASampleFrame.h>
#include <ITAUncopyable.h>
// Vorwärtsdeklarationen
class ITAConvolutionImpl;
/**
* Diese Klasse definiert die Schnittstelle für schnelle (offline) Faltungen.
* Die Funktionalität besteht darin zwei Signale möglichst schnell und effizient
* miteinander zu falten. Die Eingaben und Ausgaben werden im Zeitbereich übergeben.
* Instanzen der Klasse repräsentieren Faltungen eines bestimmten Typs
* (bestimmte Eingabeparameter). Damit die maximale Leistung erreicht werden kann,
* müssen vorher die Faltungsoperationen geplant werden.
*/
class ITA_CONVOLUTION_API ITAConvolution : public ITAUncopyable
{
public:
// TODO: Flags static const int
static const int DEFAULT_FLAGS = 0;
//! Standardkonstruktor
ITAConvolution();
//! Initialisierungskonstruktor (Arrays)
ITAConvolution(int src1length,
int src2length,
int flags=DEFAULT_FLAGS);
//! Destruktor
virtual ~ITAConvolution();
//! Planungsmethode (Arrays)
void plan(int src1length,
int src2length,
int flags=DEFAULT_FLAGS);
//! Gibt zurück ob die Faltung schon geplant ist
bool isPlanned() const;
//! Faltungsmethode (Arrays)
virtual void convolve(const float* src1,
int src1length,
const float* src2,
int src2length,
float* dest,
int destlength);
private:
ITAConvolutionImpl* m_pImpl;
};
#endif // INCLUDE_WATCHER_ITA_CONVOLUTION
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: ITAConvolutionDefinitions.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_ITA_CONVOLUTION_DEFINITIONS
#define INCLUDE_WATCHER_ITA_CONVOLUTION_DEFINITIONS
#ifdef ITA_CONVOLUTION_DLL
#ifdef ITA_CONVOLUTION_EXPORT
#define ITA_CONVOLUTION_API __declspec(dllexport)
#else
#define ITA_CONVOLUTION_API __declspec(dllimport)
#endif
#else
#define ITA_CONVOLUTION_API
#endif
#endif // INCLUDE_WATCHER_ITA_CONVOLUTION_DEFINITIONS
This diff is collapsed.
#include <DSMBCFilter.h>
#include <DSMBCFilterPool.h>
#include <ITAException.h>
#include <ITAFFT.h>
#include <ITANumericUtils.h>
#include <ITAFastMath.h>
#include <algorithm>
#include <cassert>
#include <cstring>
// Leistungssparende Variante: Testen ob Filterkoeffizienten = 0 und nur effektive Teile falten.
#define WITH_POWER_SAVER 1
DSMBCFilter::DSMBCFilter(int iBlocklength, int iMaxFilterLength)
: m_iBlocklength(iBlocklength)
, m_pParent(NULL)
, m_pFFT(NULL)
, m_iNumEffectiveFilterParts(0)
, m_oState(this)
{
m_iNumFilterParts = uprdiv(iMaxFilterLength, iBlocklength);
int iFreqCoeffs = iBlocklength+1;
// Anzahl Filterteile bestimmen
m_vpfFreqData.resize(m_iNumFilterParts, NULL);
// Datenpuffer allozieren
for (int i=0; i<m_iNumFilterParts; i++)
m_vpfFreqData[i] = fm_falloc(2*iFreqCoeffs, true);
// FFT initial planen
m_pFFT = new ITAFFT(ITAFFT::FFT_R2C, 2*iBlocklength, m_vpfFreqData[0], m_vpfFreqData[0]);
}
DSMBCFilter::~DSMBCFilter() {
// Datenpuffer freigeben
std::for_each(m_vpfFreqData.begin(), m_vpfFreqData.end(), fm_free);
delete m_pFFT;
}