mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-29 08:56:18 +02:00
time stuff
git-svn-id: svn://elaine/murooma/trunk@301 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
parent
1759aeb160
commit
a7118fd0a4
5 changed files with 53 additions and 45 deletions
|
@ -1,7 +1,6 @@
|
|||
#include "stream.h"
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "common/log.h"
|
||||
#include "timeProvider.h"
|
||||
|
||||
|
@ -14,7 +13,7 @@ Stream::Stream(const SampleFormat& sampleFormat) : format(format_), format_(samp
|
|||
buffer.setSize(500);
|
||||
shortBuffer.setSize(100);
|
||||
miniBuffer.setSize(20);
|
||||
cardBuffer.setSize(50);
|
||||
// cardBuffer.setSize(50);
|
||||
bufferMs = msec(500);
|
||||
}
|
||||
|
||||
|
@ -178,10 +177,10 @@ bool Stream::getPlayerChunk(void* outputBuffer, const chronos::usec& outputBuffe
|
|||
chronos::usec correction = chronos::usec(0);
|
||||
if (sleep.count() != 0)
|
||||
{
|
||||
// cout << "Sleep " << sleep.count() << "\n";
|
||||
resetBuffers();
|
||||
if (sleep < -bufferDuration/2)
|
||||
{
|
||||
// We're early: not enough chunks. play silence. Reference chunk is the oldest (front) one
|
||||
sleep = chrono::duration_cast<usec>(TimeProvider::serverNow() - getSilentPlayerChunk(outputBuffer, framesPerBuffer) - bufferMs + outputBufferDacTime);
|
||||
//cout << "-sleep: " << sleep.count() << " " << -bufferDuration.count() / 2000 << "\n";
|
||||
if (sleep < -bufferDuration/2)
|
||||
|
@ -189,17 +188,18 @@ bool Stream::getPlayerChunk(void* outputBuffer, const chronos::usec& outputBuffe
|
|||
}
|
||||
else if (sleep > bufferDuration/2)
|
||||
{
|
||||
// We're late: discard oldest chunks
|
||||
while (sleep > chunk->duration<chronos::usec>())
|
||||
{
|
||||
cout << "sleep > chunk->getDuration(): " << sleep.count() << " > " << chunk->duration<chronos::msec>().count() << ", chunks: " << chunks.size() << ", out: " << outputBufferDacTime.count() << ", needed: " << bufferDuration.count() << "\n";
|
||||
// cout << "sleep > chunk->getDuration(): " << sleep.count() << " > " << chunk->duration<chronos::msec>().count() << ", chunks: " << chunks.size() << ", out: " << outputBufferDacTime.count() << ", needed: " << bufferDuration.count() << "\n";
|
||||
if (!chunks.try_pop(chunk, outputBufferDacTime))
|
||||
return false;
|
||||
|
||||
sleep = std::chrono::duration_cast<usec>(TimeProvider::serverNow() - chunk->start() - bufferMs + outputBufferDacTime);
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// out of sync, can be corrected by playing faster/slower
|
||||
if (sleep < -chronos::usec(100))
|
||||
{
|
||||
sleep += chronos::usec(100);
|
||||
|
@ -245,14 +245,14 @@ bool Stream::getPlayerChunk(void* outputBuffer, const chronos::usec& outputBuffe
|
|||
|
||||
updateBuffers(age.count());
|
||||
|
||||
// std::cerr << "Chunk: " << age << "\t" << outputBufferDacTime*1000 << "\n";
|
||||
// print sync stats
|
||||
time_t now = time(NULL);
|
||||
if (now != lastUpdate)
|
||||
{
|
||||
lastUpdate = now;
|
||||
median = buffer.median();
|
||||
shortMedian = shortBuffer.median();
|
||||
std::cerr << "Chunk: " << age.count()/100 << "\t" << miniBuffer.median()/100 << "\t" << shortMedian/100 << "\t" << median/100 << "\t" << buffer.size() << "\t" << /*cardBuffer << "\t" <<*/ outputBufferDacTime.count() << "\n";
|
||||
std::cerr << "Chunk: " << age.count()/100 << "\t" << miniBuffer.median()/100 << "\t" << shortMedian/100 << "\t" << median/100 << "\t" << buffer.size() << "\t" << outputBufferDacTime.count() << "\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef STREAM_H
|
||||
#define STREAM_H
|
||||
|
||||
//#include <mutex>
|
||||
//#include <condition_variable>
|
||||
//#include <vector>
|
||||
//#include <chrono>
|
||||
//#include "common/timeUtils.h"
|
||||
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include "doubleBuffer.h"
|
||||
#include "message/message.h"
|
||||
#include "message/pcmChunk.h"
|
||||
#include "message/sampleFormat.h"
|
||||
#include "common/timeUtils.h"
|
||||
#include "common/queue.h"
|
||||
|
||||
|
||||
|
@ -40,10 +40,10 @@ private:
|
|||
chronos::usec sleep;
|
||||
|
||||
Queue<std::shared_ptr<PcmChunk>> chunks;
|
||||
DoubleBuffer<long> cardBuffer;
|
||||
DoubleBuffer<long> miniBuffer;
|
||||
DoubleBuffer<long> buffer;
|
||||
DoubleBuffer<long> shortBuffer;
|
||||
// DoubleBuffer<chronos::usec::rep> cardBuffer;
|
||||
DoubleBuffer<chronos::usec::rep> miniBuffer;
|
||||
DoubleBuffer<chronos::usec::rep> buffer;
|
||||
DoubleBuffer<chronos::usec::rep> shortBuffer;
|
||||
std::shared_ptr<PcmChunk> chunk;
|
||||
|
||||
int median;
|
||||
|
|
|
@ -2,22 +2,45 @@
|
|||
#define TIME_DEFS_H
|
||||
|
||||
#include <chrono>
|
||||
#include <sys/time.h>
|
||||
|
||||
namespace chronos
|
||||
{
|
||||
template <class Rep, class Period>
|
||||
std::chrono::duration<Rep, Period> abs(std::chrono::duration<Rep, Period> d)
|
||||
{
|
||||
Rep x = d.count();
|
||||
return std::chrono::duration<Rep, Period>(x >= 0 ? x : -x);
|
||||
}
|
||||
|
||||
typedef std::chrono::high_resolution_clock hrc;
|
||||
typedef std::chrono::time_point<hrc> time_point_hrc;
|
||||
typedef std::chrono::seconds sec;
|
||||
typedef std::chrono::milliseconds msec;
|
||||
typedef std::chrono::microseconds usec;
|
||||
typedef std::chrono::nanoseconds nsec;
|
||||
|
||||
static void addUs(timeval& tv, int us)
|
||||
{
|
||||
if (us < 0)
|
||||
{
|
||||
timeval t;
|
||||
t.tv_sec = -us / 1000000;
|
||||
t.tv_usec = (-us % 1000000);
|
||||
timersub(&tv, &t, &tv);
|
||||
return;
|
||||
}
|
||||
tv.tv_usec += us;
|
||||
tv.tv_sec += (tv.tv_usec / 1000000);
|
||||
tv.tv_usec %= 1000000;
|
||||
}
|
||||
|
||||
static long getTickCount()
|
||||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_sec*1000 + now.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
std::chrono::duration<Rep, Period> abs(std::chrono::duration<Rep, Period> d)
|
||||
{
|
||||
Rep x = d.count();
|
||||
return std::chrono::duration<Rep, Period>(x >= 0 ? x : -x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ inline static long getAge(const time_point_ms& time_point)
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
static void addMs(timeval& tv, int ms)
|
||||
{
|
||||
if (ms < 0)
|
||||
|
@ -75,7 +75,7 @@ static void addUs(timeval& tv, int us)
|
|||
tv.tv_sec += (tv.tv_usec / 1000000);
|
||||
tv.tv_usec %= 1000000;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*static long diffMs(const timeval& t1, const timeval& t2)
|
||||
{
|
||||
|
@ -84,21 +84,6 @@ static void addUs(timeval& tv, int us)
|
|||
}*/
|
||||
|
||||
|
||||
static long getTickCount()
|
||||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_sec*1000 + now.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
|
||||
static long getuTickCount()
|
||||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_sec*1000000 + now.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
timeval tvChunk;
|
||||
gettimeofday(&tvChunk, NULL);
|
||||
long nextTick = getTickCount();
|
||||
long nextTick = chronos::getTickCount();
|
||||
|
||||
mkfifo(fifoName.c_str(), 0777);
|
||||
SampleFormat format(sampleFormat);
|
||||
|
@ -122,9 +122,9 @@ int main(int argc, char* argv[])
|
|||
controlServer->send(chunk);
|
||||
//cout << chunk->tv_sec << ", " << chunk->tv_usec / 1000 << "\n";
|
||||
// addUs(tvChunk, 1000*chunk->getDuration());
|
||||
addUs(tvChunk, chunkDuration * 1000);
|
||||
chronos::addUs(tvChunk, chunkDuration * 1000);
|
||||
nextTick += duration;
|
||||
long currentTick = getTickCount();
|
||||
long currentTick = chronos::getTickCount();
|
||||
if (nextTick > currentTick)
|
||||
{
|
||||
usleep((nextTick - currentTick) * 1000);
|
||||
|
@ -132,7 +132,7 @@ int main(int argc, char* argv[])
|
|||
else
|
||||
{
|
||||
gettimeofday(&tvChunk, NULL);
|
||||
nextTick = getTickCount();
|
||||
nextTick = chronos::getTickCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue