diff --git a/chunk.h b/chunk.h index a219d0b1..6ab29315 100644 --- a/chunk.h +++ b/chunk.h @@ -16,6 +16,10 @@ template struct ChunkT { +// ChunkT() +// { +// memset(&payload[0], 0, T); +// } int32_t tv_sec; int32_t tv_usec; int32_t idx; diff --git a/client.cpp b/client.cpp index a4454de5..facd9e07 100644 --- a/client.cpp +++ b/client.cpp @@ -50,14 +50,14 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, (void) statusFlags; (void) inputBuffer; - std::vector s = stream->getChunk(timeInfo->outputBufferDacTime, framesPerBuffer); - + PlayerChunk* playerChunk = stream->getChunk(timeInfo->outputBufferDacTime, framesPerBuffer); + for (size_t n=0; npayload[2*n]; + *out++ = playerChunk->payload[2*n+1]; } -// delete chunk; + delete playerChunk; return paContinue; } diff --git a/stream.h b/stream.h index 4ba599c9..fcd31fde 100644 --- a/stream.h +++ b/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(30000 / PLAYER_CHUNK_MS); pShortBuffer = new DoubleBuffer(5000 / PLAYER_CHUNK_MS); pLock = new std::unique_lock(mtx); @@ -33,24 +34,73 @@ public: } - - - - std::vector 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; + } + + 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; - age = getAge(*chunk) + outputBufferDacTime*1000 - bufferMs; - if (age < -500) + 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 v; if (skip < 0) @@ -68,51 +118,50 @@ public: time_t now = time(NULL); - if (skip == 0) + if (skip == 0) + { + if (now != lastUpdate) { - if (now != lastUpdate) - { - lastUpdate = now; - median = pBuffer->median(); - shortMedian = pShortBuffer->median(); - if (abs(age) > 500) - skip = age / PLAYER_CHUNK_SIZE; - if (pShortBuffer->full() && (abs(shortMedian) > WIRE_CHUNK_MS)) - skip = shortMedian / PLAYER_CHUNK_SIZE; - 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"; + lastUpdate = now; + median = pBuffer->median(); + shortMedian = pShortBuffer->median(); + if (abs(age) > 500) + skip = age / PLAYER_CHUNK_SIZE; + if (pShortBuffer->full() && (abs(shortMedian) > WIRE_CHUNK_MS)) + skip = shortMedian / PLAYER_CHUNK_SIZE; + if (pBuffer->full() && (abs(median) > WIRE_CHUNK_MS)) + skip = median / PLAYER_CHUNK_SIZE; } - - std::vector v; - if (skip < 0) - { - ++skip; - std::cerr << "chunk too new, sleeping\n";//age > WIRE_CHUNK_MS (" << age << " ms)\n"; - for (size_t n=0; n<(size_t)PLAYER_CHUNK_SIZE; ++n) - v.push_back(chunk->payload[n]); - return v; - } - - for (size_t n=chunk->idx; nidx + (size_t)PLAYER_CHUNK_SIZE; ++n) - { + std::cerr << "Chunk: " << age << "\t" << shortMedian << "\t" << median << "\t" << pBuffer->size() << "\t" << chunkCount << "\t" << outputBufferDacTime*1000 << "\n"; + } + + std::vector v; + if (skip < 0) + { + ++skip; + std::cerr << "chunk too new, sleeping\n";//age > WIRE_CHUNK_MS (" << age << " ms)\n"; + for (size_t n=0; n<(size_t)PLAYER_CHUNK_SIZE; ++n) v.push_back(chunk->payload[n]); - } -//std::cerr << "before: " << chunkTime(*chunk) << ", after: "; - addMs(*chunk, -PLAYER_CHUNK_MS); -//std::cerr << chunkTime(*chunk) << "\n"; - chunk->idx += PLAYER_CHUNK_SIZE; - if (chunk->idx >= WIRE_CHUNK_SIZE) - { -//std::cerr << "Chunk played out, deleting\n"; - chunks.pop_front(); - delete chunk; - } return v; } - } + for (size_t n=chunk->idx; nidx + (size_t)PLAYER_CHUNK_SIZE; ++n) + { + v.push_back(chunk->payload[n]); + } +//std::cerr << "before: " << chunkTime(*chunk) << ", after: "; + addMs(*chunk, -PLAYER_CHUNK_MS); +//std::cerr << chunkTime(*chunk) << "\n"; + chunk->idx += PLAYER_CHUNK_SIZE; + if (chunk->idx >= WIRE_CHUNK_SIZE) + { +//std::cerr << "Chunk played out, deleting\n"; + chunks.pop_front(); + delete chunk; + } + return v; + } +*/ @@ -304,6 +353,9 @@ private: DoubleBuffer* pBuffer; DoubleBuffer* pShortBuffer; + PlayerChunk* lastPlayerChunk; + PlayerChunk* silentPlayerChunk; + int median; int shortMedian; time_t lastUpdate; diff --git a/timeUtils.h b/timeUtils.h index 19d5060c..f1fd1967 100644 --- a/timeUtils.h +++ b/timeUtils.h @@ -34,13 +34,13 @@ long diff_ms(const timeval& t1, const timeval& t2) template -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 -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; }