Commits (27)
......@@ -8,10 +8,17 @@ include( VistaCommon )
# dependencies
vista_use_package( VistaCoreLibs REQUIRED COMPONENTS VistaBase VistaInterProcComm VistaTools FIND_DEPENDENCIES )
vista_use_package( sndfile )
vista_use_package( samplerate )
vista_use_package( IPP QUIET )
vista_use_package( PCRE QUIET )
vista_use_package( SimpleIni QUIET )
vista_use_package( SPLINE QUIET )
vista_use_package( SPLINE REQUIRED )
if ( NOT WIN32 )
vista_use_package ( Threads REQUIRED )
list ( APPEND VISTA_USE_PACKAGE_LIBRARIES pthread )
endif ()
if( NOT DEFINED ITA_BASE_WITH_FASTMATH_IPP )
set( ITA_BASE_WITH_FASTMATH_IPP OFF CACHE BOOL "Build with IPP implementation of fast math ops" )
......@@ -25,6 +32,10 @@ if( NOT DEFINED ITA_BASE_WITH_SNDFILE )
set( ITA_BASE_WITH_SNDFILE ON CACHE BOOL "Build with libsndfile to read/write audio samples for ITASampleFrame" )
endif( )
if( NOT DEFINED ITA_BASE_WITH_SAMPLERATE )
set( ITA_BASE_WITH_SAMPLERATE ON CACHE BOOL "Build with libsamplerate to auto-convert between samplerates" )
endif( )
if( NOT DEFINED ITA_BASE_WITH_OLD_ATOMICS )
set( ITA_BASE_WITH_OLD_ATOMICS OFF CACHE BOOL "Build with old atomic code for non-C++11 compatible compilers" )
endif( )
......@@ -49,6 +60,7 @@ include_directories( "include" )
# files
set( ITABaseHeader
"include/ITAASCIITable.h"
"include/ITAAudioSample.h"
"include/ITABaseDefinitions.h"
"include/ITABlockMath.h"
"include/ITABufferedAudioFileWriter.h"
......@@ -62,12 +74,14 @@ set( ITABaseHeader
"include/ITAFade.h"
"include/ITAFastMath.h"
"include/ITAFileSystemUtils.h"
"include/ITAFiniteImpulseResponse.h"
"include/ITAHDFTSpectra.h"
"include/ITAHDFTSpectrum.h"
"include/ITAFunctors.h"
"include/ITAInterpolation.h"
"include/ITALog.h"
"include/ITAMagnitudeSpectrum.h"
"include/ITAMultichannelFiniteImpulseResponse.h"
"include/ITANumericUtils.h"
"include/ITASampleBuffer.h"
"include/ITASampleFrame.h"
......@@ -97,11 +111,13 @@ set( ITABaseSources
"src/ITAException.cpp"
"src/ITAFade.cpp"
"src/ITAFileSystemUtils.cpp"
"src/ITAFiniteImpulseResponse.cpp"
"src/ITAHDFTSpectra.cpp"
"src/ITAHDFTSpectrum.cpp"
"src/ITAInterpolation.cpp"
"src/ITALog.cpp"
"src/ITAMagnitudeSpectrum.cpp"
"src/ITAMultichannelFiniteImpulseResponse.cpp"
"src/ITANumericUtils.cpp"
"src/ITASampleBuffer.cpp"
"src/ITASampleFrame.cpp"
......@@ -140,6 +156,11 @@ if( VSNDFILE_FOUND AND ITA_BASE_WITH_SNDFILE )
add_definitions( -DITABASE_WITH_SNDFILE )
endif( )
if( VSAMPLERATE_FOUND AND ITA_BASE_WITH_SAMPLERATE )
set( ITABaseHeader "${ITABaseHeader}" "include/ITAAudioSample.h" )
set( ITABaseSources "${ITABaseSources}" "src/ITAAudioSample.cpp" )
endif( )
if( VIPP_FOUND AND ITA_BASE_WITH_FASTMATH_IPP )
set( ITABaseSources "${ITABaseSources}" "src/ITAFastMathImplIPP.cpp" )
elseif( ITA_BASE_WITH_FASTMATH_ASSEMBLER )
......
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_AUDIO_SAMPLE
#define INCLUDE_WATCHER_ITA_AUDIO_SAMPLE
// ITABase
#include <ITABaseDefinitions.h>
#include <ITASampleFrame.h>
#include <string>
//! Multi-channel audio sample with floating point quantization
/**
* ITASampleFrame with a sampling rate. Also converts from other sampling rates.
*/
class ITA_BASE_API CITAAudioSample : public ITASampleFrame
{
public:
//! Create empty audio sample
/**
* Requires initialization or load to be used, otherwise methods will throw ITAException.
*/
CITAAudioSample( const float fSampleRate = 44100.0f );
//! Create audio sample from file
/**
* Requires initialization or load to be used, otherwise methods will throw ITAException.
*/
CITAAudioSample( const std::string& sFilePath );
//! Create (empty) audio sample with given parameters
/**
* @param[in] iNumChannels Number of channels
* @param[in] iLengthSamples Number of new samples
* @param[in] fSampleRate Sampling rate of audio sample
* @param[in] bZeroInit Init with zeros
*/
explicit CITAAudioSample( const int iChannels, const int iLength, const float fSampleRate, const bool bZeroInit = true );
//! Copy constructor as pointer
/**
* \param pSource Pointer to source audio sample
*/
CITAAudioSample( const CITAAudioSample* pSource );
//! Copy constructor as reference
/**
* \param pbSource Reference to source audio sample
*/
CITAAudioSample( const CITAAudioSample& sbSource );
virtual inline ~CITAAudioSample() {};
//! Sampling frequency of audio sample
float GetSampleRate() const;
//! Initialize
/**
* (Re-)Initialize an audio sample
*
* @param[in] iNumChannels Number of channels
* @param[in] iLengthSamples Number of new samples
* @param[in] fSampleRate Sampling rate of audio sample
* @param[in] bZeroInit Init with zeros
*/
void Init( const int iNumChannels, const int iLengthSamples, const float fSampleRate, const bool bZeroInit = true );
//! Read from sample buffer with sample rate conversion
void Load( const ITASampleFrame& sfSource, const float fSourceSampleRate );
//! Read from other audio sample with sample rate conversion
void Load( const CITAAudioSample& oSource );
//! Load audio sample from file and inherit it's sample rate
void Load( const std::string& sFilePath );
//! Load audio sample from file and convert sample rate, if necessary
void LoadWithSampleRateConversion( const std::string& sFilePath );
//! Load audio sample from file and convert sample rate, if necessary
void LoadWithSampleRateConversion( const CITAAudioSample& asSource );
private:
//! Disable this Init method from sample buffer
void Init( int, int, bool );
//! Disable load without sample rate
void Load( const std::string&, const double& );
float m_fSampleRate; //!< Sampling rate
};
#endif // INCLUDE_WATCHER_ITA_AUDIO_SAMPLE
......@@ -47,7 +47,7 @@ public:
LAST,
};
ITAException( int uiErrorcode = UNKNOWN, std::string sModule = "", std::string sReason = "");
ITAException( int uiErrorcode = UNKNOWN, std::string sModule = "", std::string sReason = "" );
inline virtual ~ITAException() {};
std::string ToString() const;
......@@ -60,8 +60,9 @@ public:
// Helper macros
#define ITA_EXCEPT0( TYPE ) throw ITAException( ITAException::TYPE, __FUNCTION__ );
#define ITA_EXCEPT1( TYPE, REASON ) throw ITAException( ITAException::TYPE, __FUNCTION__, REASON );
#define ITA_EXCEPT_INVALID_PARAMETER( REASON ) throw ITAException( ITAException::INVALID_PARAMETER, __FUNCTION__, REASON );
//! STL stream output operator
ITA_BASE_API std::ostream& operator<<(std::ostream& os, const ITAException& ex);
ITA_BASE_API std::ostream& operator<<( std::ostream& os, const ITAException& ex );
#endif
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_FINITE_IMPULSE_RESPONSE
#define INCLUDE_WATCHER_ITA_FINITE_IMPULSE_RESPONSE
// ITABase
#include <ITABaseDefinitions.h>
#include <ITASampleBuffer.h>
#include <string>
//! Single channel finite impulse response class / FIR filter
/**
* ITASampleBuffer with a sampling rate = finite impulse response.
* For multi channel FIR filter, @sa ITAMultichannelFiniteImpulseResponse
*/
class ITA_BASE_API CITAFiniteImpulseResponse : public ITASampleBuffer
{
public:
//! Create empty FIR filter
/**
* Requires initialization to be used, otherwise methods will throw ITAException.
*/
CITAFiniteImpulseResponse();
//! Create FIR filter of certain size with given sampling frequency
/**
* \param iLength Length (size) of buffer in samples
*/
explicit CITAFiniteImpulseResponse( const int iLength, const float fSampleRate, const bool bZeroInit = true );
//! Copy constructor as pointer
/**
* \param pSource Pointer to source buffer
*/
CITAFiniteImpulseResponse( const CITAFiniteImpulseResponse* pSource );
//! Copy constructor as reference
/**
* \param pbSource Reference to source buffer
*/
CITAFiniteImpulseResponse( const CITAFiniteImpulseResponse& sbSource );
virtual inline ~CITAFiniteImpulseResponse() {};
//! Sampling frequency of FIR filter (double of Nyquist frequency)
float GetSampleRate() const;
//! Nyquist frequency of FIR filter (half of sample rate)
float GetNyquistFrequency() const;
//! Initialize
/**
* (Re-)Initialize a sample buffer
*
* @param[in] iLength Number of new samples
* @param[in] fSampleRate Sampling rate of FIR filter (double of Nyquist frequency)
* @param[in] bZeroInit Init with zeros
*/
void Init( const int iLength, const float fSampleRate, const bool bZeroInit = true );
private:
//! Disable this Init method from sample buffer
void Init( int, bool );
float m_fSampleRate; //!< Sampling rate
};
#endif // INCLUDE_WATCHER_ITA_FINITE_IMPULSE_RESPONSE
......@@ -42,7 +42,7 @@ class ITA_BASE_API ITAHDFTSpectra
public:
//! Constructor that initializes the
ITAHDFTSpectra( const double dSampleRate, const int iNumChannels, const int iDFTSize, const bool bZeroInit=true );
ITAHDFTSpectra( const float fSampleRate, const int iNumChannels, const int iDFTSize, const bool bZeroInit=true );
//! Constructor that uses a non-empty HDFTSpectrum vector
ITAHDFTSpectra( const std::vector< ITAHDFTSpectrum* >& vpSpectrumVec );
......
......@@ -21,17 +21,19 @@
#include <ITABaseDefinitions.h>
#include <ccomplex>
#include <string>
#include <vector>
/**
* Diese Klasse realisiert half-size DFT-Spektren. Dies sind die DFT-Spektren
* rein reellwertiger Signale, wie sie in der Akustik/Audiosignalverarbeitung
* blich sind. Das DFT-Spektrum solcher Signale erfllt die Hermitische Symetrie.
* Daher mssen von n komplexwertigen diskreten Fourierkoeffizienten eines
* vollstndigen DFT-Spektrums nur n/2+1 komplexwertigen Koeffizienten
* vollstndigen DFT-Spektrums nur n/2+1 komplexwertigen Koeffizienten
* gespeichert werden.
*
* Grundstzlich werden die komplexwertigen Fourierkoeffizienten im
* Grundstzlich werden die komplexwertigen Fourierkoeffizienten im
* interleaved Speicherlayout abgelegt, d.h. Re(0), Im(0), Re(1), Im(1), ...
*
* Die Klasse stellt Methoden fr die Arbeit mit solchen Spektren bereit.
......@@ -43,46 +45,37 @@ class ITA_BASE_API ITAHDFTSpectrum
public:
//! Standard-Konstruktor
ITAHDFTSpectrum();
//! Konstruktor
/**
* Erzeugt ein Spektrum mit vorgegebener Gre und optional zu Null gesetztem Puffer
*
* \param iDFTSize DFT-Spektrum-Gre
* \param bZeroinit Setzt den Speicher bei wahr auf Null
*/
explicit ITAHDFTSpectrum(int iDFTSize, bool bZeroinit=true);
//! Constructor
/**
* Erzeugt ein Spektrum mit vorgegebener Gre und optional zu Null gesetztem Puffer
*
* \param dSampleRate Sampling rate
*
* \param fSampleRate Sampling rate
* \param iDFTSize DFT-Spektrum-Gre
* \param bZeroInit Setzt den Speicher bei wahr auf Null
*/
explicit ITAHDFTSpectrum(double dSampleRate, int iDFTSize, bool bZeroInit);
explicit ITAHDFTSpectrum( const float fSampleRate, const int iDFTSize, const bool bZeroInit );
//! Kopierkonstruktor (Zeiger)
/**
* Erzeugt einen unabhngiges Spektrum als Kopie des gegebenen Spektrums.
* Erzeugt einen unabhngiges Spektrum als Kopie des gegebenen Spektrums.
* Das neue Spektrum hat die selbe Lnge und enthlt die gleichen Werte
* wie das Quellspektrum.
*
* \param pSource Zeiger auf das Quellspektrum
*/
explicit ITAHDFTSpectrum(const ITAHDFTSpectrum* pSource);
explicit ITAHDFTSpectrum( const ITAHDFTSpectrum* pSource );
//! Kopierkonstruktor (Referenz)
/**
* Erzeugt einen unabhngiges Spektrum als Kopie des gegebenen Spektrums.
* Erzeugt einen unabhngiges Spektrum als Kopie des gegebenen Spektrums.
* Das neue Spektrum hat die selbe Lnge und enthlt die gleichen Werte
* wie das Quellspektrum.
*
* \param oSource Zeiger auf das Quellspektrum
*/
explicit ITAHDFTSpectrum(const ITAHDFTSpectrum& oSource);
explicit ITAHDFTSpectrum( const ITAHDFTSpectrum& oSource );
//! Destruktor
virtual ~ITAHDFTSpectrum();
......@@ -91,113 +84,116 @@ public:
* init(0) gibt belegten Speicher frei
* vorherige Werte werden grundstzlich verworfen!
*/
ITAHDFTSpectrum& init(int iDFTSize, bool bZeroinit=true);
void Init( const int iDFTSize, const bool bZeroinit = true );
// Gre des Spektrums (Anzahl Koeffizienten insgesamt) zurckgeben
// Hinweis: Symmetrische Koeffizienten werden hier nicht mitgezhlt.
int getSize() const;
int GetSize() const;
// Lnge des korrespondieren Zeitsignals zurckgeben (Gre der DFT)
int getDFTSize() const;
int GetDFTSize() const;
// Abtastrate des korrespondieren Zeitsignals zurckgeben
double getSamplerate() const;
float GetSampleRate() const;
// Abtastrate des korrespondieren Zeitsignals setzen
void setSamplerate(double dSamplerate);
void SetSampleRate( const float fSampleRate );
// Frequenzauflsung des Spektrums [Hz] zurckgeben
double getFrequencyResolution() const;
float GetFrequencyResolution() const;
// Datenzeiger abrufen
float* data() const;
float* GetData() const;
// DFT Koeffizient(en) setzen (Real-/Imaginrteil bzw. Betrag/Phase)
void setCoeffRI(int iIndex, float fReal, float fImag=0);
void setCoeffsRI(float fReal, float fImag=0);
void setCoeffsRI(int iOffset, int iCount, float fReal, float fImag=0);
void SetCoeffRI( const int iIndex, const float fReal, const float fImag = 0 );
void SetCoeffsRI( const float fReal, const float fImag = 0 );
void SetCoeffsRI( const int iOffset, const int iCount, const float fReal, const float fImag = 0 );
//! Set coefficient by index
void SetCoeff( const int iIndex, std::complex< float >& cfCoeff );
void setCoeffMP(int iIndex, float fMagnitude, float fPhase);
void setCoeffsMP(float fMagnitude, float fPhase);
void setCoeffsMP(int iOffset, int iCount, float fMagnitude, float fPhase);
void SetCoeffMP( const int iIndex, const float fMagnitude, const float fPhase );
void SetCoeffsMP( const float fMagnitude, const float fPhase );
void SetCoeffsMP( const int iOffset, const int iCount, const float fMagnitude, const float fPhase );
//! Betragswert setzen, vorhandene Phasen erhalten
void setMagnitudePreservePhase( int iIndex, float fMagnitude );
void setMagnitudesPreservePhases(float fMagnitude);
void setMagnitudesPreservePhases(int iOffset, int iCount, float fMagnitude);
void SetMagnitudePreservePhase( const int iIndex, const float fMagnitude );
void SetMagnitudesPreservePhases( const float fMagnitude );
void SetMagnitudesPreservePhases( const int iOffset, const int iCount, const float fMagnitude );
//! Phase setzen, vorhandene Betrge erhalten
void setPhasePreserveMagnitude(int iIndex, float fPhase);
void setPhasesPreserveMagnitudes(float fPhase);
void setPhasesPreserveMagnitudes(int iOffset, int iCount, float fPhase);
void SetPhasePreserveMagnitude( const int iIndex, const float fPhase );
void SetPhasesPreserveMagnitudes( const float fPhase );
void SetPhasesPreserveMagnitudes( const int iOffset, const int iCount, const float fPhase );
// Konstante addieren
void add(float fReal, float fImag=0);
void sub(float fReal, float fImag=0);
void Add( const float fReal, const float fImag = 0 );
void Sub( const float fReal, const float fImag = 0 );
// Spektrum addieren
void add(const ITAHDFTSpectrum& s);
void add( const ITAHDFTSpectrum* );
void sub(const ITAHDFTSpectrum& s);
void sub( const ITAHDFTSpectrum* );
void mul( const ITAHDFTSpectrum& s );
void mul( const float fFactor );
void mul( const ITAHDFTSpectrum* );
void Add( const ITAHDFTSpectrum& s );
void Add( const ITAHDFTSpectrum* );
void Sub( const ITAHDFTSpectrum& s );
void Sub( const ITAHDFTSpectrum* );
void Mul( const ITAHDFTSpectrum& s );
void Mul( const float fFactor );
void Mul( const ITAHDFTSpectrum* );
//! Multiplies the conjugate of the given spectrum without data copy
void mul_conj( const ITAHDFTSpectrum* );
void MulConj( const ITAHDFTSpectrum* );
//! Devide spectrum
void div( const ITAHDFTSpectrum& s );
void div( const ITAHDFTSpectrum* );
void Div( const ITAHDFTSpectrum& s );
void Div( const ITAHDFTSpectrum* );
//! Betragsspektrum berechnen und in gegebenes Array speichern
// Zeiger drfen Null sein
void calcMagnitudes( float* pfMagnitudes ) const;
void CalcMagnitudes( float* pfMagnitudes ) const;
//! Calculates magnitude from real and imaginary part for a given frequency bin
float calcMagnitude( int iIndex ) const;
float CalcMagnitude( const int iIndex ) const;
//! Phasenspektrum berechnen und in gegebenes Array speichern
// Zeiger drfen Null sein
void calcPhases(float* pfPhasess);
void CalcPhases( float* pfPhasess );
//! Betragsgrten Koeffizienten ermitteln
float findMax() const;
float findMax(int& iMaxIndex) const;
float FindMax() const;
float FindMax( int& iMaxIndex ) const;
//! Negieren (Multiplikation mit -1 bzw. Phasendrehungum 180)
void negate();
void Negate();
//! Konjugiert das Spectrum
void conjugate();
void Conjugate();
//! Set unity DFT coeffs (re == 1, im == 0)
void SetUnity();
//! Set unity DFT coeffs (re == 1, im == 0)
void SetZero();
//! Komplexen bzw. rellen natrlichen Logarithmus berechnen
/**
/**
* Reller log entspricht dem Betrag des komplexen log.
* Intern wird std::logf verwendet, so dass Betrag 0 den Wert -HUGE_VAL und der relle
* Logarithmus fr negative Werte den Wert NAN zurckgibt
*/
void log(bool bComplex=true);
void Log( const bool bComplex = true );
//! Komplexe bzw. reelle Exponentialfunktion berechnen
/**
/**
* Intern wird std::exp verwendet, so dass groe Betrge +-HUGE_VAL zurckgeben
*/
void exp(bool bComplex=true);
void Exp( const bool bComplex = true );
//! Alle Filterkoeffizienten eines anderen Spektrums in dieses kopieren
void copyFrom(const ITAHDFTSpectrum& s);
void copy( const ITAHDFTSpectrum* );
void CopyFrom( const ITAHDFTSpectrum& s );
void Copy( const ITAHDFTSpectrum* );
//! Einen Teil der Filterkoeffizienten eines anderen Spektrums in dieses kopieren
void copyFrom(const ITAHDFTSpectrum& s, int iOffset, int iCount);
void CopyFrom( const ITAHDFTSpectrum& s, const int iOffset, const int iCount );
//! Zuweisungsoperator
/**
......@@ -205,24 +201,24 @@ public:
* Hierzu wird zunchst die Gre des Spektrums angepasst.
* Anschlieend werden alle Koeffizienten kopiert.
*/
ITAHDFTSpectrum& operator=(const ITAHDFTSpectrum& rhs);
ITAHDFTSpectrum& operator=( const ITAHDFTSpectrum& rhs );
//! Zeichenkette mit den Werten zurckgeben
std::string toString();
std::string ToString();
//! Calculates the energy of the spectrum
/**
* Returns the energy of a HDFTSpectrum as a float
*/
float getEnergy() const;
float GetEnergy() const;
private:
int m_iSize;
int m_iDFTSize;
double m_dSamplerate;
int m_iDFTSize;
float m_fSampleRate;
float* m_pfData;
mutable std::vector< float > m_vfData;
};
#endif // __ITA_HDFT_SPECTRUM_H__
......@@ -30,7 +30,7 @@ class ITASampleBuffer;
* For equidistant sampling.
*
*/
class IITAVDLInterpolationRoutine
class IITASampleInterpolationRoutine
{
public:
//! Human-readable name
......@@ -70,37 +70,37 @@ public:
};
//! Linear interpolation (fast)
class ITA_BASE_API CITAVDLLinearInterpolation : public IITAVDLInterpolationRoutine
class ITA_BASE_API CITASampleLinearInterpolation : public IITASampleInterpolationRoutine
{
public:
inline CITAVDLLinearInterpolation() {};
inline ~CITAVDLLinearInterpolation() {};
inline CITASampleLinearInterpolation() {};
inline ~CITASampleLinearInterpolation() {};
inline std::string GetName() const { return "Linear Interpolation"; };
inline void GetOverlapSamples( int& iLeft, int& iRight ) const { iLeft = 1; iRight = 0; };
bool Interpolate( const ITASampleBuffer* pInput, const int iInputLength, const int iInputStartOffset, ITASampleBuffer* pOutput, const int iOutputLength, const int iOutputOffset = 0 ) const;
};
//! Cubic-Spline interpolation (efficient)
class ITA_BASE_API CITAVDLCubicSplineInterpolation : public IITAVDLInterpolationRoutine
class ITA_BASE_API CITASampleCubicSplineInterpolation : public IITASampleInterpolationRoutine
{
public:
inline CITAVDLCubicSplineInterpolation() {};
inline ~CITAVDLCubicSplineInterpolation() {};
inline CITASampleCubicSplineInterpolation() {};
inline ~CITASampleCubicSplineInterpolation() {};
inline std::string GetName() const { return "Cubic Spline Interpolation"; };
inline void GetOverlapSamples( int& iLeft, int& iRight ) const { iLeft = 2; iRight = 2; };
bool Interpolate( const ITASampleBuffer* pInput, const int iInputLength, const int iInputStartOffset, ITASampleBuffer* pOutput, const int iOutputLength, const int iOutputOffset = 0 ) const;
};
//! Windowed Sinc-Interpolation (costly)
class ITA_BASE_API CITAVDLWindowedSincInterpolation : public IITAVDLInterpolationRoutine
class ITA_BASE_API CITASampleWindowedSincInterpolation : public IITASampleInterpolationRoutine
{
public:
inline CITAVDLWindowedSincInterpolation( const int iWindowSize = 13 ) : m_iWindowSize( iWindowSize )
inline CITASampleWindowedSincInterpolation( const int iWindowSize = 13 ) : m_iWindowSize( iWindowSize )
{
m_iWindowSize = m_iWindowSize + m_iWindowSize % 1;
};
inline ~CITAVDLWindowedSincInterpolation() {};
inline ~CITASampleWindowedSincInterpolation() {};
inline std::string GetName() const { return "Windowed Sinc-Interpolation"; };
inline void GetOverlapSamples( int& iLeft, int& iRight ) const { iLeft = m_iWindowSize / 2; iRight = m_iWindowSize / 2; };
bool Interpolate( const ITASampleBuffer* pInput, const int iInputLength, const int iInputStartOffset, ITASampleBuffer* pOutput, const int iOutputLength, const int iOutputOffset = 0 ) const;
......
......@@ -22,14 +22,27 @@
#include <ITABaseDefinitions.h>
#include <ITASpectrum.h>
// Forward for aliasing classes
class CITAGainMagnitudeSpectrum;
//! A factor magnitude spectrum with linear values that are greater zero and usually between 0..1, but can also exceed.
/**
* This alias class is used to give the user a hint that the underlying data should be treated as linear values (factors)
* or gains, because a magnitude spectrum does not specify on that. It is used like a CITAMagnitudeSpectrum.
* There is no real difference between a factor and a gain except that gains are commonly used in DSP (i.e. for "gain" control
* of audio signal channels) and factors are more common in acoustic materials such as absorption and transmission "factor".
*/
typedef CITAGainMagnitudeSpectrum CITAFactorMagnitudeSpectrum;
//! Magnitude spectrum of arbitrary size and base frequencies
/**
* Class for magnitude spectra, that is intended to be used with decibel values (magnitudes).
* Implementation class for magnitude spectra, that does not specify on underlying data. To be more precise in your code and
* for validation of data it is recommended to use the alias classes CITADecibelMagnitudeSpectrum, CITAGainMagnitudeSpectrum or CITAFactorMagnitudeSpectrum,
* which implement the abstract methods and are ready to use.
*
* Will raise CITAException on errors.
*
* @sa CITAAmplitudeSpectrum, CITAPhaseSpectrum, CITAHDFTSpectrum
* @sa CITAThirdOctaveSpectrum, CITAPhaseSpectrum, CITAHDFTSpectrum
*
*/
class ITA_BASE_API CITAMagnitudeSpectrum : public CITASpectrum
......@@ -43,13 +56,42 @@ public:
void SetMagnitudes( const std::vector< float >& vfMagnitudes );
void SetMagnitude( const int iFrequencyBandIndex, const float fMagnitudeValue );
bool CompareEqualValues( const CITAMagnitudeSpectrum& oOtherSpectrum, const float fThreshold = 10.0e-10 ) const;
};
//! A decibel magnitude spectrum with values that have been transformed into logarithmic scale. Values are mostly between -\infinity and 0, but can also exceed.
/**
* This alias class is used to give the user a hint that the underlying data should be treated as decibel values (log scale),
* because a magnitude spectrum does not specify on that. It is used like a CITAMagnitudeSpectrum.
*/
class ITA_BASE_API CITADecibelMagnitudeSpectrum : public CITAMagnitudeSpectrum
{
public:
CITADecibelMagnitudeSpectrum( const int nNumBands );
virtual ~CITADecibelMagnitudeSpectrum();
void SetIdentity();
void SetZero();
bool IsIdentity() const;
bool IsZero() const;
};
//! A gain magnitude spectrum with linear values that are greater zero and usually between 0..1, but can also exceed.
/**
* @sa CITAFactorMagnitudeSpectrum
*/
class ITA_BASE_API CITAGainMagnitudeSpectrum : public CITAMagnitudeSpectrum
{
public:
CITAGainMagnitudeSpectrum( const int nNumBands );
virtual ~CITAGainMagnitudeSpectrum();
void SetIdentity();
void SetZero();
bool IsIdentity() const;
bool IsZero() const;
bool CompareEqualValues( const CITAMagnitudeSpectrum& oOtherSpectrum, const float fThreshold = 10.0e-10 ) const;
};
#endif // INCLUDE_WATCHER_ITA_MAGNITUDE_SPECTRUM
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_MULTICHANNEL_FINITE_IMPULSE_RESPONSE
#define INCLUDE_WATCHER_ITA_MULTICHANNEL_FINITE_IMPULSE_RESPONSE
// ITABase
#include <ITABaseDefinitions.h>
#include <ITASampleFrame.h>
//! Multichannel finite impulse response class / FIR filters
/**
* ITASampleFrame with a sampling rate = multichannel finite impulse response.
*/
class ITA_BASE_API CITAMultichannelFiniteImpulseResponse : public ITASampleFrame
{
public:
//! Create empty FIR filters
/**
* Requires initialization to be used, otherwise methods will throw ITAException.
*/
CITAMultichannelFiniteImpulseResponse();
//! Create FIR filter of certain size with given sampling frequency
/**
* \param iLength Length (size) of buffer in samples
*/
explicit CITAMultichannelFiniteImpulseResponse( const int iNumChannels, const int iLength, const double dSampleRate, const bool bZeroInit = true );
//! Copy constructor as pointer
/**
* \param pSource Pointer to source buffer
*/
CITAMultichannelFiniteImpulseResponse( const CITAMultichannelFiniteImpulseResponse* pSource );
//! Copy constructor as reference
/**
* \param pbSource Reference to source buffer
*/
CITAMultichannelFiniteImpulseResponse( const CITAMultichannelFiniteImpulseResponse& sbSource );
virtual inline ~CITAMultichannelFiniteImpulseResponse() {};
//! Load from file constructor (audiofile)
/**
* Loads FIR data from an audio file.
*
* @note Will throw ITAException on error.
*/
CITAMultichannelFiniteImpulseResponse( const std::string& sFilePath );
//! Loads FIR from file (will re-init length, if necessary)
void LoadFromFile( const std::string& sFilePath );
void StoreToFile( const std::string& sFilePath ) const;
//! Sampling frequency of FIR filter (double of Nyquist frequency)
double GetSampleRate() const;
//! Nyquist frequency of FIR filter (half of sample rate)
double GetNyquistFrequency() const;
//! Initialize
/**
* (Re-)Initialize a sample buffer
*
* @param[in] iNumChannels Number of FIR channels
* \param iLength Number of new samples
* @param[in] dSampleRate Sampling rate of FIR filter (double of Nyquist frequency)
* \param bZeroInit Init with zeros
*/
void Init( const int iNumChannels, const int iLength, const double dSampleRate, const bool bZeroInit = true );
private:
//! Disable these methods from ITASampleFrame
void Init( int, int, bool );
void Load( const std::string& );
void Load( const std::string&, double& );
void Store( const std::string&, double);
double m_dSampleRate; //!< Sampling rate
};
#endif // INCLUDE_WATCHER_ITA_MULTICHANNEL_FINITE_IMPULSE_RESPONSE
......@@ -47,8 +47,15 @@ ITA_BASE_API unsigned int nextPow2( unsigned int x );
// Rundung auf Compilern definieren die dies nicht standardmäßig mitliefern
#ifndef HAVE_ROUND
ITA_BASE_API inline double round( double x ) { return ( x < 0 ? ceil( ( x ) -0.5 ) : floor( ( x ) +0.5 ) ); }
ITA_BASE_API inline float roundf( float x ) { return ( x < 0 ? ceil( ( x ) -0.5f ) : floor( ( x ) +0.5f ) ); }
ITA_BASE_API inline double round( double x )
{
return ( x < 0 ? ceil( ( x ) -0.5 ) : floor( ( x ) +0.5 ) );
};
ITA_BASE_API inline float roundf( float x )
{
return ( x < 0 ? ceil( ( x ) -0.5f ) : floor( ( x ) +0.5f ) );
};
#endif
//! Nächstkleineres Vielfaches von mul zu einer Zahl x zurückgeben
......@@ -60,7 +67,7 @@ ITA_BASE_API inline float roundf( float x ) { return ( x < 0 ? ceil( ( x ) -0.5f
* lwrmul(-10, 6) = -12
* lwrmul(10, -6) = 12
*/
ITA_BASE_API int lwrmul( int x, int mul );
ITA_BASE_API int lwrmul( const int x, const int mul );
//! Nächstgrößeres Vielfaches von mul zu einer Zahl x zurückgeben
/**
......@@ -71,21 +78,21 @@ ITA_BASE_API int lwrmul( int x, int mul );
* uprmul(-10, 6) = -6
* uprmul(10, -6) = 12
*/
ITA_BASE_API int uprmul( int x, int mul );
ITA_BASE_API int uprmul( const int x, const int mul );
//! Nächstkleineres Vielfaches von mul zu einer Zahl x zurückgeben
/**
* Beispiele: lwrmulu(10, 5) = 10
* lwrmulu(10, 6) = 6
*/
ITA_BASE_API unsigned int lwrmulu( unsigned int x, unsigned int mul );
ITA_BASE_API unsigned int lwrmulu( const unsigned int x, const unsigned int mul );
//! Nächstgrößeres Vielfaches von mul zu einer Zahl x zurückgeben
/**
* Beispiele: uprmulu(10, 5) = 10
* uprmulu(10, 6) = 12
*/
ITA_BASE_API unsigned int uprmulu( unsigned int x, unsigned int mul );
ITA_BASE_API unsigned int uprmulu( const unsigned int x, const unsigned int mul );
//! Aufrundende Ganzzahl-Division
/**
......@@ -96,13 +103,13 @@ ITA_BASE_API unsigned int uprmulu( unsigned int x, unsigned int mul );
* Anwendungen: Wieviele Blöcke der Länge b sind erforderlich
* um ein Signal der Länge l zu beschreiben: uprdiv(l, b)
*/
ITA_BASE_API int uprdiv( int a, int b );
ITA_BASE_API int uprdiv( const int a, const int b );
//! Aufrundende Ganzzahl-Division
/**
* Variante von uprdiv für vorzeichenlose Ganzzahlen.
*/
ITA_BASE_API unsigned int uprdivu( unsigned int a, unsigned int b );
ITA_BASE_API unsigned int uprdivu( const unsigned int a, const unsigned int b );
//! Einen (beliebigen) Winkel ins Interval (-180,180] abbilden
/**
......@@ -110,13 +117,13 @@ ITA_BASE_API unsigned int uprdivu( unsigned int a, unsigned int b );
* \note Der exakte Wert -180 wird durch die Funktion erhalten
* und nicht auf +180 abgebildet (Ästethik :-))
*/
ITA_BASE_API float correctAngle180( float phi );
ITA_BASE_API float correctAngle180( const float fPhiDeg );
//! Einen (beliebigen) Winkel ins Interval [0,360) abbilden
/**
* Beispiel: correctAngle(380°) = 20°
*/
ITA_BASE_API float correctAngle360( float phi );
ITA_BASE_API float correctAngle360( const float fPhiDeg );
//! Verhältnis in Dezibel (Energie) (im 10er-Logarithmus) umrechnen
/**
......@@ -172,34 +179,32 @@ ITA_BASE_API double ratio_to_db20( const double r );
+------------------------------------+ */
//! Betrag einer komplexen Zahl berechnen
ITA_BASE_API float cabsf( float re, float im );
/**
* @param[in] fReal Real part
* @param[in] fImag Imaginary part
*/
ITA_BASE_API float cabsf( const float fReal, const float fImag );
//! Phase einer komplexen Zahl berechnen
ITA_BASE_API float canglef( float re, float im );
ITA_BASE_API float canglef( const float fReal, const float fImag );
//! Betrag einer komplexen Zahl setzen, deren Phase aber erhalten (auch in-place)
ITA_BASE_API void csabsparg( const float& in_re, const float& in_im, const float& dest_abs, float& out_re, float& out_im );
ITA_BASE_API void csabsparg( const float fInReal, const float fInImag, const float fTargetAbs, float& fOutReal, float& fOutImag );
//! Winkel einer komplexen Zahl setzen, deren Betrag aber erhalten (auch in-place)
ITA_BASE_API void csargpabs( const float& in_re, const float& in_im, const float& dest_arg, float& out_re, float& out_im );
/* +---------------------------+
| |
| Neue Winkelfunktionen |
| |
+---------------------------+ */
ITA_BASE_API void csargpabs( const float fInReal, const float fInImag, const float fTargetAbs, float& fOutReal, float& fOutImag );
//! Winkel im Bogenmaß in Grad [°] umrechnen
ITA_BASE_API float rad2gradf( float phi );
ITA_BASE_API float rad2gradf( const float fPhiRad );
//! Winkel im Bogenmaß in Grad [°] umrechnen
ITA_BASE_API double rad2grad( double phi );
ITA_BASE_API double rad2grad( const double dPhiRad );
//! Winkel in Grad [°] ins Bogenmaß umrechnen
ITA_BASE_API float grad2radf( float phi );
ITA_BASE_API float grad2radf( const float fPhiDeg );
//! Winkel im Bogenmaß in Grad [°] umrechnen
ITA_BASE_API double grad2rad( double phi );
ITA_BASE_API double grad2rad( const double dPhiDeg );
/* ---------- RAD ----------- */
......@@ -212,7 +217,7 @@ ITA_BASE_API double grad2rad( double phi );
*
* Beispiele: 0->0, 2*PI->0, (-2*PI)->0, (2*PI+0.1)->0.1, (-0.1)->(2*PI-0.1)
*/
ITA_BASE_API float anglef_proj_0_2PI( float alpha );
ITA_BASE_API float anglef_proj_0_2PI( const float fAlphaRad );
//! Einen Winkel (rad) in das Intervall (-PI, PI] projezieren
/**
......@@ -223,7 +228,7 @@ ITA_BASE_API float anglef_proj_0_2PI( float alpha );
*
* Beispiele: 0->0, 2*PI->0, (-2*PI)->0, (PI+0.1)->(-PI+0.1), (-PI-0.1)->(PI-0.1)
*/
ITA_BASE_API float anglef_proj_NPI_PI( float alpha );
ITA_BASE_API float anglef_proj_NPI_PI( const float fAlphaRad );
//! (Gerichtete) minimale Winkeldifferenz für zwei Winkel [rad] (nicht Grad) im Intervall [0,2PI)
/**
......@@ -244,7 +249,7 @@ ITA_BASE_API float anglef_proj_NPI_PI( float alpha );
*
* Beispiele: (0,PI/2) -> PI/2, (PI/5,PI/4) -> PI/20, (PI/3,PI/4) -> -PI/12, (0,2*PI-0.1) -> -0.1
*/
ITA_BASE_API float anglef_mindiff_0_2PI( float alpha, float beta );
ITA_BASE_API float anglef_mindiff_0_2PI( const float alpha, const float beta );
//! Absolute minimale Winkeldifferenz für zwei Winkel [rad] im Intervall [0,2PI)
/**
......@@ -258,7 +263,7 @@ ITA_BASE_API float anglef_mindiff_0_2PI( float alpha, float beta );
*
* Beispiele: (0,PI/2) -> PI/2, (PI/2,PI/3) -> PI/6, (PI/3,PI/2) -> PI/6, (0,2*PI-0.1) -> 0.1
*/
ITA_BASE_API float anglef_mindiff_abs_0_2PI( float alpha, float beta );
ITA_BASE_API float anglef_mindiff_abs_0_2PI( const float alpha, const float beta );
/* ---------- GRAD ---------- */
......@@ -270,7 +275,7 @@ ITA_BASE_API float anglef_mindiff_abs_0_2PI( float alpha, float beta );
*
* Beispiele: 0°->0°, 360°->0°, -360°->0°, 361°->1°, -1°->359°
*/
ITA_BASE_API float anglef_proj_0_360_DEG( float alpha );
ITA_BASE_API float anglef_proj_0_360_DEG( const float alpha );
//! Einen Winkel (°) in das Intervall (-180°, 180°] projezieren
/**
......@@ -281,7 +286,7 @@ ITA_BASE_API float anglef_proj_0_360_DEG( float alpha );
*
* Beispiele: 0°->0°, 360°->0°, -360°->0°, 181°->-179°, -181°->179°
*/
ITA_BASE_API float anglef_proj_N180_180_DEG( float alpha );
ITA_BASE_API float anglef_proj_N180_180_DEG( const float alpha );
//! (Gerichtete) minimale Winkeldifferenz für zwei Winkel [°] im Intervall [0°,360°)
/**
......@@ -302,7 +307,7 @@ ITA_BASE_API float anglef_proj_N180_180_DEG( float alpha );
*
* Beispiele: (0°,90°) -> 90°, (45°,70°) -> 25°, (70°,45°) -> -25°, (0°,359°) -> -1°
*/
ITA_BASE_API float anglef_mindiff_0_360_DEG( float alpha, float beta );
ITA_BASE_API float anglef_mindiff_0_360_DEG( const float alpha, const float beta );
//! Absolute minimale Winkeldifferenz für zwei Winkel [°] im Intervall [0°,360°)
/**
......@@ -316,7 +321,7 @@ ITA_BASE_API float anglef_mindiff_0_360_DEG( float alpha, float beta );
*
* Beispiele: (0°,90°) -> 90°, (45°,70°) -> 25°, (70°,45°) -> 25°, (0°,359°) -> 1°
*/
ITA_BASE_API float anglef_mindiff_abs_0_360_DEG( float alpha, float beta );
ITA_BASE_API float anglef_mindiff_abs_0_360_DEG( const float alpha, const float beta );
// Orientierung in Yaw-Pitch-Roll Winkeln in View-Up-Vektor umrechnen (Alle Winkel in Bogenmaß)
......@@ -340,8 +345,9 @@ ITA_BASE_API void convertVU2YPR( const float vx, const float vy, const float vz,
float& yaw, float& pitch, float& roll );
// Datenklasse für Fehlerwerte
template <typename T>
class ITA_BASE_API ErrorValues {
template< typename T >
class ITA_BASE_API ErrorValues
{
public:
T minAbsError;
T avgAbsError;
......@@ -349,12 +355,17 @@ public:
int indexMaxAbsError; // Index of element where max abs error
ErrorValues() : minAbsError( 0 ), avgAbsError( 0 ), maxAbsError( 0 ), indexMaxAbsError( 0 ) {}
inline ErrorValues()
: minAbsError( 0 )
, avgAbsError( 0 )
, maxAbsError( 0 )
, indexMaxAbsError( 0 )
{};
};
// Fehler zwischen zwei Vektoren berechnen
template <typename Tc, typename Ta, typename Tb>
ErrorValues<Tc> computeErrorValues( const Ta* A, const Tb* B, int size )
template< typename Tc, typename Ta, typename Tb >
inline ErrorValues<Tc> computeErrorValues( const Ta* A, const Tb* B, const int size )
{
ErrorValues<Tc> v;
if( size == 0 ) return v;
......@@ -362,11 +373,13 @@ ErrorValues<Tc> computeErrorValues( const Ta* A, const Tb* B, int size )
Tb absErr = std::abs( ( Tc ) A[ 0 ] - ( Tc ) B[ 0 ] );
v.minAbsError = v.avgAbsError = v.maxAbsError = absErr;
for( int i = 1; i < size; ++i ) {
for( int i = 1; i < size; ++i )
{
absErr = std::abs( ( Tc ) A[ i ] - ( Tc ) B[ i ] );
v.minAbsError = std::min( v.minAbsError, absErr );
if( absErr > v.maxAbsError ) {
if( absErr > v.maxAbsError )
{
v.maxAbsError = absErr;
v.indexMaxAbsError = i;
}
......@@ -385,45 +398,53 @@ ErrorValues<Tc> computeErrorValues( const Ta* A, const Tb* B, int size )
+-----------------------+ */
// Fills a vector with numbers dest = { a+n*s < b | n in N }
template <typename T> void linspace( std::vector<T>& dest, T a, T b, T s = 1 ) {
template< typename T > inline void linspace( std::vector< T >& dest, T a, T b, T s = 1 )
{
dest.clear();
if( s == 0 ) {
if( s == 0 )
{
dest.push_back( a );
return;
}
if( s < 0 ) {
if( a < b ) return; // No elements contained
if( s < 0 )
{
if( a < b )
return; // No elements contained
dest.reserve( ( a - b ) / s + 1 );
for( T x = a; x >= b; x += s ) dest.push_back( x );
for( T x = a; x >= b; x += s )
dest.push_back( x );
}
else {
if( a > b ) return; // No elements contained
else
{
if( a > b )
return; // No elements contained
dest.reserve( ( b - a ) / s + 1 );
for( T x = a; x <= b; x += s ) dest.push_back( x );
for( T x = a; x <= b; x += s )
dest.push_back( x );
}
};
// Fills a vector with powers of two in the range a=2^i <= 2^j <= 2^k=b
// (Note a and b must be powers of two, otherwise an exception is thrown)
ITA_BASE_API void pow2space( std::vector<int>& dest, int a, int b );
ITA_BASE_API void pow2space( std::vector< int >& dest, const int a, const int b );
// Calculates the factorial of an positive integer m
ITA_BASE_API int factorial( int m );
ITA_BASE_API int factorial( const int m );
//Calculates the normalizing constant for SHRealvaluedBasefunctions
ITA_BASE_API double SHNormalizeConst( int m, int n );
ITA_BASE_API double SHNormalizeConst( const int m, const int n );
//Calculates the Kronecker delta
ITA_BASE_API int SHKronecker( int m );
ITA_BASE_API int SHKronecker( const int m );
// Returns the index of a basefunction with degree m and order n
ITA_BASE_API int SHDegreeOrder2Linear( int m, int n );
ITA_BASE_API int SHDegreeOrder2Linear( const int m, const int n );
//Calculates the realvalued Basefunctions of SH for e.g. Ambisonics
ITA_BASE_API std::vector<double> SHRealvaluedBasefunctions( double elevation, double azimuth, int maxOrder );
ITA_BASE_API std::vector<double> SHRealvaluedBasefunctions( const double elevation, const double azimuth, const int maxOrder );
//Calculates the associated legendre polynomials
ITA_BASE_API std::vector<double> SHAssociatedLegendre( int N, double mu );
ITA_BASE_API std::vector<double> SHAssociatedLegendre( const int N, const double mu );
#endif // INCLUDE_WATCHER_ITA_NUMERIC_UTILS
......@@ -61,7 +61,7 @@ public:
//! Deprecated
inline int length()
{
{
return GetLength();
};
......@@ -332,7 +332,11 @@ public:
std::string toString() const;
//! Werte als Zeichenkette zurckgeben
std::string valuesToString() const;
std::string ValuesToString() const;
void Load( const std::string& sFilePath );
void Load( const std::string& sFilePath, float& fSampleRate );
void Store( const std::string& sFilePath, const float fSampleRate = 44100.0f ) const;
//! berblendfunktionen
enum
......
......@@ -52,27 +52,27 @@ public:
* \param bZeroinit Frame mit Nullen initialisieren?
*/
explicit ITASampleFrame(int iChannels, int iLength, bool bZeroinit);
explicit ITASampleFrame( const int iChannels, const int iLength, const bool bZeroinit = 0 );
//! Kopierkonstruktor (Zeiger)
/**
* Erzeugt einen unabhngigen Frame als Kopie des gegebenen Frames.
* Erzeugt einen unabhngigen Frame als Kopie des gegebenen Frames.
* Der neue Frame hat die selbe Anzahl Kanle und Lnge und enthlt
* die gleichen Werte wie der Quellframe.
*
* \param pSource Zeiger auf den Quellframe
*/
ITASampleFrame(const ITASampleFrame* pSource);
ITASampleFrame( const ITASampleFrame* pSource );
//! Kopierkonstruktor (Referenz)
/**
* Erzeugt einen unabhngigen Frame als Kopie des gegebenen Frames.
* Erzeugt einen unabhngigen Frame als Kopie des gegebenen Frames.
* Der neue Frame hat die selbe Anzahl Kanle und Lnge und enthlt
* die gleichen Werte wie der Quellframe.
*
* \param bSource Referenz auf den Quellframe
*/
ITASampleFrame(const ITASampleFrame& fSource);
ITASampleFrame( const ITASampleFrame& fSource );
//! Ladekonstruktor (Audiodatei)
/**
......@@ -80,7 +80,7 @@ public:
*
* \note Im Fehlerfall wird eine ITAException ausgelst.
*/
ITASampleFrame(const std::string& sFilename);
ITASampleFrame( const std::string& sFilePath );
//! Destruktor
virtual ~ITASampleFrame();
......@@ -92,7 +92,12 @@ public:
bool empty() const;
//! Anzahl Kanle zurckgeben
int channels() const;
inline int channels() const
{
return GetNumChannels();
};
int GetNumChannels() const;
// Deprecated
int length() const;
......@@ -107,10 +112,10 @@ public:
* Falls ein Frame bereits initialisiert war, gehen alle vorherigen Daten verloren.
* Die Methode ermglich bequemes programmieren, da Frames zunchst per
* Standard-Konstruktor erzeugt werden knnen und erst spter initialisiert werden.
*
*
* \param dSamplerate Abtastrate [Hz] (0 => unbestimmt)
* \param iChannels Anzahl Kanle
* \param iLength Lnge [Anzahl Samples]
* \param iLength Lnge [Anzahl Samples]
* \param bZeroinit Samples mit Nullen initialisieren?
*/
void Init( int iChannels, int iLength, bool bZeroinit );
......@@ -127,13 +132,13 @@ public:
//! Speicher freigeben
/**
* Gibt den fr den Frame allozierten Speicher frei und setzt seine
* Gibt den fr den Frame allozierten Speicher frei und setzt seine
* Anzahl Kanle und Lnge auf 0. Hierbei gehen natrlich alle Daten verloren.
*/
void free();
//! Setzt alle Samples alles Kanle auf den gegebenen Wert
void fill(float fValue);
void fill( float fValue );
//! Setzt die Samples aller Kanle in einem Bereich auf den angegebenen Wert
/**
......@@ -141,13 +146,13 @@ public:
* \param iCount Anzahl Samples
* \param fFloat Wert
*/
void fill(int iOffset, int iCount, float fValue);
void fill( int iOffset, int iCount, float fValue );
//! Setzt alle Samples aller Kanle zu Null
void zero();
//! Setzt einen Bereich von Samples aller Kanle zu Null
void zero(int iOffset, int iCount);
void zero( int iOffset, int iCount );
//! Setzt Einheitsimpulse in jedem Kanal
void identity();
......@@ -157,7 +162,7 @@ public:
* Blendet die Samples im Bereich [iOffset, iOffset+iCount] mit der
* angegebenen Blendfunktion ein.
*/
void fade(int iOffset, int iCount, int iFadeDirection, int iFadeFunction);
void fade( int iOffset, int iCount, int iFadeDirection, int iFadeFunction );
//! Kreuzblenden
/**
......@@ -169,22 +174,22 @@ public:
* Danach werden iCount Samples zwischen den beiden Puffern kreuzgeblendet.
* Dahinter folgen nur noch Samples dieses Puffers.
*/
void crossfade(const ITASampleFrame* psfSrc, int iOffset, int iCount, int iFadeDirection, int iFadeFunction);
void crossfade(const ITASampleFrame& sfSrc, int iOffset, int iCount, int iFadeDirection, int iFadeFunction);
void crossfade( const ITASampleFrame* psfSrc, int iOffset, int iCount, int iFadeDirection, int iFadeFunction );
void crossfade( const ITASampleFrame& sfSrc, int iOffset, int iCount, int iFadeDirection, int iFadeFunction );
//! Einhllende
/**
/* Wendet eine lineare Einhllende (envelope) auf den Frame an.
*
* \param fGain0 Startwert [0..1]
* \param fGain1 Endwert [0..1]
*/
void envelope(float fGain0, float fGain1);
*
* \param fGain0 Startwert [0..1]
* \param fGain1 Endwert [0..1]
*/
void envelope( float fGain0, float fGain1 );
//! Samples aus einem anderen Frame in den Frame kopieren
/**
* Kopiert iCount Samples aus angegebenen Frame beginnend bei Leseposition iSrcOffset
* in disen Frame, dort beginnend ab Schreibposition iDestOffset.
* in disen Frame, dort beginnend ab Schreibposition iDestOffset.
*
* \param psfSrc Quellframe
* \param iCount Anzahl zu kopierender Samples
......@@ -194,8 +199,8 @@ public:
* \note Kein Schreiben ber das Frameende hinaus!
* \note Beide Frames mssen die gleiche Anzahl Kanle haben
*/
void write(const ITASampleFrame* psfSrc, int iCount, int iSrcOffset=0, int iDestOffset=0);
void write(const ITASampleFrame& sfSrc, int iCount, int iSrcOffset=0, int iDestOffset=0);
void write( const ITASampleFrame* psfSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
void write( const ITASampleFrame& sfSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
//! Zyklisches Schreiben
/**
......@@ -214,61 +219,61 @@ public:
*
* TODO: Memory alignment fr SSE?
*/
void cyclic_write(const ITASampleFrame* psfSrc, int iCount, int iSrcOffset=0, int iDestOffset=0);
void cyclic_write(const ITASampleFrame& sfSrc, int iCount, int iSrcOffset=0, int iDestOffset=0);
void cyclic_write( const ITASampleFrame* psfSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
void cyclic_write( const ITASampleFrame& sfSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
//! Cyclic shifting of samples
/**
* @param [in] iCount Shifts the samples in frames by given count
*/
void CyclicShift(int iCount);
void CyclicShift( int iCount );
//! In-place Addition: Jedem Sample einen konstanten Wert addieren
void add_scalar(float fValue);
void add_scalar( float fValue );
//! In-place Subtraktion: Jedem Sample einen konstanten Wert subtrahieren
void sub_scalar(float fValue);
void sub_scalar( float fValue );
//! In-place Multiplikation: Jedes Sample mit einem konstanten Wert multiplizieren
void mul_scalar(float fValue);
void mul_scalar( float fValue );
//! In-place Division: Jedes Sample durch einen konstanten Wert dividieren
void div_scalar(float fValue);
void div_scalar( float fValue );
// TODO: Bereiche Addieren usw.
// Operatoren: Alle Kanle mit einem SampleBuffer
void add_buf(const ITASampleBuffer* psbSource);
void sub_buf(const ITASampleBuffer* psbSource);
void mul_buf(const ITASampleBuffer* psbSource);
void div_buf(const ITASampleBuffer* psbSource);
void add_buf( const ITASampleBuffer* psbSource );
void sub_buf( const ITASampleBuffer* psbSource );
void mul_buf( const ITASampleBuffer* psbSource );
void div_buf( const ITASampleBuffer* psbSource );
// Varianten mit Referenzen
void add_buf(const ITASampleBuffer& sbSource);
void sub_buf(const ITASampleBuffer& sbSource);
void mul_buf(const ITASampleBuffer& sbSource);
void div_buf(const ITASampleBuffer& sbSource);
void add_buf( const ITASampleBuffer& sbSource );
void sub_buf( const ITASampleBuffer& sbSource );
void mul_buf( const ITASampleBuffer& sbSource );
void div_buf( const ITASampleBuffer& sbSource );
//! Paarweise alle Samples des gegebenen Blockes zu den Samples diesem addieren
/*
* - Mssen gleiche Anzahl Kanle und Lngen haben!
*/
void add_frame(const ITASampleFrame* psfSource);
void sub_frame(const ITASampleFrame* psfSource);
void mul_frame(const ITASampleFrame* psfSource);
void div_frame(const ITASampleFrame* psfSource);
void add_frame( const ITASampleFrame* psfSource );
void sub_frame( const ITASampleFrame* psfSource );
void mul_frame( const ITASampleFrame* psfSource );
void div_frame( const ITASampleFrame* psfSource );
// Varianten mit Referenzen
void add_frame(const ITASampleFrame& sfSource);
void sub_frame(const ITASampleFrame& sfSource);
void mul_frame(const ITASampleFrame& sfSource);
void div_frame(const ITASampleFrame& sfSource);
void add_frame( const ITASampleFrame& sfSource );
void sub_frame( const ITASampleFrame& sfSource );
void mul_frame( const ITASampleFrame& sfSource );
void div_frame( const ITASampleFrame& sfSource );
// mit bergabe der Position - keine identische Lnge bentigt
void add_frame(const ITASampleFrame* psfSource, int iPos);
void add_frame( const ITASampleFrame* psfSource, int iPos );
// Kombinierte Operatoren
// Werte eines anderen Frames mit einer Konstante multiplizieren und dann hierauf addieren
// Semantik:
// for i from 0 to iCount-1 do
......@@ -277,8 +282,8 @@ public:
// iSrcOffset = Leseposition im Quellpuffer
// iDestOffset = Schreibposition in diesem Puffer
// iCount = Anzahl Samples
void muladd_frame(const ITASampleFrame* psfSource, float fScalar, int iSrcOffset, int iDestOffset, int iCount);
void muladd_frame(const ITASampleFrame& sfSource, float fScalar, int iSrcOffset, int iDestOffset, int iCount);
void muladd_frame( const ITASampleFrame* psfSource, float fScalar, int iSrcOffset, int iDestOffset, int iCount );
void muladd_frame( const ITASampleFrame& sfSource, float fScalar, int iSrcOffset, int iDestOffset, int iCount );
//! Spitzenwert suchen
......@@ -287,7 +292,7 @@ public:
* Auf Wunsch wird auch der Kanal und Index der ersten Samples zurckgegeben, das diesen
* Spitzenwert erreichte (erste Fundstelle).
*/
float findPeak(int* piChannel=NULL, int* piPeakIndex=NULL);
float findPeak( int* piChannel = NULL, int* piPeakIndex = NULL );
//! Negieren (Multiplikation mit -1 bzw. Phasendrehungum 180)
void negate();
......@@ -306,10 +311,10 @@ public:
};
//! Read/Write Indizierungsoperator fr Zugriff auf Kanaldaten
ITASampleBuffer& operator[](int iChannel);