diff --git a/llcon.pro b/llcon.pro index e5203762..6f453b32 100755 --- a/llcon.pro +++ b/llcon.pro @@ -103,6 +103,7 @@ HEADERS += src/audiomixerboard.h \ src/soundbase.h \ src/testbench.h \ src/util.h \ + src/analyzerconsole.h \ libs/celt/cc6_celt.h \ libs/celt/cc6_celt_types.h \ libs/celt/cc6_celt_header.h \ @@ -211,6 +212,7 @@ SOURCES += src/audiomixerboard.cpp \ src/socket.cpp \ src/soundbase.cpp \ src/util.cpp \ + src/analyzerconsole.cpp \ libs/celt/cc6_bands.c \ libs/celt/cc6_celt.c \ libs/celt/cc6_cwrs.c \ diff --git a/src/analyzerconsole.cpp b/src/analyzerconsole.cpp new file mode 100644 index 00000000..2e790ae7 --- /dev/null +++ b/src/analyzerconsole.cpp @@ -0,0 +1,214 @@ +/******************************************************************************\ + * Copyright (c) 2004-2013 + * + * 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 + * +\******************************************************************************/ + +#include "analyzerconsole.h" + + +// Analyzer console implementation ********************************************* +CAnalyzerConsole::CAnalyzerConsole ( CClient* pNCliP, + QWidget* parent, + Qt::WindowFlags ) : + QDialog ( parent ), + pClient ( pNCliP ), + GraphErrRateCanvasRect ( 0, 0, 600, 450 ), // defines total size of graph + iGridFrameOffset ( 10 ), + iLineWidth ( 2 ), + iMarkerSize ( 10 ), + iXAxisTextHeight ( 22 ), + GraphBackgroundColor ( Qt::white ), // background + GraphFrameColor ( Qt::black ), // frame + GraphGridColor ( Qt::gray ), // grid + LineColor ( Qt::blue ), + LineLimitColor ( Qt::red ), + GraphImage ( 1, 1, QImage::Format_RGB32 ) +{ + QVBoxLayout* pMainLayout = new QVBoxLayout; + + // create and add main tab widget + pMainTabWidget = new QTabWidget ( this ); + pMainLayout->addWidget ( pMainTabWidget ); + + setLayout ( pMainLayout ); + + // error rate gaph tab + pTabWidgetBufErrRate = new QWidget(); + QVBoxLayout* pTabErrRateLayout = new QVBoxLayout ( pTabWidgetBufErrRate ); + + pGraphErrRate = new QLabel ( this ); + pTabErrRateLayout->addWidget ( pGraphErrRate ); + + pMainTabWidget->addTab ( pTabWidgetBufErrRate, "Error Rate" ); + + + // Connections ------------------------------------------------------------- + // timers + QObject::connect ( &TimerErrRateUpdate, SIGNAL ( timeout() ), + this, SLOT ( OnTimerErrRateUpdate() ) ); + + // window events + QObject::connect ( this, SIGNAL ( resizeEvent ( QResizeEvent* ) ), + this, SLOT ( OnResizeEvent ( QResizeEvent* ) ) ); + + + // Timers ------------------------------------------------------------------ + // start timer for error rate graph + TimerErrRateUpdate.start ( ERR_RATE_GRAPH_UPDATE_TIME_MS ); +} + +void CAnalyzerConsole::OnResizeEvent ( QResizeEvent* event ) +{ + +} + +void CAnalyzerConsole::OnTimerErrRateUpdate() +{ + + DrawFrame(); + DrawErrorRateTrace(); + + +pGraphErrRate->setPixmap ( QPixmap().fromImage ( GraphImage ) ); + + +} + +void CAnalyzerConsole::DrawFrame() +{ +/* + // scale image to correct size + GraphImage = GraphImage.scaled ( + pTabWidgetBufErrRate->width(), pTabWidgetBufErrRate->height() ); + + // generate plot grid frame rectangle + GraphGridFrame.setRect ( pTabWidgetBufErrRate->x() + iGridFrameOffset, + pTabWidgetBufErrRate->y() + iGridFrameOffset, + pTabWidgetBufErrRate->width() - 2 * iGridFrameOffset, + pTabWidgetBufErrRate->height() - 2 * iGridFrameOffset - iXAxisTextHeight ); +*/ + + // scale image to correct size + GraphImage = GraphImage.scaled ( + GraphErrRateCanvasRect.width(), GraphErrRateCanvasRect.height() ); + + // generate plot grid frame rectangle + GraphGridFrame.setRect ( GraphErrRateCanvasRect.x() + iGridFrameOffset, + GraphErrRateCanvasRect.y() + iGridFrameOffset, + GraphErrRateCanvasRect.width() - 2 * iGridFrameOffset, + GraphErrRateCanvasRect.height() - 2 * iGridFrameOffset - iXAxisTextHeight ); + + + + GraphImage.fill ( GraphBackgroundColor.rgb() ); // fill background + + // create painter + QPainter GraphPainter ( &GraphImage ); + + // create actual plot region (grid frame) + GraphPainter.setPen ( GraphFrameColor ); + GraphPainter.drawRect ( GraphGridFrame ); +} + +void CAnalyzerConsole::DrawErrorRateTrace() +{ + int i; + + // create painter + QPainter GraphPainter ( &GraphImage ); + + // get the network buffer error rates to be displayed + CVector vecButErrorRates; + double dLimit; + + pClient->GetBufErrorRates ( vecButErrorRates, dLimit ); + + // get the number of data elements + const int iNumBuffers = vecButErrorRates.Size(); + + // convert the limit in the log domain + const double dLogLimit = log10 ( dLimit ); + + // use fixed y-axis scale where the limit line is in the middle of the graph + const double dMax = 0; + const double dMin = dLogLimit * 2; + + // calculate space between points on the x-axis + const double dXSpace = + static_cast ( GraphGridFrame.width() ) / ( iNumBuffers - 1 ); + + // plot the limit line + + +// TEST +const double dYValLimitInGraph = CalcYPosInGraph ( dMin, dMax, dLogLimit ); +GraphPainter.setPen ( QPen ( QBrush ( LineLimitColor ), iLineWidth, Qt::DashLine ) ); +GraphPainter.drawLine ( QPoint ( GraphGridFrame.x(), dYValLimitInGraph ), + QPoint ( GraphGridFrame.x() + GraphGridFrame.width(), dYValLimitInGraph ) ); + + + // plot the data + for ( i = 0; i < iNumBuffers; i++ ) + { + // data convert in log domain + // check for special case if error rate is 0 (which would lead to -Inf + // after the log operation) + if ( vecButErrorRates[i] > 0 ) + { + vecButErrorRates[i] = log10 ( vecButErrorRates[i] ); + } + else + { + // definition: set it to lowest possible axis value + vecButErrorRates[i] = dMin; + } + + // calculate the actual point in the graph (in pixels) + const QPoint curPoint ( + GraphGridFrame.x() + static_cast ( dXSpace * i ), + CalcYPosInGraph ( dMin, dMax, vecButErrorRates[i] ) ); + + +// TEST +GraphPainter.setPen ( QPen ( QBrush ( LineColor ), iMarkerSize, Qt::SolidLine, Qt::RoundCap ) ); +GraphPainter.drawPoint ( curPoint ); +GraphPainter.setPen ( QPen ( QBrush ( LineColor ), iLineWidth ) ); +GraphPainter.drawLine ( QPoint ( curPoint.x(), GraphGridFrame.y() + GraphGridFrame.height() ), curPoint ); + + + } +} + +int CAnalyzerConsole::CalcYPosInGraph ( const double dAxisMin, + const double dAxisMax, + const double dValue ) const +{ + // calculate value range + const double dValRange = dAxisMax - dAxisMin; + + // calculate current normalized y-axis value + const double dYValNorm = ( dValue - dAxisMin ) / dValRange; + + // consider the graph grid size to calculate the final y-axis value + return GraphGridFrame.y() + static_cast ( + static_cast ( GraphGridFrame.height() ) * ( 1 - dYValNorm ) ); +} diff --git a/src/analyzerconsole.h b/src/analyzerconsole.h new file mode 100644 index 00000000..3e5a36b0 --- /dev/null +++ b/src/analyzerconsole.h @@ -0,0 +1,91 @@ +/******************************************************************************\ + * Copyright (c) 2004-2013 + * + * 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 ( ANALYZERCONSOLE_H__FD6BKUBVE723IUH06C2AC__INCLUDED_ ) +#define ANALYZERCONSOLE_H__FD6BKUBVE723IUH06C2AC__INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include "client.h" + + +/* Definitions ****************************************************************/ +// defines the update time of the error rate graph +#define ERR_RATE_GRAPH_UPDATE_TIME_MS 200 // ms + + +/* Classes ********************************************************************/ +class CAnalyzerConsole : public QDialog +{ + Q_OBJECT + +public: + CAnalyzerConsole ( CClient* pNCliP, + QWidget* parent = 0, + Qt::WindowFlags f = 0 ); + + +protected: + void DrawFrame(); + void DrawErrorRateTrace(); + int CalcYPosInGraph ( const double dAxisMin, + const double dAxisMax, + const double dValue ) const; + + CClient* pClient; + + QTabWidget* pMainTabWidget; + QWidget* pTabWidgetBufErrRate; + + QLabel* pGraphErrRate; + QImage GraphImage; + + QRect GraphErrRateCanvasRect; + QRect GraphGridFrame; + + int iGridFrameOffset; + int iLineWidth; + int iMarkerSize; + int iXAxisTextHeight; + + QColor GraphBackgroundColor; + QColor GraphFrameColor; + QColor GraphGridColor; + QColor LineColor; + QColor LineLimitColor; + + QTimer TimerErrRateUpdate; + + +public slots: + void OnTimerErrRateUpdate(); + void OnResizeEvent ( QResizeEvent* event ); +}; + +#endif // ANALYZERCONSOLE_H__FD6BKUBVE723IUH06C2AC__INCLUDED_