From 559baf31e3d3f571870d19d378afd8b80ec846eb Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@d8a302eb-03bc-478d-80e4-98257eca68ef> Date: Sun, 24 Aug 2014 18:40:27 +0000 Subject: [PATCH] seeking git-svn-id: svn://elaine/murooma/trunk@209 d8a302eb-03bc-478d-80e4-98257eca68ef --- client/player.cpp | 12 ++++++-- client/snapClient.cpp | 7 ----- client/stream.cpp | 64 +++++++++++++++++++++++++++++++++---------- client/stream.h | 1 + common/chunk.cpp | 21 ++++++++++++-- common/chunk.h | 2 ++ 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/client/player.cpp b/client/player.cpp index 669baf64..9033332a 100644 --- a/client/player.cpp +++ b/client/player.cpp @@ -22,6 +22,9 @@ void Player::start() rate = stream_->format.rate; channels = stream_->format.channels; + unsigned int buffer_time = 100 * 1000; + unsigned int period_time = buffer_time / 8; + /* Open the PCM device in playback mode */ if ((pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) @@ -50,9 +53,12 @@ void Player::start() if ((pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0)) < 0) cout << "ERROR: Can't set rate. " << snd_strerror(pcm) << "\n"; - long unsigned int periodsize = 2*rate/50; - if ((pcm = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, params, &periodsize)) < 0) - cout << "Unable to set buffer size " << (long int)periodsize << ": " << snd_strerror(pcm) << "\n"; + snd_pcm_hw_params_set_period_time_near(pcm_handle, params, &period_time, 0); + snd_pcm_hw_params_set_buffer_time_near(pcm_handle, params, &buffer_time, 0); + +// long unsigned int periodsize = stream_->format.msRate() * 50;//2*rate/50; +// if ((pcm = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, params, &periodsize)) < 0) +// cout << "Unable to set buffer size " << (long int)periodsize << ": " << snd_strerror(pcm) << "\n"; /* Write parameters */ if ((pcm = snd_pcm_hw_params(pcm_handle, params)) < 0) diff --git a/client/snapClient.cpp b/client/snapClient.cpp index e5749e23..d60a5000 100644 --- a/client/snapClient.cpp +++ b/client/snapClient.cpp @@ -6,13 +6,6 @@ // Olivier Chamoux // #include -#include -#include -#include -#include -#include -#include -#include #include #include diff --git a/client/stream.cpp b/client/stream.cpp index 3e36c2bd..424ecdd3 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -51,6 +51,20 @@ time_point_ms Stream::getSilentPlayerChunk(void* outputBuffer, unsigned long fra } +time_point_ms Stream::seek(unsigned long ms) +{ + if (!chunk) + chunk = chunks.pop(); +// time_point_ms tp = chunk->timePoint(); + while (ms > chunk->getDuration()) + { + chunk = chunks.pop(); + ms -= min(ms, (unsigned long)chunk->getDuration()); + } + chunk->seek(ms * format.msRate()); + return chunk->timePoint(); +} + time_point_ms Stream::getNextPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer, int correction) { @@ -117,7 +131,7 @@ void Stream::resetBuffers() void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsigned long framesPerBuffer) { //cout << "framesPerBuffer: " << framesPerBuffer << "\tms: " << framesPerBuffer*2 / PLAYER_CHUNK_MS_SIZE << "\t" << PLAYER_CHUNK_SIZE << "\n"; -//int msBuffer = framesPerBuffer / (format_.rate/1000); +int msBuffer = framesPerBuffer / format_.msRate(); //cout << msBuffer << " ms, " << framesPerBuffer << "\t" << format_.rate/1000 << "\n"; int ticks = 0; long currentTick = getTickCount(); @@ -136,28 +150,43 @@ void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsi if (sleep != 0) { resetBuffers(); - if (sleep < -10) + if (sleep < -msBuffer/2) { + cout << "Sleep " << sleep; sleep = Chunk::getAge(getSilentPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime; - std::cerr << "Sleep: " << sleep << ", chunks: " << chunks.size() << "\n"; + std::cerr << " after: " << sleep << ", chunks: " << chunks.size() << "\n"; // std::clog << kLogNotice << "sleep: " << sleep << std::endl; // if (sleep > -msBuffer/2) // sleep = 0; - return; + if (sleep < -msBuffer/2) + return; } - else if (sleep > 10) + else if (sleep > msBuffer/2) { + cout << "Sleep " << sleep; + sleep = Chunk::getAge(seek(sleep)) - bufferMs + outputBufferDacTime; + cout << " after: " << sleep << "\n"; // std::clog << kLogNotice << "sleep: " << sleep << std::endl; - while (true) - { - sleep = Chunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime; - usleep(100); -// std::clog << kLogNotice << "age: " << age << std::endl; - if (sleep < 0) - break; - } +// while (true) +// { +// if (!chunk) +// chunk = chunks.pop(); +/* while (chunk->getAge() - bufferMs + outputBufferDacTime > chunk->getDuration()) + { + cout << "chunk->getAge() > chunk->getDuration(): " << chunk->getAge() - bufferMs + outputBufferDacTime << " > " << chunk->getDuration() << ", chunks: " << chunks.size() << ", out: " << outputBufferDacTime << ", needed: " << msBuffer << "\n"; +usleep(10); + chunk = chunks.pop(); + } +*/ +// while +// sleep = Chunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime; +// usleep(100); +// cout << "age: " << sleep << "\t out: " << outputBufferDacTime << "\t frames: " << framesPerBuffer << ", chunks: " << chunks.size() << "\n"; +// if (sleep < 0) +// break; +// } // sleep = 0; - return; +// return; } else if (sleep < 0) { @@ -179,7 +208,7 @@ void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsi // if (pCardBuffer->full()) // age += 4*cardBuffer; -// cout << age << "\t" << framesPerBuffer << "\t" << msBuffer << "\t" << ticks << "\t" << cardBuffer << "\t" << outputBufferDacTime*1000 << "\n"; +// cout << age << "\t" << outputBufferDacTime << "\t";// << framesPerBuffer << "\t" << msBuffer << "\t" << ticks << "\t" << cardBuffer << "\t" << outputBufferDacTime << "\n"; if (sleep == 0) @@ -199,6 +228,11 @@ void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsi cout << "pMiniBuffer->full() && (abs(pMiniBuffer->mean()) > 50): " << pMiniBuffer->median() << "\n"; sleep = pMiniBuffer->mean(); } + else if (abs(age) > 50) + { + cout << "age > 50): " << age << "\n"; + sleep = age; + } } if (sleep != 0) diff --git a/client/stream.h b/client/stream.h index d67eb6ed..ced7ff5b 100644 --- a/client/stream.h +++ b/client/stream.h @@ -27,6 +27,7 @@ public: private: time_point_ms getNextPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer, int correction = 0); time_point_ms getSilentPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer); + time_point_ms seek(unsigned long ms); void updateBuffers(int age); void resetBuffers(); diff --git a/common/chunk.cpp b/common/chunk.cpp index de31c13d..b092cc3e 100644 --- a/common/chunk.cpp +++ b/common/chunk.cpp @@ -27,18 +27,33 @@ Chunk::~Chunk() bool Chunk::isEndOfChunk() const { - return idx >= (wireChunk->length / format.frameSize); + return idx >= getFrameCount(); +} + + +double Chunk::getFrameCount() const +{ + return (wireChunk->length / format.frameSize); } double Chunk::getDuration() const { -// std::cout << wireChunk->length << "\t" << format.frameSize << "\t" << (wireChunk->length / format.frameSize) << "\t" << ((double)format.rate / 1000.) << "\n"; - return (wireChunk->length / format.frameSize) / ((double)format.rate / 1000.); + return getFrameCount() / format.msRate(); } +int Chunk::seek(int frames) +{ + idx += frames; + if (idx > getFrameCount()) + idx = getFrameCount(); + if (idx < 0) + idx = 0; + return idx; +} + int Chunk::read(void* outputBuffer, size_t frameCount) { diff --git a/common/chunk.h b/common/chunk.h index 28f727c2..f487c49d 100644 --- a/common/chunk.h +++ b/common/chunk.h @@ -67,7 +67,9 @@ public: return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - time_point); } + int seek(int frames); double getDuration() const; + double getFrameCount() const; WireChunk* wireChunk; SampleFormat format;