Commits (18)
......@@ -26,4 +26,3 @@ svnaccess
*.lib
*.exp
*.log
*.txt
......@@ -53,8 +53,7 @@ set( ITADataSourcesHeader
"include/ITADataSourcesDefinitions.h"
"include/ITAFileDataSink.h"
"include/ITAFileDataSource.h"
"include/ITAPeakDetector.h"
"include/ITARMSDetector.h"
"include/ITAStreamDetector.h"
"include/ITAStreamAmplifier.h"
"include/ITAStreamFunctionGenerator.h"
"include/ITAStreamModalSynthesizer.h"
......@@ -72,8 +71,7 @@ set( ITADataSourcesSources
"src/ITADataSourceRealization.cpp"
"src/ITAFileDataSink.cpp"
"src/ITAFileDataSource.cpp"
"src/ITAPeakDetector.cpp"
"src/ITARMSDetector.cpp"
"src/ITAStreamDetector.cpp"
"src/ITAStreamAmplifier.cpp"
"src/ITAStreamFunctionGenerator.cpp"
"src/ITAStreamModalSynthesizer.cpp"
......
......@@ -41,20 +41,15 @@ class ITADatasource;
* \param uiNumberOfSamples Anzahl der Samples
* \param dGain Verstärkungsfaktor (optional)
* \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)
* \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
* \note Ausnahmebehandlung mittels der Klasse ITAException
*/
ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer(ITADatasource* pSource,
float** ppfDest,
unsigned int uiNumberOfSamples,
double dGain=1.0,
bool bOnline=true,
bool bDisplayProgress=false);
ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer( ITADatasource* pSource, float** ppfDest, unsigned int uiNumberOfSamples, double dGain = 1.0, bool bOnline = true, bool bDisplayProgress = false );
//! Daten einer Datenquelle in eine Datei schreiben
/**
......@@ -66,20 +61,14 @@ ITA_DATA_SOURCES_API void WriteFromDatasourceToBuffer(ITADatasource* pSource,
* \param uiNumberOfSamples Anzahl der Samples
* \param dGain Verstärkungsfaktor (optional)
* \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)
* \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
* \note Ausnahmebehandlung mittels der Klasse ITAException
*/
ITA_DATA_SOURCES_API void WriteFromDatasourceToFile(ITADatasource* pSource,
std::string sFilename,
unsigned int uiNumberOfSamples,
double dGain=1.0,
bool bOnline=true,
bool bDisplayProgress=false);
ITA_DATA_SOURCES_API void WriteFromDatasourceToFile( ITADatasource* pSource, std::string sFilename, unsigned int uiNumberOfSamples, double dGain = 1.0, bool bOnline = true, bool bDisplayProgress = false );
#endif // INCLUDE_WATCHER_ITA_DATA_SOURCES_UTILS
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: ITAPeakDetector.h 2900 2012-09-17 08:42:42Z stienen $
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_PEAK_DETECTOR
#define INCLUDE_WATCHER_ITA_PEAK_DETECTOR
#include <ITADataSourcesDefinitions.h>
#include <ITACriticalSection.h>
#include <ITADataSource.h>
#include <atomic>
#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
* 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
* und stellt selber die Schnittstelle ITADatasource zur Verfgung.
* Aufrufe von GetBlockPointer und IncrementBlockPointer werden an die
......@@ -45,23 +46,41 @@
*
* \note Die Klasse ist Thread-safe
*/
class ITA_DATA_SOURCES_API ITAPeakDetector : public ITADatasource {
class ITA_DATA_SOURCES_API ITAStreamDetector : public ITADatasource
{
public:
//! Mode of detection
enum Mode
{
DEACTIVATED = -1,
PEAK_AND_RMS,
PEAK,
RMS
};
//! Konstruktor
/**
* \note Es darf kein Nullzeiger bergeben werden.
*/
ITAPeakDetector(ITADatasource* pDatasource);
ITAStreamDetector( ITADatasource* pDatasource, int iMode = PEAK_AND_RMS );
//! Destruktor
virtual ~ITAPeakDetector();
virtual inline ~ITAStreamDetector() {};
//! Datenquelle zurckgeben
ITADatasource* GetDatasource() const { return m_pDataSource; }
inline ITADatasource* GetDatasource() const
{
return m_pDataSource;
};
//! Messung zurcksetzen
void Reset();
void SetMode( const int iMode );
int GetMode() const;
//! Spitzenwert ber alle Kanle abrufen
/**
* Diese Methode dient zum Abrufen des Spitzenwertes ber alle
......@@ -71,7 +90,7 @@ public:
* so bleibt der bisherige Spitzenwert und der Kanal im dem er auftrat
* 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
/**
......@@ -79,34 +98,24 @@ public:
* symbolische Konstante DECIBEL_MINUS_INFINITY zurck
* (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
/**
* \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.
*/
float GetPeak(unsigned int uiChannel, bool bReset=true);
float GetPeak( const int iChannel, const bool bReset = true );
//! Spitzenwert eines Kanals in Dezibel zurckgeben
/**
* \note Falls der Spitzenwert 0 ist, gibt die Methode die
* symbolische Konstante DECIBEL_MINUS_INFINITY zurck
* (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.
*/
double GetPeakDecibel(unsigned int uiChannel, 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);
double GetPeakDecibel( const int iChannel, bool bReset = true );
//! Spitzenwerte aller Kanle abrufen
/**
......@@ -116,46 +125,55 @@ public:
* \note Falls der Vektor weniger Felder als Kanle hat,
* so wird er automatisch vergrert.
*/
void GetPeaks(std::vector<float>& vfDest, 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);
void GetPeaks( std::vector< float >& vfDest, const bool bReset = true );
//! 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.
*
* \note Falls der Vektor weniger Felder als Kanle hat,
* so wird er automatisch vergrert.
*/
void GetPeaksDecibel(std::vector<double>& vdDestDecibel, bool bReset=true);
// -= Überladene Methoden von ITADatasource =-
unsigned int GetBlocklength() const { return m_uiBlocklength; }
unsigned int GetNumberOfChannels() const { return m_uiChannels; }
double GetSampleRate() const { return m_dSamplerate; }
virtual const float* GetBlockPointer(unsigned int uiChannel, const ITAStreamInfo* pStreamInfo);
void GetPeaksDecibel( std::vector< double >& vdDestDecibel, const bool bReset = true );
float GetOverallRMS( const bool bReset = true );
double GetOverallRMSDecibel( const bool bReset = true );
float GetRMS( const int iChannel, const bool bReset = true );
double GetRMSDecibel( const int iChannel, const bool bReset = true );
void GetRMSs( std::vector< float >& vfDest, const bool bReset = true );
void GetRMSsDecibel( std::vector< float >& vfDestDecibel, const bool bReset = true );
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();
protected:
ITADatasource* m_pDataSource; // Angeschlossene Datenquelle
double m_dSamplerate; // Abtastrate [Hz]
unsigned int m_uiChannels; // Anzahl Kanäle
unsigned int m_uiBlocklength; // Streaming Puffergröße [Samples]
ITACriticalSection m_cs; // Sichert exklusiven Zugriff auf die Daten (s.u.)
float* m_pfPeaks; // Spitzenwerte der einzelnen Kanäle
float m_fOverallPeak; // Spitzenwert über alle Kanäle
unsigned int m_uiOverallPeakChannel; // Kanal in dem der Spitzenwert auftrat
ITADatasource* m_pDataSource; //!< Angeschlossene Datenquelle
double m_dSamplerate; //!< Abtastrate [Hz]
int m_iChannels; //!< Anzahl Kanle
int m_iBlocklength; //!< Streaming Puffergre [Samples]
std::atomic< int > m_iMode;
ITACriticalSection m_cs; //!< Sichert exklusiven Zugriff auf die Daten (s.u.)
std::vector< float > m_vfPeaks; //!< Spitzenwerte der einzelnen Kanle
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
\ No newline at end of file
#endif // INCLUDE_WATCHER_ITA_PEAK_DETECTOR
......@@ -34,14 +34,15 @@ class ITAAudiofileWriter;
//! A measuring sensor for audio streams
/**
* Instanzen der Klasse ITAStreamProbe knnen als "Messspitze" in Audiostreams
* eingehngt werden. Sie schreiben dann alle vorbeigeflossenen Daten in eine Audiodatei.
* This class captures (records) the entire data stream passing through and stores
* the result into a file on the hard drive.
*/
class ITA_DATA_SOURCES_API ITAStreamProbe : public ITADatasource
{
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();
inline ITADatasource* GetDatasource() const
......@@ -49,6 +50,7 @@ public:
return m_pDataSource;
}
//! Deprecated
inline std::string GetFilename() const
{
return GetFilePath();
......
......@@ -24,59 +24,62 @@
#include <unistd.h>
#endif
void WriteFromDatasourceToBuffer(ITADatasource* pSource,
float** ppfDest,
unsigned int uiNumberOfSamples,
double dGain,
bool bOnline,
bool bDisplayProgress) {
void WriteFromDatasourceToBuffer( ITADatasource* pSource, float** ppfDest, unsigned int uiNumberOfSamples, double dGain, bool bOnline, bool bDisplayProgress )
{
// Nullzeiger ausschlieen
// TODO: Fehlerbehandlung
if (!pSource) return;
if( !pSource )
return;
unsigned int uiChannels = pSource->GetNumberOfChannels();
double dSamplerate = pSource->GetSampleRate();
unsigned int uiBlocklength = pSource->GetBlocklength();
ITAStreamInfo siState;
long periodMs = (long)ceil(uiBlocklength / dSamplerate * 1000);
long periodMs = ( long ) ceil( uiBlocklength / dSamplerate * 1000 );
#ifdef _WIN32
HANDLE hTimer=0;
if (bOnline) {
HANDLE hTimer = 0;
if( bOnline )
{
// Timer erzeugen
if (FAILED(hTimer = CreateWaitableTimer(NULL, false, NULL)))
ITA_EXCEPT1(UNKNOWN, "Timer konnte nicht erzeugt werden");
if( FAILED( hTimer = CreateWaitableTimer( NULL, false, NULL ) ) )
ITA_EXCEPT1( UNKNOWN, "Timer konnte nicht erzeugt werden" );
LARGE_INTEGER liDueTime;
liDueTime.QuadPart = 0;
SetWaitableTimer(hTimer, &liDueTime, periodMs, NULL, NULL, true);
SetWaitableTimer( hTimer, &liDueTime, periodMs, NULL, NULL, true );
}
#endif
try {
unsigned int n=0;
unsigned int n = 0;
float fProgress = 0.0f;
while (n < uiNumberOfSamples)
while( n < uiNumberOfSamples )
{
#ifdef _WIN32
// Warten
if (bOnline) WaitForSingleObject(hTimer, INFINITE);
if( bOnline )
WaitForSingleObject( hTimer, INFINITE );
#else
if (bOnline) usleep(periodMs * 1000);
if( bOnline )
usleep( periodMs * 1000 );
#endif
// Daten von der Quelle holen
for (unsigned int i=0; i<uiChannels; i++) {
const float* pfData = pSource->GetBlockPointer(i, &siState);
for( unsigned int i = 0; i < uiChannels; i++ )
{
const float* pfData = pSource->GetBlockPointer( i, &siState );
unsigned int k = (uiNumberOfSamples - n);
if (k > uiBlocklength) k = uiBlocklength;
unsigned int k = ( uiNumberOfSamples - n );
if( k > uiBlocklength )
k = uiBlocklength;
if( !pfData )
{ // Stille einfgen
{
// Stille einfgen
for( unsigned int j = 0; j < uiBlocklength; j++ )
ppfDest[ i ][ n + j ] = 0;
}
......@@ -94,52 +97,52 @@ void WriteFromDatasourceToBuffer(ITADatasource* pSource,
n += uiBlocklength;
siState.nSamples += uiBlocklength;
siState.dStreamTimeCode = (double) (siState.nSamples) / dSamplerate;
siState.dStreamTimeCode = ( double ) ( siState.nSamples ) / dSamplerate;
siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
if (bDisplayProgress)
if( bDisplayProgress )
{
float p = 100 * (float) n / uiNumberOfSamples;
if(p > fProgress + 5.0f)
float p = 100 * ( float ) n / uiNumberOfSamples;
if( p > fProgress + 5.0f )
{
fProgress = p;
printf("WriteFromDatasourceToBuffer: %0.2f%% geschrieben", p);
printf( "WriteFromDatasourceToBuffer: %0.2f%% geschrieben", p );
}
}
}
} catch (...) {
}
catch( ... )
{
#ifdef _WIN32
if (bOnline) CloseHandle(hTimer);
if( bOnline )
CloseHandle( hTimer );
#endif
throw;
}
if (bDisplayProgress)
printf("WriteFromDatasourceToBuffer: 100,00%% geschrieben");
if( bDisplayProgress )
printf( "WriteFromDatasourceToBuffer: 100,00%% geschrieben" );
#ifdef _WIN32
if (bOnline)
CloseHandle(hTimer);
if( bOnline )
CloseHandle( hTimer );
#endif
}
void WriteFromDatasourceToFile(ITADatasource* pSource,
std::string sFilename,
unsigned int uiNumberOfSamples,
double dGain,
bool bOnline,
bool bDisplayProgress) {
void WriteFromDatasourceToFile( ITADatasource* pSource, std::string sFilename, unsigned int uiNumberOfSamples, double dGain, bool bOnline, bool bDisplayProgress )
{
// Nullzeiger ausschlieen
// TODO: Fehlerbehandlung
if (!pSource) return;
if( !pSource )
return;
unsigned int uiChannels = pSource->GetNumberOfChannels();
unsigned int uiBlocklength = pSource->GetBlocklength();
double dSamplerate = pSource->GetSampleRate();
std::vector<float*> vpfData;
for (unsigned int i=0; i<uiChannels; i++)
vpfData.push_back(new float[uiBlocklength]);
for( unsigned int i = 0; i < uiChannels; i++ )
vpfData.push_back( new float[ uiBlocklength ] );
ITAAudiofileProperties props;
props.iChannels = uiChannels;
......@@ -147,91 +150,103 @@ void WriteFromDatasourceToFile(ITADatasource* pSource,
props.eQuantization = ITAQuantization::ITA_FLOAT;
props.eDomain = ITADomain::ITA_TIME_DOMAIN;
props.iLength = uiNumberOfSamples;
ITAAudiofileWriter* writer = ITAAudiofileWriter::create(sFilename, props);
ITAAudiofileWriter* writer = ITAAudiofileWriter::create( sFilename, props );
ITAStreamInfo siState;
long periodMs = (long)ceil(uiBlocklength / dSamplerate * 1000);
long periodMs = ( long ) ceil( uiBlocklength / dSamplerate * 1000 );
#ifdef _WIN32
HANDLE hTimer=0;
HANDLE hTimer = 0;
if (bOnline) {
if( bOnline )
{
// Timer erzeugen
if (FAILED(hTimer = CreateWaitableTimer(NULL, false, NULL))) {
if( FAILED( hTimer = CreateWaitableTimer( NULL, false, NULL ) ) )
{
delete writer;
ITA_EXCEPT1(UNKNOWN, "Timer konnte nicht erzeugt werden");
ITA_EXCEPT1( UNKNOWN, "Timer konnte nicht erzeugt werden" );
}
LARGE_INTEGER liDueTime;
liDueTime.QuadPart=0;
SetWaitableTimer(hTimer, &liDueTime, periodMs, NULL, NULL, true);
liDueTime.QuadPart = 0;
SetWaitableTimer( hTimer, &liDueTime, periodMs, NULL, NULL, true );
}
#endif
try {
unsigned int n=0;
unsigned int n = 0;
float fProgress = 0.0;
while (n < uiNumberOfSamples) {
while( n < uiNumberOfSamples )
{
#ifdef _WIN32
// Warten
if (bOnline) WaitForSingleObject(hTimer, INFINITE);
if( bOnline )
WaitForSingleObject( hTimer, INFINITE );
#else
if (bOnline) usleep(periodMs * 1000);
if( bOnline )
usleep( periodMs * 1000 );
#endif
// Daten von der Quelle holen
for (unsigned int i=0; i<uiChannels; i++) {
const float* pfSource = pSource->GetBlockPointer(i, &siState);
float* pfDest = vpfData[i];
if (!pfSource)
for( unsigned int i = 0; i < uiChannels; i++ )
{
const float* pfSource = pSource->GetBlockPointer( i, &siState );
float* pfDest = vpfData[ i ];
if( !pfSource )
{
// Stille einfgen
for (unsigned int j=0; j<uiBlocklength; j++) pfDest[j] = 0;
else {
if (dGain == 1)
memcpy(pfDest, pfSource, uiBlocklength*sizeof(float));
else
for (unsigned int j=0; j<uiBlocklength; j++)
pfDest[j] = pfSource[j] * (float) dGain;
for( unsigned int j = 0; j < uiBlocklength; j++ )
pfDest[ j ] = 0;
}
else
{
if( dGain == 1 )
memcpy( pfDest, pfSource, uiBlocklength*sizeof( float ) );
else
for( unsigned int j = 0; j < uiBlocklength; j++ )
pfDest[ j ] = pfSource[ j ] * ( float ) dGain;
}
}
pSource->IncrementBlockPointer();
siState.nSamples += uiBlocklength;
siState.dStreamTimeCode = (double) (siState.nSamples) / dSamplerate;
siState.dStreamTimeCode = ( double ) ( siState.nSamples ) / dSamplerate;
siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
// Daten schreiben
writer->write((std::min)(uiBlocklength, (uiNumberOfSamples - n)), vpfData);
writer->write( ( std::min )( uiBlocklength, ( uiNumberOfSamples - n ) ), vpfData );
n += uiBlocklength;
if (bDisplayProgress)
if( bDisplayProgress )
{
float p = 100 * (float) n / uiNumberOfSamples;
if(p > fProgress + 5.0f)
float p = 100 * ( float ) n / uiNumberOfSamples;
if( p > fProgress + 5.0f )
{
fProgress = p;
printf("WriteFromDatasourceToFile: %0.2f%% geschrieben\r", p);
printf( "WriteFromDatasourceToFile: %0.2f%% written\r", p );
}
}
}
} catch (...) {
}
catch( ... )
{
#ifdef _WIN32
if (bOnline) CloseHandle(hTimer);
if( bOnline )
CloseHandle( hTimer );
#endif
delete writer;
throw;
}
if (bDisplayProgress)
printf("WriteFromDatasourceToFile: 100,00%% geschrieben\r");
if( bDisplayProgress )
printf( "WriteFromDatasourceToFile: 100,00%% written\r" );
#ifdef _WIN32
if (bOnline)
CloseHandle(hTimer);
if( bOnline )
CloseHandle( hTimer );
#endif
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 <ITADataSourceRealization.h>
......@@ -13,28 +13,20 @@
#include <memory.h>
#endif
ITAStreamFunctionGenerator::ITAStreamFunctionGenerator(unsigned int uiChannels,
double dSamplerate,
unsigned int uiBlocklength,
int iSignalFunction,
double dFrequency,
float fAmplitude,
bool bPeriodic)
: ITADatasourceRealization(uiChannels, dSamplerate, uiBlocklength),
// Initial values
m_iFunction(iSignalFunction),
m_bPeriodic(bPeriodic),
m_bMuted(false),
m_fAmplitude(fAmplitude),
m_iSampleCount(0),
m_fPhase(0.0f)
{
assert(uiChannels > 0);
assert(dSamplerate > 0);
assert(uiBlocklength > 0);
SetFrequency(dFrequency);
ITAStreamFunctionGenerator::ITAStreamFunctionGenerator( unsigned int uiChannels, double dSamplerate, unsigned int uiBlocklength, int iSignalFunction, double dFrequency, float fAmplitude, bool bPeriodic )
: ITADatasourceRealization( uiChannels, dSamplerate, uiBlocklength ),
m_iFunction( iSignalFunction ),
m_bPeriodic( bPeriodic ),
m_bMuted( false ),
m_fAmplitude( fAmplitude ),
m_iSampleCount( 0 ),
m_fPhase( 0.0f )
{
assert( uiChannels > 0 );
assert( dSamplerate > 0 );
assert( uiBlocklength > 0 );
SetFrequency( dFrequency );
Reset();
}
......@@ -49,20 +41,20 @@ int ITAStreamFunctionGenerator::GetFunction() const
return m_iFunction;
}
void ITAStreamFunctionGenerator::SetFunction(int iFunction)
void ITAStreamFunctionGenerator::SetFunction( int iFunction )
{
m_iFunction = iFunction;
}
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 );
m_iPeriodLengthSamples = (int) round( m_dSampleRate / dFrequency );
m_iPeriodLengthSamples = ( int ) round( m_dSampleRate / dFrequency );
}
int ITAStreamFunctionGenerator::GetPeriodAsSamples() const
......@@ -70,7 +62,7 @@ int ITAStreamFunctionGenerator::GetPeriodAsSamples() const
return m_iPeriodLengthSamples;
}
void ITAStreamFunctionGenerator::SetPeriodAsSamples(int iNumSamples)
void ITAStreamFunctionGenerator::SetPeriodAsSamples( int iNumSamples )
{
assert( iNumSamples >= 0 );
m_iPeriodLengthSamples = iNumSamples;
......@@ -78,12 +70,12 @@ void ITAStreamFunctionGenerator::SetPeriodAsSamples(int iNumSamples)
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
......@@ -91,7 +83,7 @@ bool ITAStreamFunctionGenerator::IsPeriodic() const
return m_bPeriodic;
}
void ITAStreamFunctionGenerator::SetPeriodic(bool bPeriodic)
void ITAStreamFunctionGenerator::SetPeriodic( bool bPeriodic )
{
m_bPeriodic = bPeriodic;
}
......@@ -101,7 +93,7 @@ bool ITAStreamFunctionGenerator::IsMuted() const
return m_bMuted;
}
void ITAStreamFunctionGenerator::SetMuted(bool bMuted)
void ITAStreamFunctionGenerator::SetMuted( bool bMuted )
{
m_bMuted = bMuted;
}
......@@ -111,112 +103,115 @@ float ITAStreamFunctionGenerator::GetAmplitude() const
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
float* pfOutputData = GetWritePointer(0);
fm_zero(pfOutputData, m_uiBlocklength);
float* pfOutputData = GetWritePointer( 0 );
fm_zero( pfOutputData, m_uiBlocklength );
// Variables
int N = m_iPeriodLengthSamples;
float a = m_fAmplitude;
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 iNumSamples; // Anzahl zu erzeugender Samples
switch (m_iFunction) {
switch( m_iFunction ) {
case SINE:
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);
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 );
for (int i=0;i<iNumSamples;i++) {
pfOutputData[i] = a * sin(omega*i + m_fPhase);
for( int i = 0; i < iNumSamples; i++ ) {
pfOutputData[ i ] = a * sin( omega*i + m_fPhase );
}
m_fPhase = fmodf( iNumSamples*omega + m_fPhase, ITAConstants::TWO_PI_F );
m_iSampleCount += iNumSamples;
break;
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++) {
float x = fmodf((float) m_iSampleCount++, (float) m_iPeriodLengthSamples);
for( int i = 0; i < iNumSamples; i++ )
{
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;
case SAWTOOTH: // Sgezahn
iNumSamples = (m_bPeriodic ? (int) m_uiBlocklength : (std::min)( (int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount) );
for (int i=0;i<iNumSamples;i++) {
iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
float x = fmodf((float) m_iSampleCount++, (float) m_iPeriodLengthSamples);
pfOutputData[i] = a * (x*gradient);
for( int i = 0; i < iNumSamples; i++ ) {
float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
pfOutputData[ i ] = a * ( x*gradient );
}
break;
case RECTANGLE:
// Position des Wechsels von 1 zu 0 innerhalb einer Periode
iZero = (int)(m_iPeriodLengthSamples / 2);
iNumSamples = (m_bPeriodic ? (int) m_uiBlocklength : (std::min)((int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount) );
// Position des Wechsels von 1 zu 0 innerhalb einer Periode
iZero = ( int ) ( m_iPeriodLengthSamples / 2 );
iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
for (int i=0; i<iNumSamples; i++)
{
// Position innerhalb einer Periodenlnge
float x = fmodf((float) m_iSampleCount++, (float) m_iPeriodLengthSamples);
int iOffset = (int) roundf(x);
pfOutputData[i] = (iOffset < iZero ? a : 0);
}
for( int i = 0; i < iNumSamples; i++ )
{
// Position innerhalb einer Periodenlnge
float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
int iOffset = ( int ) roundf( x );
pfOutputData[ i ] = ( iOffset < iZero ? a : 0 );
}
break;
break;
case DIRAC:
iNumSamples = (m_bPeriodic ? (int) m_uiBlocklength : (std::min)( (int) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
if (m_bPeriodic) {
for (int i=0;i<iNumSamples;i++) pfOutputData[i] = ( m_iSampleCount++ % N ? 0 : a );
} else {
pfOutputData[0] = (m_iSampleCount == 0 ? a : 0);
for (int i=1;i<iNumSamples;i++) pfOutputData[i] = 0;
iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
if( m_bPeriodic )
{
for( int i = 0; i < iNumSamples; i++ ) pfOutputData[ i ] = ( m_iSampleCount++ % N ? 0 : a );
}
else {
pfOutputData[ 0 ] = ( m_iSampleCount == 0 ? a : 0 );
for( int i = 1; i < iNumSamples; i++ ) pfOutputData[ i ] = 0;
m_iSampleCount += iNumSamples;
}
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);
for(unsigned int i= 0; i< m_uiBlocklength; i++)
pfOutputData[i] = a * (float)rand()/ RAND_MAX;
break;
// ...
break;
// ...
default:
// Case: Invalid signal function => Generate zeros
for (unsigned int i=0; i<m_uiBlocklength; i++)
pfOutputData[i] = 0;
for( unsigned int i = 0; i < m_uiBlocklength; i++ )
pfOutputData[ i ] = 0;
}
/*
......@@ -225,9 +220,9 @@ void ITAStreamFunctionGenerator::ProcessStream(const ITAStreamInfo* pStreamInfo)
* then copy the data into all further channels.
*/
for (unsigned int c=1; c<m_uiChannels; c++)
memcpy( GetWritePointer(c), pfOutputData, m_uiBlocklength * sizeof(float) );
for( unsigned int c = 1; c < m_uiChannels; c++ )
memcpy( GetWritePointer( c ), pfOutputData, m_uiBlocklength * sizeof( float ) );
IncrementWritePointer();
}