time provider

git-svn-id: svn://elaine/murooma/trunk@268 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
(no author) 2014-09-16 05:20:16 +00:00
parent 19e77f0f20
commit 2fedce489c
6 changed files with 93 additions and 12 deletions

View file

@ -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

View file

@ -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<TimeMsg> reply = controlConnection->sendReq<TimeMsg>(&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<long> timeBuffer(100);
while (active_)
{
usleep(1000000);//1000000);
usleep(1000000);
try
{
RequestMsg requestMsg("time");
shared_ptr<TimeMsg> reply = controlConnection->sendReq<TimeMsg>(&requestMsg, 2000);
shared_ptr<TimeMsg> reply = controlConnection->sendReq<TimeMsg>(&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)

View file

@ -8,7 +8,7 @@ template <class T>
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<T> buffer;
@ -71,3 +77,5 @@ private:
#endif

View file

@ -3,6 +3,7 @@
#include <string.h>
#include <unistd.h>
#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())

29
client/timeProvider.cpp Normal file
View file

@ -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;
}

34
client/timeProvider.h Normal file
View file

@ -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<long> diffBuffer;
long diffToServer;
};
#endif