/* * ---------------------------------------------------------------- * * ITA core libs * (c) Copyright Institute of Technical Acoustics (ITA) * RWTH Aachen University, Germany, 2015-2016 * * ---------------------------------------------------------------- * ____ __________ _______ * // / //__ ___/ // _ | * // / // / // /_| | * // / // / // ___ | * //__/ //__/ //__/ |__| * * ---------------------------------------------------------------- * */ // $Id: ITAHDFTSpectrum.h 3913 2015-01-06 12:42:15Z stienen $ #ifndef __ITA_HDFT_SPECTRUM_H__ #define __ITA_HDFT_SPECTRUM_H__ #include #include /** * 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 erfüllt die Hermitische Symetrie. * Daher müssen von n komplexwertigen diskreten Fourierkoeffizienten eines * vollständigen DFT-Spektrums nur n/2+1 komplexwertigen Koeffizienten * gespeichert werden. * * Grundsätzlich werden die komplexwertigen Fourierkoeffizienten im * interleaved Speicherlayout abgelegt, d.h. Re(0), Im(0), Re(1), Im(1), ... * * Die Klasse stellt Methoden für die Arbeit mit solchen Spektren bereit. * */ class ITA_BASE_API ITAHDFTSpectrum { public: //! Standard-Konstruktor ITAHDFTSpectrum(); //! Konstruktor /** * Erzeugt ein Spektrum mit vorgegebener Größe und optional zu Null gesetztem Puffer * * \param iDFTSize DFT-Spektrum-Größe * \param bZeroinit Setzt den Speicher bei wahr auf Null */ explicit ITAHDFTSpectrum(int iDFTSize, bool bZeroinit=true); //! Constructor /** * Erzeugt ein Spektrum mit vorgegebener Größe und optional zu Null gesetztem Puffer * * \param dSampleRate Sampling rate * \param iDFTSize DFT-Spektrum-Größe * \param bZeroInit Setzt den Speicher bei wahr auf Null */ explicit ITAHDFTSpectrum(double dSampleRate, int iDFTSize, bool bZeroInit); //! Kopierkonstruktor (Zeiger) /** * Erzeugt einen unabhängiges Spektrum als Kopie des gegebenen Spektrums. * Das neue Spektrum hat die selbe Länge und enthält die gleichen Werte * wie das Quellspektrum. * * \param pSource Zeiger auf das Quellspektrum */ explicit ITAHDFTSpectrum(const ITAHDFTSpectrum* pSource); //! Kopierkonstruktor (Referenz) /** * Erzeugt einen unabhängiges Spektrum als Kopie des gegebenen Spektrums. * Das neue Spektrum hat die selbe Länge und enthält die gleichen Werte * wie das Quellspektrum. * * \param oSource Zeiger auf das Quellspektrum */ explicit ITAHDFTSpectrum(const ITAHDFTSpectrum& oSource); //! Destruktor virtual ~ITAHDFTSpectrum(); // Initialisieren /** * init(0) gibt belegten Speicher frei * vorherige Werte werden grundsätzlich verworfen! */ ITAHDFTSpectrum& init(int iDFTSize, bool bZeroinit=true); // Größe des Spektrums (Anzahl Koeffizienten insgesamt) zurückgeben // Hinweis: Symmetrische Koeffizienten werden hier nicht mitgezählt. int getSize() const; // Länge des korrespondieren Zeitsignals zurückgeben (Größe der DFT) int getDFTSize() const; // Abtastrate des korrespondieren Zeitsignals zurückgeben double getSamplerate() const; // Abtastrate des korrespondieren Zeitsignals setzen void setSamplerate(double dSamplerate); // Frequenzauflösung des Spektrums [Hz] zurückgeben double getFrequencyResolution() const; // Datenzeiger abrufen float* data() const; // DFT Koeffizient(en) setzen (Real-/Imaginärteil 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 setCoeffMP(int iIndex, float fMagnitude, float fPhase); void setCoeffsMP(float fMagnitude, float fPhase); void setCoeffsMP(int iOffset, int iCount, float fMagnitude, 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); //! Phase setzen, vorhandene Beträge erhalten void setPhasePreserveMagnitude(int iIndex, float fPhase); void setPhasesPreserveMagnitudes(float fPhase); void setPhasesPreserveMagnitudes(int iOffset, int iCount, float fPhase); // Konstante addieren void add(float fReal, float fImag=0); void sub(float fReal, 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* ); //! Multiplies the conjugate of the given spectrum without data copy void mul_conj( const ITAHDFTSpectrum* ); //! Devide spectrum void div( const ITAHDFTSpectrum& s ); void div( const ITAHDFTSpectrum* ); //! Betragsspektrum berechnen und in gegebenes Array speichern // Zeiger dürfen Null sein void calcMagnitudes(float* pfMagnitudes); //! Phasenspektrum berechnen und in gegebenes Array speichern // Zeiger dürfen Null sein void calcPhases(float* pfPhasess); //! Betragsgrößten Koeffizienten ermitteln float findMax() const; float findMax(int& iMaxIndex) const; //! Negieren (Multiplikation mit -1 bzw. Phasendrehungum 180°) void negate(); //! Konjugiert das Spectrum 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 natürlichen 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 für negative Werte den Wert NAN zurückgibt */ void log(bool bComplex=true); //! Komplexe bzw. reelle Exponentialfunktion berechnen /** * Intern wird std::exp verwendet, so dass große Beträge +-HUGE_VAL zurückgeben */ void exp(bool bComplex=true); //! Alle Filterkoeffizienten eines anderen Spektrums in dieses kopieren 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); //! Zuweisungsoperator /** * Dieser Operator weist dem Spektrum eines anderen Spektrums zu. * Hierzu wird zunächst die Größe des Spektrums angepasst. * Anschließend werden alle Koeffizienten kopiert. */ ITAHDFTSpectrum& operator=(const ITAHDFTSpectrum& rhs); //! Zeichenkette mit den Werten zurückgeben std::string toString(); private: int m_iSize; int m_iDFTSize; double m_dSamplerate; float* m_pfData; }; #endif // __ITA_HDFT_SPECTRUM_H__