From 2f3850676359c8d0626ba987d69d95e8b20f0b62 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Feb 2012 15:07:47 +0000 Subject: [PATCH] merged existing p3VoRS service with VOIP plugin git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4965 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- plugins/VOIP/VOIP.pro | 30 +- plugins/VOIP/VOIPPlugin.cpp | 12 +- plugins/VOIP/VOIPPlugin.h | 5 +- plugins/VOIP/gui/AudioInputConfig.cpp | 60 +-- plugins/VOIP/gui/AudioWizard.cpp | 28 +- plugins/VOIP/gui/SpeexProcessor.cpp | 24 +- plugins/VOIP/gui/VoipStatistics.cpp | 393 ++++++++++++++++++ plugins/VOIP/gui/VoipStatistics.h | 68 +++ plugins/VOIP/gui/VoipStatistics.ui | 55 +++ plugins/VOIP/{ => interface}/rsvoip.h | 26 +- plugins/VOIP/{service => services}/p3vors.cc | 76 +++- plugins/VOIP/{service => services}/p3vors.h | 52 ++- .../VOIP/{service => services}/rsvoipitems.cc | 3 +- .../VOIP/{service => services}/rsvoipitems.h | 0 14 files changed, 730 insertions(+), 102 deletions(-) create mode 100644 plugins/VOIP/gui/VoipStatistics.cpp create mode 100644 plugins/VOIP/gui/VoipStatistics.h create mode 100644 plugins/VOIP/gui/VoipStatistics.ui rename plugins/VOIP/{ => interface}/rsvoip.h (71%) rename plugins/VOIP/{service => services}/p3vors.cc (87%) rename plugins/VOIP/{service => services}/p3vors.h (66%) rename plugins/VOIP/{service => services}/rsvoipitems.cc (99%) rename plugins/VOIP/{service => services}/rsvoipitems.h (100%) diff --git a/plugins/VOIP/VOIP.pro b/plugins/VOIP/VOIP.pro index a8608ecba..542ffa5cd 100644 --- a/plugins/VOIP/VOIP.pro +++ b/plugins/VOIP/VOIP.pro @@ -2,17 +2,37 @@ CONFIG += qt uic qrc resources CONFIG += mobility -#/QT += multimedia MOBILITY = multimedia QMAKE_CXXFLAGS *= -Wall -SOURCES = p3Voip.cpp VOIPPlugin.cpp AudioInputConfig.cpp AudioStats.cpp AudioWizard.cpp SpeexProcessor.cpp audiodevicehelper.cpp -HEADERS = p3Voip.h AudioInputConfig.h AudioStats.h AudioWizard.h SpeexProcessor.h audiodevicehelper.h -FORMS = AudioInputConfig.ui AudioStats.ui AudioWizard.ui +SOURCES = services/p3vors.cc \ + services/rsvoipitems.cc \ + gui/AudioInputConfig.cpp \ + gui/AudioStats.cpp \ + gui/AudioWizard.cpp \ + gui/SpeexProcessor.cpp \ + gui/audiodevicehelper.cpp \ + gui/VoipStatistics.cpp \ + VOIPPlugin.cpp + +HEADERS = services/p3vors.h \ + services/rsvoipitems.h \ + gui/AudioInputConfig.h \ + gui/AudioStats.h \ + gui/AudioWizard.h \ + gui/SpeexProcessor.h \ + gui/audiodevicehelper.h \ + gui/VoipStatistics.h \ + interface/rsvoip.h + +FORMS = gui/AudioInputConfig.ui \ + gui/AudioStats.ui \ + gui/VoipStatistics.ui \ + gui/AudioWizard.ui TARGET = VOIP -RESOURCES = VOIP_images.qrc +RESOURCES = gui/VOIP_images.qrc LIBS += -lspeex -lspeexdsp diff --git a/plugins/VOIP/VOIPPlugin.cpp b/plugins/VOIP/VOIPPlugin.cpp index 0a5990f80..995aa46e5 100644 --- a/plugins/VOIP/VOIPPlugin.cpp +++ b/plugins/VOIP/VOIPPlugin.cpp @@ -3,7 +3,8 @@ #include #include "VOIPPlugin.h" -#include "AudioInputConfig.h" +#include "interface/rsvoip.h" +#include "gui/AudioInputConfig.h" static void *inited = new VOIPPlugin() ; @@ -38,18 +39,15 @@ void VOIPPlugin::setInterfaces(RsPlugInInterfaces &interfaces) ConfigPage *VOIPPlugin::qt_config_page() const { - if(config_page == NULL) - config_page = new AudioInputConfig() ; - - return config_page ; + return new AudioInputConfig() ; } RsPQIService *VOIPPlugin::rs_pqi_service() const { if(mVoip == NULL) { - mVoip = new p3VoipService(mPlugInHandler) ; // , 3600 * 24 * 30 * 6); // 6 Months - rsVoipSI = mVoip ; + mVoip = new p3VoRS(mPlugInHandler) ; // , 3600 * 24 * 30 * 6); // 6 Months + rsVoip = mVoip ; } return mVoip ; diff --git a/plugins/VOIP/VOIPPlugin.h b/plugins/VOIP/VOIPPlugin.h index 0f53daad5..8459c180d 100644 --- a/plugins/VOIP/VOIPPlugin.h +++ b/plugins/VOIP/VOIPPlugin.h @@ -1,8 +1,7 @@ #pragma once #include -#include -#include "p3Voip.h" +#include "services/p3vors.h" class VOIPPlugin: public RsPlugin { @@ -26,7 +25,7 @@ class VOIPPlugin: public RsPlugin virtual void setInterfaces(RsPlugInInterfaces& interfaces); private: - mutable p3VoipService *mVoip ; + mutable p3VoRS *mVoip ; mutable RsPluginHandler *mPlugInHandler; mutable RsPeers* mPeers; mutable ConfigPage *config_page ; diff --git a/plugins/VOIP/gui/AudioInputConfig.cpp b/plugins/VOIP/gui/AudioInputConfig.cpp index c5b648eb6..bf7cc0225 100644 --- a/plugins/VOIP/gui/AudioInputConfig.cpp +++ b/plugins/VOIP/gui/AudioInputConfig.cpp @@ -37,7 +37,7 @@ //#include "NetworkConfig.h" #include "audiodevicehelper.h" #include "AudioWizard.h" -#include "rsvoip.h" +#include #define iroundf(x) ( static_cast(x) ) @@ -83,9 +83,9 @@ void AudioInputConfig::load() } qcbSystem->setEnabled(qcbSystem->count() > 1);*/ - ui.qcbTransmit->addItem(tr("Continuous"), RsVoipServiceInterface::AudioTransmitContinous); - ui.qcbTransmit->addItem(tr("Voice Activity"), RsVoipServiceInterface::AudioTransmitVAD); - ui.qcbTransmit->addItem(tr("Push To Talk"), RsVoipServiceInterface::AudioTransmitPushToTalk); + ui.qcbTransmit->addItem(tr("Continuous"), RsVoip::AudioTransmitContinous); + ui.qcbTransmit->addItem(tr("Voice Activity"), RsVoip::AudioTransmitVAD); + ui.qcbTransmit->addItem(tr("Push To Talk"), RsVoip::AudioTransmitPushToTalk); abSpeech = new AudioBar(); abSpeech->qcBelow = Qt::red; @@ -125,26 +125,26 @@ void AudioInputConfig::loadSettings() { loadSlider(qsTransmitMax, iroundf(r.fVADmax * 32767.0f + 0.5f)); loadSlider(qsFrames, (r.iFramesPerPacket == 1) ? 1 : (r.iFramesPerPacket/2 + 1)); loadSlider(qsDoublePush, iroundf(static_cast(r.uiDoublePush) / 1000.f + 0.5f));*/ - ui.qcbTransmit->setCurrentIndex(rsVoipSI->getVoipATransmit()-1); - on_qcbTransmit_currentIndexChanged(rsVoipSI->getVoipATransmit()-1); - ui.qsTransmitHold->setValue(rsVoipSI->getVoipVoiceHold()); - on_qsTransmitHold_valueChanged(rsVoipSI->getVoipVoiceHold()); - ui.qsTransmitMin->setValue(rsVoipSI->getVoipfVADmin()); - ui.qsTransmitMax->setValue(rsVoipSI->getVoipfVADmax()); - ui.qcbEchoCancel->setChecked(rsVoipSI->getVoipEchoCancel()); + ui.qcbTransmit->setCurrentIndex(rsVoip->getVoipATransmit()-1); + on_qcbTransmit_currentIndexChanged(rsVoip->getVoipATransmit()-1); + ui.qsTransmitHold->setValue(rsVoip->getVoipVoiceHold()); + on_qsTransmitHold_valueChanged(rsVoip->getVoipVoiceHold()); + ui.qsTransmitMin->setValue(rsVoip->getVoipfVADmin()); + ui.qsTransmitMax->setValue(rsVoip->getVoipfVADmax()); + ui.qcbEchoCancel->setChecked(rsVoip->getVoipEchoCancel()); //ui.qsDoublePush->setValue(iroundf(static_cast(r.uiDoublePush) / 1000.f + 0.5f)); //loadCheckBox(qcbPushClick, r.bPushClick); //loadSlider(qsQuality, r.iQuality); - if (rsVoipSI->getVoipiNoiseSuppress() != 0) - ui.qsNoise->setValue(-rsVoipSI->getVoipiNoiseSuppress()); + if (rsVoip->getVoipiNoiseSuppress() != 0) + ui.qsNoise->setValue(-rsVoip->getVoipiNoiseSuppress()); else ui.qsNoise->setValue(14); - on_qsNoise_valueChanged(-rsVoipSI->getVoipiNoiseSuppress()); + on_qsNoise_valueChanged(-rsVoip->getVoipiNoiseSuppress()); - ui.qsAmp->setValue(20000 - rsVoipSI->getVoipiMinLoudness()); - on_qsAmp_valueChanged(20000 - rsVoipSI->getVoipiMinLoudness()); + ui.qsAmp->setValue(20000 - rsVoip->getVoipiMinLoudness()); + on_qsAmp_valueChanged(20000 - rsVoip->getVoipiMinLoudness()); //loadSlider(qsIdle, r.iIdleTime); /*int echo = 0; @@ -161,14 +161,14 @@ void AudioInputConfig::loadSettings() { bool AudioInputConfig::save(QString &/*errmsg*/) {//mainly useless beacause saving occurs in realtime //s.iQuality = qsQuality->value(); - rsVoipSI->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); - rsVoipSI->setVoipiMinLoudness(20000 - ui.qsAmp->value()); - rsVoipSI->setVoipVoiceHold(ui.qsTransmitHold->value()); - rsVoipSI->setVoipfVADmin(ui.qsTransmitMin->value()); - rsVoipSI->setVoipfVADmax(ui.qsTransmitMax->value()); + rsVoip->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); + rsVoip->setVoipiMinLoudness(20000 - ui.qsAmp->value()); + rsVoip->setVoipVoiceHold(ui.qsTransmitHold->value()); + rsVoip->setVoipfVADmin(ui.qsTransmitMin->value()); + rsVoip->setVoipfVADmax(ui.qsTransmitMax->value()); /*s.uiDoublePush = qsDoublePush->value() * 1000;*/ - rsVoipSI->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() + 1)); - rsVoipSI->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); + rsVoip->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() + 1)); + rsVoip->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); return true; } @@ -191,7 +191,7 @@ void AudioInputConfig::on_qsTransmitHold_valueChanged(int v) { float val = static_cast(v * FRAME_SIZE); val = val / SAMPLING_RATE; ui.qlTransmitHold->setText(tr("%1 s").arg(val, 0, 'f', 2)); - rsVoipSI->setVoipVoiceHold(v); + rsVoip->setVoipVoiceHold(v); } void AudioInputConfig::on_qsNoise_valueChanged(int v) { @@ -204,18 +204,18 @@ void AudioInputConfig::on_qsNoise_valueChanged(int v) { ui.qlNoise->setText(tr("-%1 dB").arg(v)); } ui.qlNoise->setPalette(pal); - rsVoipSI->setVoipiNoiseSuppress(- ui.qsNoise->value()); + rsVoip->setVoipiNoiseSuppress(- ui.qsNoise->value()); } void AudioInputConfig::on_qsAmp_valueChanged(int v) { v = 20000 - v; float d = 20000.0f/static_cast(v); ui.qlAmp->setText(QString::fromLatin1("%1").arg(d, 0, 'f', 2)); - rsVoipSI->setVoipiMinLoudness(20000 - ui.qsAmp->value()); + rsVoip->setVoipiMinLoudness(20000 - ui.qsAmp->value()); } void AudioInputConfig::on_qcbEchoCancel_clicked() { - rsVoipSI->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); + rsVoip->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); } @@ -232,7 +232,7 @@ void AudioInputConfig::on_qcbTransmit_currentIndexChanged(int v) { break; } if (loaded) - rsVoipSI->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() + 1)); + rsVoip->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() + 1)); } @@ -251,8 +251,8 @@ void AudioInputConfig::on_Tick_timeout() { abSpeech->iBelow = ui.qsTransmitMin->value(); abSpeech->iAbove = ui.qsTransmitMax->value(); if (loaded) { - rsVoipSI->setVoipfVADmin(ui.qsTransmitMin->value()); - rsVoipSI->setVoipfVADmax(ui.qsTransmitMax->value()); + rsVoip->setVoipfVADmin(ui.qsTransmitMin->value()); + rsVoip->setVoipfVADmax(ui.qsTransmitMax->value()); } abSpeech->iValue = iroundf(inputProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); diff --git a/plugins/VOIP/gui/AudioWizard.cpp b/plugins/VOIP/gui/AudioWizard.cpp index 623c63e34..38d12c89b 100644 --- a/plugins/VOIP/gui/AudioWizard.cpp +++ b/plugins/VOIP/gui/AudioWizard.cpp @@ -35,7 +35,7 @@ //#include "Log.h" //#include "MainWindow.h" #include "audiodevicehelper.h" -#include "rsvoip.h" +#include "interface/rsvoip.h" #define iroundf(x) ( static_cast(x) ) @@ -70,9 +70,9 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { verticalLayout_3->addWidget(abAmplify); - if (rsVoipSI->getVoipATransmit() == RsVoipServiceInterface::AudioTransmitPushToTalk) + if (rsVoip->getVoipATransmit() == RsVoip::AudioTransmitPushToTalk) qrPTT->setChecked(true); - else if (rsVoipSI->getVoipATransmit() == RsVoipServiceInterface::AudioTransmitVAD) + else if (rsVoip->getVoipATransmit() == RsVoip::AudioTransmitVAD) qrVAD->setChecked(true); else qrContinuous->setChecked(true); @@ -82,13 +82,13 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { abVAD->qcInside = Qt::yellow; abVAD->qcAbove = Qt::green; - qsTransmitMin->setValue(rsVoipSI->getVoipfVADmin()); - qsTransmitMax->setValue(rsVoipSI->getVoipfVADmax()); + qsTransmitMin->setValue(rsVoip->getVoipfVADmin()); + qsTransmitMax->setValue(rsVoip->getVoipfVADmax()); verticalLayout_6->addWidget(abVAD); // Volume - qsMaxAmp->setValue(rsVoipSI->getVoipiMinLoudness()); + qsMaxAmp->setValue(rsVoip->getVoipiMinLoudness()); setOption(QWizard::NoCancelButton, false); resize(700, 500); @@ -130,7 +130,7 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { void AudioWizard::on_qsMaxAmp_valueChanged(int v) { - rsVoipSI->setVoipiMinLoudness(qMin(v, 30000)); + rsVoip->setVoipiMinLoudness(qMin(v, 30000)); } void AudioWizard::on_Ticker_timeout() { @@ -158,8 +158,8 @@ void AudioWizard::on_Ticker_timeout() { abVAD->iBelow = qsTransmitMin->value(); abVAD->iAbove = qsTransmitMax->value(); - rsVoipSI->setVoipfVADmin(qsTransmitMin->value()); - rsVoipSI->setVoipfVADmax(qsTransmitMax->value()); + rsVoip->setVoipfVADmin(qsTransmitMin->value()); + rsVoip->setVoipfVADmax(qsTransmitMax->value()); abVAD->iValue = iroundf(inputProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); @@ -214,19 +214,19 @@ void AudioWizard::on_playEcho_timeout() { void AudioWizard::on_qsTransmitMax_valueChanged(int v) { if (! bInit) { - rsVoipSI->setVoipfVADmax(v); + rsVoip->setVoipfVADmax(v); } } void AudioWizard::on_qsTransmitMin_valueChanged(int v) { if (! bInit) { - rsVoipSI->setVoipfVADmin(v); + rsVoip->setVoipfVADmin(v); } } void AudioWizard::on_qrVAD_clicked(bool on) { if (on) { - rsVoipSI->setVoipATransmit(RsVoipServiceInterface::AudioTransmitVAD); + rsVoip->setVoipATransmit(RsVoip::AudioTransmitVAD); updateTriggerWidgets(true); bTransmitChanged = true; } @@ -234,7 +234,7 @@ void AudioWizard::on_qrVAD_clicked(bool on) { void AudioWizard::on_qrPTT_clicked(bool on) { if (on) { - rsVoipSI->setVoipATransmit(RsVoipServiceInterface::AudioTransmitPushToTalk); + rsVoip->setVoipATransmit(RsVoip::AudioTransmitPushToTalk); updateTriggerWidgets(false); bTransmitChanged = true; } @@ -242,7 +242,7 @@ void AudioWizard::on_qrPTT_clicked(bool on) { void AudioWizard::on_qrContinuous_clicked(bool on) { if (on) { - rsVoipSI->setVoipATransmit(RsVoipServiceInterface::AudioTransmitContinous); + rsVoip->setVoipATransmit(RsVoip::AudioTransmitContinous); updateTriggerWidgets(false); bTransmitChanged = true; } diff --git a/plugins/VOIP/gui/SpeexProcessor.cpp b/plugins/VOIP/gui/SpeexProcessor.cpp index c70743dba..7b80b6f5b 100644 --- a/plugins/VOIP/gui/SpeexProcessor.cpp +++ b/plugins/VOIP/gui/SpeexProcessor.cpp @@ -11,7 +11,7 @@ #include #include -#include "rsvoip.h" +#include "interface/rsvoip.h" //#include "gui/settings/rsharesettings.h" @@ -163,7 +163,7 @@ qint64 SpeexInputProcessor::writeData(const char *data, qint64 maxSize) { iArg = -60; speex_preprocess_ctl(preprocessor, SPEEX_PREPROCESS_SET_AGC_DECREMENT, &iArg); - iArg = rsVoipSI->getVoipiNoiseSuppress(); + iArg = rsVoip->getVoipiNoiseSuppress(); speex_preprocess_ctl(preprocessor, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg); if (echo_state) { @@ -175,18 +175,18 @@ qint64 SpeexInputProcessor::writeData(const char *data, qint64 maxSize) { bResetProcessor = false; } - float v = 30000.0f / static_cast(rsVoipSI->getVoipiMinLoudness()); + float v = 30000.0f / static_cast(rsVoip->getVoipiMinLoudness()); iArg = iroundf(floorf(20.0f * log10f(v))); speex_preprocess_ctl(preprocessor, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &iArg); speex_preprocess_ctl(preprocessor, SPEEX_PREPROCESS_GET_AGC_GAIN, &iArg); float gainValue = static_cast(iArg); - iArg = rsVoipSI->getVoipiNoiseSuppress() - iArg; + iArg = rsVoip->getVoipiNoiseSuppress() - iArg; speex_preprocess_ctl(preprocessor, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg); short * psSource = psMic; - if (echo_state && rsVoipSI->getVoipEchoCancel()) { + if (echo_state && rsVoip->getVoipEchoCancel()) { speex_echo_playback(echo_state, (short*)lastEchoFrame->data()); speex_echo_capture(echo_state,psMic,psClean); psSource = psClean; @@ -210,24 +210,24 @@ qint64 SpeexInputProcessor::writeData(const char *data, qint64 maxSize) { bool bIsSpeech = false; - if (dVoiceAcivityLevel > (static_cast(rsVoipSI->getVoipfVADmax()) / 32767)) + if (dVoiceAcivityLevel > (static_cast(rsVoip->getVoipfVADmax()) / 32767)) bIsSpeech = true; - else if (dVoiceAcivityLevel > (static_cast(rsVoipSI->getVoipfVADmin()) / 32767) && bPreviousVoice) + else if (dVoiceAcivityLevel > (static_cast(rsVoip->getVoipfVADmin()) / 32767) && bPreviousVoice) bIsSpeech = true; if (! bIsSpeech) { iHoldFrames++; - if (iHoldFrames < rsVoipSI->getVoipVoiceHold()) + if (iHoldFrames < rsVoip->getVoipVoiceHold()) bIsSpeech = true; } else { iHoldFrames = 0; } - if (rsVoipSI->getVoipATransmit() == RsVoipServiceInterface::AudioTransmitContinous) { + if (rsVoip->getVoipATransmit() == RsVoip::AudioTransmitContinous) { bIsSpeech = true; } - else if (rsVoipSI->getVoipATransmit() == RsVoipServiceInterface::AudioTransmitPushToTalk) + else if (rsVoip->getVoipATransmit() == RsVoip::AudioTransmitPushToTalk) bIsSpeech = false;//g.s.uiDoublePush && ((g.uiDoublePush < g.s.uiDoublePush) || (g.tDoublePush.elapsed() < g.s.uiDoublePush)); //bIsSpeech = bIsSpeech || (g.iPushToTalk > 0); @@ -269,7 +269,7 @@ qint64 SpeexInputProcessor::writeData(const char *data, qint64 maxSize) { int vbr_on=0; //just use fixed bitrate for now //encryption of VBR-encoded speech may not ensure complete privacy, as phrases can still be identified, at least in a controlled setting with a small dictionary of phrases, by analysing the pattern of variation of the bit rate. - if (rsVoipSI->getVoipATransmit() == RsVoipServiceInterface::AudioTransmitVAD) {//maybe we can do fixer bitrate when voice detection is active + if (rsVoip->getVoipATransmit() == RsVoip::AudioTransmitVAD) {//maybe we can do fixer bitrate when voice detection is active vbr_on = 1;//test it on for all modes } else {//maybe we can do vbr for ppt and continuous vbr_on = 1; @@ -368,7 +368,7 @@ bool SpeexInputProcessor::isSequential() const { } void SpeexInputProcessor::addEchoFrame(QByteArray* echo_frame) { - if (rsVoipSI->getVoipEchoCancel() && echo_frame) { + if (rsVoip->getVoipEchoCancel() && echo_frame) { QMutexLocker l(&qmSpeex); lastEchoFrame = echo_frame; if (!echo_state) {//init echo_state diff --git a/plugins/VOIP/gui/VoipStatistics.cpp b/plugins/VOIP/gui/VoipStatistics.cpp new file mode 100644 index 000000000..7d01f2572 --- /dev/null +++ b/plugins/VOIP/gui/VoipStatistics.cpp @@ -0,0 +1,393 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 20011, RetroShare Team + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include +#include + +#include +#include + +#include +#include +#include "VoipStatistics.h" +#include "time.h" + +#include "gui/settings/rsharesettings.h" + +#define PLOT_HEIGHT 100 +#define PLOT_WIDTH 500 + +#define MAX_DISPLAY_PERIOD 300 + +double convertDtToPixels(double refTs, double minTs, double ts) +{ + double dt = refTs - ts; + double maxdt = refTs - minTs; + double pix = PLOT_WIDTH - dt / maxdt * PLOT_WIDTH; + return pix; +} + + +double convertRttToPixels(double maxRTT, double rtt) +{ + double pix = rtt / maxRTT * PLOT_HEIGHT; + return PLOT_HEIGHT - pix; +} + +class VoipLagPlot +{ + public: + VoipLagPlot(const std::map > &info, + double refTS, double maxRTT, double minTS, double maxTS) + :mInfo(info), mRefTS(refTS), mMaxRTT(maxRTT), mMinTS(minTS), mMaxTS(maxTS) {} + + + QColor colorScale(float f) + { + if(f == 0) + return QColor::fromHsv(0,0,192) ; + else + return QColor::fromHsv((int)((1.0-f)*280),200,255) ; + } + + virtual void draw(QPainter *painter,int& ox,int& oy,const QString& title) + { + //static const int MaxTime = 61 ; + //static const int MaxDepth = 8 ; + static const int cellx = 7 ; + static const int celly = 12 ; + + //int save_ox = ox ; + painter->setPen(QColor::fromRgb(0,0,0)) ; + painter->drawText(2+ox,celly+oy,title) ; + oy+=2+2*celly ; + + //std::cerr << "VoipLagPlot::draw()"; + //std::cerr << std::endl; + + painter->drawRect(ox, oy, PLOT_WIDTH, PLOT_HEIGHT); + + if(mInfo.empty()) + return ; + + double maxdt = mRefTS - mMinTS; + if (maxdt > MAX_DISPLAY_PERIOD) + { + mMinTS = mRefTS - MAX_DISPLAY_PERIOD; + } + + /* draw a different line for each peer */ + std::map >::const_iterator mit; + int i = 0; + int nLines = mInfo.size(); + for(mit = mInfo.begin(); mit != mInfo.end(); mit++, i++) + { + //std::cerr << "VoipLagPlot::draw() Line of " << mit->second.size(); + //std::cerr << " Elements for: " << mit->first; + //std::cerr << std::endl; + + QPainterPath path; + std::list::const_iterator it = mit->second.begin(); + if (it != mit->second.end()) + { + double x = convertDtToPixels(mRefTS, mMinTS, it->mTS); + double y = convertRttToPixels(mMaxRTT, it->mRTT); + path.moveTo(ox + x, oy + y); + it++; + } + + for(; it != mit->second.end(); it++) + { + /* skip old elements */ + if (it->mTS < mMinTS) + { + continue; + } + + double x = convertDtToPixels(mRefTS, mMinTS, it->mTS); + double y = convertRttToPixels(mMaxRTT, it->mRTT); + + path.lineTo(ox + x, oy + y); + + //std::cerr << "VoipLagPlot::draw() Point: (" << x << "," << y << ")"; + //std::cerr << std::endl; + + //painter->drawLine(ox,oy, ox + x, oy + y); + } + + /* draw line */ + painter->setPen(QColor::fromRgb(((255.0 * i) / (nLines-1)),0, 255 - (255.0 * i) / (nLines-1))) ; + painter->drawPath(path); + + /* draw name */ + } + + painter->setPen(QColor::fromRgb(0,0,0)) ; + painter->drawText(ox+PLOT_WIDTH + cellx ,oy + celly / 2, QString::number(mMaxRTT)+" "+QObject::tr("secs")) ; + oy += PLOT_HEIGHT / 2; + painter->drawText(ox+PLOT_WIDTH + cellx ,oy + celly / 2, QString::number(mMaxRTT / 2.0)+" "+QObject::tr("secs")) ; + oy += PLOT_HEIGHT / 2; + painter->drawText(ox+PLOT_WIDTH + cellx ,oy + celly / 2, QString::number(0.0)+" "+QObject::tr("secs")) ; + oy += celly; + painter->drawText(ox ,oy, QObject::tr("Old")); + painter->drawText(ox + PLOT_WIDTH - cellx ,oy, QObject::tr("Now")); + oy += celly; + + // Now do names. + i = 0; + for(mit = mInfo.begin(); mit != mInfo.end(); mit++, i++) + { + painter->fillRect(ox,oy,cellx,celly, + QColor::fromRgb(((255.0 * i) / (nLines-1)),0, 255 - (255.0 * i) / (nLines-1))) ; + + painter->setPen(QColor::fromRgb(0,0,0)) ; + painter->drawRect(ox,oy,cellx,celly) ; + painter->drawText(ox + cellx + 4,oy + celly / 2,VoipStatistics::getPeerName(mit->first)); + + oy += 2 * celly; + } + } + + private: + const std::map > &mInfo; + double mRefTS; + double mMaxRTT; + double mMinTS; + double mMaxTS; + +}; + +VoipStatistics::VoipStatistics(QWidget *parent) + : RsAutoUpdatePage(2000,parent) +{ + setupUi(this) ; + + m_bProcessSettings = false; + + _tunnel_statistics_F->setWidget( _tst_CW = new VoipStatisticsWidget() ) ; + _tunnel_statistics_F->setWidgetResizable(true); + _tunnel_statistics_F->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + _tunnel_statistics_F->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + _tunnel_statistics_F->viewport()->setBackgroundRole(QPalette::NoRole); + _tunnel_statistics_F->setFrameStyle(QFrame::NoFrame); + _tunnel_statistics_F->setFocusPolicy(Qt::NoFocus); + + // load settings + processSettings(true); +} + +VoipStatistics::~VoipStatistics() +{ + + // save settings + processSettings(false); +} + +void VoipStatistics::processSettings(bool bLoad) +{ + m_bProcessSettings = true; + + Settings->beginGroup(QString("VoipStatistics")); + + if (bLoad) { + // load settings + + // state of splitter + //splitter->restoreState(Settings->value("Splitter").toByteArray()); + } else { + // save settings + + // state of splitter + //Settings->setValue("Splitter", splitter->saveState()); + + } + + Settings->endGroup(); + + m_bProcessSettings = false; + +} + + +void VoipStatistics::updateDisplay() +{ + std::map > info; + + if (!rsVoip) + { + return; + } + + std::list idList; + std::list::iterator it; + + rsPeers->getOnlineList(idList); + + time_t now = time(NULL); + time_t minTS = now; + time_t maxTS = 0; + double maxRTT = 0; + + for(it = idList.begin(); it != idList.end(); it++) + { + std::list results; + std::list::iterator rit; + +#define MAX_RESULTS 60 + rsVoip->getPongResults(*it, MAX_RESULTS, results); + + for(rit = results.begin(); rit != results.end(); rit++) + { + /* only want maxRTT to include plotted bit */ + double dt = now - rit->mTS; + if (dt < MAX_DISPLAY_PERIOD) + { + if (maxRTT < rit->mRTT) + { + maxRTT = rit->mRTT; + } + } + if (minTS > rit->mTS) + { + minTS = rit->mTS; + } + if (maxTS < rit->mTS) + { + maxTS = rit->mTS; + } + } + + info[*it] = results; + } + + + _tst_CW->updateVoipStatistics(info, maxRTT, minTS, maxTS); + _tst_CW->update(); +} + +QString VoipStatistics::getPeerName(const std::string& peer_id) +{ + static std::map names ; + + std::map::const_iterator it = names.find(peer_id) ; + + if( it != names.end()) + return it->second ; + else + { + RsPeerDetails detail ; + if(!rsPeers->getPeerDetails(peer_id,detail)) + return "unknown peer"; + + return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ; + } +} + +VoipStatisticsWidget::VoipStatisticsWidget(QWidget *parent) + : QWidget(parent) +{ + maxWidth = 200 ; + maxHeight = 0 ; +} + +void VoipStatisticsWidget::updateVoipStatistics(const std::map >& info, + double maxRTT, double minTS, double maxTS) +{ + //static const int cellx = 6 ; + //static const int celly = 10+4 ; + + QPixmap tmppixmap(maxWidth, maxHeight); + tmppixmap.fill(this, 0, 0); + setFixedHeight(maxHeight); + + QPainter painter(&tmppixmap); + painter.initFrom(this); + + maxHeight = 500 ; + + //std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl; + // draw... + int ox=5,oy=5 ; + + double refTS = time(NULL); + + //painter.setPen(QColor::fromRgb(70,70,70)) ; + //painter.drawLine(0,oy,maxWidth,oy) ; + //oy += celly ; + //painter.setPen(QColor::fromRgb(0,0,0)) ; + + // round up RTT to nearest + double roundedRTT = maxRTT; + if (maxRTT < 0.15) + { + roundedRTT = 0.2; + } + else if (maxRTT < 0.4) + { + roundedRTT = 0.5; + } + else if (maxRTT < 0.8) + { + roundedRTT = 1.0; + } + else if (maxRTT < 1.8) + { + roundedRTT = 2.0; + } + else if (maxRTT < 4.5) + { + roundedRTT = 5.0; + } + + VoipLagPlot(info, refTS, roundedRTT, minTS, maxTS).draw(&painter,ox,oy,QObject::tr("Round Trip Time:")) ; + + // update the pixmap + pixmap = tmppixmap; + maxHeight = oy; // + PLOT_HEIGHT * 2; +} + +QString VoipStatisticsWidget::speedString(float f) +{ + if(f < 1.0f) + return QString("0 B/s") ; + if(f < 1024.0f) + return QString::number((int)f)+" B/s" ; + + return QString::number(f/1024.0,'f',2) + " KB/s"; +} + +void VoipStatisticsWidget::paintEvent(QPaintEvent */*event*/) +{ + QStylePainter(this).drawPixmap(0, 0, pixmap); +} + +void VoipStatisticsWidget::resizeEvent(QResizeEvent *event) +{ + QRect TaskGraphRect = geometry(); + maxWidth = TaskGraphRect.width(); + maxHeight = TaskGraphRect.height() ; + + QWidget::resizeEvent(event); + update(); +} + + diff --git a/plugins/VOIP/gui/VoipStatistics.h b/plugins/VOIP/gui/VoipStatistics.h new file mode 100644 index 000000000..7f4dcfa38 --- /dev/null +++ b/plugins/VOIP/gui/VoipStatistics.h @@ -0,0 +1,68 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 20011, RetroShare Team + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#pragma once + +#include +#include +#include "ui_VoipStatistics.h" +#include + +class VoipStatisticsWidget ; + +class VoipStatistics: public RsAutoUpdatePage, public Ui::VoipStatistics +{ + public: + VoipStatistics(QWidget *parent = NULL) ; + ~VoipStatistics(); + + // Cache for peer names. + static QString getPeerName(const std::string& peer_id) ; + + private: + + void processSettings(bool bLoad); + bool m_bProcessSettings; + + virtual void updateDisplay() ; + + VoipStatisticsWidget *_tst_CW ; +} ; + +class VoipStatisticsWidget: public QWidget +{ + public: + VoipStatisticsWidget(QWidget *parent = NULL) ; + + virtual void paintEvent(QPaintEvent *event) ; + virtual void resizeEvent(QResizeEvent *event); + + + void updateVoipStatistics(const std::map >& info, + double maxRTT, double minTS, double maxTS); + + private: + static QString speedString(float f) ; + + QPixmap pixmap ; + int maxWidth,maxHeight ; +}; + diff --git a/plugins/VOIP/gui/VoipStatistics.ui b/plugins/VOIP/gui/VoipStatistics.ui new file mode 100644 index 000000000..ae1c3c650 --- /dev/null +++ b/plugins/VOIP/gui/VoipStatistics.ui @@ -0,0 +1,55 @@ + + + VoipStatistics + + + + 0 + 0 + 611 + 408 + + + + VoipTest Statistics + + + + :/images/rstray3.png:/images/rstray3.png + + + + + + Qt::Vertical + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 587 + 384 + + + + + + + + + + + + + diff --git a/plugins/VOIP/rsvoip.h b/plugins/VOIP/interface/rsvoip.h similarity index 71% rename from plugins/VOIP/rsvoip.h rename to plugins/VOIP/interface/rsvoip.h index 08c3a345e..74383b08b 100644 --- a/plugins/VOIP/rsvoip.h +++ b/plugins/VOIP/interface/rsvoip.h @@ -5,13 +5,27 @@ #include -class RsVoipServiceInterface ; -extern RsVoipServiceInterface *rsVoipSI; - +class RsVoip ; +extern RsVoip *rsVoip; + static const uint32_t CONFIG_TYPE_VOIP_PLUGIN = 0xe001 ; static const uint32_t RS_SERVICE_TYPE_VOIP_PLUGIN = 0xe001 ; -class RsVoipServiceInterface +class RsVoipPongResult +{ + public: + RsVoipPongResult() + :mTS(0), mRTT(0), mOffset(0) { return; } + + RsVoipPongResult(double ts, double rtt, double offset) + :mTS(ts), mRTT(rtt), mOffset(offset) { return; } + + double mTS; + double mRTT; + double mOffset; +}; + +class RsVoip { public: virtual int sendVoipData(const void *data,uint32_t size) = 0; @@ -34,4 +48,8 @@ class RsVoipServiceInterface virtual void setVoipiMinLoudness(int) = 0 ; virtual bool getVoipEchoCancel() const = 0 ; virtual void setVoipEchoCancel(bool) = 0 ; + + virtual uint32_t getPongResults(std::string id, int n, std::list &results) = 0; }; + + diff --git a/plugins/VOIP/service/p3vors.cc b/plugins/VOIP/services/p3vors.cc similarity index 87% rename from plugins/VOIP/service/p3vors.cc rename to plugins/VOIP/services/p3vors.cc index 1bec880f8..7a139a888 100644 --- a/plugins/VOIP/service/p3vors.cc +++ b/plugins/VOIP/services/p3vors.cc @@ -29,9 +29,12 @@ #include "pqi/pqinotify.h" #include "pqi/pqistore.h" #include "pqi/p3linkmgr.h" +#include +#include + #include "services/p3vors.h" -#include "serialiser/rsvoipitems.h" +#include "services/rsvoipitems.h" #include @@ -130,7 +133,6 @@ static uint64_t convertTsTo64bits(double ts) return bits; } - static double convert64bitsToTs(uint64_t bits) { uint32_t usecs = (uint32_t) (bits & 0xffffffff); @@ -140,11 +142,8 @@ static double convert64bitsToTs(uint64_t bits) return ts; } - - - -p3VoRS::p3VoRS(p3LinkMgr *lm) - :p3Service(RS_SERVICE_TYPE_VOIP), /* p3Config(CONFIG_TYPE_VOIP), */ mVorsMtx("p3VoRS"), mLinkMgr(lm) +p3VoRS::p3VoRS(RsPluginHandler *handler) + : RsPQIService(RS_SERVICE_TYPE_VOIP_PLUGIN,CONFIG_TYPE_VOIP_PLUGIN,0,handler), mVorsMtx("p3VoRS"), mLinkMgr(handler->getLinkMgr()) { addSerialType(new RsVoipSerialiser()); @@ -153,7 +152,6 @@ p3VoRS::p3VoRS(p3LinkMgr *lm) } - int p3VoRS::tick() { processIncoming(); @@ -167,8 +165,6 @@ int p3VoRS::status() return 1; } - - int p3VoRS::sendPackets() { time_t now = time(NULL); @@ -188,7 +184,12 @@ int p3VoRS::sendPackets() return true ; } +int p3VoRS::sendVoipData(const void *data,uint32_t size) +{ + std::cerr << "Sending " << size << " bytes of voip data." << std::endl; + return size ; +} void p3VoRS::sendPingMeasurements() { @@ -476,6 +477,61 @@ bool VorsPeerInfo::initialisePeerInfo(std::string id) return true; } +void p3VoRS::setVoipATransmit(int t) +{ + _atransmit = t ; + IndicateConfigChanged() ; +} +void p3VoRS::setVoipVoiceHold(int vh) +{ + _voice_hold = vh ; + IndicateConfigChanged() ; +} +void p3VoRS::setVoipfVADmin(int vad) +{ + _vadmin = vad ; + IndicateConfigChanged() ; +} +void p3VoRS::setVoipfVADmax(int vad) +{ + _vadmax = vad ; + IndicateConfigChanged() ; +} +void p3VoRS::setVoipiNoiseSuppress(int n) +{ + _noise_suppress = n ; + IndicateConfigChanged() ; +} +void p3VoRS::setVoipiMinLoudness(int ml) +{ + _min_loudness = ml ; + IndicateConfigChanged() ; +} +void p3VoRS::setVoipEchoCancel(bool b) +{ + _echo_cancel = b ; + IndicateConfigChanged() ; +} + +bool p3VoRS::saveList(bool& cleanup, std::list&) +{ + cleanup = true ; + return true ; +} +bool p3VoRS::loadList(std::list& load) +{ + return true ; +} + +RsSerialiser *p3VoRS::setupSerialiser() +{ + RsSerialiser *rsSerialiser = new RsSerialiser(); +// rsSerialiser->addSerialType(new RsVoipSerialiser()); + rsSerialiser->addSerialType(new RsGeneralConfigSerialiser()); + + return rsSerialiser ; +} + diff --git a/plugins/VOIP/service/p3vors.h b/plugins/VOIP/services/p3vors.h similarity index 66% rename from plugins/VOIP/service/p3vors.h rename to plugins/VOIP/services/p3vors.h index 1db9e80d1..46e717164 100644 --- a/plugins/VOIP/service/p3vors.h +++ b/plugins/VOIP/services/p3vors.h @@ -30,9 +30,10 @@ #include #include -#include "serialiser/rsvoipitems.h" +#include "services/rsvoipitems.h" #include "services/p3service.h" -#include "retroshare/rsvoip.h" +#include "plugins/rspqiservice.h" +#include class p3LinkMgr; @@ -60,16 +61,17 @@ class VorsPeerInfo * This is only used to test Latency for the moment. */ -class p3VoRS: public RsVoip, public p3Service +class p3VoRS: public RsPQIService, public RsVoip // Maybe we inherit from these later - but not needed for now. //, public p3Config, public pqiMonitor { public: - p3VoRS(p3LinkMgr *cm); + p3VoRS(RsPluginHandler *cm); /***** overloaded from rsVoip *****/ -virtual uint32_t getPongResults(std::string id, int n, std::list &results); + virtual uint32_t getPongResults(std::string id, int n, std::list &results); + virtual int sendVoipData(const void *data,uint32_t size) ; /***** overloaded from p3Service *****/ /*! @@ -82,7 +84,6 @@ virtual uint32_t getPongResults(std::string id, int n, std::list &chats); - /*************** pqiMonitor callback ***********************/ //virtual void statusChange(const std::list &plist); + virtual int getVoipATransmit() const { return _atransmit ; } + virtual void setVoipATransmit(int) ; + virtual int getVoipVoiceHold() const { return _voice_hold ; } + virtual void setVoipVoiceHold(int) ; + virtual int getVoipfVADmin() const { return _vadmin ; } + virtual void setVoipfVADmin(int) ; + virtual int getVoipfVADmax() const { return _vadmax ; } + virtual void setVoipfVADmax(int) ; + virtual int getVoipiNoiseSuppress() const { return _noise_suppress ; } + virtual void setVoipiNoiseSuppress(int) ; + virtual int getVoipiMinLoudness() const { return _min_loudness ; } + virtual void setVoipiMinLoudness(int) ; + virtual bool getVoipEchoCancel() const { return _echo_cancel ; } + virtual void setVoipEchoCancel(bool) ; /************* from p3Config *******************/ - //virtual RsSerialiser *setupSerialiser() ; - //virtual bool saveList(bool& cleanup, std::list&) ; - //virtual void saveDone(); - //virtual bool loadList(std::list& load) ; + virtual RsSerialiser *setupSerialiser() ; + + /*! + * chat msg items and custom status are saved + */ + virtual bool saveList(bool& cleanup, std::list&) ; + virtual bool loadList(std::list& load) ; + private: RsMutex mVorsMtx; @@ -120,6 +133,13 @@ virtual uint32_t getPongResults(std::string id, int n, std::list