git-svn-id: svn://elaine/murooma/trunk@209 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
(no author) 2014-08-24 18:40:27 +00:00
parent 10323c0485
commit 559baf31e3
6 changed files with 79 additions and 28 deletions

View file

@ -22,6 +22,9 @@ void Player::start()
rate = stream_->format.rate; rate = stream_->format.rate;
channels = stream_->format.channels; channels = stream_->format.channels;
unsigned int buffer_time = 100 * 1000;
unsigned int period_time = buffer_time / 8;
/* Open the PCM device in playback mode */ /* Open the PCM device in playback mode */
if ((pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) 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) 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"; cout << "ERROR: Can't set rate. " << snd_strerror(pcm) << "\n";
long unsigned int periodsize = 2*rate/50; snd_pcm_hw_params_set_period_time_near(pcm_handle, params, &period_time, 0);
if ((pcm = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, params, &periodsize)) < 0) snd_pcm_hw_params_set_buffer_time_near(pcm_handle, params, &buffer_time, 0);
cout << "Unable to set buffer size " << (long int)periodsize << ": " << snd_strerror(pcm) << "\n";
// 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 */ /* Write parameters */
if ((pcm = snd_pcm_hw_params(pcm_handle, params)) < 0) if ((pcm = snd_pcm_hw_params(pcm_handle, params)) < 0)

View file

@ -6,13 +6,6 @@
// Olivier Chamoux <olivier.chamoux@fr.thalesgroup.com> // Olivier Chamoux <olivier.chamoux@fr.thalesgroup.com>
// //
#include <iostream> #include <iostream>
#include <sstream>
#include <sys/time.h>
#include <unistd.h>
#include <deque>
#include <vector>
#include <algorithm>
#include <thread>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>

View file

@ -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) 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) 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"; //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"; //cout << msBuffer << " ms, " << framesPerBuffer << "\t" << format_.rate/1000 << "\n";
int ticks = 0; int ticks = 0;
long currentTick = getTickCount(); long currentTick = getTickCount();
@ -136,28 +150,43 @@ void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsi
if (sleep != 0) if (sleep != 0)
{ {
resetBuffers(); resetBuffers();
if (sleep < -10) if (sleep < -msBuffer/2)
{ {
cout << "Sleep " << sleep;
sleep = Chunk::getAge(getSilentPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime; 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; // std::clog << kLogNotice << "sleep: " << sleep << std::endl;
// if (sleep > -msBuffer/2) // if (sleep > -msBuffer/2)
// sleep = 0; // 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; // std::clog << kLogNotice << "sleep: " << sleep << std::endl;
while (true) // while (true)
{ // {
sleep = Chunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime; // if (!chunk)
usleep(100); // chunk = chunks.pop();
// std::clog << kLogNotice << "age: " << age << std::endl; /* while (chunk->getAge() - bufferMs + outputBufferDacTime > chunk->getDuration())
if (sleep < 0) {
break; 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; // sleep = 0;
return; // return;
} }
else if (sleep < 0) else if (sleep < 0)
{ {
@ -179,7 +208,7 @@ void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsi
// if (pCardBuffer->full()) // if (pCardBuffer->full())
// age += 4*cardBuffer; // 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) 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"; cout << "pMiniBuffer->full() && (abs(pMiniBuffer->mean()) > 50): " << pMiniBuffer->median() << "\n";
sleep = pMiniBuffer->mean(); sleep = pMiniBuffer->mean();
} }
else if (abs(age) > 50)
{
cout << "age > 50): " << age << "\n";
sleep = age;
}
} }
if (sleep != 0) if (sleep != 0)

View file

@ -27,6 +27,7 @@ public:
private: private:
time_point_ms getNextPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer, int correction = 0); time_point_ms getNextPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer, int correction = 0);
time_point_ms getSilentPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer); time_point_ms getSilentPlayerChunk(void* outputBuffer, unsigned long framesPerBuffer);
time_point_ms seek(unsigned long ms);
void updateBuffers(int age); void updateBuffers(int age);
void resetBuffers(); void resetBuffers();

View file

@ -27,18 +27,33 @@ Chunk::~Chunk()
bool Chunk::isEndOfChunk() const 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 double Chunk::getDuration() const
{ {
// std::cout << wireChunk->length << "\t" << format.frameSize << "\t" << (wireChunk->length / format.frameSize) << "\t" << ((double)format.rate / 1000.) << "\n"; return getFrameCount() / format.msRate();
return (wireChunk->length / format.frameSize) / ((double)format.rate / 1000.);
} }
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) int Chunk::read(void* outputBuffer, size_t frameCount)
{ {

View file

@ -67,7 +67,9 @@ public:
return std::chrono::duration_cast<T>(std::chrono::high_resolution_clock::now() - time_point); return std::chrono::duration_cast<T>(std::chrono::high_resolution_clock::now() - time_point);
} }
int seek(int frames);
double getDuration() const; double getDuration() const;
double getFrameCount() const;
WireChunk* wireChunk; WireChunk* wireChunk;
SampleFormat format; SampleFormat format;