mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-20 20:46:16 +02:00
time provider
git-svn-id: svn://elaine/murooma/trunk@268 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
parent
19e77f0f20
commit
2fedce489c
6 changed files with 93 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
29
client/timeProvider.cpp
Normal 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
34
client/timeProvider.h
Normal 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
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue