Aufgrund einer Wartung wird GitLab am 21.09. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 21.09. between 8:00 and 9:00 am.

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

Adding ITAOps for RAVEN

parent d4a2015f
......@@ -61,6 +61,7 @@ set( ITABaseHeader
"include/ITALog.h"
"include/ITAMutex.h"
"include/ITANumericUtils.h"
"include/ITAOps.h"
"include/ITASampleBuffer.h"
"include/ITASampleFrame.h"
"include/ITASampleTypeConversion.h"
......@@ -90,6 +91,7 @@ set( ITABaseSources
"src/ITALog.cpp"
"src/ITAMutex.cpp"
"src/ITANumericUtils.cpp"
"src/ITAOps.cpp"
"src/ITASampleBuffer.cpp"
"src/ITASampleFrame.cpp"
"src/ITASampleTypeConversion.cpp"
......
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2016
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_OPS
#define INCLUDE_WATCHER_ITA_OPS
//--------------------------------------------------------------------------------------
// includes
//--------------------------------------------------------------------------------------
#include <ITABaseDefinitions.h>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <list>
#include <map>
//--------------------------------------------------------------------------------------
float ITA_BASE_API roundIt(const float Zahl, const int Stellen);
//--------------------------------------------------------------------------------------
// define
//--------------------------------------------------------------------------------------
void ITA_BASE_API getUniqueIDsFromList(
const std::vector<unsigned int> &inputList,
std::list<unsigned int> &outputList);
void ITA_BASE_API getUniqueIDsFromList(
unsigned int* &inputList,
const int &inputListLength,
std::list<unsigned int> &outputList);
void ITA_BASE_API getUniqueIDsFromList(
const std::list<unsigned int> &inputList,
std::list<unsigned int> &outputList);
unsigned int ITA_BASE_API getID_BinaryToInteger(
const std::list<unsigned int> &inputList);
void ITA_BASE_API getID_BinaryToInteger(
const std::list<unsigned int> &inputList,
const unsigned int &roomCombinationListID);
void ITA_BASE_API storeCurrentSubPowerSet(
const std::list<unsigned int> &my_power_set, // IN
std::list<unsigned int> &valid_power_set_ids); // OUT
void ITA_BASE_API buildSubPowerSets(
unsigned int &counter,
unsigned int startIndex,
const std::list<unsigned int> &my_power_set,
std::list<unsigned int> &my_helper,
std::list<unsigned int> &valid_power_set_ids);
void ITA_BASE_API buildSubPowerSets(
const std::list<unsigned int> &my_power_set,
std::list<unsigned int> &valid_power_set_ids );
// --= Interpolationsroutinen =--
//! Einfache lineare Interpolation zwischen zwei Vektoren
void ITA_BASE_API interpolate(
std::vector<float> &result,
const std::vector<float> &a,
const std::vector<float> &b);
//! Interpolationroutine
/**
* \param x Ergebnis der Interpolation
* \param y Zu interpolierende Daten
* \param xDomainScale Skala des gewünschten Ergebnisses (gleiche Grösse wie x)
* \param yDomainScale Skala der Eingabedaten (gleiche Grösse wie y)
* \param IntType Gewünschte Interpolationsart: 0 für Halteglied, 1 für lineare Interpolation, 2 für Spline-Interpolation
*/
void ITA_BASE_API Interpolation(
std::vector<float> &x,
const std::vector<float> &y,
const std::vector<float> &xDomainScale,
const std::vector<float> &yDomainScale,
const unsigned int IntType);
// --= Insert-Routinen =--
//! Fügt das Einzelfilter in das Gesamtfilter ein (Float-Vector zu Float-Vector Implementierung)
void ITA_BASE_API Insert(
const std::vector<float> &pfSource,
std::vector<float> &pfDest,
const float fOffset,
const unsigned int uiLength);
//! Fügt das Einzelfilter in das Gesamtfilter ein (Float-Feld zu Float-Vector Implementierung)
void ITA_BASE_API Insert(
const float *pfSource,
std::vector<float> &pfDest,
const float fOffset,
const unsigned int uiLength);
//! Fügt das Einzelfilter in das Gesamtfilter mit Skalierung ein
void ITA_BASE_API Insert_scaled(
const std::vector<float> &pfSource,
std::vector<float> &pfDest,
const float iDestinationOffset,
const unsigned int uiLength,
const float fScaleFactor);
//! Fügt das Einzelfilter in das Gesamtfilter mit Skalierung ein
void Insert_scaled(
const std::vector<float> &pfSource,
std::vector<float> &pfDest,
const unsigned int uiDestinationOffset,
const unsigned int uiLength,
const float scaleFactor);
//! Fügt das Einzelfilter in das Gesamtfilter mit Skalierung ein
void ITA_BASE_API Insert_scaled(
const float* pfSource,
std::vector<float> &pfDest,
const unsigned int uiDestinationOffset,
const unsigned int uiLength,
const float fScaleFactor);
//! Fügt das Einzelfilter in das Gesamtfilter mit Skalierung ein
void ITA_BASE_API Insert_scaled(
const float* pfSource,
float* pfDest,
const unsigned int uiDestinationOffset,
const unsigned int uiNumSamples,
const float fScaleFactor);
//! Fügt das Einzelfilter in das Gesamtfilter mit Skalierung ein
void ITA_BASE_API Insert_scaled(
const std::vector<float> &pfSource,
std::vector<float> &pfDest,
const unsigned int iInsertPosition,
const float fScaleFactor);
//! Fügt das Einzelfilter in das Gesamtfilter mit Skalierung ein
void ITA_BASE_API Insert_scaled(
const float* pfSource,
float* pfDest,
const int iDestinationOffset,
const int iNumSamples,
const float fScaleFactor );
//! cartesian2polar - converts a complex number from real/imaginary to magnitude/phase representation
void ITA_BASE_API cartesian2polar(
float real,
float imaginary,
float& magnitude,
float& phase);
//! polar2cartesian - converts a complex number from magnitude/phase to real/imaginary representation
void ITA_BASE_API polar2cartesian(
float magnitude,
float phase,
float& real,
float& imaginary);
int ITA_BASE_API readPortalParameter(
const std::string filename_fullPath,
std::vector<float>& transfer_function,
std::string &portal_name,
std::string &portal_notes,
std::string & portal_surface_material);
/**
*determineCurrentValidPowerSetIDs
*
**/
void ITA_BASE_API determineCurrentValidPowerSetIDs(
const std::list<unsigned int> &currentValidRoomIDs,
std::list<unsigned int> &currentValidPowerSetIDs);
//! Schreibt den Inhalt eines std::vector mit Float-Werten in den RavenOutput (zu Debugging-zwecken)
/**
* \param vfVec Der Vektor, der runtergeschrieben werden soll
* \param sName Dateiname
*
* \note Exportiert die Daten in den Ordner "..\RavenOutput" (muss existieren!)
*/
void ITA_BASE_API writeVector( const std::vector<float> vfVec, std::string sName );
#endif // INCLUDE_WATCHER_ITA_OPS
//--------------------------------------------------------------------------------------
// includes
//--------------------------------------------------------------------------------------
#include "ITAOps.h"
#include <ITAConfigUtils.h>
#include <ITALog.h>
#include <ITAStringUtils.h>
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <spline.h>
#include <fstream>
#include <algorithm>
#ifndef ITAOPS_LOG_LEVEL
#define ITAOPS_LOG_LEVEL ITALOG_ERROR
#endif
#ifdef _DEBUG
#define ITAOPS_INFO(...) { if (ITAOPS_LOG_LEVEL >= ITALOG_INFO) { ITALOG_MSVC1("[I] OPS", __VA_ARGS__); } }
#else
#define ITAOPS_INFO(...) { if (ITAOPS_LOG_LEVEL >= ITALOG_INFO) { ITALOG_PRINTF1("[I] OPS", __VA_ARGS__); } }
#endif
//--------------------------------------------------------------------------------------
// cartesian2polar
//--------------------------------------------------------------------------------------
void cartesian2polar(
float real,
float imaginary,
float& magnitude,
float& phase)
{
magnitude = (float)sqrt( real * real + imaginary * imaginary );
phase = (float)atan2( imaginary, real );
}
//--------------------------------------------------------------------------------------
// polar2cartesian
//--------------------------------------------------------------------------------------
void polar2cartesian(
float magnitude,
float phase,
float& real,
float& imaginary)
{
real = magnitude * cos(phase);
imaginary = magnitude * sin(phase);
}
//--------------------------------------------------------------------------------------
// roundIt
//--------------------------------------------------------------------------------------
float roundIt(const float Zahl, const int Stellen)
{
float tmp = Zahl;
tmp *= pow(10.0f, Stellen);
tmp = floor(tmp + 0.5f);
tmp *= pow(10.0f, -Stellen);
return tmp;
}
//--------------------------------------------------------------------------------------
// getUniqueIDsFromList
//--------------------------------------------------------------------------------------
void getUniqueIDsFromList(
const std::list<unsigned int> &inputList,
std::list<unsigned int> &outputList)
{
// returns only unique ids from list
// example:
// input: 0 2 0 0 1
// returns: 0 2 1 // note, ids not sorted, as we don't need that (so far)
bool idExists = false;
for (std::list<unsigned int>::const_iterator i = inputList.begin();
i != inputList.end();
++i)
{
// check if id is alreay in output list
for (std::list<unsigned int>::const_iterator j = outputList.begin();
j != outputList.end();
++j)
{
if( (*i) == (*j) )
{
idExists = true;
break;
}
}// for all output ids
if(idExists == true)
{
idExists = false;
}
else
{
outputList.push_back( (*i) );
}
} // for all input ids
// TODO: nur zum testen, wenn es laeuft, raus damit
//print output:
printf("------------------------------------------------------------\n");
printf("Input list contains: ");
for (std::list<unsigned int>::const_iterator i = inputList.begin();
i != inputList.end();
i++)
{
printf("%d, ", (*i));
}
printf("\nOutput list contains: ");
for (std::list<unsigned int>::const_iterator j = outputList.begin();
j != outputList.end();
++j)
{
printf("%d, ", (*j));
}
printf("\n------------------------------------------------------------\n");
}
void getUniqueIDsFromList(
unsigned int* &inputList,
const int &inputListLength,
std::list<unsigned int> &outputList)
{
// returns only unique ids from list
// example:
// input: 0 2 0 0 1
// returns: 0 2 1 // note, ids not sorted, as we don't need that (so far)
bool idExists = false;
for (int i = 0; i < inputListLength; ++i)
{
// check if id is alreay in output list
for (std::list<unsigned int>::const_iterator j = outputList.begin();
j != outputList.end();
++j)
{
if( inputList[i] == (*j) )
{
idExists = true;
break;
}
}// for all output ids
if(idExists == true)
{
idExists = false;
}
else
{
outputList.push_back( inputList[i] );
}
} // for all input ids
}
void getUniqueIDsFromList(
const std::vector<unsigned int> &inputList,
std::list<unsigned int> &outputList)
{
// returns only unique ids from list
// example:
// input: 0 2 0 0 1
// returns: 0 2 1 // note, ids not sorted, as we don't need that (so far)
bool idExists = false;
for (unsigned int i = 0; i < inputList.size(); ++i)
{
// check if id is alreay in output list
for (std::list<unsigned int>::const_iterator j = outputList.begin();
j != outputList.end();
++j)
{
if( inputList[i] == (*j) )
{
idExists = true;
break;
}
}// for all output ids
if(idExists == true)
{
idExists = false;
}
else
{
outputList.push_back( inputList[i] );
}
} // for all input ids
/* // TODO: nur zum testen, wenn es laeuft, raus damit
//print output:
printf("------------------------------------------------------------\n");
printf("Input list contains: ");
for (unsigned int i = 0; i < inputList.size(); i++)
{
printf("%d, ", inputList[i]);
}
printf("\nOutput list contains: ");
for (std::list<unsigned int>::const_iterator j = outputList.begin();
j != outputList.end();
j++)
{
printf("%d, ", (*j));
}
printf("\n------------------------------------------------------------\n");
*/
}
//--------------------------------------------------------------------------------------
// getID_BinaryToInteger
//--------------------------------------------------------------------------------------
void getID_BinaryToInteger(
const std::list<unsigned int> &inputList,
unsigned int &roomCombinationListID)
{
roomCombinationListID = 0;
for (std::list<unsigned int>::const_iterator i = inputList.begin();
i != inputList.end();
i++)
{
roomCombinationListID = (unsigned int) (roomCombinationListID + pow(2.0f,(int)(*i)));
}
}
unsigned int getID_BinaryToInteger(
const std::list<unsigned int> &inputList)
{
if (inputList.size() == 1) return 1;
unsigned int roomCombinationListID = 0;
for (std::list<unsigned int>::const_iterator i = inputList.begin();
i != inputList.end();
++i)
{
roomCombinationListID = (unsigned int) (roomCombinationListID + pow(2.0f, (int)(*i)));
}
return roomCombinationListID;
}
//--------------------------------------------------------------------------------------
// storeCurrentSubPowerSet
//--------------------------------------------------------------------------------------
void storeCurrentSubPowerSet(
const std::list<unsigned int> &my_power_set, // IN
std::list<unsigned int> &valid_power_set_ids) // OUT
{
// printf("\nids: ");
for (std::list<unsigned int>::const_iterator i = my_power_set.begin();
i != my_power_set.end();
++i)
{
// printf("%d", (*i));
}
unsigned int tmp_id = getID_BinaryToInteger(my_power_set);
// we don't need index 0
if(tmp_id != 0)
{
valid_power_set_ids.push_back(tmp_id);
}
// printf("\n");
}
//--------------------------------------------------------------------------------------
// buildSubPowerSets (for recursive calls)
//--------------------------------------------------------------------------------------
void buildSubPowerSets(
unsigned int &counter,
unsigned int startIndex,
const std::list<unsigned int> &my_power_set,
std::list<unsigned int> &my_helper,
std::list<unsigned int> &valid_power_set_ids)
{
storeCurrentSubPowerSet(
my_helper,
valid_power_set_ids);
counter++;
std::list<unsigned int>::const_iterator i = my_power_set.begin();
unsigned int counter2 = startIndex;
// verschieben des zeigers auf den startIndex
for(unsigned int k = 0; k < startIndex; k++)
{
i++;
}
//for( unsigned int i = startIndex; i < my_power_set.size(); ++i )
for (i;
i != my_power_set.end();
++i)
{
counter2++;
my_helper.push_back( (*i) );
buildSubPowerSets(counter, counter2, my_power_set, my_helper,valid_power_set_ids );
my_helper.pop_back();
}
}
//--------------------------------------------------------------------------------------
// buildSubPowerSets (initial)
//--------------------------------------------------------------------------------------
void buildSubPowerSets(
const std::list<unsigned int> &my_power_set,
std::list<unsigned int> &valid_power_set_ids )
{
std::list<unsigned int> tmp_power_set;
unsigned int my_counter = 1;
buildSubPowerSets( my_counter, 0, my_power_set, tmp_power_set,valid_power_set_ids);
}
//--------------------------------------------------------------------------------------
// Interpolation
//--------------------------------------------------------------------------------------
void Interpolation(
std::vector<float> &x,
const std::vector<float> &y,
const std::vector<float> &xDomainScale,
const std::vector<float> &yDomainScale,
const unsigned int IntType)
{
// Ausgabe auf richtige Gre skalieren
x.resize(xDomainScale.size());
float m = 0.0f;
unsigned int counter = 0; // Zhlvariable
unsigned int xSize = (unsigned int)xDomainScale.size(); // Gre x-Array
unsigned int ySize = (unsigned int)yDomainScale.size(); // Gre y-Array
if (IntType == 0) // Halteglied
{
for (unsigned int i=0; i<xSize; i++)
{
if( xDomainScale[i] <= yDomainScale[counter])
{
x[i] = y[counter];
} else if (( xDomainScale[i] > yDomainScale[counter] ) && (counter<(ySize-1)))
{
counter++;
x[i] = y[counter];
}else
{
x[i] = y[counter];
}
}
} else if (IntType == 1) // lineare Interpolation
{
for (unsigned int i=0; i<xSize; i++)
{
// Frequenzindex unter der Untergrenze, einfaches Halteglied
if (xDomainScale[i] < yDomainScale[0])
{
x[i] = y[0];
}
// Frequenzindex ber Obergrenze, einfaches Halteglied
else if (xDomainScale[i] > yDomainScale[ySize-1])
{
x[i] = y[ySize-1];
}else // sonst: lineare Interpolation
{
//// trick um nullen im spten bereich zu vermeiden...
//// ####################################################################################################
//if (y[counter+1] == 0)
// y[counter+1] = y[counter]/2;
//// ####################################################################################################
//// soll hier wirklich das input array berschrieben werden??????
m = (y[counter+1] - y[counter]) / (yDomainScale[counter+1] - yDomainScale[counter]);
x[i] = y[counter] + m * (xDomainScale[i] - yDomainScale[counter]);
if ((xDomainScale[i] >= yDomainScale[counter]) && (counter< (ySize-2)))
counter++;
}
}
} else if (IntType == 2) // Spline Interpolation
{
//TODO: eventuell noch die Erweiterung der Sttzstellen einfhren um ein
// bersprechen an den Grenzen zu vermeiden.
float *ypp = NULL;
// determine needed matrix for spline interpolation and store it in ypp
ypp = spline_cubic_set(ySize, &yDomainScale[0], &y[0], 0, y[0], 0, y[ySize-1]);
// interpolate all required nodes
for (unsigned int i=0; i<xSize; i++)
x[i] = spline_cubic_val(ySize, &yDomainScale[0], xDomainScale[i], &y[0], ypp);
delete [] ypp;
} else
{
printf("Fehler!! Diese Interpolationsmethode gibt es nicht!!");