Aufgrund einer Störung des s3 Storage, könnten in nächster Zeit folgende GitLab Funktionen nicht zur Verfügung stehen: LFS, Container Registry, Job Artifacs, Uploads (Wiki, Bilder, Projekt-Exporte). Wir bitten um Verständnis. Es wird mit Hochdruck an der Behebung des Problems gearbeitet. Weitere Informationen zur Störung des Object Storage finden Sie hier: https://maintenance.itc.rwth-aachen.de/ticket/status/messages/59-object-storage-pilot

Commits (18)
...@@ -26,4 +26,3 @@ svnaccess ...@@ -26,4 +26,3 @@ svnaccess
*.lib *.lib
*.exp *.exp
*.log *.log
*.txt
...@@ -53,8 +53,7 @@ set( ITADataSourcesHeader ...@@ -53,8 +53,7 @@ set( ITADataSourcesHeader
"include/ITADataSourcesDefinitions.h" "include/ITADataSourcesDefinitions.h"
"include/ITAFileDataSink.h" "include/ITAFileDataSink.h"
"include/ITAFileDataSource.h" "include/ITAFileDataSource.h"
"include/ITAPeakDetector.h" "include/ITAStreamDetector.h"
"include/ITARMSDetector.h"
"include/ITAStreamAmplifier.h" "include/ITAStreamAmplifier.h"
"include/ITAStreamFunctionGenerator.h" "include/ITAStreamFunctionGenerator.h"
"include/ITAStreamModalSynthesizer.h" "include/ITAStreamModalSynthesizer.h"
...@@ -72,8 +71,7 @@ set( ITADataSourcesSources ...@@ -72,8 +71,7 @@ set( ITADataSourcesSources
"src/ITADataSourceRealization.cpp" "src/ITADataSourceRealization.cpp"
"src/ITAFileDataSink.cpp" "src/ITAFileDataSink.cpp"
"src/ITAFileDataSource.cpp" "src/ITAFileDataSource.cpp"
"src/ITAPeakDetector.cpp" "src/ITAStreamDetector.cpp"
"src/ITARMSDetector.cpp"
"src/ITAStreamAmplifier.cpp" "src/ITAStreamAmplifier.cpp"
"src/ITAStreamFunctionGenerator.cpp" "src/ITAStreamFunctionGenerator.cpp"
"src/ITAStreamModalSynthesizer.cpp" "src/ITAStreamModalSynthesizer.cpp"
......
...@@ -41,20 +41,15 @@ class ITADatasource; ...@@ -41,20 +41,15 @@ class ITADatasource;
* \param uiNumberOfSamples Anzahl der Samples * \param uiNumberOfSamples Anzahl der Samples
* \param dGain Verstärkungsfaktor (optional) * \param dGain Verstärkungsfaktor (optional)
* \param bOnline Echtzeit-Modus verwenden? (d.h. reale Dauern zwischen den * \param bOnline Echtzeit-Modus verwenden? (d.h. reale Dauern zwischen den
* Datenanforderungen verwenden). Falls false, werden die * Datenanforderungen verwenden). Falls false, werden die
* Daten direkt hintereinander angefordert (Maximaler Datendurchsatz) * Daten direkt hintereinander angefordert (Maximaler Datendurchsatz)
* \param bDisplayProgress Fortschritt auf der Konsole ausgeben? (Optional, Standard: Nein) * \param bDisplayProgress Fortschritt auf der Konsole ausgeben? (Optional, Standard: Nein)
* *
* \note Gibt die Datenquelle den Nullzeiger zurück, wird für * \note Gibt die Datenquelle den Nullzeiger zurück, wird für
* den betreffenden Block Stille in den Puffer geschrieben * den betreffenden Block Stille in den Puffer geschrieben
* \note Ausnahmebehandlung mittels der Klasse ITAException * \note Ausnahmebehandlung mittels der Klasse ITAException
*/ */
ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer(ITADatasource* pSource, ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer( ITADatasource* pSource, float** ppfDest, unsigned int uiNumberOfSamples, double dGain = 1.0, bool bOnline = true, bool bDisplayProgress = false );
float** ppfDest,
unsigned int uiNumberOfSamples,
double dGain=1.0,
bool bOnline=true,
bool bDisplayProgress=false);
//! Daten einer Datenquelle in eine Datei schreiben //! Daten einer Datenquelle in eine Datei schreiben
/** /**
...@@ -66,20 +61,14 @@ ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer(ITADatasource* pSource, ...@@ -66,20 +61,14 @@ ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer(ITADatasource* pSource,
* \param uiNumberOfSamples Anzahl der Samples * \param uiNumberOfSamples Anzahl der Samples
* \param dGain Verstärkungsfaktor (optional) * \param dGain Verstärkungsfaktor (optional)
* \param bOnline Echtzeit-Modus verwenden? (d.h. reale Dauern zwischen den * \param bOnline Echtzeit-Modus verwenden? (d.h. reale Dauern zwischen den
* Datenanforderungen verwenden). Falls false, werden die * Datenanforderungen verwenden). Falls false, werden die
* Daten direkt hintereinander angefordert (Maximaler Datendurchsatz) * Daten direkt hintereinander angefordert (Maximaler Datendurchsatz)
* \param bDisplayProgress Fortschritt auf der Konsole ausgeben? (Optional, Standard: Nein) * \param bDisplayProgress Fortschritt auf der Konsole ausgeben? (Optional, Standard: Nein)
* *
* \note Gibt die Datenquelle den Nullzeiger zurück, wird für * \note Gibt die Datenquelle den Nullzeiger zurück, wird für
* den betreffenden Block Stille in die Datei geschrieben * den betreffenden Block Stille in die Datei geschrieben
* \note Ausnahmebehandlung mittels der Klasse ITAException * \note Ausnahmebehandlung mittels der Klasse ITAException
*/ */
ITA_DATA_SOURCES_API void WriteFromDatasourceToFile(ITADatasource* pSource, ITA_DATA_SOURCES_API void WriteFromDatasourceToFile( ITADatasource* pSource, std::string sFilename, unsigned int uiNumberOfSamples, double dGain = 1.0, bool bOnline = true, bool bDisplayProgress = false );
std::string sFilename,
unsigned int uiNumberOfSamples,
double dGain=1.0,
bool bOnline=true,
bool bDisplayProgress=false);
#endif // INCLUDE_WATCHER_ITA_DATA_SOURCES_UTILS #endif // INCLUDE_WATCHER_ITA_DATA_SOURCES_UTILS
/* /*
* ---------------------------------------------------------------- * ----------------------------------------------------------------
* *
* ITA core libs * ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA) * (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017 * RWTH Aachen University, Germany, 2015-2017
* *
* ---------------------------------------------------------------- * ----------------------------------------------------------------
* ____ __________ _______ * ____ __________ _______
* // / //__ ___/ // _ | * // / //__ ___/ // _ |
* // / // / // /_| | * // / // / // /_| |
* // / // / // ___ | * // / // / // ___ |
* //__/ //__/ //__/ |__| * //__/ //__/ //__/ |__|
* *
* ---------------------------------------------------------------- * ----------------------------------------------------------------
* *
*/ */
// $Id: ITAPeakDetector.h 2900 2012-09-17 08:42:42Z stienen $
#ifndef INCLUDE_WATCHER_ITA_PEAK_DETECTOR #ifndef INCLUDE_WATCHER_ITA_PEAK_DETECTOR
#define INCLUDE_WATCHER_ITA_PEAK_DETECTOR #define INCLUDE_WATCHER_ITA_PEAK_DETECTOR
#include <ITADataSourcesDefinitions.h> #include <ITADataSourcesDefinitions.h>
#include <ITACriticalSection.h> #include <ITACriticalSection.h>
#include <ITADataSource.h> #include <ITADataSource.h>
#include <atomic>
#include <vector> #include <vector>
//! Detektor für Spitzwerte (peak values) in Audiostreams //! Detektor for statistic values in audio stream (i.e. for level metering)
/** /**
* Die Klasse ITAPeakDetector wird zwischen eine Datenquelle und einen * Die Klasse ITAStreamDetector wird zwischen eine Datenquelle und einen
* Konsumenten fr die Datenquelle geschaltet und detektiert dabei * Konsumenten fr die Datenquelle geschaltet und detektiert dabei
* die Spitzenwerte (peak values) in den Audiostreams der Kanäle der * die Spitzenwerte (peak values) und Mittelwerte (RMS) in den Audiostreams der Kanle der
* Datenquelle. Die Klasse bekommt im Konstruktor ihre Datenquelle gesetzt * Datenquelle. Die Klasse bekommt im Konstruktor ihre Datenquelle gesetzt
* und stellt selber die Schnittstelle ITADatasource zur Verfgung. * und stellt selber die Schnittstelle ITADatasource zur Verfgung.
* Aufrufe von GetBlockPointer und IncrementBlockPointer werden an die * Aufrufe von GetBlockPointer und IncrementBlockPointer werden an die
...@@ -45,23 +46,41 @@ ...@@ -45,23 +46,41 @@
* *
* \note Die Klasse ist Thread-safe * \note Die Klasse ist Thread-safe
*/ */
class ITA_DATA_SOURCES_API ITAPeakDetector : public ITADatasource { class ITA_DATA_SOURCES_API ITAStreamDetector : public ITADatasource
{
public: public:
//! Mode of detection
enum Mode
{
DEACTIVATED = -1,
PEAK_AND_RMS,
PEAK,
RMS
};
//! Konstruktor //! Konstruktor
/** /**
* \note Es darf kein Nullzeiger bergeben werden. * \note Es darf kein Nullzeiger bergeben werden.
*/ */
ITAPeakDetector(ITADatasource* pDatasource); ITAStreamDetector( ITADatasource* pDatasource, int iMode = PEAK_AND_RMS );
//! Destruktor //! Destruktor
virtual ~ITAPeakDetector(); virtual inline ~ITAStreamDetector() {};
//! Datenquelle zurckgeben //! Datenquelle zurckgeben
ITADatasource* GetDatasource() const { return m_pDataSource; } inline ITADatasource* GetDatasource() const
{
return m_pDataSource;
};
//! Messung zurcksetzen //! Messung zurcksetzen
void Reset(); void Reset();
void SetMode( const int iMode );
int GetMode() const;
//! Spitzenwert ber alle Kanle abrufen //! Spitzenwert ber alle Kanle abrufen
/** /**
* Diese Methode dient zum Abrufen des Spitzenwertes ber alle * Diese Methode dient zum Abrufen des Spitzenwertes ber alle
...@@ -71,7 +90,7 @@ public: ...@@ -71,7 +90,7 @@ public:
* so bleibt der bisherige Spitzenwert und der Kanal im dem er auftrat * so bleibt der bisherige Spitzenwert und der Kanal im dem er auftrat
* fr die weitere Analyse erhalten. * fr die weitere Analyse erhalten.
*/ */
void GetOverallPeak(float* pfPeak, unsigned int* puiChannel=0, bool bReset=true); float GetOverallPeak( int& iPeakChannelIndex, const bool bReset = true );
//! Spitzenwert ber alle Kanle in Dezibel zurckgeben //! Spitzenwert ber alle Kanle in Dezibel zurckgeben
/** /**
...@@ -79,34 +98,24 @@ public: ...@@ -79,34 +98,24 @@ public:
* symbolische Konstante DECIBEL_MINUS_INFINITY zurck * symbolische Konstante DECIBEL_MINUS_INFINITY zurck
* (siehe ITANumericUtils.h) * (siehe ITANumericUtils.h)
*/ */
void GetOverallPeakDecibel(double* pdPeakDecibel, unsigned int* puiChannel=0, bool bReset=true); double GetOverallPeakDecibel( int& iPeakChannelIndex, const bool bReset = true );
//! Spitzenwert eines Kanals zurckgeben //! Spitzenwert eines Kanals zurckgeben
/** /**
* \note Wenn Sie die Spitzenwerte aller Kanäle abrufen möchten, * \note Wenn Sie die Spitzenwerte aller Kanle abrufen mchten,
* so empfiehlt sich die Methode GetChannelPeaks, da diese schneller ist. * so empfiehlt sich die Methode GetChannelPeaks, da diese schneller ist.
*/ */
float GetPeak(unsigned int uiChannel, bool bReset=true); float GetPeak( const int iChannel, const bool bReset = true );
//! Spitzenwert eines Kanals in Dezibel zurckgeben //! Spitzenwert eines Kanals in Dezibel zurckgeben
/** /**
* \note Falls der Spitzenwert 0 ist, gibt die Methode die * \note Falls der Spitzenwert 0 ist, gibt die Methode die
* symbolische Konstante DECIBEL_MINUS_INFINITY zurck * symbolische Konstante DECIBEL_MINUS_INFINITY zurck
* (siehe ITANumericUtils.h) * (siehe ITANumericUtils.h)
* \note Wenn Sie die Spitzenwerte aller Kanäle abrufen möchten, * \note Wenn Sie die Spitzenwerte aller Kanle abrufen mchten,
* so empfiehlt sich die Methode GetChannelPeaksDecibel, da diese schneller ist. * so empfiehlt sich die Methode GetChannelPeaksDecibel, da diese schneller ist.
*/ */
double GetPeakDecibel(unsigned int uiChannel, bool bReset=true); double GetPeakDecibel( const int iChannel, bool bReset = true );
//! Spitzenwerte aller Kanäle abrufen
/**
* Diese Methode speichert die Spitzenwerte aller Kanäle im
* angegebenen Zielarray.
*
* \note Das Zielarray muß mindestens so viele Felder haben,
* wie die Datenquelle Kanäle hat
*/
void GetPeaks(float* pfDest, bool bReset=true);
//! Spitzenwerte aller Kanle abrufen //! Spitzenwerte aller Kanle abrufen
/** /**
...@@ -116,46 +125,55 @@ public: ...@@ -116,46 +125,55 @@ public:
* \note Falls der Vektor weniger Felder als Kanle hat, * \note Falls der Vektor weniger Felder als Kanle hat,
* so wird er automatisch vergrert. * so wird er automatisch vergrert.
*/ */
void GetPeaks(std::vector<float>& vfDest, bool bReset=true); void GetPeaks( std::vector< float >& vfDest, const bool bReset = true );
//! Spitzenwerte aller Kanäle in Dezibel abrufen
/**
* Diese Methode speichert die Spitzenwerte aller Kanäle
* in Dezibel im angegebenen Zielarray.
*
* \note Das Zielarray muß mindestens so viele Felder haben,
* wie die Datenquelle Kanäle hat
*/
void GetPeaksDecibel(double* pdDestDecibel, bool bReset=true);
//! Spitzenwerte aller Kanle in Dezibel abrufen //! Spitzenwerte aller Kanle in Dezibel abrufen
/** /**
* Diese Methode speichert die Spitzenwerte aller Kanäle * Diese Methode speichert die Spitzenwerte aller Kanle
* in Dezibel im angegebenen Vektor. * in Dezibel im angegebenen Vektor.
* *
* \note Falls der Vektor weniger Felder als Kanle hat, * \note Falls der Vektor weniger Felder als Kanle hat,
* so wird er automatisch vergrert. * so wird er automatisch vergrert.
*/ */
void GetPeaksDecibel(std::vector<double>& vdDestDecibel, bool bReset=true); void GetPeaksDecibel( std::vector< double >& vdDestDecibel, const bool bReset = true );
// -= Überladene Methoden von ITADatasource =- float GetOverallRMS( const bool bReset = true );
double GetOverallRMSDecibel( const bool bReset = true );
unsigned int GetBlocklength() const { return m_uiBlocklength; } float GetRMS( const int iChannel, const bool bReset = true );
unsigned int GetNumberOfChannels() const { return m_uiChannels; } double GetRMSDecibel( const int iChannel, const bool bReset = true );
double GetSampleRate() const { return m_dSamplerate; } void GetRMSs( std::vector< float >& vfDest, const bool bReset = true );
void GetRMSsDecibel( std::vector< float >& vfDestDecibel, const bool bReset = true );
virtual const float* GetBlockPointer(unsigned int uiChannel, const ITAStreamInfo* pStreamInfo);
inline unsigned int GetBlocklength() const
{
return m_iBlocklength;
};
inline unsigned int GetNumberOfChannels() const
{
return m_iChannels;
};
inline double GetSampleRate() const
{
return m_dSamplerate;
};
virtual const float* GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* pStreamInfo );
virtual void IncrementBlockPointer(); virtual void IncrementBlockPointer();
protected: protected:
ITADatasource* m_pDataSource; // Angeschlossene Datenquelle ITADatasource* m_pDataSource; //!< Angeschlossene Datenquelle
double m_dSamplerate; // Abtastrate [Hz] double m_dSamplerate; //!< Abtastrate [Hz]
unsigned int m_uiChannels; // Anzahl Kanäle int m_iChannels; //!< Anzahl Kanle
unsigned int m_uiBlocklength; // Streaming Puffergröße [Samples] int m_iBlocklength; //!< Streaming Puffergre [Samples]
ITACriticalSection m_cs; // Sichert exklusiven Zugriff auf die Daten (s.u.) std::atomic< int > m_iMode;
float* m_pfPeaks; // Spitzenwerte der einzelnen Kanäle ITACriticalSection m_cs; //!< Sichert exklusiven Zugriff auf die Daten (s.u.)
float m_fOverallPeak; // Spitzenwert über alle Kanäle std::vector< float > m_vfPeaks; //!< Spitzenwerte der einzelnen Kanle
unsigned int m_uiOverallPeakChannel; // Kanal in dem der Spitzenwert auftrat float m_fOverallPeak; //!< Spitzenwert ber alle Kanle
int m_iOverallPeakChannel; //!< Kanal in dem der Spitzenwert auftrat
std::vector< double > m_vdRMSSquaredSums;
int m_iRMSBlocks;
}; };
#endif // INCLUDE_WATCHER_ITA_PEAK_DETECTOR #endif // INCLUDE_WATCHER_ITA_PEAK_DETECTOR
\ No newline at end of file
...@@ -34,14 +34,15 @@ class ITAAudiofileWriter; ...@@ -34,14 +34,15 @@ class ITAAudiofileWriter;
//! A measuring sensor for audio streams //! A measuring sensor for audio streams
/** /**
* Instanzen der Klasse ITAStreamProbe knnen als "Messspitze" in Audiostreams * This class captures (records) the entire data stream passing through and stores
* eingehngt werden. Sie schreiben dann alle vorbeigeflossenen Daten in eine Audiodatei. * the result into a file on the hard drive.
*/ */
class ITA_DATA_SOURCES_API ITAStreamProbe : public ITADatasource class ITA_DATA_SOURCES_API ITAStreamProbe : public ITADatasource
{ {
public: public:
ITAStreamProbe( ITADatasource* pDatasource, const std::string& sFilename, ITAQuantization iQuantization = ITAQuantization::ITA_FLOAT ); ITAStreamProbe( ITADatasource* pDatasource, const std::string& sFilePath, ITAQuantization iQuantization = ITAQuantization::ITA_FLOAT );
//! Destructor also moves saples from memory to hard drive once.
virtual ~ITAStreamProbe(); virtual ~ITAStreamProbe();
inline ITADatasource* GetDatasource() const inline ITADatasource* GetDatasource() const
...@@ -49,6 +50,7 @@ public: ...@@ -49,6 +50,7 @@ public:
return m_pDataSource; return m_pDataSource;
} }
//! Deprecated
inline std::string GetFilename() const inline std::string GetFilename() const
{ {
return GetFilePath(); return GetFilePath();
......
...@@ -24,59 +24,62 @@ ...@@ -24,59 +24,62 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
void WriteFromDatasourceToBuffer(ITADatasource* pSource, void WriteFromDatasourceToBuffer( ITADatasource* pSource, float** ppfDest, unsigned int uiNumberOfSamples, double dGain, bool bOnline, bool bDisplayProgress )
float** ppfDest, {
unsigned int uiNumberOfSamples,
double dGain,
bool bOnline,
bool bDisplayProgress) {
// Nullzeiger ausschlieen // Nullzeiger ausschlieen
// TODO: Fehlerbehandlung // TODO: Fehlerbehandlung
if (!pSource) return; if( !pSource )
return;
unsigned int uiChannels = pSource->GetNumberOfChannels(); unsigned int uiChannels = pSource->GetNumberOfChannels();
double dSamplerate = pSource->GetSampleRate(); double dSamplerate = pSource->GetSampleRate();
unsigned int uiBlocklength = pSource->GetBlocklength(); unsigned int uiBlocklength = pSource->GetBlocklength();
ITAStreamInfo siState; ITAStreamInfo siState;
long periodMs = (long)ceil(uiBlocklength / dSamplerate * 1000); long periodMs = ( long ) ceil( uiBlocklength / dSamplerate * 1000 );
#ifdef _WIN32 #ifdef _WIN32
HANDLE hTimer=0; HANDLE hTimer = 0;
if (bOnline) { if( bOnline )
{
// Timer erzeugen // Timer erzeugen
if (FAILED(hTimer = CreateWaitableTimer(NULL, false, NULL))) if( FAILED( hTimer = CreateWaitableTimer( NULL, false, NULL ) ) )
ITA_EXCEPT1(UNKNOWN, "Timer konnte nicht erzeugt werden"); ITA_EXCEPT1( UNKNOWN, "Timer konnte nicht erzeugt werden" );
LARGE_INTEGER liDueTime; LARGE_INTEGER liDueTime;
liDueTime.QuadPart = 0; liDueTime.QuadPart = 0;
SetWaitableTimer(hTimer, &liDueTime, periodMs, NULL, NULL, true); SetWaitableTimer( hTimer, &liDueTime, periodMs, NULL, NULL, true );
} }
#endif #endif
try { try {
unsigned int n=0; unsigned int n = 0;
float fProgress = 0.0f; float fProgress = 0.0f;
while (n < uiNumberOfSamples) while( n < uiNumberOfSamples )
{ {
#ifdef _WIN32 #ifdef _WIN32
// Warten // Warten
if (bOnline) WaitForSingleObject(hTimer, INFINITE); if( bOnline )
WaitForSingleObject( hTimer, INFINITE );
#else #else
if (bOnline) usleep(periodMs * 1000); if( bOnline )
usleep( periodMs * 1000 );
#endif #endif
// Daten von der Quelle holen // Daten von der Quelle holen
for (unsigned int i=0; i<uiChannels; i++) { for( unsigned int i = 0; i < uiChannels; i++ )
const float* pfData = pSource->GetBlockPointer(i, &siState); {
const float* pfData = pSource->GetBlockPointer( i, &siState );
unsigned int k = (uiNumberOfSamples - n); unsigned int k = ( uiNumberOfSamples - n );
if (k > uiBlocklength) k = uiBlocklength; if( k > uiBlocklength )
k = uiBlocklength;
if( !pfData ) if( !pfData )
{ // Stille einfgen {
// Stille einfgen
for( unsigned int j = 0; j < uiBlocklength; j++ ) for( unsigned int j = 0; j < uiBlocklength; j++ )
ppfDest[ i ][ n + j ] = 0; ppfDest[ i ][ n + j ] = 0;
} }
...@@ -94,52 +97,52 @@ void WriteFromDatasourceToBuffer(ITADatasource* pSource, ...@@ -94,52 +97,52 @@ void WriteFromDatasourceToBuffer(ITADatasource* pSource,
n += uiBlocklength; n += uiBlocklength;
siState.nSamples += uiBlocklength; siState.nSamples += uiBlocklength;
siState.dStreamTimeCode = (double) (siState.nSamples) / dSamplerate; siState.dStreamTimeCode = ( double ) ( siState.nSamples ) / dSamplerate;
siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime(); siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
if (bDisplayProgress) if( bDisplayProgress )
{ {
float p = 100 * (float) n / uiNumberOfSamples; float p = 100 * ( float ) n / uiNumberOfSamples;
if(p > fProgress + 5.0f) if( p > fProgress + 5.0f )
{ {
fProgress = p; fProgress = p;
printf("WriteFromDatasourceToBuffer: %0.2f%% geschrieben", p); printf( "WriteFromDatasourceToBuffer: %0.2f%% geschrieben", p );
} }
} }
} }
} catch (...) { }
catch( ... )
{
#ifdef _WIN32 #ifdef _WIN32
if (bOnline) CloseHandle(hTimer); if( bOnline )
CloseHandle( hTimer );
#endif #endif
throw; throw;
} }
if (bDisplayProgress) if( bDisplayProgress )
printf("WriteFromDatasourceToBuffer: 100,00%% geschrieben"); printf( "WriteFromDatasourceToBuffer: 100,00%% geschrieben" );
#ifdef _WIN32 #ifdef _WIN32
if (bOnline) if( bOnline )
CloseHandle(hTimer); CloseHandle( hTimer );
#endif #endif
} }
void WriteFromDatasourceToFile(ITADatasource* pSource, void WriteFromDatasourceToFile( ITADatasource* pSource, std::string sFilename, unsigned int uiNumberOfSamples, double dGain, bool bOnline, bool bDisplayProgress )
std::string sFilename, {
unsigned int uiNumberOfSamples,
double dGain,
bool bOnline,
bool bDisplayProgress) {
// Nullzeiger ausschlieen // Nullzeiger ausschlieen
// TODO: Fehlerbehandlung // TODO: Fehlerbehandlung
if (!pSource) return; if( !pSource )
return;
unsigned int uiChannels = pSource->GetNumberOfChannels(); unsigned int uiChannels = pSource->GetNumberOfChannels();
unsigned int uiBlocklength = pSource->GetBlocklength(); unsigned int uiBlocklength = pSource->GetBlocklength();
double dSamplerate = pSource->GetSampleRate(); double dSamplerate = pSource->GetSampleRate();
std::vector<float*> vpfData; std::vector<float*> vpfData;
for (unsigned int i=0; i<uiChannels; i++) for( unsigned int i = 0; i < uiChannels; i++ )
vpfData.push_back(new float[uiBlocklength]); vpfData.push_back( new float[ uiBlocklength ] );
ITAAudiofileProperties props; ITAAudiofileProperties props;
props.iChannels = uiChannels; props.iChannels = uiChannels;
...@@ -147,91 +150,103 @@ void WriteFromDatasourceToFile(ITADatasource* pSource, ...@@ -147,91 +150,103 @@ void WriteFromDatasourceToFile(ITADatasource* pSource,
props.eQuantization = ITAQuantization::ITA_FLOAT; props.eQuantization = ITAQuantization::ITA_FLOAT;
props.eDomain = ITADomain::ITA_TIME_DOMAIN; props.eDomain = ITADomain::ITA_TIME_DOMAIN;
props.iLength = uiNumberOfSamples; props.iLength = uiNumberOfSamples;
ITAAudiofileWriter* writer = ITAAudiofileWriter::create(sFilename, props); ITAAudiofileWriter* writer = ITAAudiofileWriter::create( sFilename, props );
ITAStreamInfo siState; ITAStreamInfo siState;
long periodMs = (long)ceil(uiBlocklength / dSamplerate * 1000); long periodMs = ( long ) ceil( uiBlocklength / dSamplerate * 1000 );
#ifdef _WIN32 #ifdef _WIN32
HANDLE hTimer=0; HANDLE hTimer = 0;
if (bOnline) { if( bOnline )
{
// Timer erzeugen // Timer erzeugen
if (FAILED(hTimer = CreateWaitableTimer(NULL, false, NULL))) { if( FAILED( hTimer = CreateWaitableTimer( NULL, false, NULL ) ) )
{
delete writer; delete writer;
ITA_EXCEPT1(UNKNOWN, "Timer konnte nicht erzeugt werden"); ITA_EXCEPT1( UNKNOWN, "Timer konnte nicht erzeugt werden" );
} }
LARGE_INTEGER liDueTime; LARGE_INTEGER liDueTime;
liDueTime.QuadPart=0; liDueTime.QuadPart = 0;
SetWaitableTimer(hTimer, &liDueTime, periodMs, NULL, NULL, true); SetWaitableTimer( hTimer, &liDueTime, periodMs, NULL, NULL, true );
} }
#endif #endif
try { try {
unsigned int n=0; unsigned int n = 0;
float fProgress = 0.0; float fProgress = 0.0;
while (n < uiNumberOfSamples) { while( n < uiNumberOfSamples )
{
#ifdef _WIN32 #ifdef _WIN32
// Warten // Warten
if (bOnline) WaitForSingleObject(hTimer, INFINITE); if( bOnline )
WaitForSingleObject( hTimer, INFINITE );
#else #else
if (bOnline) usleep(periodMs * 1000); if( bOnline )
usleep( periodMs * 1000 );
#endif #endif
// Daten von der Quelle holen // Daten von der Quelle holen
for (unsigned int i=0; i<uiChannels; i++) { for( unsigned int i = 0; i < uiChannels; i++ )
const float* pfSource = pSource->GetBlockPointer(i, &siState); {
float* pfDest = vpfData[i]; const float* pfSource = pSource->GetBlockPointer( i, &siState );
if (!pfSource) float* pfDest = vpfData[ i ];
if( !pfSource )
{
// Stille einfgen // Stille einfgen
for (unsigned int j=0; j<uiBlocklength; j++) pfDest[j] = 0; for( unsigned int j = 0; j < uiBlocklength; j++ )
else { pfDest[ j ] = 0;
if (dGain == 1) }
memcpy(pfDest, pfSource, uiBlocklength*sizeof(float)); else
else {
for (unsigned int j=0; j<uiBlocklength; j++) if( dGain == 1 )
pfDest[j] = pfSource[j] * (float) dGain; memcpy( pfDest, pfSource, uiBlocklength*sizeof( float ) );
else
for( unsigned int j = 0; j < uiBlocklength; j++ )
pfDest[ j ] = pfSource[ j ] * ( float ) dGain;
} }
} }
pSource->IncrementBlockPointer(); pSource->IncrementBlockPointer();
siState.nSamples += uiBlocklength; siState.nSamples += uiBlocklength;
siState.dStreamTimeCode = (double) (siState.nSamples) / dSamplerate; siState.dStreamTimeCode = ( double ) ( siState.nSamples ) / dSamplerate;
siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime(); siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
// Daten schreiben // Daten schreiben
writer->write((std::min)(uiBlocklength, (uiNumberOfSamples - n)), vpfData); writer->write( ( std::min )( uiBlocklength, ( uiNumberOfSamples - n ) ), vpfData );
n += uiBlocklength; n += uiBlocklength;
if (bDisplayProgress) if( bDisplayProgress )
{ {
float p = 100 * (float) n / uiNumberOfSamples; float p = 100 * ( float ) n / uiNumberOfSamples;
if(p > fProgress + 5.0f) if( p > fProgress + 5.0f )
{ {
fProgress = p; fProgress = p;
printf("WriteFromDatasourceToFile: %0.2f%% geschrieben\r", p); printf( "WriteFromDatasourceToFile: %0.2f%% written\r", p );
} }
} }
} }
} catch (...) { }
catch( ... )
{
#ifdef _WIN32 #ifdef _WIN32
if (bOnline) CloseHandle(hTimer); if( bOnline )
CloseHandle( hTimer );
#endif #endif
delete writer; delete writer;
throw; throw;
} }
if (bDisplayProgress) if( bDisplayProgress )
printf("WriteFromDatasourceToFile: 100,00%% geschrieben\r"); printf( "WriteFromDatasourceToFile: 100,00%% written\r" );
#ifdef _WIN32 #ifdef _WIN32
if (bOnline) if( bOnline )
CloseHandle(hTimer); CloseHandle( hTimer );
#endif #endif
delete writer; delete writer;
} }
#include "ITAPeakDetector.h"
#include <ITAException.h>
#include <ITANumericUtils.h>
#include <cmath>
ITAPeakDetector::ITAPeakDetector( ITADatasource* pDataSource )
: m_pDataSource( pDataSource )
{
m_dSamplerate = pDataSource->GetSampleRate();
m_uiChannels = pDataSource->GetNumberOfChannels();
m_uiBlocklength = pDataSource->GetBlocklength();
m_pfPeaks = 0;
// Unspezifizierte Parameter werden nicht erlaubt!
if ((m_uiBlocklength == 0) ||
(m_uiChannels == 0) ||
(m_dSamplerate == 0)) ITA_EXCEPT0(INVALID_PARAMETER);
// Analyse-Resourcen anlegen
m_pfPeaks = new float[m_uiChannels];
Reset();
}
ITAPeakDetector::~ITAPeakDetector() {
// Analyse-Resourcen freigeben
delete[] m_pfPeaks;
};
void ITAPeakDetector::Reset() {
m_cs.enter();
for (unsigned int c=0; c<m_uiChannels; c++) m_pfPeaks[c] = 0.00001f;
m_fOverallPeak = 0;
m_uiOverallPeakChannel = 0;
m_cs.leave();
}
void ITAPeakDetector::GetOverallPeak(float* pfPeak, unsigned int* puiChannel, bool bReset) {
m_cs.enter();
if (pfPeak) *pfPeak = m_fOverallPeak;
if (puiChannel) *puiChannel = m_uiOverallPeakChannel;
if (bReset) {
m_fOverallPeak = 0;
m_uiOverallPeakChannel = 0;
}
m_cs.leave();
}
void ITAPeakDetector::GetOverallPeakDecibel(double* pdPeakDecibel, unsigned int* puiChannel, bool bReset) {
m_cs.enter();
if (pdPeakDecibel) *pdPeakDecibel = ratio_to_db20(m_fOverallPeak);
if (puiChannel) *puiChannel = m_uiOverallPeakChannel;
if (bReset) {
m_fOverallPeak = 0;
m_uiOverallPeakChannel = 0;
}
m_cs.leave();
}
float ITAPeakDetector::GetPeak(unsigned int uiChannel, bool bReset) {
// Bereichsprfung des Kanalindex
if (uiChannel >= m_uiChannels) ITA_EXCEPT0(INVALID_PARAMETER);
m_cs.enter();
float fResult = m_pfPeaks[uiChannel];
if (bReset) m_pfPeaks[uiChannel] = 0;
m_cs.leave();
return fResult;
}
double ITAPeakDetector::GetPeakDecibel(unsigned int uiChannel, bool bReset) {
return ratio_to_db20(GetPeak(uiChannel));
}
void ITAPeakDetector::GetPeaks(float* pfDest, bool bReset) {
// Nullzeiger abfangen
if (!pfDest) ITA_EXCEPT0(INVALID_PARAMETER);
m_cs.enter();
for (unsigned int c=0; c<m_uiChannels; c++) {
pfDest[c] = m_pfPeaks[c];
if (bReset) m_pfPeaks[c] = 0;
}
m_cs.leave();
}
void ITAPeakDetector::GetPeaks(std::vector<float>& vfDest, bool bReset) {
// Vektor konditionieren
if (((unsigned int) vfDest.size()) < m_uiChannels) vfDest.resize(m_uiChannels);
m_cs.enter();
for (unsigned int c=0; c<m_uiChannels; c++) {
vfDest[c] = m_pfPeaks[c];
if (bReset) m_pfPeaks[c] = 0;
}
m_cs.leave();
}
void ITAPeakDetector::GetPeaksDecibel(double* pdDestDecibel, bool bReset) {
// Nullzeiger abfangen
if (!pdDestDecibel) ITA_EXCEPT0(INVALID_PARAMETER);
m_cs.enter();
for (unsigned int c=0; c<m_uiChannels; c++) {
pdDestDecibel[c] = ratio_to_db20(m_pfPeaks[c]);
if (bReset) m_pfPeaks[c] = 0;
}
m_cs.leave();
}
void ITAPeakDetector::GetPeaksDecibel(std::vector<double>& vdDestDecibel, bool bReset) {
// Vektor konditionieren
if (((unsigned int) vdDestDecibel.size()) < m_uiChannels) vdDestDecibel.resize(m_uiChannels);
m_cs.enter();
for (unsigned int c=0; c<m_uiChannels; c++) {
vdDestDecibel[c] = ratio_to_db20(m_pfPeaks[c]);
if (bReset) m_pfPeaks[c] = 0;
}
m_cs.leave();
}
const float* ITAPeakDetector::GetBlockPointer(unsigned int uiChannel, const ITAStreamInfo* pStreamInfo) {
// Datenzeiger seinerseits bei der angeschlossenen Datenquelle abrufen
const float* pfData = m_pDataSource->GetBlockPointer(uiChannel, pStreamInfo);
if (pfData) {
// TODO: Ist es wirklich ntig bei jedem GBP die CS zu betreten? :-(
m_cs.enter();
// Daten analysieren
for (unsigned int i=0; i<m_uiBlocklength; i++) {
float fAbs = std::abs(pfData[i]);
if (fAbs > m_pfPeaks[uiChannel]) m_pfPeaks[uiChannel] = fAbs;
if (fAbs > m_fOverallPeak) {
m_fOverallPeak = fAbs;
m_uiOverallPeakChannel = uiChannel;
}
}
m_cs.leave();
}
// Daten "weitergeben"
return pfData;
}
void ITAPeakDetector::IncrementBlockPointer() {
// Blockzeiger der angeschlossenen Datenquelle inkrementieren
m_pDataSource->IncrementBlockPointer();
}
#include "ITAStreamDetector.h"
#include <ITAConstants.h>
#include <ITAException.h>
#include <ITANumericUtils.h>
#include <cmath>
ITAStreamDetector::ITAStreamDetector( ITADatasource* pDataSource, const int iMode )
: m_pDataSource( pDataSource )
, m_iMode( iMode )
{
m_dSamplerate = pDataSource->GetSampleRate();
m_iChannels = int( pDataSource->GetNumberOfChannels() );
m_iBlocklength = int( pDataSource->GetBlocklength() );
// Unspezifizierte Parameter werden nicht erlaubt!
if( ( m_iBlocklength == 0 ) || ( m_iChannels == 0 ) || ( m_dSamplerate == 0 ) )
ITA_EXCEPT1( INVALID_PARAMETER, "Could not create stream detector" );
m_vfPeaks.resize( m_iChannels, 0.0f );
m_vdRMSSquaredSums.resize( m_iChannels, 0.0f );
Reset();
}
void ITAStreamDetector::Reset()
{
m_cs.enter();
for( size_t c = 0; c < m_vfPeaks.size(); c++ )
{
m_vfPeaks[ c ] = 0.0f;
m_vdRMSSquaredSums[ c ] = 0.0f;
}
m_fOverallPeak = 0;
m_iOverallPeakChannel = 0;
m_iRMSBlocks = 0;
m_cs.leave();
}
int ITAStreamDetector::GetMode() const
{
return m_iMode;
}
void ITAStreamDetector::SetMode( const int iMode )
{
if( iMode < ITAStreamDetector::DEACTIVATED || iMode > ITAStreamDetector::RMS )
ITA_EXCEPT1( INVALID_PARAMETER, "Unkown mode for a stream detector" );
m_iMode = iMode;
}
float ITAStreamDetector::GetOverallPeak( int& iChannel, const bool bReset )
{
if( m_iMode != ITAStreamDetector::PEAK && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
m_cs.enter();
iChannel = m_iOverallPeakChannel;
const float fOverallPeak = m_fOverallPeak;
if( bReset )
{
m_fOverallPeak = 0;
m_iOverallPeakChannel = 0;
}
m_cs.leave();
return fOverallPeak;
}
double ITAStreamDetector::GetOverallPeakDecibel( int& iChannel, const bool bReset )
{
if( m_iMode != ITAStreamDetector::PEAK && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
m_cs.enter();
const double dOverallPeakDB = ratio_to_db20( m_fOverallPeak );
iChannel = m_iOverallPeakChannel;
if( bReset )
{
m_fOverallPeak = 0;
m_iOverallPeakChannel = 0;
}
m_cs.leave();
return dOverallPeakDB;
}
float ITAStreamDetector::GetPeak( const int iChannel, const bool bReset )
{
if( m_iMode != ITAStreamDetector::PEAK && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
if( iChannel >= m_iChannels )
ITA_EXCEPT1( INVALID_PARAMETER, "Invalid channel number, can not get peak" );
m_cs.enter();
const float fResult = m_vfPeaks[ iChannel ];
if( bReset )
{
m_vfPeaks[ iChannel ] = 0.0f;
}
m_cs.leave();
return fResult;
}
double ITAStreamDetector::GetPeakDecibel( int iChannel, const bool bReset )
{
return ratio_to_db20( GetPeak( iChannel, bReset ) );
}
void ITAStreamDetector::GetPeaks( std::vector< float >& vfDest, const bool bReset )
{
if( m_iMode != ITAStreamDetector::PEAK && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
m_cs.enter();
vfDest = m_vfPeaks;
if( bReset )
{
m_fOverallPeak = 0.0f;
for( size_t c = 0; c < m_iChannels; c++ )
m_vfPeaks[ c ] = 0.0f;
}
m_cs.leave();
}
void ITAStreamDetector::GetPeaksDecibel( std::vector< double >& vdDestDecibel, const bool bReset )
{
if( m_iMode != ITAStreamDetector::PEAK && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
if( vdDestDecibel.size() != m_vfPeaks.size() )
vdDestDecibel.resize( m_vfPeaks.size() );
m_cs.enter();
for( size_t c = 0; c < m_vfPeaks.size(); c++ )
{
vdDestDecibel[ c ] = ratio_to_db20( m_vfPeaks[ c ] );
if( bReset )
m_vfPeaks[ c ] = 0.0f;
}
m_cs.leave();
}
float ITAStreamDetector::GetOverallRMS( const bool bReset )
{
if( m_iMode != ITAStreamDetector::RMS && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
m_cs.enter();
if( m_iRMSBlocks == 0 )
return 0.0f;
double dOverallRMSSums = 0;
for( size_t i = 0; i < m_vdRMSSquaredSums.size(); i++ )
dOverallRMSSums += m_vdRMSSquaredSums[ i ] / double( m_iRMSBlocks * m_iBlocklength );
const float fOverallRMS = float( std::sqrt( dOverallRMSSums / double( m_iChannels ) ) ); // RMS over all channels
if( bReset )
{
m_iRMSBlocks = 0;
m_vdRMSSquaredSums.resize( m_iChannels, 0.0f );
}
m_cs.leave();
return fOverallRMS;
}
double ITAStreamDetector::GetOverallRMSDecibel( const bool bReset )
{
return ratio_to_db20( GetOverallRMS( bReset ) );
}
float ITAStreamDetector::GetRMS( const int iChannel, const bool bReset )
{
if( m_iMode != ITAStreamDetector::RMS && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
if( iChannel >= m_iChannels )
ITA_EXCEPT1( INVALID_PARAMETER, "Invalid channel number, can not get peak" );
m_cs.enter();
const float fResult = std::sqrt( float( m_vdRMSSquaredSums[ iChannel ] / double( m_iRMSBlocks *m_iBlocklength ) ) );
if( bReset )
m_vdRMSSquaredSums[ iChannel ] = 0.0f;
m_cs.leave();
return fResult;
}
double ITAStreamDetector::GetRMSDecibel( int iChannel, const bool bReset )
{
return ratio_to_db20( GetRMS( iChannel, bReset ) );
}
void ITAStreamDetector::GetRMSs( std::vector< float >& vfDest, const bool bReset )
{
if( m_iMode != ITAStreamDetector::RMS && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
m_cs.enter();
vfDest.resize( m_vdRMSSquaredSums.size(), 0.0f );
if( m_iRMSBlocks == 0 )
return;
for( size_t c = 0; c < m_vdRMSSquaredSums.size(); c++ )
vfDest[ c ] = float( std::sqrt( ( m_vdRMSSquaredSums[ c ] / double( m_iRMSBlocks ) ) ) ); // RMS
if( bReset )
m_vdRMSSquaredSums.resize( m_iChannels, 0.0f );
m_cs.leave();
}
void ITAStreamDetector::GetRMSsDecibel( std::vector< float >& vdDestDecibel, const bool bReset )
{
if( m_iMode != ITAStreamDetector::RMS && m_iMode != ITAStreamDetector::PEAK_AND_RMS )
ITA_EXCEPT1( MODAL_EXCEPTION, "Can not provide stream detector data because it is not calculated in this mode" );
vdDestDecibel.resize( m_vdRMSSquaredSums.size(), ITAConstants::MINUS_INFINITY_F );
if( m_iRMSBlocks == 0 )
return;
for( size_t c = 0; c < m_vdRMSSquaredSums.size(); c++ )
vdDestDecibel[ c ] = float( ratio_to_db20( std::sqrt( m_vdRMSSquaredSums[ c ] / double( m_iRMSBlocks * m_iBlocklength ) ) ) ); // RMS
if( bReset )
m_vdRMSSquaredSums.resize( m_iChannels, 0.0f );
m_cs.leave();
}
const float* ITAStreamDetector::GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* pStreamInfo )
{
const float* pfData = m_pDataSource->GetBlockPointer( uiChannel, pStreamInfo );
if( pfData && m_iMode != ITAStreamDetector::DEACTIVATED )
{
m_cs.enter();
if( m_iMode == ITAStreamDetector::PEAK || m_iMode == ITAStreamDetector::PEAK_AND_RMS )
{
for( int i = 0; i < m_iBlocklength; i++ )
{
const float fAbs = std::abs( pfData[ i ] );
if( fAbs > m_vfPeaks[ uiChannel ] )
m_vfPeaks[ uiChannel ] = fAbs;
if( fAbs > m_fOverallPeak )
{
m_fOverallPeak = fAbs;
m_iOverallPeakChannel = uiChannel;
}
}
}
if( m_iMode == ITAStreamDetector::RMS || m_iMode == ITAStreamDetector::PEAK_AND_RMS )
{
for( int i = 0; i < m_iBlocklength; i++ )
{
const float fSampleValue = std::abs( pfData[ i ] );
m_vdRMSSquaredSums[ uiChannel ] += fSampleValue * fSampleValue; // square & sum
}
}
m_cs.leave();
}
return pfData;
}
void ITAStreamDetector::IncrementBlockPointer()
{
m_iRMSBlocks++;
m_pDataSource->IncrementBlockPointer();
}
#include "ITAStreamFunctionGenerator.h" #include "ITAStreamFunctionGenerator.h"
#include <ITAConstants.h> #include <ITAConstants.h>
#include <ITADataSourceRealization.h> #include <ITADataSourceRealization.h>
...@@ -13,28 +13,20 @@ ...@@ -13,28 +13,20 @@
#include <memory.h> #include <memory.h>
#endif #endif
ITAStreamFunctionGenerator::ITAStreamFunctionGenerator(unsigned int uiChannels, ITAStreamFunctionGenerator::ITAStreamFunctionGenerator( unsigned int uiChannels, double dSamplerate, unsigned int uiBlocklength, int iSignalFunction, double dFrequency, float fAmplitude, bool bPeriodic )
double dSamplerate, : ITADatasourceRealization( uiChannels, dSamplerate, uiBlocklength ),
unsigned int uiBlocklength, m_iFunction( iSignalFunction ),
int iSignalFunction, m_bPeriodic( bPeriodic ),
double dFrequency, m_bMuted( false ),
float fAmplitude, m_fAmplitude( fAmplitude ),
bool bPeriodic) m_iSampleCount( 0 ),
: ITADatasourceRealization(uiChannels, dSamplerate, uiBlocklength), m_fPhase( 0.0f )
{
// Initial values assert( uiChannels > 0 );
m_iFunction(iSignalFunction), assert( dSamplerate > 0 );
m_bPeriodic(bPeriodic), assert( uiBlocklength > 0 );
m_bMuted(false),
m_fAmplitude(fAmplitude), SetFrequency( dFrequency );
m_iSampleCount(0),
m_fPhase(0.0f)
{
assert(uiChannels > 0);
assert(dSamplerate > 0);
assert(uiBlocklength > 0);
SetFrequency(dFrequency);
Reset(); Reset();
} }
...@@ -49,20 +41,20 @@ int ITAStreamFunctionGenerator::GetFunction() const ...@@ -49,20 +41,20 @@ int ITAStreamFunctionGenerator::GetFunction() const
return m_iFunction; return m_iFunction;
} }
void ITAStreamFunctionGenerator::SetFunction(int iFunction) void ITAStreamFunctionGenerator::SetFunction( int iFunction )
{ {
m_iFunction = iFunction; m_iFunction = iFunction;
} }
double ITAStreamFunctionGenerator::GetFrequency() const double ITAStreamFunctionGenerator::GetFrequency() const
{ {
return m_dSampleRate / (double) m_iPeriodLengthSamples; return m_dSampleRate / ( double ) m_iPeriodLengthSamples;
} }
void ITAStreamFunctionGenerator::SetFrequency(double dFrequency) void ITAStreamFunctionGenerator::SetFrequency( double dFrequency )
{ {
assert( dFrequency >= 0 ); assert( dFrequency >= 0 );
m_iPeriodLengthSamples = (int) round( m_dSampleRate / dFrequency ); m_iPeriodLengthSamples = ( int ) round( m_dSampleRate / dFrequency );
} }
int ITAStreamFunctionGenerator::GetPeriodAsSamples() const int ITAStreamFunctionGenerator::GetPeriodAsSamples() const
...@@ -70,7 +62,7 @@ int ITAStreamFunctionGenerator::GetPeriodAsSamples() const ...@@ -70,7 +62,7 @@ int ITAStreamFunctionGenerator::GetPeriodAsSamples() const
return m_iPeriodLengthSamples; return m_iPeriodLengthSamples;
} }
void ITAStreamFunctionGenerator::SetPeriodAsSamples(int iNumSamples) void ITAStreamFunctionGenerator::SetPeriodAsSamples( int iNumSamples )
{ {
assert( iNumSamples >= 0 ); assert( iNumSamples >= 0 );
m_iPeriodLengthSamples = iNumSamples; m_iPeriodLengthSamples = iNumSamples;
...@@ -78,12 +70,12 @@ void ITAStreamFunctionGenerator::SetPeriodAsSamples(int iNumSamples) ...@@ -78,12 +70,12 @@ void ITAStreamFunctionGenerator::SetPeriodAsSamples(int iNumSamples)
double ITAStreamFunctionGenerator::GetPeriodAsTime() const double ITAStreamFunctionGenerator::GetPeriodAsTime() const
{ {
return (double) m_iPeriodLengthSamples / m_dSampleRate; return ( double ) m_iPeriodLengthSamples / m_dSampleRate;
} }
void ITAStreamFunctionGenerator::SetPeriodAsTime(double dPeriodLength) void ITAStreamFunctionGenerator::SetPeriodAsTime( double dPeriodLength )
{ {
m_iPeriodLengthSamples = (int) round(dPeriodLength * m_dSampleRate); m_iPeriodLengthSamples = ( int ) round( dPeriodLength * m_dSampleRate );
} }
bool ITAStreamFunctionGenerator::IsPeriodic() const bool ITAStreamFunctionGenerator::IsPeriodic() const
...@@ -91,7 +83,7 @@ bool ITAStreamFunctionGenerator::IsPeriodic() const ...@@ -91,7 +83,7 @@ bool ITAStreamFunctionGenerator::IsPeriodic() const
return m_bPeriodic; return m_bPeriodic;
} }
void ITAStreamFunctionGenerator::SetPeriodic(bool bPeriodic) void ITAStreamFunctionGenerator::SetPeriodic( bool bPeriodic )
{ {
m_bPeriodic = bPeriodic; m_bPeriodic = bPeriodic;
} }
...@@ -101,7 +93,7 @@ bool ITAStreamFunctionGenerator::IsMuted() const ...@@ -101,7 +93,7 @@ bool ITAStreamFunctionGenerator::IsMuted() const
return m_bMuted; return m_bMuted;
} }
void ITAStreamFunctionGenerator::SetMuted(bool bMuted) void ITAStreamFunctionGenerator::SetMuted( bool bMuted )
{ {
m_bMuted = bMuted; m_bMuted = bMuted;
} }
...@@ -111,112 +103,115 @@ float ITAStreamFunctionGenerator::GetAmplitude() const ...@@ -111,112 +103,115 @@ float ITAStreamFunctionGenerator::GetAmplitude() const
return m_fAmplitude; return m_fAmplitude;
} }
void ITAStreamFunctionGenerator::SetAmplitude(float fAmplitude) void ITAStreamFunctionGenerator::SetAmplitude( float fAmplitude )
{ {
m_fAmplitude = (float) fAmplitude; m_fAmplitude = ( float ) fAmplitude;
} }
void ITAStreamFunctionGenerator::ProcessStream(const ITAStreamInfo* pStreamInfo) void ITAStreamFunctionGenerator::ProcessStream( const ITAStreamInfo* )
{ {
// Generate the next output samples // Generate the next output samples
float* pfOutputData = GetWritePointer(0); float* pfOutputData = GetWritePointer( 0 );
fm_zero(pfOutputData, m_uiBlocklength); fm_zero( pfOutputData, m_uiBlocklength );
// Variables // Variables
int N = m_iPeriodLengthSamples; int N = m_iPeriodLengthSamples;
float a = m_fAmplitude; float a = m_fAmplitude;
float omega; float omega;
float gradient = a / (float) (N-1); // Steigung der Sgezahn und Dreieck float gradient = a / ( float ) ( N - 1 ); // Steigung der Sgezahn und Dreieck
int iZero; // Offset bergang 1=>0 bei Rechteck int iZero; // Offset bergang 1=>0 bei Rechteck
int iNumSamples; // Anzahl zu erzeugender Samples int iNumSamples; // Anzahl zu erzeugender Samples
switch (m_iFunction) { switch( m_iFunction ) {
case SINE: case SINE:
omega = ITAConstants::TWO_PI_F / (float) N; // 2*pi/T omega = ITAConstants::TWO_PI_F / ( float ) N; // 2*pi/T
iNumSamples = m_bPeriodic ? (int) m_uiBlocklength : (std::min)( (int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount); iNumSamples = m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount );
for (int i=0;i<iNumSamples;i++) { for( int i = 0; i < iNumSamples; i++ ) {
pfOutputData[i] = a * sin(omega*i + m_fPhase); pfOutputData[ i ] = a * sin( omega*i + m_fPhase );
} }
m_fPhase = fmodf( iNumSamples*omega + m_fPhase, ITAConstants::TWO_PI_F ); m_fPhase = fmodf( iNumSamples*omega + m_fPhase, ITAConstants::TWO_PI_F );
m_iSampleCount += iNumSamples; m_iSampleCount += iNumSamples;
break; break;
case TRIANGLE: case TRIANGLE:
iNumSamples = (m_bPeriodic ? (int)m_uiBlocklength : (std::min)( (int)m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount) ); iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
for (int i=0;i<iNumSamples;i++) { for( int i = 0; i < iNumSamples; i++ )
float x = fmodf((float) m_iSampleCount++, (float) m_iPeriodLengthSamples); {
float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
pfOutputData[i] = x < N/2 ? 2*(x*gradient) : 2*((-x*gradient)+a); pfOutputData[ i ] = x < N / 2 ? 2 * ( x*gradient ) : 2 * ( ( -x*gradient ) + a );
} }
break; break;
case SAWTOOTH: // Sgezahn case SAWTOOTH: // Sgezahn
iNumSamples = (m_bPeriodic ? (int) m_uiBlocklength : (std::min)( (int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount) ); iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
for (int i=0;i<iNumSamples;i++) {
float x = fmodf((float) m_iSampleCount++, (float) m_iPeriodLengthSamples); for( int i = 0; i < iNumSamples; i++ ) {
pfOutputData[i] = a * (x*gradient);
float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
pfOutputData[ i ] = a * ( x*gradient );
} }
break; break;
case RECTANGLE: case RECTANGLE:
// Position des Wechsels von 1 zu 0 innerhalb einer Periode // Position des Wechsels von 1 zu 0 innerhalb einer Periode
iZero = (int)(m_iPeriodLengthSamples / 2); iZero = ( int ) ( m_iPeriodLengthSamples / 2 );
iNumSamples = (m_bPeriodic ? (int) m_uiBlocklength : (std::min)((int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount) ); iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
for (int i=0; i<iNumSamples; i++) for( int i = 0; i < iNumSamples; i++ )
{ {
// Position innerhalb einer Periodenlnge // Position innerhalb einer Periodenlnge
float x = fmodf((float) m_iSampleCount++, (float) m_iPeriodLengthSamples); float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
int iOffset = (int) roundf(x); int iOffset = ( int ) roundf( x );
pfOutputData[i] = (iOffset < iZero ? a : 0); pfOutputData[ i ] = ( iOffset < iZero ? a : 0 );
} }
break; break;
case DIRAC: case DIRAC:
iNumSamples = (m_bPeriodic ? (int) m_uiBlocklength : (std::min)( (int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) ); iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
if (m_bPeriodic) { if( m_bPeriodic )
{
for (int i=0;i<iNumSamples;i++) pfOutputData[i] = ( m_iSampleCount++ % N ? 0 : a );
} else { for( int i = 0; i < iNumSamples; i++ ) pfOutputData[ i ] = ( m_iSampleCount++ % N ? 0 : a );
pfOutputData[0] = (m_iSampleCount == 0 ? a : 0); }
for (int i=1;i<iNumSamples;i++) pfOutputData[i] = 0; else {
pfOutputData[ 0 ] = ( m_iSampleCount == 0 ? a : 0 );
for( int i = 1; i < iNumSamples; i++ ) pfOutputData[ i ] = 0;
m_iSampleCount += iNumSamples; m_iSampleCount += iNumSamples;
} }
break; break;
case WHITE_NOISE: case WHITE_NOISE:
srand( 100 );
for( unsigned int i = 0; i < m_uiBlocklength; i++ )
pfOutputData[ i ] = a * ( float ) rand() / RAND_MAX;
srand(100); break;