Commits (8)
......@@ -75,10 +75,11 @@ set( ITABaseHeader
"include/ITAFastMath.h"
"include/ITAFileSystemUtils.h"
"include/ITAFiniteImpulseResponse.h"
"include/ITAFunctors.h"
"include/ITAHDFTSpectra.h"
"include/ITAHDFTSpectrum.h"
"include/ITAFunctors.h"
"include/ITAInterpolation.h"
"include/ITAISO9613.h"
"include/ITALog.h"
"include/ITAMagnitudeSpectrum.h"
"include/ITAMultichannelFiniteImpulseResponse.h"
......@@ -115,6 +116,7 @@ set( ITABaseSources
"src/ITAHDFTSpectra.cpp"
"src/ITAHDFTSpectrum.cpp"
"src/ITAInterpolation.cpp"
"src/ITAISO9613.cpp"
"src/ITALog.cpp"
"src/ITAMagnitudeSpectrum.cpp"
"src/ITAMultichannelFiniteImpulseResponse.cpp"
......
......@@ -22,6 +22,7 @@
#include <ITABaseDefinitions.h>
#include <ITAAudiofileWriter.h>
//! Audio file writer that first buffers samples and exports on demand or destruction
/**
* Klasse welche Schreiber von Audiodateien um Pufferung erweitert.
* Dies ist u.A. wichtig in der Echtzeit-Verarbeitung, wobei keine
......@@ -34,15 +35,25 @@
* werden. Wird diese Aufgebraucht, wird der Puffer automatisch um die
* angegebene Wachstumsgröße erweitert.
*/
class ITA_BASE_API ITABufferedAudiofileWriter : public ITAAudiofileWriter
{
public:
//! Factory method. Erzeugt einen gepufferten Schreiber.
static ITABufferedAudiofileWriter* create(const std::string& sFilename,
const ITAAudiofileProperties& props,
double dInitialBufferSizeSeconds=60,
double dGrowBufferSizeSeconds=20);
static ITABufferedAudiofileWriter* create( const ITAAudiofileProperties& props, double dInitialBufferSizeSeconds = 60, double dGrowBufferSizeSeconds = 20 );
//! Returns current file path or empty string
/**
* @return Current file path or empty string
*
*/
virtual std::string GetFilePath() const = 0;
//! Sets the export file path (without any checks)
/**
* @param[in] sFilePath File path (make sure base folder exists)
*
*/
virtual void SetFilePath( const std::string& sFilePath ) = 0;
};
#endif // INCLUDE_WATCHER_ITA_BUFFERED_AUDIO_FILE_WRITER
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2018
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_ISO_9613
#define INCLUDE_WATCHER_ITA_ISO_9613
// ITABase
#include <ITABaseDefinitions.h>
#include <ITAThirdOctaveMagnitudeSpectrum.h>
#include <string>
namespace ITABase
{
namespace ISO9613
{
//! Calculates the atmospheric absorption after ISO 9613-1 for one frequency in decibels
/**
* Standard: ISO 9613-1:1993
*
* \param dFrequency Base frequency [Hz]
* \param fDistance Distance [m]
* \param fTemperature Temperature [C]
* \param fHumidity Relative humidity [%]
* \param fStaticPressure Static air pressure [kPa]
*
* @return Atmospheric absorption in dB
*/
ITA_BASE_API double AtmosphericAbsorptionLevel( double dFrequency, double dDistance, double dTemperature, double dHumidity, double dStaticPressure = 101.325);
//! Calculates the atmospheric absorption after ISO 9613-1 for one frequency in linear factors (instead of decibels)
/**
* Standard: ISO 9613-1:1993
*
* \param dFrequency Base frequency [Hz]
* \param fDistance Distance [m]
* \param fTemperature Temperature [C]
* \param fHumidity Relative humidity [%]
* \param fStaticPressure Static air pressure [kPa]
*
* @return Atmospheric absorption in linear factors (instead of decibels)
*/
ITA_BASE_API double AtmosphericAbsorptionFactor(double dFrequency, double dDistance, double dTemperature, double dHumidity, double dStaticPressure = 101.325);
//! Calculates the atmospheric absorption after ISO 9613-1: A_{atm} (formula 8) in decibels
/**
* Standard: ISO 9613-1:1993
*
* \param oA_atm_dB Third-octave magnitude spectrum with atmospheric attenuation values in decibel
* \param fDistance Distance [m]
* \param fTemperature Temperature [C]
* \param fHumidity Relative humidity [%]
* \param fStaticPressure Static air pressure [kPa]
*/
ITA_BASE_API void AtmosphericAbsorption( ITABase::CThirdOctaveDecibelMagnitudeSpectrum& oA_atm_dB, double dDistance, double dTemperature, double dHumidity, double dStaticPressure = 101.325);
//! Calculates the atmospheric absorption in linear factors (instead of decibels)
ITA_BASE_API void AtmosphericAbsorption( ITABase::CThirdOctaveFactorMagnitudeSpectrum& oA_atm_factor, double dDistance, double dTemperature, double dHumidity, double dStaticPressure = 101.325);
}
}
#endif // INCLUDE_WATCHER_ITA_ISO_9613
......@@ -76,8 +76,11 @@ public:
void Add( const float fSummand );
//! Element-wise addition
void Add( const CITASpectrum& oOtherSpetrum );
void Add( const CITASpectrum& oOtherSpectrum );
//! Element-wise subtraction
void Sub(const CITASpectrum& oOtherSpectrum);
//! Compare equality of values (ignores center frequencies, but requires matching number of bands)
bool CompareEqualValues( const CITASpectrum& oOtherSpectrum, const float fThreshold = 10.0e-10 ) const;
......
......@@ -12,71 +12,78 @@
class ITABufferedAudiofileWriterImpl : public ITABufferedAudiofileWriter
{
public:
inline ITABufferedAudiofileWriterImpl( const std::string& sFilePath,
const ITAAudiofileProperties& props,
double dInitialBufferSizeSeconds,
double dGrowBufferSizeSeconds )
inline ITABufferedAudiofileWriterImpl( const ITAAudiofileProperties& props, double dInitialBufferSizeSeconds, double dGrowBufferSizeSeconds )
: m_pWriter( NULL )
, m_oProps( props )
{
// Zunächst versuchen den regulären (ungepufferten) Schreiber aufzusetzen
m_pWriter = ITAAudiofileWriter::create( sFilePath, props );
// Initialen Chunk anlegen
m_iInitialBufferSizeSamples = (int) ceil( dInitialBufferSizeSeconds*props.dSampleRate );
m_iGrowBufferSizeSamples = (int) ceil( dGrowBufferSizeSeconds*props.dSampleRate );
m_iInitialBufferSizeSamples = ( int ) ceil( dInitialBufferSizeSeconds*props.dSampleRate );
m_iGrowBufferSizeSamples = ( int ) ceil( dGrowBufferSizeSeconds*props.dSampleRate );
m_lpChunks.push_back( new Chunk( (int) props.iChannels, m_iInitialBufferSizeSamples ) );
}
m_lpChunks.push_back( new Chunk( ( int ) props.iChannels, m_iInitialBufferSizeSamples ) );
};
inline virtual ~ITABufferedAudiofileWriterImpl()
{
// Alle Chunks schreiben und freigeben
for (std::list<Chunk*>::iterator it=m_lpChunks.begin(); it!=m_lpChunks.end(); ++it) {
Chunk* pChunk = (*it);
if (m_pWriter && (pChunk->m_iTail > 0))
m_pWriter->write(pChunk->m_iTail, pChunk->m_vpfData);
for( std::list<Chunk*>::iterator it = m_lpChunks.begin(); it != m_lpChunks.end(); ++it ) {
Chunk* pChunk = ( *it );
if( m_pWriter && ( pChunk->m_iTail > 0 ) )
m_pWriter->write( pChunk->m_iTail, pChunk->m_vpfData );
delete pChunk;
}
// Schreiber freigeben
delete m_pWriter;
}
};
inline void SetFilePath( const std::string& sFilePath )
{
delete m_pWriter;
m_pWriter = ITAAudiofileWriter::create( sFilePath, m_oProps );
m_sFilePath = sFilePath;
};
inline std::string GetFilePath() const
{
return m_sFilePath;
};
inline virtual void write( int iLength, std::vector<const float*> vpfSource )
{
// Korrekte Anzahl Kanäle
int iChannels = m_lpChunks.back()->m_sfSamples.channels();
if ((int) vpfSource.size() != iChannels)
ITA_EXCEPT1(INVALID_PARAMETER, "Wrong number of channels in source data");
if( ( int ) vpfSource.size() != iChannels )
ITA_EXCEPT1( INVALID_PARAMETER, "Wrong number of channels in source data" );
if( iLength == 0 ) return;
int iWritten = 0;
int iTotal = iLength;
int iRemain = iTotal;
while (iWritten < iTotal) {
while( iWritten < iTotal ) {
Chunk* pTailChunk = m_lpChunks.back();
// Soviel in diesen Chunk schreiben wie möglich
int iChunkRemain = pTailChunk->m_sfSamples.length() - pTailChunk->m_iTail;
int iCount = std::min( iRemain, iChunkRemain );
for (int i=0; i<iChannels; i++)
pTailChunk->m_sfSamples[i].write( vpfSource[i], iCount, pTailChunk->m_iTail );
for( int i = 0; i < iChannels; i++ )
pTailChunk->m_sfSamples[ i ].write( vpfSource[ i ], iCount, pTailChunk->m_iTail );
pTailChunk->m_iTail += iCount;
iWritten += iCount;
iRemain = iTotal - iWritten;
// Neuen Chunk anlegen, falls noch Daten zu schreiben ...
if (iRemain > 0) {
m_lpChunks.push_back( new Chunk( iChannels, m_iGrowBufferSizeSamples) );
if( iRemain > 0 ) {
m_lpChunks.push_back( new Chunk( iChannels, m_iGrowBufferSizeSamples ) );
}
}
}
};
private:
// Interner Speicherblock für Samples
......@@ -88,26 +95,31 @@ private:
int m_iTail;
inline Chunk( int iChannels, int iCapacity )
: m_sfSamples( iChannels, iCapacity, false )
, m_vpfData(iChannels)
, m_iTail(0)
: m_sfSamples( iChannels, iCapacity, false )
, m_vpfData( iChannels )
, m_iTail( 0 )
{
for( int i=0; i<iChannels; i++ )
m_vpfData[i] = m_sfSamples[i].GetData();
for( int i = 0; i < iChannels; i++ )
m_vpfData[ i ] = m_sfSamples[ i ].GetData();
}
};
ITAAudiofileWriter* m_pWriter;
std::string m_sFilePath;
std::list<Chunk*> m_lpChunks;
int m_iInitialBufferSizeSamples;
int m_iGrowBufferSizeSamples;
const ITAAudiofileProperties m_oProps;
//! Copy protection
inline ITABufferedAudiofileWriterImpl& operator=( ITABufferedAudiofileWriterImpl& )
{
ITA_EXCEPT_NOT_IMPLEMENTED;
};
};
ITABufferedAudiofileWriter* ITABufferedAudiofileWriter::create(const std::string& sFilePath,
const ITAAudiofileProperties& props,
double dInitialBufferSizeSeconds,
double dGrowBufferSizeSeconds)
ITABufferedAudiofileWriter* ITABufferedAudiofileWriter::create( const ITAAudiofileProperties& props, double dInitialBufferSizeSeconds, double dGrowBufferSizeSeconds )
{
return new ITABufferedAudiofileWriterImpl( sFilePath, props, dInitialBufferSizeSeconds, dGrowBufferSizeSeconds );
return new ITABufferedAudiofileWriterImpl( props, dInitialBufferSizeSeconds, dGrowBufferSizeSeconds );
}
......@@ -33,7 +33,8 @@ bool INIFileKeyExists( const std::string& sINIFilename, const std::string& sSect
return false;
}
void INIFileUseFile( const std::string& sINIFilename ) {
void INIFileUseFile( const std::string& sINIFilename )
{
// Sicherstellen das die INI-Datei existiert
// [fwe 2008-11-07] Bugfix, baby! Das geht beim reinen Schreiben nicht: INIFileRequireINIFile(sINIFilename);
......@@ -478,11 +479,13 @@ bool INIFileWriteStringList( const std::string& sINIFilename,
* | |
* +-----------------------------------------------------------------------------------------+ */
bool INIFileSectionExists( const std::string& sSection ) {
bool INIFileSectionExists( const std::string& sSection )
{
return INIFileSectionExists( sCurrentINIFile, sSection );
}
std::vector<std::string> INIFileGetSections() {
std::vector<std::string> INIFileGetSections()
{
return INIFileGetSections( sCurrentINIFile );
}
......@@ -530,39 +533,48 @@ bool INIFileReadBool( const std::string& sKey, bool bDefaultValue ) {
return INIFileReadBool( sCurrentINIFile, sCurrentSection, sKey, bDefaultValue );
}
std::string INIFileReadString( const std::string& sKey, std::string sDefaultValue ) {
std::string INIFileReadString( const std::string& sKey, std::string sDefaultValue )
{
return INIFileReadString( sCurrentINIFile, sCurrentSection, sKey, sDefaultValue );
}
std::vector<int> INIFileReadIntList( const std::string& sKey, char cSeparator ) {
std::vector<int> INIFileReadIntList( const std::string& sKey, char cSeparator )
{
return INIFileReadIntList( sCurrentINIFile, sCurrentSection, sKey, cSeparator );
}
std::vector<unsigned int> INIFileReadUIntList( const std::string& sKey, char cSeparator ) {
std::vector<unsigned int> INIFileReadUIntList( const std::string& sKey, char cSeparator )
{
return INIFileReadUIntList( sCurrentINIFile, sCurrentSection, sKey, cSeparator );
}
std::vector<float> INIFileReadFloatList( const std::string& sKey, char cSeparator ) {
std::vector<float> INIFileReadFloatList( const std::string& sKey, char cSeparator )
{
return INIFileReadFloatList( sCurrentINIFile, sCurrentSection, sKey, cSeparator );
}
std::vector<double> INIFileReadDoubleList( const std::string& sKey, char cSeparator ) {
std::vector<double> INIFileReadDoubleList( const std::string& sKey, char cSeparator )
{
return INIFileReadDoubleList( sCurrentINIFile, sCurrentSection, sKey, cSeparator );
}
std::vector<std::string> INIFileReadStringList( const std::string& sKey, char cSeparator ) {
std::vector<std::string> INIFileReadStringList( const std::string& sKey, char cSeparator )
{
return INIFileReadStringList( sCurrentINIFile, sCurrentSection, sKey, cSeparator );
}
int INIFileReadIntExplicit( const std::string& sKey ) {
int INIFileReadIntExplicit( const std::string& sKey )
{
return INIFileReadIntExplicit( sCurrentINIFile, sCurrentSection, sKey );
}
unsigned int INIFileReadUIntExplicit( const std::string& sKey ) {
unsigned int INIFileReadUIntExplicit( const std::string& sKey )
{
return INIFileReadUIntExplicit( sCurrentINIFile, sCurrentSection, sKey );
}
long INIFileReadLongExplicit( const std::string& sKey ) {
long INIFileReadLongExplicit( const std::string& sKey )
{
return INIFileReadLongExplicit( sCurrentINIFile, sCurrentSection, sKey );
}
......
......@@ -25,85 +25,92 @@ std::string FixPath( const std::string& sPath )
return std::string( "." ) + PATH_SEPARATOR + sPath;
}
std::vector<std::string> INIFileGetSections(const std::string& sINIFilename) {
std::vector<std::string> INIFileGetSections( const std::string& sINIFilename )
{
// [fwe: Bugfix 2008-09-09] Sicherstellen das die Datei berhaupt existiert
INIFileRequireINIFile(sINIFilename);
INIFileRequireINIFile( sINIFilename );
// fwe: Insgesamt 64k Zeichen fr die Liste der Sektionsnamen
// sollte fr die meisten Anwendungen reichen
const unsigned int SECTION_NAME_BUFFER_SIZE = 65536;
char buf[SECTION_NAME_BUFFER_SIZE];
char buf[ SECTION_NAME_BUFFER_SIZE ];
std::vector<std::string> vsResult;
if (GetPrivateProfileSectionNamesA(buf, SECTION_NAME_BUFFER_SIZE, FixPath(sINIFilename).c_str()) > 0) {
if( GetPrivateProfileSectionNamesA( buf, SECTION_NAME_BUFFER_SIZE, FixPath( sINIFilename ).c_str() ) > 0 )
{
char* p = buf;
unsigned int l;
while ((l = (unsigned int) strlen(p)) > 0) {
vsResult.push_back(p);
p += l+1;
while( ( l = ( unsigned int ) strlen( p ) ) > 0 ) {
vsResult.push_back( p );
p += l + 1;
}
}
return vsResult;
}
std::vector<std::string> INIFileGetKeys(const std::string& sINIFilename, const std::string& sSection) {
std::vector<std::string> INIFileGetKeys( const std::string& sINIFilename, const std::string& sSection )
{
// [fwe: Bugfix 2008-09-09] Sicherstellen das die Datei berhaupt existiert
INIFileRequireINIFile(sINIFilename);
INIFileRequireINIFile( sINIFilename );
// fwe: Insgesamt 64k Zeichen fr die Liste der Sektionsnamen
// sollte fr die meisten Anwendungen reichen
const unsigned int SECTION_BUFFER_SIZE = 65536;
char buf[SECTION_BUFFER_SIZE];
char buf[ SECTION_BUFFER_SIZE ];
std::vector<std::string> vsResult;
if (GetPrivateProfileSectionA(sSection.c_str(), buf, SECTION_BUFFER_SIZE, FixPath(sINIFilename).c_str()) > 0) {
if( GetPrivateProfileSectionA( sSection.c_str(), buf, SECTION_BUFFER_SIZE, FixPath( sINIFilename ).c_str() ) > 0 )
{
char* p = buf;
unsigned int l;
while ((l = (unsigned int) strlen(p)) > 0) {
while( ( l = ( unsigned int ) strlen( p ) ) > 0 )
{
std::string s = p;
// Windows macht einen Fehler und gibt hier auch auskommentierte Schlssel zurck. Deshalb Filtern:
if (s[0] != '#') {
if( s[ 0 ] != '#' ) {
// Gleichheitszeichen suchen
std::string t = s.substr(0, s.find_first_of('='));
if (!t.empty()) vsResult.push_back(t);
std::string t = s.substr( 0, s.find_first_of( '=' ) );
if( !t.empty() ) vsResult.push_back( t );
}
p += l+1;
p += l + 1;
}
}
return vsResult;
}
std::string INIFileReadString(const std::string& sINIFilename, const std::string& sSection, const std::string& sKey, std::string sDefaultValue) {
std::string INIFileReadString( const std::string& sINIFilename, const std::string& sSection, const std::string& sKey, std::string sDefaultValue )
{
// Sicherstellen das die INI-Datei existiert
INIFileRequireINIFile(sINIFilename);
INIFileRequireINIFile( sINIFilename );
// Zeichenpuffer
char buf[MAX_VALUE_STRING_LENGTH];
GetPrivateProfileStringA(sSection.c_str(),
sKey.c_str(),
sDefaultValue.c_str(),
(LPSTR) buf,
(DWORD) MAX_VALUE_STRING_LENGTH,
FixPath(sINIFilename).c_str());
return std::string(buf);
char buf[ MAX_VALUE_STRING_LENGTH ];
GetPrivateProfileStringA( sSection.c_str(),
sKey.c_str(),
sDefaultValue.c_str(),
( LPSTR ) buf,
( DWORD ) MAX_VALUE_STRING_LENGTH,
FixPath( sINIFilename ).c_str() );
return std::string( buf );
}
bool INIFileWriteString(const std::string& sINIFilename, const std::string& sSection, const std::string& sKey, const std::string& sValue) {
bool INIFileWriteString( const std::string& sINIFilename, const std::string& sSection, const std::string& sKey, const std::string& sValue )
{
// [fwe 2011-06-14] Improvement: Put a whitespace after the = in the file. Looks much nicer ;-)
std::string s(" ");
s.append(sValue);
return (WritePrivateProfileStringA(sSection.c_str(),
sKey.c_str(),
s.c_str(),
FixPath(sINIFilename).c_str()) == TRUE);
std::string s( " " );
s.append( sValue );
return ( WritePrivateProfileStringA( sSection.c_str(),
sKey.c_str(),
s.c_str(),
FixPath( sINIFilename ).c_str() ) == TRUE );
}
#endif // _WIN32
......
#include <ITAISO9613.h>
#include <ITAConstants.h>
#include <ITAException.h>
#include <ITAThirdOctaveMagnitudeSpectrum.h>
#include <cassert>
using namespace ITABase;
double ISO9613::AtmosphericAbsorptionLevel( double dFrequency, double dDistance, double dTemperature, double dHumidity, double dStaticPressure /*= 101.325*/ )
{
// ISO 9613-1 Acoustics - Attenuation of sound during propagation outdoors
// Reference ambient atmospheric pressure (Standard Ambient Atmosphere) [kPa]
// (Referenzatmosphrendruck Umgebung nach ISO Standard)
const double p_r = 101.325f;
// Ambient atmospheric pressure [kPa]
const double p_a = dStaticPressure;
// Reference air temperature [K]
const double T_0 = 273.15 + 20.0;
// Temperature [K] used for equation (B.3)
const double T_01 = 273.15 + 0.01;
// Ambient atmospheric temperature [K]
const double T = 273.15 + dTemperature;
// Equations (B.3) and (B.2) of Annex B used for calculation of h in (B.1)
const double C = -6.8346 * pow( T_01 / T, 1.261 ) + 4.6151;
const double p_sat_p_r = pow( ( double ) 10.0f, C );
// Molar concentration of water vapour [%] (Molekldichte Wasserdampf)
// Equation (B.2)
assert( 0.0f <= dHumidity && dHumidity <= 100.0f );
const double h = dHumidity * p_sat_p_r / ( p_a / p_r );
// Oxygen relaxation frequency [Hz]
// Equation (3)
const double f_r_o = ( p_a / p_r ) * ( 24.0 + 4.04e4*h*( 0.02 + h ) / ( 0.391 + h ) );
// Nitrogen relaxation frequency [Hz]
// Equation (4)
const double f_r_n = ( p_a / p_r ) * pow( T / T_0, -1.0 / 2.0 ) * ( 9.0f + 280.0*h*exp( -4.710 * ( pow( T / T_0, -( 1 / 3.0 ) ) - 1.0 ) ) );
// Parts of Equation (5) for the calculation of the attenuation coefficient [dB/m]
double dAlpha1 = 8.686 * pow( dFrequency, 2.0 );
double dAlpha2 = 1.84e-11 * pow( p_a / p_r, -1.0 ) * pow( T / T_0, 1.0 / 2.0 );
double dAlpha3 = pow( T / T_0, -5.0 / 2.0 );
double dAlpha4 = 0.01275f * exp( -2239.1 / T ) * pow( f_r_o + pow( dFrequency, 2.0 ) / f_r_o, -1.0 );
double dAlpha5 = 0.10680f * exp( -3352.0 / T ) * pow( f_r_n + pow( dFrequency, 2.0 ) / f_r_n, -1.0 );
// Attenuation coefficient [dB/m], ~f, as assembly of Equation (5) parts
double dAlpha = dAlpha1 * ( dAlpha2 + dAlpha3 * ( dAlpha4 + dAlpha5 ) );
// Resulting atmospheric absorption [dB], ~alpha (~f)
// Equation (2)
double dAirAbsorptionDecibel = dAlpha * dDistance;
// Attenuation factor in decibel
return dAirAbsorptionDecibel;
}
double ISO9613::AtmosphericAbsorptionFactor( double dFrequency, double dDistance, double dTemperature, double dHumidity, double dStaticPressure /*= 101.325*/ )
{
double dAirAbsorptionDecibel = AtmosphericAbsorptionLevel( dFrequency, dDistance, dTemperature, dHumidity, dStaticPressure );
//Factor of absorbed signal energy [0:1]
double dAirAbsorptionFactor = 1 - pow( 10, -dAirAbsorptionDecibel / 10.0 );
return dAirAbsorptionFactor;
}
void ISO9613::AtmosphericAbsorption( ITABase::CThirdOctaveDecibelMagnitudeSpectrum& oA_atm_dB, double dDistance, double dTemperature, double dHumidity, double dStaticPressure/*= 101.325*/ )
{
// loop over all frequencies
for( int i = 0; i < oA_atm_dB.GetNumBands(); i++ )
{
double dFrequency = ( double ) oA_atm_dB.GetCenterFrequencies()[ i ];
double dAirAbsorptionDecibel = AtmosphericAbsorptionLevel( dFrequency, dDistance, dTemperature, dHumidity, dStaticPressure );
oA_atm_dB.SetMagnitude( i, ( float ) dAirAbsorptionDecibel );
}
}
void ISO9613::AtmosphericAbsorption( ITABase::CThirdOctaveFactorMagnitudeSpectrum& oA_atm_factor, double dDistance, double dTemperature, double dHumidity, double dStaticPressure/*= 101.325*/ )
{
// loop over all frequencies and converting from decibel to a factor between 0 and 1
for( int i = 0; i < oA_atm_factor.GetNumBands(); i++ )
{
double dFrequency = ( double ) oA_atm_factor.GetCenterFrequencies()[ i ];
double dAirAbsorptionFactor = AtmosphericAbsorptionFactor( dFrequency, dDistance, dTemperature, dHumidity, dStaticPressure );
oA_atm_factor.SetMagnitude( i, ( float ) dAirAbsorptionFactor );
}
}
\ No newline at end of file
......@@ -96,13 +96,22 @@ void CITASpectrum::Add( const float fSummand )
m_vfValues[ n ] += fSummand;
}
void CITASpectrum::Add( const CITASpectrum& oOtherSpetrum )
void CITASpectrum::Add( const CITASpectrum& oOtherSpectrum )
{
if( GetNumBands() != oOtherSpetrum.GetNumBands() )
if( GetNumBands() != oOtherSpectrum.GetNumBands() )
ITA_EXCEPT1( INVALID_PARAMETER, "Number of bands mismatching, can not add spectra" );
for( size_t n = 0; n < m_vfValues.size(); n++ )
m_vfValues[ n ] += oOtherSpetrum[ int( n ) ];
m_vfValues[ n ] += oOtherSpectrum[ int( n ) ];
}
void CITASpectrum::Sub(const CITASpectrum& oOtherSpectrum)
{
if (GetNumBands() != oOtherSpectrum.GetNumBands())
ITA_EXCEPT1(INVALID_PARAMETER, "Number of bands mismatching, can not sub spectra");
for (size_t n = 0; n < m_vfValues.size(); n++)
m_vfValues[n] -= oOtherSpectrum[int(n)];
}
bool CITASpectrum::CompareEqualValues( const CITASpectrum& oOtherSpectrum, const float fThreshold /*= 10.0e-10 */ ) const
......
#include <ITAISO9613.h>
#include <iostream>
#include<VistaBase/VistaVector3D.h>
using namespace std;
int main(int nArgsIn, char** pccArgs)
{
//Test values taken from ISO 9613-1 Table 1
// Static air pressure [kPa]
const double dStaticPressure = 101.325;
//Distance [m]
const double dDistance = 1000.0;
// Temperature [C], frequency [Hz] and relative humidity [%]
// for different test environments as well as the respective
// atmospheric-absorption absorption coefficients [dB] of Table 1.
const double dTemperatureA = -20.0;
const double dFrequencyA = 50.0;
const double dHumidityA = 10.0;
const double dTargetAttenuationA = 5.89e-1;
double dActualAttenuationA = ITABase::ISO9613::AtmosphericAbsorptionLevel(dFrequencyA, dDistance, dTemperatureA, dHumidityA, dStaticPressure);
const double dTemperatureB =-5.0;
const double dFrequencyB = 1000.0;
const double dHumidityB = 50.0;
const double dTargetAttenuationB = 9.68;
double dActualAttenuationB = ITABase::ISO9613::AtmosphericAbsorptionLevel(dFrequencyB, dDistance, dTemperatureB, dHumidityB, dStaticPressure);
const double dTemperatureC = 0.0;
const double dFrequencyC = 315.0;
const double dHumidityC = 30.0;
const double dTargetAttenuationC = 1.69;
double dActualAttenuationC = ITABase::ISO9613::AtmosphericAbsorptionLevel(dFrequencyC, dDistance, dTemperatureC, dHumidityC, dStaticPressure);
const double dTemperatureD = 20.0;
const double dFrequencyD = 6300.0;
const double dHumidityD = 15.0;
const double dTargetAttenuationD = 1.75e2;
double dActualAttenuationD = ITABase::ISO9613::AtmosphericAbsorptionLevel(dFrequencyD, dDistance, dTemperatureD, dHumidityD, dStaticPressure);
const double dTemperatureE = 35.0;
const double dFrequencyE = 125.0;
const double dHumidityE = 80.0;
const double dTargetAttenuationE = 1.95e-1;
double dActualAttenuationE = ITABase::ISO9613::AtmosphericAbsorptionLevel(dFrequencyE, dDistance, dTemperatureE, dHumidityE, dStaticPressure);
const double dTemperatureF = 50.0;
const double dFrequencyF = 10000.0;
const double dHumidityF = 100.0;
const double dTargetAttenuationF = 1.09e2;
double dActualAttenuationF = ITABase::ISO9613::AtmosphericAbsorptionLevel(dFrequencyF, dDistance, dTemperatureF, dHumidityF, dStaticPressure);
//Compare the here calculated values with the values taken from ISO 9613-1 Table 1.
cout << "Temperature: " << dTemperatureA << " C\t Relative humidity: " << dHumidityA << " %\t Frequency: " << dFrequencyA << " Hz\t Target attenuation: " << dTargetAttenuationA << " dB\t Calculated attenuation: " << dActualAttenuationA << " dB" << endl;
cout << "Temperature: " << dTemperatureB << " C\t Relative humidity: " << dHumidityB << " %\t Frequency: " << dFrequencyB << " Hz\t Target attenuation: " << dTargetAttenuationB << " dB\t Calculated attenuation: " << dActualAttenuationB << " dB" << endl;
cout << "Temperature: " << dTemperatureC << " C\t Relative humidity: " << dHumidityC << " %\t Frequency: " << dFrequencyC << " Hz\t Target attenuation: " << dTargetAttenuationC << " dB\t Calculated attenuation: " << dActualAttenuationC << " dB" << endl;
cout << "Temperature: " << dTemperatureD << " C\t Relative humidity: " << dHumidityD << " %\t Frequency: " << dFrequencyD << " Hz\t Target attenuation: " << dTargetAttenuationD << " dB\t Calculated attenuation: " << dActualAttenuationD << " dB" << endl;
cout << "Temperature: " << dTemperatureE << " C\t Relative humidity: " << dHumidityE << " %\t Frequency: " << dFrequencyE << " Hz\t Target attenuation: " << dTargetAttenuationE << " dB\t Calculated attenuation: " << dActualAttenuationE << " dB" << endl;
cout << "Temperature: " << dTemperatureF << " C\t Relative humidity: " << dHumidityF << " %\t Frequency: " << dFrequencyF << " Hz\t Target attenuation: " << dTargetAttenuationF << " dB\t Calculated attenuation: " << dActualAttenuationF << " dB" << endl;
}
\ No newline at end of file
......@@ -17,6 +17,25 @@ vista_create_default_info_file( ITAStringUtilsTest )
set_property( TARGET ITAStringUtilsTest PROPERTY FOLDER "ITACoreLibs/Tests/ITABase" )
add_executable( ConfigUtilsTest ConfigUtilsTest.cpp )
target_link_libraries( ConfigUtilsTest ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( ConfigUtilsTest )
vista_install( ConfigUtilsTest )
vista_create_default_info_file( ConfigUtilsTest )
set_property( TARGET ConfigUtilsTest PROPERTY FOLDER "ITACoreLibs/Tests/ITABase" )
add_executable( AttenuationISO9613Test AttenuationISO9613Test.cpp )
target_link_libraries( AttenuationISO9613Test ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( AttenuationISO9613Test )
vista_install( AttenuationISO9613Test )
vista_create_default_info_file( AttenuationISO9613Test )
set_property( TARGET AttenuationISO9613Test PROPERTY FOLDER "ITACoreLibs/Tests/ITABase" )
add_executable( ITABaseSampleBufferTest ITABaseSampleBufferTest.cpp )
target_link_libraries( ITABaseSampleBufferTest ${VISTA_USE_PACKAGE_LIBRARIES} )
......
#include <ITAConfigUtils.h>
#include <iostream>
using namespace std;
int main( int nArgsIn, char** pccArgs )
{
if( nArgsIn > 1 )
INIFileUseFile( std::string( pccArgs[ 1 ] ) );
else
INIFileUseFile( "ConfigUtilsTest.ini" );
auto sections = INIFileGetSections();
for( auto section : sections )
{
cout << section << endl;
INIFileUseSection( section );
auto keys = INIFileGetKeys( section );
for( auto key : keys )
cout << " + " << key << "\t'" << INIFileReadString( key ) << "' [STRING] " << endl;
}
return 0;
}
#
# ConfigUtilsTest
#
[ff]
enabled1 = true
enabled2 = 1
enabled3 = false
[a:b]
enabled = true
[a:c]
enabled = false
[d:x]
enabled = true
[dd]
enabled = true
\ No newline at end of file