From 2fedce489c7b23402ae3867d36383060e146fa46 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@d8a302eb-03bc-478d-80e4-98257eca68ef> Date: Tue, 16 Sep 2014 05:20:16 +0000 Subject: [PATCH] time provider git-svn-id: svn://elaine/murooma/trunk@268 d8a302eb-03bc-478d-80e4-98257eca68ef --- client/Makefile | 2 +- client/controller.cpp | 23 ++++++++++++++++------- client/doubleBuffer.h | 10 +++++++++- client/stream.cpp | 7 ++++--- client/timeProvider.cpp | 29 +++++++++++++++++++++++++++++ client/timeProvider.h | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 client/timeProvider.cpp create mode 100644 client/timeProvider.h diff --git a/client/Makefile b/client/Makefile index f0deb6f6..3cb625e1 100644 --- a/client/Makefile +++ b/client/Makefile @@ -3,7 +3,7 @@ CC = /usr/bin/g++ CFLAGS = -std=gnu++0x -Wall -Wno-unused-function -g -D_REENTRANT -DVERSION=\"$(VERSION)\" -I.. LDFLAGS = -lrt -lpthread -lboost_system -lboost_program_options -lasound -logg -lvorbis -lvorbisenc -OBJ = snapClient.o stream.o player.o ../common/socketConnection.o streamClient.o oggDecoder.o pcmDecoder.o controller.o ../common/pcmChunk.o ../common/log.o ../common/sampleFormat.o +OBJ = snapClient.o stream.o player.o ../common/socketConnection.o timeProvider.o streamClient.o oggDecoder.o pcmDecoder.o controller.o ../common/pcmChunk.o ../common/log.o ../common/sampleFormat.o BIN = snapclient all: client diff --git a/client/controller.cpp b/client/controller.cpp index 0f839c83..f03d599f 100644 --- a/client/controller.cpp +++ b/client/controller.cpp @@ -6,6 +6,7 @@ #include "oggDecoder.h" #include "pcmDecoder.h" #include "player.h" +#include "timeProvider.h" #include "common/serverSettings.h" #include "common/timeMsg.h" #include "common/requestMsg.h" @@ -104,6 +105,17 @@ void Controller::worker() decoder->setHeader(headerChunk.get()); } + RequestMsg timeReq("time"); + for (size_t n=0; n<10; ++n) + { + shared_ptr reply = controlConnection->sendReq(&timeReq, 2000); + if (reply) + { + double latency = (reply->received.sec - reply->sent.sec) + (reply->received.usec - reply->sent.usec) / 1000000.; + TimeProvider::getInstance().setDiffToServer((reply->latency - latency) * 1000 / 2); + usleep(1000); + } + } streamClient->start(); stream = new Stream(*sampleFormat); @@ -112,21 +124,18 @@ void Controller::worker() Player player(stream); player.start(); - DoubleBuffer timeBuffer(100); while (active_) { - usleep(1000000);//1000000); + usleep(1000000); try { - RequestMsg requestMsg("time"); - shared_ptr reply = controlConnection->sendReq(&requestMsg, 2000); + shared_ptr reply = controlConnection->sendReq(&timeReq, 2000); if (reply) { -//cout << "Reply: " << reply->message.type << ", size: " << reply->message.size << ", sent: " << reply->message.sent.sec << "," << reply->message.sent.usec << ", recv: " << reply->message.received.sec << "," << reply->message.received.usec << "\n"; double latency = (reply->received.sec - reply->sent.sec) + (reply->received.usec - reply->sent.usec) / 1000000.; // cout << "C2S: " << timeMsg.latency << ", S2C: " << latency << ", diff: " << (timeMsg.latency - latency) / 2 << endl; - timeBuffer.add((reply->latency - latency) * 10000 / 2); - cout << timeBuffer.median() << "\n"; + TimeProvider::getInstance().setDiffToServer((reply->latency - latency) * 1000 / 2); + cout << TimeProvider::getInstance().getDiffToServer() << "\n"; } } catch (const std::exception& e) diff --git a/client/doubleBuffer.h b/client/doubleBuffer.h index 434bcd71..1d018fb8 100644 --- a/client/doubleBuffer.h +++ b/client/doubleBuffer.h @@ -8,7 +8,7 @@ template class DoubleBuffer { public: - DoubleBuffer(size_t size) : bufferSize(size) + DoubleBuffer(size_t size = 10) : bufferSize(size) { } @@ -62,6 +62,12 @@ public: return buffer.size(); } + void setSize(size_t size) + { + bufferSize = size; + } + + private: size_t bufferSize; std::deque buffer; @@ -71,3 +77,5 @@ private: #endif + + diff --git a/client/stream.cpp b/client/stream.cpp index 91f08fc2..ceb1a3c2 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -3,6 +3,7 @@ #include #include #include "common/log.h" +#include "timeProvider.h" using namespace std; @@ -175,7 +176,7 @@ int msBuffer = framesPerBuffer / format_.msRate(); if (sleep < -msBuffer/2) { cout << "Sleep " << sleep; - sleep = PcmChunk::getAge(getSilentPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime; + sleep = PcmChunk::getAge(getSilentPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime + TimeProvider::getInstance().getDiffToServerMs(); std::cerr << " after: " << sleep << ", chunks: " << chunks.size() << "\n"; // std::clog << kLogNotice << "sleep: " << sleep << std::endl; // if (sleep > -msBuffer/2) @@ -197,7 +198,7 @@ cout << "\nms: " << Chunk::getAge(ms) << "\t chunk: " << chunk->getAge() << "\n" while (sleep > chunk->getDuration()) { chunk = chunks.pop(); - sleep = chunk->getAge() - bufferMs + outputBufferDacTime; + sleep = chunk->getAge() - bufferMs + outputBufferDacTime + TimeProvider::getInstance().getDiffToServerMs(); // cout << "chunk->getAge() > chunk->getDuration(): " << chunk->getAge() - bufferMs + outputBufferDacTime << " > " << chunk->getDuration() << ", chunks: " << chunks.size() << ", out: " << outputBufferDacTime << ", needed: " << msBuffer << ", sleep: " << sleep << "\n"; usleep(1000); } @@ -218,7 +219,7 @@ cout << "\nms: " << Chunk::getAge(ms) << "\t chunk: " << chunk->getAge() << "\n" - long age = PcmChunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer, correction)) - bufferMs + outputBufferDacTime; + long age = PcmChunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer, correction)) - bufferMs + outputBufferDacTime + TimeProvider::getInstance().getDiffToServerMs(); // if (pCardBuffer->full()) diff --git a/client/timeProvider.cpp b/client/timeProvider.cpp new file mode 100644 index 00000000..d894cf15 --- /dev/null +++ b/client/timeProvider.cpp @@ -0,0 +1,29 @@ +#include "timeProvider.h" + + +TimeProvider::TimeProvider() : diffToServer(0) +{ + diffBuffer.setSize(60); +} + + +void TimeProvider::setDiffToServer(double ms) +{ + diffBuffer.add(ms * 1000); + diffToServer = diffBuffer.median(); +} + + +long TimeProvider::getDiffToServer() +{ + return diffToServer; +} + + +long TimeProvider::getDiffToServerMs() +{ + return diffToServer / 1000; +} + + + diff --git a/client/timeProvider.h b/client/timeProvider.h new file mode 100644 index 00000000..9290ca4c --- /dev/null +++ b/client/timeProvider.h @@ -0,0 +1,34 @@ +#ifndef TIME_PROVIDER_H +#define TIME_PROVIDER_H + +#include "doubleBuffer.h" + +class TimeProvider +{ + public: + static TimeProvider& getInstance() + { + static TimeProvider instance; + return instance; + } + + void setDiffToServer(double ms); + long getDiffToServer(); + long getDiffToServerMs(); + + private: + TimeProvider(); // Constructor? (the {} brackets) are needed here. + // Dont forget to declare these two. You want to make sure they + // are unaccessable otherwise you may accidently get copies of + // your singleton appearing. + TimeProvider(TimeProvider const&); // Don't Implement + void operator=(TimeProvider const&); // Don't implement + + DoubleBuffer diffBuffer; + long diffToServer; +}; + + +#endif + +