Commit c78b1c8b authored by Jonas Stienen's avatar Jonas Stienen

Adding SimpleConvolution (used by Raven VA module)

parent 234a4292
......@@ -67,6 +67,7 @@ set( ITABaseHeader
"include/ITASampleBuffer.h"
"include/ITASampleFrame.h"
"include/ITASampleTypeConversion.h"
"include/ITASimpleConvolution.h"
"include/ITAStopWatch.h"
"include/ITAStringUtils.h"
"include/ITATimer.h"
......@@ -99,6 +100,7 @@ set( ITABaseSources
"src/ITASampleBuffer.cpp"
"src/ITASampleFrame.cpp"
"src/ITASampleTypeConversion.cpp"
"src/ITASimpleConvolution.cpp"
"src/ITAStopWatch.cpp"
"src/ITATimer.cpp"
"src/ITAWinPCClock.cpp"
......
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_SIMPLE_CONVOLUTION
#define INCLUDE_WATCHER_ITA_SIMPLE_CONVOLUTION
#include <ITABaseDefinitions.h>
//! Diskrete Faltung im Zeitbereich durchfhren
/**
* Diese Funktion fhrt die diskrete Faltung zweier Signale A und B im
* Zeitbereich durch. Diese Operation hat eine Laufzeitkomplexitt von
* O(M*N) und ist nur effizient fr Signale geringer Lnge. (Fr lngere
* Signale sollen Blockfaltungsverfahren benutzt werden).
*
* Semantik: C(n) = sum( A(k)B(n-k), k=-inf..+inf )
*
* \param A Eingangssignal 1
* \param M Anzahl Felder im Eingangssignal 1
* \param B Eingangssignal 2
* \param N Anzahl Felder im Eingangssignal 2
* \param C Ausgangssignal
* \param K Anzahl Felder im Ausgangssignal
*
* Hinweis: Das vollstndige Ausgangssignal hat eine Lnge von M+N-1 Feldern.
* Trotzdem darf die Anzahl Felder im Ausgangssignal geringer sein.
* In diesem Falle wird das Faltungsergebnis gekrzt.
*/
void ITA_BASE_API conv( const float *A, int M, const float *B, int N, float* C, int K );
void ITA_BASE_API conv( const double *A, int M, const double *B, int N, double* C, int K );
#endif // INCLUDE_WATCHER_ITA_SIMPLE_CONVOLUTION
#include <ITASimpleConvolution.h>
#include <algorithm>
void conv(const float *A, int M, const float *B, int N, float* C, int K) {
// TODO: Mehr Geschwindigkeit durch Vektorisierung?!
/*
* Annahme: Impulsantwort i.A. k�rzer als Signal. Deshalb soll diese
* bevorzugt im Cache gehalten werden. Daher soll die innere
* Schleife �ber die Impulsantwort iterieren. Da die Faltung
* assoziativ ist, wird hier gegenenfalles die Reihenfolge
* der Operanden vertauscht, um diese Bedingungen zu erf�llen.
*/
const float* X;
const float* Y;
int nx, ny;
if (M >= N) {
X = A;
nx = M;
Y = B;
ny = N;
} else {
X = B;
nx = N;
Y = A;
ny = M;
}
// �u�ere Schleife �ber die Ausgangssamples
for (int n=0; n<std::min(nx+ny-1, K); n++) {
C[n] = 0;
// Inner Schleife �ber die Filterkoeffizienten der Impulsantwort
for (int k=std::max(0, n+1-ny); k<std::min(nx, n+1); k++)
C[n] += X[k]*Y[n-k];
}
}
void conv(const double *A, int M, const double *B, int N, double* C, int K) {
// TODO: Mehr Geschwindigkeit durch Vektorisierung?!
/*
* Annahme: Impulsantwort i.A. k�rzer als Signal. Deshalb soll diese
* bevorzugt im Cache gehalten werden. Daher soll die innere
* Schleife �ber die Impulsantwort iterieren. Da die Faltung
* assoziativ ist, wird hier gegenenfalles die Reihenfolge
* der Operanden vertauscht, um diese Bedingungen zu erf�llen.
*/
const double* X;
const double* Y;
int nx, ny;
if (M >= N) {
X = A;
nx = M;
Y = B;
ny = N;
} else {
X = B;
nx = N;
Y = A;
ny = M;
}
// �u�ere Schleife �ber die Ausgangssamples
for (int n=0; n<std::min(nx+ny-1, K); n++) {
C[n] = 0;
// Inner Schleife �ber die Filterkoeffizienten der Impulsantwort
for (int k=std::max(0, n+1-ny); k<std::min(nx, n+1); k++)
C[n] += X[k]*Y[n-k];
}
}
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