common: cleanup

This commit is contained in:
sinamas 2013-04-21 15:20:45 +02:00
parent 3557a37c9d
commit 7a0cf00a3c
17 changed files with 173 additions and 195 deletions

View File

@ -23,31 +23,26 @@ static usec_t absdiff(usec_t a, usec_t b) { return a < b ? b - a : a - b; }
usec_t AdaptiveSleep::sleepUntil(usec_t base, usec_t inc) {
usec_t now = getusecs();
usec_t diff = now - base;
if (diff >= inc)
return diff - inc;
diff = inc - diff;
if (diff > oversleep + oversleepVar) {
diff -= oversleep + oversleepVar;
if (diff > oversleep_ + oversleepVar_) {
diff -= oversleep_ + oversleepVar_;
usecsleep(diff);
const usec_t ideal = now + diff;
usec_t const sleepTarget = now + diff;
now = getusecs();
{
usec_t curOversleep = now - ideal;
if (negate(curOversleep) < curOversleep)
curOversleep = 0;
usec_t curOversleep = now - sleepTarget;
if (curOversleep > usec_t(-1) / 2)
curOversleep = 0;
oversleepVar = (oversleepVar * 15 + absdiff(curOversleep, oversleep) + 8) >> 4;
oversleep = (oversleep * 15 + curOversleep + 8) >> 4;
}
noSleep = 60;
} else if (--noSleep == 0) {
noSleep = 60;
oversleep = oversleepVar = 0;
oversleepVar_ = (oversleepVar_ * 15 + absdiff(curOversleep, oversleep_) + 8) >> 4;
oversleep_ = (oversleep_ * 15 + curOversleep + 8) >> 4;
noSleep_ = 60;
} else if (--noSleep_ == 0) {
noSleep_ = 60;
oversleep_ = oversleepVar_ = 0;
}
while (now - base < inc)

View File

@ -22,13 +22,14 @@
#include "usec.h"
class AdaptiveSleep {
usec_t oversleep;
usec_t oversleepVar;
unsigned noSleep;
public:
AdaptiveSleep() : oversleep(0), oversleepVar(0), noSleep(60) {}
AdaptiveSleep() : oversleep_(0), oversleepVar_(0), noSleep_(60) {}
usec_t sleepUntil(usec_t base, usec_t inc);
private:
usec_t oversleep_;
usec_t oversleepVar_;
unsigned noSleep_;
};
#endif

View File

@ -24,30 +24,30 @@
#include <cstddef>
template<typename T>
class Array : Uncopyable {
T *a;
std::size_t sz;
class SimpleArray : Uncopyable {
public:
explicit Array(std::size_t size = 0) : a(size ? new T[size] : 0), sz(size) {}
~Array() { delete[] defined_ptr(a); }
void reset(std::size_t size = 0) { delete[] defined_ptr(a); a = size ? new T[size] : 0; sz = size; }
std::size_t size() const { return sz; }
T * get() const { return a; }
operator T*() const { return a; }
explicit SimpleArray(std::size_t size = 0) : a_(size ? new T[size] : 0) {}
~SimpleArray() { delete[] defined_ptr(a_); }
void reset(std::size_t size = 0) { delete[] defined_ptr(a_); a_ = size ? new T[size] : 0; }
T * get() const { return a_; }
operator T *() const { return a_; }
private:
T *a_;
};
template<typename T>
class ScopedArray : Uncopyable {
T *a_;
class Array {
public:
explicit ScopedArray(T *a = 0) : a_(a) {}
~ScopedArray() { delete[] defined_ptr(a_); }
void reset(T *a = 0) { delete[] defined_ptr(a_); a_ = a; }
T * release() { T *a = a_; a_ = 0; return a; }
explicit Array(std::size_t size = 0) : a_(size), size_(size) {}
void reset(std::size_t size = 0) { a_.reset(size); size_ = size; }
std::size_t size() const { return size_; }
T * get() const { return a_; }
operator T*() const { return a_; }
operator T *() const { return a_; }
private:
SimpleArray<T> a_;
std::size_t size_;
};
#endif

View File

@ -19,29 +19,24 @@
#include "rateest.h"
#include <cstdlib>
void RateEst::SumQueue::reset() {
q.clear();
samples_ = usecs_ = 0;
}
void RateEst::SumQueue::push(const long samples, const usec_t usecs) {
q.push_back(pair_t(samples, usecs));
void RateEst::SumQueue::push(std::ptrdiff_t const samples, usec_t const usecs) {
q_.push_back(std::make_pair(samples, usecs));
samples_ += samples;
usecs_ += usecs;
}
void RateEst::SumQueue::pop() {
const pair_t &f = q.front();
std::pair<std::ptrdiff_t, usec_t> const &f = q_.front();
samples_ -= f.first;
usecs_ -= f.second;
q.pop_front();
q_.pop_front();
}
static usec_t sampleUsecs(long samples, long rate) {
static usec_t sampleUsecs(std::ptrdiff_t samples, long rate) {
return usec_t((samples * 1000000.0f) / (rate ? rate : 1) + 0.5f);
}
static long limit(long est, const long reference) {
static long limit(long est, long const reference) {
if (est > reference + (reference >> 6))
est = reference + (reference >> 6);
else if (est < reference - (reference >> 6))
@ -50,45 +45,44 @@ static long limit(long est, const long reference) {
return est;
}
void RateEst::init(long srate, long reference, const long maxSamplePeriod) {
maxPeriod = sampleUsecs(maxSamplePeriod, reference);
enum { mean_scale = 1 << 5 };
srate <<= UPSHIFT;
reference <<= UPSHIFT;
this->srate = limit(srate, reference);
last = 0;
this->reference = reference;
samples = (this->srate >> UPSHIFT) * 12 << 5;
usecs = 12000000 << 5;
sumq.reset();
RateEst::RateEst(long const nominalSampleRate, std::size_t const maxValidFeedPeriodSamples)
: srate_(nominalSampleRate * est_scale)
, reference_(srate_)
, maxPeriod_(sampleUsecs(maxValidFeedPeriodSamples, nominalSampleRate))
, last_(0)
, usecs_(12000000 * mean_scale)
, samples_(nominalSampleRate * 12 * mean_scale)
{
}
void RateEst::feed(long samplesIn, const usec_t now) {
usec_t usecsIn = now - last;
void RateEst::feed(std::ptrdiff_t samplesIn, usec_t const now) {
usec_t usecsIn = now - last_;
if (last && usecsIn < maxPeriod) {
sumq.push(samplesIn, usecsIn);
if (last_ && usecsIn < maxPeriod_) {
sumq_.push(samplesIn, usecsIn);
while ((usecsIn = sumq.usecs()) > 100000) {
samplesIn = sumq.samples();
sumq.pop();
while ((usecsIn = sumq_.usecs()) > 100000) {
samplesIn = sumq_.samples();
sumq_.pop();
if (std::abs(long(samplesIn * (1000000.0f * UP) / usecsIn) - reference) < reference >> 1) {
samples += (samplesIn - sumq.samples()) << 5;
usecs += ( usecsIn - sumq.usecs() ) << 5;
long const srateIn = long(samplesIn * (1000000.0f * est_scale) / usecsIn);
if (std::abs(srateIn - reference_) < reference_ >> 1) {
samples_ += (samplesIn - sumq_.samples()) * mean_scale;
usecs_ += ( usecsIn - sumq_.usecs() ) * mean_scale;
long est = long(samples * (1000000.0f * UP) / usecs + 0.5f);
est = limit((srate * 31 + est + 16) >> 5, reference);
srate = est;
long est = long(samples_ * (1000000.0f * est_scale) / usecs_ + 0.5f);
est = limit((srate_ * 31 + est + 16) >> 5, reference_);
srate_ = est;
if (usecs > 16000000 << 5) {
samples = (samples * 3 + 2) >> 2;
usecs = (usecs * 3 + 2) >> 2;
if (usecs_ > 16000000 * mean_scale) {
samples_ = (samples_ * 3 + 2) >> 2;
usecs_ = (usecs_ * 3 + 2) >> 2;
}
}
}
}
last = now;
last_ = now;
}

View File

@ -20,47 +20,43 @@
#define RATEEST_H
#include "usec.h"
#include <cstddef>
#include <deque>
#include <utility>
class RateEst {
public:
RateEst() { *this = RateEst(0, 0); }
RateEst(long nominalSampleRate, std::size_t maxValidFeedPeriodSamples);
void resetLastFeedTimeStamp() { last_ = 0; }
void feed(std::ptrdiff_t samples, usec_t usecsNow = getusecs());
long result() const { return (srate_ + est_scale / 2) >> est_lshift; }
private:
class SumQueue {
typedef std::pair<long, usec_t> pair_t;
typedef std::deque<pair_t> q_t;
q_t q;
long samples_;
usec_t usecs_;
public:
SumQueue() : samples_(0), usecs_(0) {}
void reset();
long samples() const { return samples_; }
std::ptrdiff_t samples() const { return samples_; }
usec_t usecs() const { return usecs_; }
void push(long samples, usec_t usecs);
void push(std::ptrdiff_t samples, usec_t usecs);
void pop();
private:
std::deque< std::pair<std::ptrdiff_t, usec_t> > q_;
std::ptrdiff_t samples_;
usec_t usecs_;
};
enum { UPSHIFT = 5 };
enum { UP = 1 << UPSHIFT };
enum { est_lshift = 5 };
enum { est_scale = 1 << est_lshift };
long srate;
SumQueue sumq;
usec_t last;
usec_t usecs;
usec_t maxPeriod;
long reference;
long samples;
public:
explicit RateEst(long srate = 0) { init(srate); }
RateEst(long srate, long reference) { init(srate, reference); }
void init(long srate) { init(srate, srate); }
void init(long srate, long reference) { init(srate, reference, reference); }
void init(long srate, long reference, long maxSamplePeriod);
void reset() { last = 0; }
void feed(long samples, usec_t usecs = getusecs());
long result() const { return (srate + UP / 2) >> UPSHIFT; }
SumQueue sumq_;
long srate_;
long reference_;
usec_t maxPeriod_;
usec_t last_;
usec_t usecs_;
std::ptrdiff_t samples_;
};
#endif

View File

@ -20,93 +20,90 @@
#define RINGBUFFER_H
#include "array.h"
#include <cstddef>
#include <algorithm>
#include <cstddef>
#include <cstring>
template<typename T>
class RingBuffer {
Array<T> buf;
std::size_t sz;
std::size_t rpos;
std::size_t wpos;
public:
explicit RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); }
std::size_t avail() const {
return (wpos < rpos ? 0 : sz) + rpos - wpos - 1;
explicit RingBuffer(std::size_t size = 0)
: endpos_(0), rpos_(0), wpos_(0)
{
reset(size);
}
void reset(std::size_t size);
void clear() {
wpos = rpos = 0;
wpos_ = rpos_ = 0;
}
void fill(T value);
void read(T *out, std::size_t num);
void write(T const *in, std::size_t num);
void reset(std::size_t sz_in);
std::size_t size() const {
return sz - 1;
std::size_t avail() const {
return (wpos_ < rpos_ ? 0 : endpos_) + rpos_ - wpos_ - 1;
}
std::size_t used() const {
return (wpos < rpos ? sz : 0) + wpos - rpos;
return (wpos_ < rpos_ ? endpos_ : 0) + wpos_ - rpos_;
}
void write(const T *in, std::size_t num);
std::size_t size() const {
return endpos_ - 1;
}
private:
Array<T> buf_;
std::size_t endpos_;
std::size_t rpos_;
std::size_t wpos_;
};
template<typename T>
void RingBuffer<T>::fill(const T value) {
std::fill(buf.get(), buf.get() + buf.size(), value);
rpos = 0;
wpos = sz - 1;
void RingBuffer<T>::reset(std::size_t size) {
endpos_ = size + 1;
rpos_ = wpos_ = 0;
buf_.reset(size ? endpos_ : 0);
}
template<typename T>
void RingBuffer<T>::fill(T value) {
std::fill(buf_.get(), buf_.get() + buf_.size(), value);
rpos_ = 0;
wpos_ = endpos_ - 1;
}
template<typename T>
void RingBuffer<T>::read(T *out, std::size_t num) {
if (rpos + num > sz) {
const std::size_t n = sz - rpos;
std::memcpy(out, buf + rpos, n * sizeof *out);
rpos = 0;
if (rpos_ + num > endpos_) {
std::size_t const n = endpos_ - rpos_;
std::memcpy(out, buf_ + rpos_, n * sizeof *out);
rpos_ = 0;
num -= n;
out += n;
}
std::memcpy(out, buf + rpos, num * sizeof *out);
if ((rpos += num) == sz)
rpos = 0;
std::memcpy(out, buf_ + rpos_, num * sizeof *out);
if ((rpos_ += num) == endpos_)
rpos_ = 0;
}
template<typename T>
void RingBuffer<T>::reset(const std::size_t sz_in) {
sz = sz_in + 1;
rpos = wpos = 0;
buf.reset(sz_in ? sz : 0);
}
template<typename T>
void RingBuffer<T>::write(const T *in, std::size_t num) {
if (wpos + num > sz) {
const std::size_t n = sz - wpos;
std::memcpy(buf + wpos, in, n * sizeof *buf);
wpos = 0;
void RingBuffer<T>::write(T const *in, std::size_t num) {
if (wpos_ + num > endpos_) {
std::size_t const n = endpos_ - wpos_;
std::memcpy(buf_ + wpos_, in, n * sizeof *buf_);
wpos_ = 0;
num -= n;
in += n;
}
std::memcpy(buf + wpos, in, num * sizeof *buf);
if ((wpos += num) == sz)
wpos = 0;
std::memcpy(buf_ + wpos_, in, num * sizeof *buf_);
if ((wpos_ += num) == endpos_)
wpos_ = 0;
}
#endif

14
common/skipsched.cpp Executable file → Normal file
View File

@ -19,17 +19,17 @@
#include "skipsched.h"
bool SkipSched::skipNext(bool skip) {
if (skipped) {
if (skipped < skippedmax / 2)
if (skipped_) {
if (skipped_ < skippedmax_ / 2)
skip = true;
else
skipped = skip = 0;
skipped_ = skip = 0;
} else if (skip) {
skippedmax += skippedmax / 2 < 8;
} else if (skippedmax / 2)
--skippedmax;
skippedmax_ += skippedmax_ / 2 < 8;
} else if (skippedmax_ / 2)
--skippedmax_;
skipped += skip;
skipped_ += skip;
return skip;
}

15
common/skipsched.h Executable file → Normal file
View File

@ -20,18 +20,13 @@
#define SKIPSCHED_H
class SkipSched {
unsigned skipped;
unsigned skippedmax;
public:
SkipSched() { reset(); }
void reset() {
skipped = 0;
skippedmax = 2 - 1;
}
SkipSched() : skipped_(0), skippedmax_(2 - 1) {}
bool skipNext(bool wantskip);
private:
unsigned skipped_;
unsigned skippedmax_;
};
#endif

View File

@ -14,7 +14,7 @@ public:
~transfer_ptr() { Deleter::del(p_); }
T * get() const { return p_; }
T * release() { T *p = p_; p_ = 0; return p; }
operator const released() { return released(release()); }
operator released const () { return released(release()); }
T & operator*() const { return *p_; }
T * operator->() const { return p_; }
operator bool() const { return p_; }

7
common/uncopyable.h Executable file → Normal file
View File

@ -20,10 +20,11 @@
#define UNCOPYABLE_H
class Uncopyable {
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
public:
protected:
Uncopyable() {}
private:
Uncopyable(Uncopyable const &);
Uncopyable& operator=(Uncopyable const &);
};
#endif

View File

@ -21,7 +21,6 @@
typedef unsigned long usec_t;
inline usec_t negate(usec_t t) { return -t; }
usec_t getusecs();
void usecsleep(usec_t usecs);

View File

@ -58,7 +58,7 @@ public:
virtual long rateEstimate() const { return est_.result(); }
virtual BufferState bufferState() const;
virtual void pause() { prevfur_ = 0; est_.reset(); }
virtual void pause() { prevfur_ = 0; est_.resetLastFeedTimeStamp(); }
virtual bool flushPausedBuffers() const { return true; }
virtual QWidget * settingsWidget() const { return conf_.settingsWidget(); }
virtual void rejectSettings() const { conf_.rejectSettings(); }
@ -161,7 +161,7 @@ long AlsaEngine::doInit(long const inrate, int const latency) {
}
prevfur_ = 0;
est_.init(rate, rate, bufSize_);
est_ = RateEst(rate, bufSize_);
pcm_ = pcm;
return rate;
}
@ -184,7 +184,7 @@ int AlsaEngine::write(void *const buffer, snd_pcm_uframes_t const samples, Buffe
}
if (underrun)
est_.reset();
est_.resetLastFeedTimeStamp();
return 0;
}

View File

@ -193,7 +193,7 @@ long DirectSoundEngine::doInit(long const rate, int const latency) {
offset += 1;
blankBuf = true;
est.init(rate, rate, bufSize >> 2);
est = RateEst(rate, bufSize >> 2);
return rate;
}
@ -304,7 +304,7 @@ int DirectSoundEngine::doWrite(
blankBuf = !frames;
}
est.reset();
est.resetLastFeedTimeStamp();
} else {
est.feed(((pc >= lastpc ? pc : bufSize + pc) - lastpc) >> 2);
}

View File

@ -79,7 +79,7 @@ public:
virtual long rateEstimate() const { return est_.result(); }
virtual BufferState bufferState() const;
virtual void pause() { prevbytes_ = 0; est_.reset(); }
virtual void pause() { prevbytes_ = 0; est_.resetLastFeedTimeStamp(); }
virtual bool flushPausedBuffers() const { return true; }
virtual QWidget * settingsWidget() const { return conf_.settingsWidget(); }
virtual void rejectSettings() const { conf_.rejectSettings(); }
@ -157,7 +157,7 @@ long OssEngine::doInit(long rate, int const latency) {
}
prevbytes_ = 0;
est_.init(rate, rate, bufSize_);
est_ = RateEst(rate, bufSize_);
return rate;
}
@ -169,7 +169,7 @@ int OssEngine::write(void *const buffer, std::size_t const samples, BufferState
if (bstate.fromUnderrun > fragSize_)
est_.feed((ci.bytes - prevbytes_) >> 2);
else
est_.reset();
est_.resetLastFeedTimeStamp();
}
prevbytes_ = ci.bytes;

View File

@ -315,7 +315,7 @@ long WasapiEngine::doInit(long rate, int const latency) {
}
pos_ = 0;
est.init(rate, rate, bufferFrameCount);
est = RateEst(rate, bufferFrameCount);
return rate;
}
@ -382,7 +382,7 @@ int WasapiEngine::write(void *buffer, std::size_t frames, UINT32 numFramesPaddin
est.feed((static_cast<UINT32>(pos) - pos_) / posFrames,
qpcpos / 10);
} else
est.reset();
est.resetLastFeedTimeStamp();
}
pos_ = pos;

View File

@ -63,8 +63,8 @@ void linearScale(T *dst, std::ptrdiff_t const dstPitch, int const outWidth, int
if (inWidth <= 0 || inHeight <= 0)
return;
ScopedArray<T> const sums(new T[inWidth + 1]);
ScopedArray<unsigned char> const hcoeffs(new unsigned char[outWidth - 1]);
SimpleArray<T> const sums(inWidth + 1);
SimpleArray<unsigned char> const hcoeffs(outWidth - 1);
{
int hppos = (outWidth + inWidth) >> 1;
@ -193,8 +193,8 @@ void semiLinearScale(
if (inWidth <= 0 || inHeight <= 0)
return;
ScopedArray<T> const sums(new T[inWidth]);
ScopedArray<unsigned char> const hcoeffs(new unsigned char[inWidth]);
SimpleArray<T> const sums(inWidth);
SimpleArray<unsigned char> const hcoeffs(inWidth);
{
int hppos = inWidth;

View File

@ -75,7 +75,7 @@ struct AudioSink::SdlDeleter {
AudioSink::AudioSink(unsigned const srate, unsigned const latency, unsigned const periods)
: rbuf_(nearestPowerOf2(srate * latency / ((periods + 1) * 1000)) * periods * 2)
, rateEst_(srate)
, rateEst_(srate, rbuf_.size() / periods)
, mut_(SDL_CreateMutex())
, bufReadyCond_(SDL_CreateCond())
, failed_(openAudio(srate, rbuf_.size() / 2 / periods, fillBuffer, this) < 0)