mirror of
https://github.com/badaix/snapcast.git
synced 2025-07-22 02:47:50 +02:00
shortBuffer
git-svn-id: svn://elaine/murooma/trunk@48 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
parent
9a253e9be0
commit
36337a1c66
3 changed files with 52 additions and 11 deletions
2
chunk.h
2
chunk.h
|
@ -8,7 +8,7 @@
|
||||||
#define WIRE_CHUNK_MS (40)
|
#define WIRE_CHUNK_MS (40)
|
||||||
#define WIRE_CHUNK_SIZE (SAMPLE_RATE*CHANNELS*SAMPLE_BIT/8*WIRE_CHUNK_MS/1000)
|
#define WIRE_CHUNK_SIZE (SAMPLE_RATE*CHANNELS*SAMPLE_BIT/8*WIRE_CHUNK_MS/1000)
|
||||||
|
|
||||||
#define PLAYER_CHUNK_MS (5)
|
#define PLAYER_CHUNK_MS (20)
|
||||||
#define PLAYER_CHUNK_SIZE (SAMPLE_RATE*CHANNELS*SAMPLE_BIT/8*PLAYER_CHUNK_MS/1000)
|
#define PLAYER_CHUNK_SIZE (SAMPLE_RATE*CHANNELS*SAMPLE_BIT/8*PLAYER_CHUNK_MS/1000)
|
||||||
|
|
||||||
#define FRAMES_PER_BUFFER (PLAYER_CHUNK_SIZE/(CHANNELS*SAMPLE_BIT/8))
|
#define FRAMES_PER_BUFFER (PLAYER_CHUNK_SIZE/(CHANNELS*SAMPLE_BIT/8))
|
||||||
|
|
50
client.cpp
50
client.cpp
|
@ -22,7 +22,8 @@
|
||||||
#include "timeUtils.h"
|
#include "timeUtils.h"
|
||||||
|
|
||||||
|
|
||||||
DoubleBuffer<int> buffer(30000 / WIRE_CHUNK_MS);
|
DoubleBuffer<int> buffer(20000 / PLAYER_CHUNK_MS);
|
||||||
|
DoubleBuffer<int> shortBuffer(500 / PLAYER_CHUNK_MS);
|
||||||
std::deque<PlayerChunk*> chunks;
|
std::deque<PlayerChunk*> chunks;
|
||||||
std::deque<int> timeDiffs;
|
std::deque<int> timeDiffs;
|
||||||
std::mutex mtx;
|
std::mutex mtx;
|
||||||
|
@ -147,19 +148,44 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||||
chunk = chunks->front();
|
chunk = chunks->front();
|
||||||
// std::cerr << "Chunks: " << chunks->size() << "\n";
|
// std::cerr << "Chunks: " << chunks->size() << "\n";
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
age = getAge(*chunk) + timeInfo->outputBufferDacTime*1000;
|
age = getAge(*chunk) + timeInfo->outputBufferDacTime*1000 - bufferMs;
|
||||||
|
buffer.add(age);
|
||||||
|
shortBuffer.add(age);
|
||||||
int median = buffer.median();
|
int median = buffer.median();
|
||||||
std::cerr << "age: " << getAge(*chunk) << "\t" << age << "\t" << median << "\t" << buffer.size() << "\t" << timeInfo->outputBufferDacTime*1000 << "\n";
|
int shortMedian = shortBuffer.median();
|
||||||
|
std::cerr << "age: " << getAge(*chunk) << "\t" << age << "\t" << shortMedian << "\t" << median << "\t" << buffer.size() << "\t" << timeInfo->outputBufferDacTime*1000 << "\n";
|
||||||
|
|
||||||
int maxDiff = 10;
|
bool skip = (age > 500) || (shortBuffer.full() && (shortMedian > 100)) || (buffer.full() && (median > 20));
|
||||||
if (/*!buffer.full() &&*/ (age > bufferMs + std::max(100, 2*PLAYER_CHUNK_MS)))
|
bool silence = (age < -500) || (shortBuffer.full() && (shortMedian < -100)) || (buffer.full() && (median < -20));
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
chunks->pop_front();
|
||||||
|
delete chunk;
|
||||||
|
std::cerr << "packe too old, dropping\n";
|
||||||
|
buffer.clear();
|
||||||
|
shortBuffer.clear();
|
||||||
|
usleep(100);
|
||||||
|
}
|
||||||
|
else if (silence)
|
||||||
|
{
|
||||||
|
chunk = new PlayerChunk();
|
||||||
|
memset(&(chunk->payload[0]), 0, PLAYER_CHUNK_SIZE);
|
||||||
|
// std::cerr << "age < bufferMs (" << age << " < " << bufferMs << "), playing silence\n";
|
||||||
|
buffer.clear();
|
||||||
|
shortBuffer.clear();
|
||||||
|
usleep(100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int maxDiff = 10;
|
||||||
|
if ((shortMedian > bufferMs + std::max(100, 3*WIRE_CHUNK_MS)))
|
||||||
{
|
{
|
||||||
chunks->pop_front();
|
chunks->pop_front();
|
||||||
delete chunk;
|
delete chunk;
|
||||||
std::cerr << "packe too old, dropping\n";
|
std::cerr << "packe too old, dropping\n";
|
||||||
usleep(100);
|
usleep(100);
|
||||||
}
|
}
|
||||||
else if (/*!buffer.full() &&*/ (age < bufferMs - std::max(100, 2*PLAYER_CHUNK_MS)))
|
else if ((shortMedian < bufferMs - std::max(100, 3*WIRE_CHUNK_MS)))
|
||||||
{
|
{
|
||||||
chunk = new PlayerChunk();
|
chunk = new PlayerChunk();
|
||||||
memset(&(chunk->payload[0]), 0, PLAYER_CHUNK_SIZE);
|
memset(&(chunk->payload[0]), 0, PLAYER_CHUNK_SIZE);
|
||||||
|
@ -170,7 +196,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||||
else if (buffer.full() && (median > bufferMs + maxDiff))
|
else if (buffer.full() && (median > bufferMs + maxDiff))
|
||||||
{
|
{
|
||||||
std::cerr << "median > bufferMs + PLAYER_CHUNK_MS (" << median << " > " << bufferMs + maxDiff << "), dropping chunk\n";
|
std::cerr << "median > bufferMs + PLAYER_CHUNK_MS (" << median << " > " << bufferMs + maxDiff << "), dropping chunk\n";
|
||||||
buffer.clear();
|
// buffer.clear();
|
||||||
chunks->pop_front();
|
chunks->pop_front();
|
||||||
delete chunk;
|
delete chunk;
|
||||||
sleepMs(median - bufferMs);
|
sleepMs(median - bufferMs);
|
||||||
|
@ -178,7 +204,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||||
else if (buffer.full() && (median + maxDiff < bufferMs))
|
else if (buffer.full() && (median + maxDiff < bufferMs))
|
||||||
{
|
{
|
||||||
std::cerr << "median + PLAYER_CHUNK_MS < bufferMs (" << median + maxDiff << " < " << bufferMs << "), playing silence\n";
|
std::cerr << "median + PLAYER_CHUNK_MS < bufferMs (" << median + maxDiff << " < " << bufferMs << "), playing silence\n";
|
||||||
buffer.clear();
|
// buffer.clear();
|
||||||
if (bufferMs - median > PLAYER_CHUNK_MS)
|
if (bufferMs - median > PLAYER_CHUNK_MS)
|
||||||
{
|
{
|
||||||
chunk = new PlayerChunk();
|
chunk = new PlayerChunk();
|
||||||
|
@ -192,9 +218,9 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||||
}
|
}
|
||||||
// delete chunk;
|
// delete chunk;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer.add(age);
|
|
||||||
chunks->pop_front();
|
chunks->pop_front();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +230,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||||
{
|
{
|
||||||
//std::cerr << (int)chunk->payload[i] << "\t" << (int)chunk->payload[i+1] << "\t" << (int)chunk->payload[i+2] << "\t" << (int)chunk->payload[i+3] << "\n";
|
//std::cerr << (int)chunk->payload[i] << "\t" << (int)chunk->payload[i+1] << "\t" << (int)chunk->payload[i+2] << "\t" << (int)chunk->payload[i+3] << "\n";
|
||||||
//std::cerr << i << "\t" << 4*i+1 << "\t" << 4*i << "\n";
|
//std::cerr << i << "\t" << 4*i+1 << "\t" << 4*i << "\n";
|
||||||
*out++ = (int)chunk->payload[4*i+1]*256 + (int)chunk->payload[4*i];
|
*out++ = (int)chunk->payload[4*i+1]*256 + (int)chunk->payload[4*i+0];
|
||||||
*out++ = (int)chunk->payload[4*i+3]*256 + (int)chunk->payload[4*i+2];
|
*out++ = (int)chunk->payload[4*i+3]*256 + (int)chunk->payload[4*i+2];
|
||||||
}
|
}
|
||||||
delete chunk;
|
delete chunk;
|
||||||
|
@ -311,12 +337,16 @@ int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
PlayerChunk* playerChunk = new PlayerChunk();
|
PlayerChunk* playerChunk = new PlayerChunk();
|
||||||
// for (size_t m=0; m<PLAYER_CHUNK_SIZE; ++m)
|
// for (size_t m=0; m<PLAYER_CHUNK_SIZE; ++m)
|
||||||
|
playerChunk->tv_sec = chunk->tv_sec;
|
||||||
|
playerChunk->tv_usec = chunk->tv_usec;
|
||||||
|
addMs(*playerChunk, n*PLAYER_CHUNK_MS);
|
||||||
memcpy(&(playerChunk->payload[0]), &chunk->payload[n*PLAYER_CHUNK_SIZE], PLAYER_CHUNK_SIZE);
|
memcpy(&(playerChunk->payload[0]), &chunk->payload[n*PLAYER_CHUNK_SIZE], PLAYER_CHUNK_SIZE);
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
chunks.push_back(playerChunk);
|
chunks.push_back(playerChunk);
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
cv.notify_all();
|
cv.notify_all();
|
||||||
}
|
}
|
||||||
|
delete chunk;
|
||||||
|
|
||||||
// timeval now;
|
// timeval now;
|
||||||
// gettimeofday(&now, NULL);
|
// gettimeofday(&now, NULL);
|
||||||
|
|
11
timeUtils.h
11
timeUtils.h
|
@ -60,6 +60,17 @@ void addMs(timeval& tv, int ms)
|
||||||
tv.tv_usec %= 1000000;
|
tv.tv_usec %= 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void addMs(T& chunk, int ms)
|
||||||
|
{
|
||||||
|
timeval tv;
|
||||||
|
tv.tv_sec = chunk.tv_sec;
|
||||||
|
tv.tv_usec = chunk.tv_usec;
|
||||||
|
addMs(tv, ms);
|
||||||
|
chunk.tv_sec = tv.tv_sec;
|
||||||
|
chunk.tv_usec = tv.tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue