/******************************************************************************\ * Copyright (c) 2004-2006 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * \******************************************************************************/ #if !defined(UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_) #define UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ #include #include #include #include #include #include #include #include "global.h" using namespace std; /* Because of the library: "vector" */ #ifdef _WIN32 # include "../windows/moc/aboutdlgbase.h" #else # include "moc/aboutdlgbase.h" #endif /* Definitions ****************************************************************/ #define METER_FLY_BACK 2 /* Global functions ***********************************************************/ /* Converting double to short */ inline short Double2Short(const double dInput) { /* Lower bound */ if (dInput < _MINSHORT) return _MINSHORT; /* Upper bound */ if (dInput > _MAXSHORT) return _MAXSHORT; return (short) dInput; } /* Debug error handling */ void DebugError(const char* pchErDescr, const char* pchPar1Descr, const double dPar1, const char* pchPar2Descr, const double dPar2); /******************************************************************************\ * CVector base class * \******************************************************************************/ template class CVector : public std::vector { public: CVector() : iVectorSize(0) {pData = this->begin();} CVector(const int iNeSi) {Init(iNeSi);} CVector(const int iNeSi, const TData tInVa) {Init(iNeSi, tInVa);} virtual ~CVector() {} /* Copy constructor: The order of the initialization list must not be changed. First, the base class must be initialized, then the pData pointer must be set to the new data source. The bit access is, by default, reset */ CVector(const CVector& vecI) : std::vector(static_cast&>(vecI)), iVectorSize(vecI.Size()), pData(this->begin()) {} void Init(const int iNewSize); /* Use this init to give all elements a defined value */ void Init(const int iNewSize, const TData tIniVal); void Reset(const TData tResetVal); void Enlarge(const int iAddedSize); void Add(const TData& tI) {Enlarge(1); pData[iVectorSize - 1] = tI;} inline int Size() const {return iVectorSize;} /* This operator allows for a l-value assignment of this object: CVector[x] = y is possible */ inline TData& operator[](const int iPos) { #ifdef _DEBUG_ if ((iPos < 0) || (iPos > iVectorSize - 1)) { DebugError("Writing vector out of bounds", "Vector size", iVectorSize, "New parameter", iPos); } #endif return pData[iPos];} inline TData operator[](const int iPos) const { #ifdef _DEBUG_ if ((iPos < 0) || (iPos > iVectorSize - 1)) { DebugError("Reading vector out of bounds", "Vector size", iVectorSize, "New parameter", iPos); } #endif return pData[iPos];} inline CVector& operator=(const CVector& vecI) { #ifdef _DEBUG_ /* Vectors which shall be copied MUST have same size! (If this is satisfied, the parameter "iVectorSize" must not be adjusted as a side effect) */ if (vecI.Size() != iVectorSize) { DebugError("Vector operator=() different size", "Vector size", iVectorSize, "New parameter", vecI.Size()); } #endif vector::operator=(vecI); /* Reset my data pointer in case, the operator=() of the base class did change the actual memory */ pData = this->begin(); return *this; } protected: typename std::vector::iterator pData; int iVectorSize; }; /* Implementation *************************************************************/ template void CVector::Init(const int iNewSize) { iVectorSize = iNewSize; /* Clear old buffer and reserve memory for new buffer, get iterator for pointer operations */ this->clear(); this->resize(iNewSize); pData = this->begin(); } template void CVector::Init(const int iNewSize, const TData tIniVal) { /* Call actual init routine */ Init(iNewSize); /* Set values */ Reset(tIniVal); } template void CVector::Enlarge(const int iAddedSize) { iVectorSize += iAddedSize; this->resize(iVectorSize); /* We have to reset the pointer since it could be that the vector size was zero before enlarging the vector */ pData = this->begin(); } template void CVector::Reset(const TData tResetVal) { /* Set all values to reset value */ for (int i = 0; i < iVectorSize; i++) pData[i] = tResetVal; } /******************************************************************************\ * CFIFO class (first in, first out) * \******************************************************************************/ template class CFIFO : public CVector { public: CFIFO() : CVector(), iCurIdx(0) {} CFIFO(const int iNeSi) : CVector(iNeSi), iCurIdx(0) {} CFIFO(const int iNeSi, const TData tInVa) : CVector(iNeSi, tInVa), iCurIdx(0) {} void Add(const TData tNewD); inline TData Get() {return this->pData[iCurIdx];} virtual void Init(const int iNewSize); virtual void Init(const int iNewSize, const TData tIniVal); protected: int iCurIdx; }; template void CFIFO::Init(const int iNewSize) { iCurIdx = 0; CVector::Init(iNewSize); } template void CFIFO::Init(const int iNewSize, const TData tIniVal) { iCurIdx = 0; CVector::Init(iNewSize, tIniVal); } template void CFIFO::Add(const TData tNewD) { this->pData[iCurIdx] = tNewD; /* Increment index */ iCurIdx++; if (iCurIdx >= this->iVectorSize) iCurIdx = 0; } /******************************************************************************\ * CMovingAv class (moving average) * \******************************************************************************/ template class CMovingAv : public CVector { public: CMovingAv() : CVector(), iCurIdx(0), iNorm(0), tCurAvResult(TData(0)) {} CMovingAv(const int iNeSi) : CVector(iNeSi), iCurIdx(0), iNorm(0), tCurAvResult(TData(0)) {} CMovingAv(const int iNeSi, const TData tInVa) : CVector(iNeSi, tInVa), iCurIdx(0), iNorm(0), tCurAvResult(TData(0)) {} void Add(const TData tNewD); inline TData GetAverage() { if (this->iNorm == 0) return TData(0); else return tCurAvResult / this->iNorm; } virtual void Init(const int iNewSize); void InitVec(const int iNewSize, const int iNewVecSize); protected: int iCurIdx; int iNorm; TData tCurAvResult; }; template void CMovingAv::Init(const int iNewSize) { iNorm = 0; iCurIdx = 0; tCurAvResult = TData(0); /* Only for scalars! */ CVector::Init(iNewSize); } template void CMovingAv::Add(const TData tNewD) { /* Optimized calculation of the moving average. We only add a new value and subtract the old value from the result. We only need one addition and a history buffer */ /* Subtract oldest value */ tCurAvResult -= this->pData[iCurIdx]; /* Add new value and write in memory */ tCurAvResult += tNewD; this->pData[iCurIdx] = tNewD; /* Increase position pointer and test if wrap */ iCurIdx++; if (iCurIdx >= this->iVectorSize) iCurIdx = 0; /* take care of norm */ if (this->iNorm < this->iVectorSize) this->iNorm++; } /******************************************************************************\ * GUI utilities * \******************************************************************************/ /* About dialog ------------------------------------------------------------- */ class CAboutDlg : public CAboutDlgBase { Q_OBJECT public: CAboutDlg(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags f = 0); }; /* Help menu ---------------------------------------------------------------- */ class CLlconHelpMenu : public QPopupMenu { Q_OBJECT public: CLlconHelpMenu(QWidget* parent = 0); protected: CAboutDlg AboutDlg; public slots: void OnHelpWhatsThis () { QWhatsThis::enterWhatsThisMode (); } void OnHelpAbout () { AboutDlg.exec(); } }; /* Other Classes **************************************************************/ /* Signal Level Meter ------------------------------------------------------- */ class CSignalLevelMeter { public: CSignalLevelMeter() : dCurLevel(0.0) {} virtual ~CSignalLevelMeter() {} void Update(CVector& vecdAudio); double MicLevel(); void Reset() {dCurLevel = 0.0;} protected: double dCurLevel; }; class CHostAddress { public: CHostAddress() : InetAddr((Q_UINT32) 0), iPort(0) {} CHostAddress(const QHostAddress NInetAddr, const Q_UINT16 iNPort) : InetAddr(NInetAddr), iPort(iNPort) {} CHostAddress(const CHostAddress& NHAddr) : InetAddr(NHAddr.InetAddr), iPort(NHAddr.iPort) {} /* copy and compare operators */ CHostAddress& operator=(const CHostAddress& NHAddr) {InetAddr = NHAddr.InetAddr; iPort = NHAddr.iPort; return *this;} bool operator==(const CHostAddress& CompAddr) /* oompare operator */ {return ((CompAddr.InetAddr == InetAddr) && (CompAddr.iPort == iPort));} QHostAddress InetAddr; Q_UINT16 iPort; }; /* Audio Reverbration ------------------------------------------------------- */ class CAudioReverb { public: CAudioReverb(const double rT60 = (double) 5.0); void Clear(); double ProcessSample(const double input); protected: void setT60(const double rT60); bool isPrime(const int number); CFIFO allpassDelays_[3]; CFIFO combDelays_[4]; double allpassCoefficient_; double combCoefficient_[4]; }; /* Time conversion ---------------------------------------------------------- */ // needed for ping measurement class CTimeConv { public: // QTime to network time vector static CVector QTi2NetTi ( const QTime qTiIn ) { // vector format: 1 byte hours, 1 byte min, 1 byte sec, 2 bytes ms CVector veccNetTi ( 5 ); veccNetTi[0] = static_cast ( qTiIn.hour () ); veccNetTi[1] = static_cast ( qTiIn.minute () ); veccNetTi[2] = static_cast ( qTiIn.second () ); const int iMs = qTiIn.msec (); veccNetTi[3] = static_cast ( ( iMs >> 8 ) & 255 ); veccNetTi[4] = static_cast ( iMs & 255 ); return veccNetTi; } // network time vector to QTime static QTime NetTi2QTi ( const CVector netTiIn ) { // vector format: 1 byte hours, 1 byte min, 1 byte sec, 2 bytes ms return QTime ( static_cast ( netTiIn[0] ), // hour static_cast ( netTiIn[1] ), // minute static_cast ( netTiIn[2] ), // seconds // msec static_cast ( ( netTiIn[3] << 8 ) | netTiIn[4] ) ); } }; #endif /* !defined(UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_) */