Commit 70eb7f34 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Adding RMS detector (untested)

parent 4b281884
......@@ -47,6 +47,7 @@ set( ITADataSourcesHeader
"include/ITAFileDataSink.h"
"include/ITAFileDataSource.h"
"include/ITAPeakDetector.h"
"include/ITARMSDetector.h"
"include/ITAStreamAmplifier.h"
#"include/ITAStreamFilter.h"
"include/ITAStreamFunctionGenerator.h"
......@@ -66,6 +67,7 @@ set( ITADataSourcesSources
"src/ITAFileDataSink.cpp"
"src/ITAFileDataSource.cpp"
"src/ITAPeakDetector.cpp"
"src/ITARMSDetector.cpp"
"src/ITAStreamAmplifier.cpp"
#"src/ITAStreamFilter.cpp"
"src/ITAStreamFunctionGenerator.cpp"
......
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_RMS_DETECTOR
#define INCLUDE_WATCHER_ITA_RMS_DETECTOR
#include <ITADataSourcesDefinitions.h>
#include <ITACriticalSection.h>
#include <ITADataSource.h>
#include <vector>
//! Detector for RMS values
/**
*
* \note Die Klasse ist Thread-safe
*/
class ITA_DATA_SOURCES_API ITARMSDetector : public ITADatasource
{
public:
ITARMSDetector( ITADatasource* pDatasource );
virtual ~ITARMSDetector();
inline ITADatasource* GetDatasource() const
{
return m_pDataSource;
};
void Reset();
void GetOverallRMS( float* pfPeak, unsigned int* puiChannel = 0, bool bReset = true );
void GetOverallRMSDecibel( double* pdPeakDecibel, unsigned int* puiChannel = 0, bool bReset = true );
float GetRMS( unsigned int uiChannel, bool bReset = true );
double GetRMSDecibel( unsigned int uiChannel, bool bReset = true );
void GetRMSs( float* pfDest, bool bReset = true );
void GetRMSs( std::vector<float>& vfDest, bool bReset = true );
void GetRMSsDecibel( std::vector<double>& vdDestDecibel, bool bReset = true );
inline unsigned int GetBlocklength() const
{
return m_uiBlocklength;
};
inline unsigned int GetNumberOfChannels() const
{
return m_uiChannels;
};
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 Kanle
unsigned int m_uiBlocklength; // Streaming Puffergre [Samples]
ITACriticalSection m_cs; // Sichert exklusiven Zugriff auf die Daten (s.u.)
float* m_pfRMSs; // Spitzenwerte der einzelnen Kanle
float m_fOverallRMS; // Spitzenwert ber alle Kanle
unsigned int m_uiOverallRMSChannel; // Kanal in dem der Spitzenwert auftrat
};
#endif // INCLUDE_WATCHER_ITA_RMS_DETECTOR
\ No newline at end of file
#include "ITARMSDetector.h"
#include <ITAException.h>
#include <ITANumericUtils.h>
#include <cmath>
ITARMSDetector::ITARMSDetector( ITADatasource* pDataSource )
: m_pDataSource( pDataSource )
{
m_dSamplerate = pDataSource->GetSampleRate();
m_uiChannels = pDataSource->GetNumberOfChannels();
m_uiBlocklength = pDataSource->GetBlocklength();
m_pfRMSs = 0;
if( ( m_uiBlocklength == 0 ) || ( m_uiChannels == 0 ) || ( m_dSamplerate == 0 ) )
ITA_EXCEPT0( INVALID_PARAMETER );
m_pfRMSs = new float[ m_uiChannels ];
Reset();
}
ITARMSDetector::~ITARMSDetector()
{
delete[] m_pfRMSs;
};
void ITARMSDetector::Reset()
{
m_cs.enter();
for( unsigned int c = 0; c < m_uiChannels; c++ )
m_pfRMSs[ c ] = 0.00001f;
m_fOverallRMS = 0;
m_uiOverallRMSChannel = 0;
m_cs.leave();
}
void ITARMSDetector::GetOverallRMS( float* pfPeak, unsigned int* puiChannel, bool bReset )
{
m_cs.enter();
if( pfPeak )
*pfPeak = m_fOverallRMS;
if( puiChannel )
*puiChannel = m_uiOverallRMSChannel;
if( bReset )
{
m_fOverallRMS = 0;
m_uiOverallRMSChannel = 0;
}
m_cs.leave();
}
void ITARMSDetector::GetOverallRMSDecibel( double* pdPeakDecibel, unsigned int* puiChannel, bool bReset )
{
m_cs.enter();
if( pdPeakDecibel )
*pdPeakDecibel = ratio_to_db20( m_fOverallRMS );
if( puiChannel )
*puiChannel = m_uiOverallRMSChannel;
if( bReset )
{
m_fOverallRMS = 0;
m_uiOverallRMSChannel = 0;
}
m_cs.leave();
}
float ITARMSDetector::GetRMS( unsigned int uiChannel, bool bReset )
{
if( uiChannel >= m_uiChannels )
ITA_EXCEPT0( INVALID_PARAMETER );
m_cs.enter();
float fResult = m_pfRMSs[ uiChannel ];
if( bReset )
m_pfRMSs[ uiChannel ] = 0;
m_cs.leave();
return fResult;
}
double ITARMSDetector::GetRMSDecibel( unsigned int uiChannel, bool bReset )
{
return ratio_to_db20( GetRMS( uiChannel, bReset ) );
}
void ITARMSDetector::GetRMSs( float* pfDest, bool bReset )
{
if( !pfDest )
ITA_EXCEPT0( INVALID_PARAMETER );
m_cs.enter();
for( unsigned int c = 0; c < m_uiChannels; c++ )
{
pfDest[ c ] = m_pfRMSs[ c ];
if( bReset )
m_pfRMSs[ c ] = 0;
}
m_cs.leave();
}
void ITARMSDetector::GetRMSs( std::vector<float>& vfDest, bool bReset )
{
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_pfRMSs[ c ];
if( bReset )
m_pfRMSs[ c ] = 0;
}
m_cs.leave();
}
void ITARMSDetector::GetRMSsDecibel( std::vector<double>& vdDestDecibel, bool bReset )
{
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_pfRMSs[ c ] );
if( bReset )
m_pfRMSs[ c ] = 0;
}
m_cs.leave();
}
const float* ITARMSDetector::GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* pStreamInfo )
{
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_pfRMSs[ uiChannel ] )
m_pfRMSs[ uiChannel ] = fAbs;
if( fAbs > m_fOverallRMS )
{
m_fOverallRMS = fAbs;
m_uiOverallRMSChannel = uiChannel;
}
}
m_cs.leave();
}
return pfData;
}
void ITARMSDetector::IncrementBlockPointer()
{
m_pDataSource->IncrementBlockPointer();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment