time stuff

git-svn-id: svn://elaine/murooma/trunk@301 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
(no author) 2014-09-28 07:43:34 +00:00
parent 1759aeb160
commit a7118fd0a4
5 changed files with 53 additions and 45 deletions

View file

@ -1,7 +1,6 @@
#include "stream.h" #include "stream.h"
#include <iostream> #include <iostream>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "common/log.h" #include "common/log.h"
#include "timeProvider.h" #include "timeProvider.h"
@ -14,7 +13,7 @@ Stream::Stream(const SampleFormat& sampleFormat) : format(format_), format_(samp
buffer.setSize(500); buffer.setSize(500);
shortBuffer.setSize(100); shortBuffer.setSize(100);
miniBuffer.setSize(20); miniBuffer.setSize(20);
cardBuffer.setSize(50); // cardBuffer.setSize(50);
bufferMs = msec(500); bufferMs = msec(500);
} }
@ -178,10 +177,10 @@ bool Stream::getPlayerChunk(void* outputBuffer, const chronos::usec& outputBuffe
chronos::usec correction = chronos::usec(0); chronos::usec correction = chronos::usec(0);
if (sleep.count() != 0) if (sleep.count() != 0)
{ {
// cout << "Sleep " << sleep.count() << "\n";
resetBuffers(); resetBuffers();
if (sleep < -bufferDuration/2) 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); sleep = chrono::duration_cast<usec>(TimeProvider::serverNow() - getSilentPlayerChunk(outputBuffer, framesPerBuffer) - bufferMs + outputBufferDacTime);
//cout << "-sleep: " << sleep.count() << " " << -bufferDuration.count() / 2000 << "\n"; //cout << "-sleep: " << sleep.count() << " " << -bufferDuration.count() / 2000 << "\n";
if (sleep < -bufferDuration/2) if (sleep < -bufferDuration/2)
@ -189,17 +188,18 @@ bool Stream::getPlayerChunk(void* outputBuffer, const chronos::usec& outputBuffe
} }
else if (sleep > bufferDuration/2) else if (sleep > bufferDuration/2)
{ {
// We're late: discard oldest chunks
while (sleep > chunk->duration<chronos::usec>()) 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)) if (!chunks.try_pop(chunk, outputBufferDacTime))
return false; return false;
sleep = std::chrono::duration_cast<usec>(TimeProvider::serverNow() - chunk->start() - bufferMs + outputBufferDacTime); 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)) if (sleep < -chronos::usec(100))
{ {
sleep += chronos::usec(100); sleep += chronos::usec(100);
@ -245,14 +245,14 @@ bool Stream::getPlayerChunk(void* outputBuffer, const chronos::usec& outputBuffe
updateBuffers(age.count()); updateBuffers(age.count());
// std::cerr << "Chunk: " << age << "\t" << outputBufferDacTime*1000 << "\n"; // print sync stats
time_t now = time(NULL); time_t now = time(NULL);
if (now != lastUpdate) if (now != lastUpdate)
{ {
lastUpdate = now; lastUpdate = now;
median = buffer.median(); median = buffer.median();
shortMedian = shortBuffer.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; return true;
} }

View file

@ -1,18 +1,18 @@
#ifndef STREAM_H #ifndef STREAM_H
#define STREAM_H #define STREAM_H
//#include <mutex>
//#include <condition_variable>
//#include <vector>
//#include <chrono>
//#include "common/timeUtils.h"
#include <deque> #include <deque>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <memory> #include <memory>
#include <chrono>
#include "doubleBuffer.h" #include "doubleBuffer.h"
#include "message/message.h" #include "message/message.h"
#include "message/pcmChunk.h" #include "message/pcmChunk.h"
#include "message/sampleFormat.h" #include "message/sampleFormat.h"
#include "common/timeUtils.h"
#include "common/queue.h" #include "common/queue.h"
@ -40,10 +40,10 @@ private:
chronos::usec sleep; chronos::usec sleep;
Queue<std::shared_ptr<PcmChunk>> chunks; Queue<std::shared_ptr<PcmChunk>> chunks;
DoubleBuffer<long> cardBuffer; // DoubleBuffer<chronos::usec::rep> cardBuffer;
DoubleBuffer<long> miniBuffer; DoubleBuffer<chronos::usec::rep> miniBuffer;
DoubleBuffer<long> buffer; DoubleBuffer<chronos::usec::rep> buffer;
DoubleBuffer<long> shortBuffer; DoubleBuffer<chronos::usec::rep> shortBuffer;
std::shared_ptr<PcmChunk> chunk; std::shared_ptr<PcmChunk> chunk;
int median; int median;

View file

@ -2,22 +2,45 @@
#define TIME_DEFS_H #define TIME_DEFS_H
#include <chrono> #include <chrono>
#include <sys/time.h>
namespace chronos 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::high_resolution_clock hrc;
typedef std::chrono::time_point<hrc> time_point_hrc; typedef std::chrono::time_point<hrc> time_point_hrc;
typedef std::chrono::seconds sec; typedef std::chrono::seconds sec;
typedef std::chrono::milliseconds msec; typedef std::chrono::milliseconds msec;
typedef std::chrono::microseconds usec; typedef std::chrono::microseconds usec;
typedef std::chrono::nanoseconds nsec; 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);
}
} }

View file

@ -45,7 +45,7 @@ inline static long getAge(const time_point_ms& time_point)
} }
*/ */
/*
static void addMs(timeval& tv, int ms) static void addMs(timeval& tv, int ms)
{ {
if (ms < 0) if (ms < 0)
@ -75,7 +75,7 @@ static void addUs(timeval& tv, int us)
tv.tv_sec += (tv.tv_usec / 1000000); tv.tv_sec += (tv.tv_usec / 1000000);
tv.tv_usec %= 1000000; tv.tv_usec %= 1000000;
} }
*/
/*static long diffMs(const timeval& t1, const timeval& t2) /*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;
}

View file

@ -65,7 +65,7 @@ int main(int argc, char* argv[])
timeval tvChunk; timeval tvChunk;
gettimeofday(&tvChunk, NULL); gettimeofday(&tvChunk, NULL);
long nextTick = getTickCount(); long nextTick = chronos::getTickCount();
mkfifo(fifoName.c_str(), 0777); mkfifo(fifoName.c_str(), 0777);
SampleFormat format(sampleFormat); SampleFormat format(sampleFormat);
@ -122,9 +122,9 @@ int main(int argc, char* argv[])
controlServer->send(chunk); controlServer->send(chunk);
//cout << chunk->tv_sec << ", " << chunk->tv_usec / 1000 << "\n"; //cout << chunk->tv_sec << ", " << chunk->tv_usec / 1000 << "\n";
// addUs(tvChunk, 1000*chunk->getDuration()); // addUs(tvChunk, 1000*chunk->getDuration());
addUs(tvChunk, chunkDuration * 1000); chronos::addUs(tvChunk, chunkDuration * 1000);
nextTick += duration; nextTick += duration;
long currentTick = getTickCount(); long currentTick = chronos::getTickCount();
if (nextTick > currentTick) if (nextTick > currentTick)
{ {
usleep((nextTick - currentTick) * 1000); usleep((nextTick - currentTick) * 1000);
@ -132,7 +132,7 @@ int main(int argc, char* argv[])
else else
{ {
gettimeofday(&tvChunk, NULL); gettimeofday(&tvChunk, NULL);
nextTick = getTickCount(); nextTick = chronos::getTickCount();
} }
} }
} }