mirror of
https://github.com/badaix/snapcast.git
synced 2025-07-19 01:18:17 +02:00
xxx
git-svn-id: svn://elaine/murooma/trunk@70 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
parent
071405049e
commit
858e49a3ed
4 changed files with 117 additions and 61 deletions
4
chunk.h
4
chunk.h
|
@ -16,6 +16,10 @@
|
|||
template <size_t T>
|
||||
struct ChunkT
|
||||
{
|
||||
// ChunkT()
|
||||
// {
|
||||
// memset(&payload[0], 0, T);
|
||||
// }
|
||||
int32_t tv_sec;
|
||||
int32_t tv_usec;
|
||||
int32_t idx;
|
||||
|
|
|
@ -50,14 +50,14 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
|||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
std::vector<short> s = stream->getChunk(timeInfo->outputBufferDacTime, framesPerBuffer);
|
||||
PlayerChunk* playerChunk = stream->getChunk(timeInfo->outputBufferDacTime, framesPerBuffer);
|
||||
|
||||
for (size_t n=0; n<framesPerBuffer; n++)
|
||||
{
|
||||
*out++ = s[2*n];
|
||||
*out++ = s[2*n+1];
|
||||
*out++ = playerChunk->payload[2*n];
|
||||
*out++ = playerChunk->payload[2*n+1];
|
||||
}
|
||||
// delete chunk;
|
||||
delete playerChunk;
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
|
76
stream.h
76
stream.h
|
@ -15,8 +15,9 @@
|
|||
class Stream
|
||||
{
|
||||
public:
|
||||
Stream() : median(0), shortMedian(0), lastUpdate(0), skip(0), idx(0)
|
||||
Stream() : lastPlayerChunk(NULL), median(0), shortMedian(0), lastUpdate(0), skip(0), idx(0)
|
||||
{
|
||||
silentPlayerChunk = new PlayerChunk();
|
||||
pBuffer = new DoubleBuffer<int>(30000 / PLAYER_CHUNK_MS);
|
||||
pShortBuffer = new DoubleBuffer<int>(5000 / PLAYER_CHUNK_MS);
|
||||
pLock = new std::unique_lock<std::mutex>(mtx);
|
||||
|
@ -33,24 +34,73 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<short> getChunk(double outputBufferDacTime, unsigned long framesPerBuffer)
|
||||
Chunk* getNextChunk()
|
||||
{
|
||||
Chunk* chunk = NULL;
|
||||
if (chunks.empty())
|
||||
cv.wait(*pLock);
|
||||
|
||||
int age(0);
|
||||
int chunkCount(0);
|
||||
mutex.lock();
|
||||
chunk = chunks.front();
|
||||
mutex.unlock();
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
||||
age = getAge(*chunk) + outputBufferDacTime*1000 - bufferMs;
|
||||
if (age < -500)
|
||||
PlayerChunk* getNextPlayerChunk()
|
||||
{
|
||||
Chunk* chunk = getNextChunk();
|
||||
// int age(0);
|
||||
// age = getAge(*chunk) + outputBufferDacTime*1000 - bufferMs;
|
||||
// std::cerr << "age: " << age << " \tidx: " << chunk->idx << "\n";
|
||||
PlayerChunk* playerChunk = new PlayerChunk();
|
||||
playerChunk->tv_sec = chunk->tv_sec;
|
||||
playerChunk->tv_usec = chunk->tv_usec;
|
||||
playerChunk->idx = 0;
|
||||
|
||||
size_t missing = PLAYER_CHUNK_SIZE;
|
||||
if (chunk->idx + PLAYER_CHUNK_SIZE > WIRE_CHUNK_SIZE)
|
||||
{
|
||||
std::cerr << "chunk->idx + PLAYER_CHUNK_SIZE >= WIRE_CHUNK_SIZE: " << chunk->idx + PLAYER_CHUNK_SIZE << " >= " << WIRE_CHUNK_SIZE << "\n";
|
||||
memcpy(&(playerChunk->payload[0]), &chunk->payload[chunk->idx], sizeof(int16_t)*(WIRE_CHUNK_SIZE - chunk->idx));
|
||||
missing = chunk->idx + PLAYER_CHUNK_SIZE - WIRE_CHUNK_SIZE;
|
||||
chunks.pop_front();
|
||||
delete chunk;
|
||||
|
||||
chunk = getNextChunk();
|
||||
}
|
||||
|
||||
memcpy(&(playerChunk->payload[0]), &chunk->payload[chunk->idx], sizeof(int16_t)*missing);
|
||||
|
||||
addMs(chunk, -PLAYER_CHUNK_MS);
|
||||
chunk->idx += missing;
|
||||
if (chunk->idx >= WIRE_CHUNK_SIZE)
|
||||
{
|
||||
chunks.pop_front();
|
||||
delete chunk;
|
||||
}
|
||||
return playerChunk;
|
||||
}
|
||||
|
||||
|
||||
PlayerChunk* getChunk(double outputBufferDacTime, unsigned long framesPerBuffer)
|
||||
{
|
||||
PlayerChunk* playerChunk = getNextPlayerChunk();
|
||||
int age = getAge(playerChunk) + outputBufferDacTime*1000 - bufferMs;
|
||||
// std::cerr << "Chunk: " << age << "\t" << outputBufferDacTime*1000 << "\n";
|
||||
if (age < -100)
|
||||
{
|
||||
std::cerr << "Playing silence, age: " << age << "\n";
|
||||
sleepMs(-age);
|
||||
// *playerChunk = new PlayerChunk();
|
||||
// return;
|
||||
}
|
||||
|
||||
// int age = getAge(*lastPlayerChunk) + outputBufferDacTime*1000 - bufferMs;
|
||||
return playerChunk;
|
||||
}
|
||||
|
||||
/* if (age < -500)
|
||||
{
|
||||
std::vector<short> v;
|
||||
if (skip < 0)
|
||||
|
@ -82,7 +132,7 @@ public:
|
|||
if (pBuffer->full() && (abs(median) > WIRE_CHUNK_MS))
|
||||
skip = median / PLAYER_CHUNK_SIZE;
|
||||
}
|
||||
std::cerr << "Chunk: " << age << /*" \tidx: " << chunk->idx <<*/ "\t" << shortMedian << "\t" << median << "\t" << pBuffer->size() << "\t" << chunkCount << "\t" << outputBufferDacTime*1000 << "\n";
|
||||
std::cerr << "Chunk: " << age << "\t" << shortMedian << "\t" << median << "\t" << pBuffer->size() << "\t" << chunkCount << "\t" << outputBufferDacTime*1000 << "\n";
|
||||
}
|
||||
|
||||
std::vector<short> v;
|
||||
|
@ -111,8 +161,7 @@ public:
|
|||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
@ -304,6 +353,9 @@ private:
|
|||
DoubleBuffer<int>* pBuffer;
|
||||
DoubleBuffer<int>* pShortBuffer;
|
||||
|
||||
PlayerChunk* lastPlayerChunk;
|
||||
PlayerChunk* silentPlayerChunk;
|
||||
|
||||
int median;
|
||||
int shortMedian;
|
||||
time_t lastUpdate;
|
||||
|
|
16
timeUtils.h
16
timeUtils.h
|
@ -34,13 +34,13 @@ long diff_ms(const timeval& t1, const timeval& t2)
|
|||
|
||||
|
||||
template <typename T>
|
||||
long getAge(const T& chunk)
|
||||
long getAge(const T* chunk)
|
||||
{
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
timeval ts;
|
||||
ts.tv_sec = chunk.tv_sec;
|
||||
ts.tv_usec = chunk.tv_usec;
|
||||
ts.tv_sec = chunk->tv_sec;
|
||||
ts.tv_usec = chunk->tv_usec;
|
||||
return diff_ms(now, ts);
|
||||
}
|
||||
|
||||
|
@ -69,14 +69,14 @@ inline void addMs(timeval& tv, int ms)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
void addMs(T& chunk, int ms)
|
||||
void addMs(T* chunk, int ms)
|
||||
{
|
||||
timeval tv;
|
||||
tv.tv_sec = chunk.tv_sec;
|
||||
tv.tv_usec = chunk.tv_usec;
|
||||
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;
|
||||
chunk->tv_sec = tv.tv_sec;
|
||||
chunk->tv_usec = tv.tv_usec;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue