trailing whitespace

This commit is contained in:
sinamas 2013-02-20 20:02:06 +01:00
parent 379ef56791
commit 1a4b00bfb6
2215 changed files with 44685 additions and 44685 deletions

View File

@ -21,36 +21,36 @@
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;
usecsleep(diff);
const usec_t ideal = now + diff;
now = getusecs();
{
usec_t curOversleep = now - ideal;
if (negate(curOversleep) < curOversleep)
curOversleep = 0;
oversleepVar = (oversleepVar * 15 + (curOversleep < oversleep ? oversleep - curOversleep : 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)
now = getusecs();
return 0;
}

View File

@ -25,7 +25,7 @@ class AdaptiveSleep {
usec_t oversleep;
usec_t oversleepVar;
unsigned noSleep;
public:
AdaptiveSleep() : oversleep(0), oversleepVar(0), noSleep(60) {}
usec_t sleepUntil(usec_t base, usec_t inc);

View File

@ -27,7 +27,7 @@ template<typename T>
class Array : Uncopyable {
T *a;
std::size_t sz;
public:
explicit Array(std::size_t size = 0) : a(size ? new T[size] : 0), sz(size) {}
~Array() { delete[] defined_ptr(a); }
@ -40,7 +40,7 @@ public:
template<typename T>
class ScopedArray : Uncopyable {
T *a_;
public:
explicit ScopedArray(T *a = 0) : a_(a) {}
~ScopedArray() { delete[] defined_ptr(a_); }

View File

@ -25,18 +25,18 @@
class Resampler {
long inRate_;
long outRate_;
protected:
void setRate(const long inRate, const long outRate) { inRate_ = inRate; outRate_ = outRate; }
Resampler() : inRate_(0), outRate_(0) {}
public:
/** Returns the sampling rate of the input that this resampler expects. */
long inRate() const { return inRate_; }
/** Returns the approximate sampling rate of the output. */
long outRate() const { return outRate_; }
/** Can be used to adjust the input and output sampling rates slightly with minimal disturbance in the output.
* Should only be used for slight changes or the quality could detoriate.
* It can for instance be useful to tweak the output rate slightly to synchronize production speed to playback
@ -47,7 +47,7 @@ public:
* @param outRate Desired new output sampling rate.
*/
virtual void adjustRate(long inRate, long outRate) = 0;
/** Returns the exact ratio that this resampler is configured to use,
* such that the actual output sampling rate is (input rate) * mul / div.
* outRate() / inRate() is not necessarily equal to mul / div.
@ -55,12 +55,12 @@ public:
* much whether the output sampling rate is 100% exact. Playback hardware is also slightly off.
*/
virtual void exactRatio(unsigned long &mul, unsigned long &div) const = 0;
/** Returns an upper bound on how many samples are produced for 'inlen' input samples.
* Can be used to calculate buffer sizes.
*/
virtual std::size_t maxOut(std::size_t inlen) const = 0;
/** Resamples the samples in 'in' and puts the resulting samples in 'out'.
*
* @param inlen The number of samples in 'in' to be resampled/consumed.

View File

@ -29,7 +29,7 @@
struct ResamplerInfo {
/** Short character string description of the resampler. */
const char *desc;
/** Points to a function that can be used to create an instance of the resampler.
* @param inRate The input sampling rate.
* @param outRate The desired output sampling rate.
@ -37,13 +37,13 @@ struct ResamplerInfo {
* @return Pointer to the created instance (on the heap). Caller must free this with the delete operator.
*/
Resampler* (*create)(long inRate, long outRate, std::size_t periodSz);
/** Returns the number of ResamplerInfos that can be gotten with get(). */
static std::size_t num() { return num_; }
/** Returns ResamplerInfo number n. Where n is less than num(). */
static const ResamplerInfo& get(std::size_t n) { return resamplers[n]; }
private:
static const ResamplerInfo resamplers[];
static const std::size_t num_;

View File

@ -48,27 +48,27 @@ public:
const float widthTimesTaps = 4.5f;
return std::max(static_cast<unsigned>(std::ceil(widthTimesTaps / rollOffWidth)), 4u);
}
static float toFc(const float rollOffStart, const int taps) {
const float startToFcDeltaTimesTaps = 1.69f;
return startToFcDeltaTimesTaps / taps + rollOffStart;
}
public:
const unsigned taps;
const float fc;
RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {}
};
BlackmanSinc(unsigned div, unsigned phaseLen, double fc)
: kernel(phaseLen * phases), convoluter_(kernel, phaseLen, div)
{ makeSincKernel(kernel, phases, phaseLen, fc, blackmanWin, 1.0); }
BlackmanSinc(unsigned div, RollOff ro, double gain)
: kernel(ro.taps * phases), convoluter_(kernel, ro.taps, div)
{ makeSincKernel(kernel, phases, ro.taps, ro.fc, blackmanWin, gain);}
std::size_t resample(short *out, const short *in, std::size_t inlen) { return convoluter_.filter(out, in, inlen); }
void adjustDiv(unsigned div) { convoluters_.adjustDiv(div); }
unsigned mul() const { return MUL; }

View File

@ -63,17 +63,17 @@ void ChainResampler::downinitAddSincResamplers(double ratio, float const outRate
// For high outRate: Start roll-off at 36000 Hz continue until outRate Hz, then wrap around back down to 40000 Hz.
const float outPeriod = 1.0f / outRate;
const float finalRollOffLen = std::max((outRate - 36000.0f + outRate - 40000.0f) * outPeriod, 0.2f);
{
const float midRollOffStart = std::min(36000.0f * outPeriod, 1.0f);
const float midRollOffEnd = std::min(40000.0f * outPeriod, 1.0f); // after wrap at folding freq.
const float midRollOffStartPlusEnd = midRollOffStart + midRollOffEnd;
const float ideal2ChainMidRatio = get2ChainMidRatio(ratio, finalRollOffLen, midRollOffStartPlusEnd);
int div_2c = int(ratio * smallSincMul / ideal2ChainMidRatio + 0.5f);
double ratio_2c = ratio * smallSincMul / div_2c;
float cost_2c = get2ChainCost(ratio, finalRollOffLen, ratio_2c, midRollOffStartPlusEnd);
if (cost_2c < get1ChainCost(ratio, finalRollOffLen)) {
const float ideal3ChainRatio1 = get3ChainRatio1(ratio_2c, finalRollOffLen,
ratio, midRollOffStartPlusEnd);
@ -83,7 +83,7 @@ void ChainResampler::downinitAddSincResamplers(double ratio, float const outRate
midRollOffStartPlusEnd);
const int div2_3c = int(ratio1_3c * smallSincMul / ideal3ChainRatio2 + 0.5f);
const double ratio2_3c = ratio1_3c * smallSincMul / div2_3c;
if (get3ChainCost(ratio, finalRollOffLen, ratio1_3c,
ratio2_3c, midRollOffStartPlusEnd) < cost_2c) {
list.push_back(createSmallSinc(div1_3c,
@ -95,7 +95,7 @@ void ChainResampler::downinitAddSincResamplers(double ratio, float const outRate
ratio_2c = ratio2_3c;
gain = 1.0;
}
list.push_back(createSmallSinc(div_2c,
0.5f * midRollOffStart / ratio,
(ratio_2c - 0.5f * midRollOffStartPlusEnd) / ratio,
@ -104,7 +104,7 @@ void ChainResampler::downinitAddSincResamplers(double ratio, float const outRate
gain = 1.0;
}
}
list.push_back(bigSinc =
createBigSinc(int(bigSincMul * ratio + 0.5),
0.5f * (1.0f + std::max((outRate - 40000.0f) * outPeriod, 0.0f) - finalRollOffLen) / ratio,
@ -115,24 +115,24 @@ std::size_t ChainResampler::reallocateBuffer() {
std::size_t bufSz[2] = { 0, 0 };
std::size_t inSz = periodSize;
int i = -1;
for (list_t::iterator it = list.begin(); it != list.end(); ++it) {
inSz = (inSz * (*it)->mul() - 1) / (*it)->div() + 1;
++i;
if (inSz > bufSz[i&1])
bufSz[i&1] = inSz;
}
if (inSz >= bufSz[i&1])
bufSz[i&1] = 0;
if (buffer.size() < (bufSz[0] + bufSz[1]) * channels)
buffer.reset((bufSz[0] + bufSz[1]) * channels);
buffer2 = bufSz[1] ? buffer + bufSz[0] * channels : 0;
return (maxOut_ = inSz);
}
@ -148,7 +148,7 @@ void ChainResampler::adjustRate(const long inRate, const long outRate) {
void ChainResampler::exactRatio(unsigned long &mul, unsigned long &div) const {
mul = 1;
div = 1;
for (list_t::const_iterator it = list.begin(); it != list.end(); ++it) {
mul *= (*it)->mul();
div *= (*it)->div();
@ -157,13 +157,13 @@ void ChainResampler::exactRatio(unsigned long &mul, unsigned long &div) const {
std::size_t ChainResampler::resample(short *const out, const short *const in, std::size_t inlen) {
assert(inlen <= periodSize);
short *const buf = buffer != buffer2 ? buffer : out;
short *const buf2 = buffer2 ? buffer2 : out;
const short *inbuf = in;
short *outbuf = 0;
for (list_t::iterator it = list.begin(); it != list.end(); ++it) {
outbuf = ++list_t::iterator(it) == list.end()
? out
@ -171,7 +171,7 @@ std::size_t ChainResampler::resample(short *const out, const short *const in, st
inlen = (*it)->resample(outbuf, inbuf, inlen);
inbuf = outbuf;
}
return inlen;
}

View File

@ -32,14 +32,14 @@
class ChainResampler : public Resampler {
typedef std::list<SubResampler*> list_t;
typedef SubResampler * (*CreateSinc)(unsigned div, float rollOffStart, float rollOffWidth, double gain);
list_t list;
SubResampler *bigSinc;
Array<short> buffer;
short *buffer2;
std::size_t periodSize;
std::size_t maxOut_;
static float get1ChainCost(float ratio, float finalRollOffLen) { return ratio / finalRollOffLen; }
static float get2ChainMidRatio(float ratio, float finalRollOffLen, float midRollOffStartPlusEnd);
@ -51,32 +51,32 @@ class ChainResampler : public Resampler {
static float get3ChainRatio1(float ratio1, float finalRollOffLen, float ratio, float midRollOffStartPlusEnd);
static float get3ChainCost(float ratio, float finalRollOffLen, float ratio1, float ratio2, float midRollOffStartPlusEnd);
void downinitAddSincResamplers(double ratio, float outRate,
CreateSinc createBigSinc, CreateSinc createSmallSinc,
unsigned bigSincMul, unsigned smallSincMul, double gain);
template<class Sinc>
static SubResampler * createSinc(unsigned div, float rollOffStart, float rollOffWidth, double gain) {
return new Sinc(div, typename Sinc::RollOff(rollOffStart, rollOffWidth), gain);
}
template<template<unsigned,unsigned> class Sinc>
std::size_t downinit(long inRate, long outRate, std::size_t periodSize);
template<template<unsigned,unsigned> class Sinc>
std::size_t upinit(long inRate, long outRate, std::size_t periodSize);
std::size_t reallocateBuffer();
public:
enum { channels = 2 };
ChainResampler();
~ChainResampler() { uninit(); }
void adjustRate(long inRate, long outRate);
void exactRatio(unsigned long &mul, unsigned long &div) const;
template<template<unsigned,unsigned> class Sinc>
std::size_t init(long inRate, long outRate, std::size_t periodSize);
std::size_t maxOut(std::size_t /*inlen*/) const { return maxOut_; }
@ -87,7 +87,7 @@ public:
template<template<unsigned,unsigned> class Sinc>
std::size_t ChainResampler::init(const long inRate, const long outRate, const std::size_t periodSize) {
setRate(inRate, outRate);
if (outRate > inRate)
return upinit<Sinc>(inRate, outRate, periodSize);
else
@ -98,23 +98,23 @@ template<template<unsigned,unsigned> class Sinc>
std::size_t ChainResampler::downinit(const long inRate, const long outRate, const std::size_t periodSize) {
typedef Sinc<channels,2048> BigSinc;
typedef Sinc<channels, 32> SmallSinc;
uninit();
this->periodSize = periodSize;
double ratio = static_cast<double>(inRate) / outRate;
double gain = 1.0;
while (ratio >= BigSinc::cicLimit() * 2) {
const int div = std::min<int>(static_cast<int>(ratio / BigSinc::cicLimit()), BigSinc::Cic::MAX_DIV);
list.push_back(new typename BigSinc::Cic(div));
ratio /= div;
gain *= 1.0 / BigSinc::Cic::gain(div);
}
downinitAddSincResamplers(ratio, outRate, createSinc<BigSinc>,
createSinc<SmallSinc>, BigSinc::MUL, SmallSinc::MUL, gain);
return reallocateBuffer();
}
@ -125,47 +125,47 @@ std::size_t ChainResampler::upinit(const long inRate, const long outRate, const
uninit();
this->periodSize = periodSize;
double ratio = static_cast<double>(outRate) / inRate;
// Spectral images above 20 kHz assumed inaudible
{
const int div = outRate / std::max(inRate, 40000l);
if (div >= 2) {
list.push_front(new Upsampler<channels>(div));
ratio /= div;
}
}
const float rollOff = std::max((inRate - 36000.0f) / inRate, 0.2f);
/*{
int div_2c = get2ChainMidRatio(ratio, rollOff) * SmallSinc::MUL / ratio + 0.5f;
double ratio_2c = ratio * div_2c / SmallSinc::MUL;
float cost_2c = get2ChainCost(ratio, rollOff, ratio_2c);
if (cost_2c < get1ChainCost(ratio, rollOff)) {
const int div1_3c = get3ChainRatio1(ratio_2c, rollOff, ratio) * SmallSinc::MUL / ratio + 0.5f;
const double ratio1_3c = ratio * div1_3c / SmallSinc::MUL;
const int div2_3c = get3ChainRatio2(ratio1_3c, rollOff) * SmallSinc::MUL / ratio1_3c + 0.5f;
const double ratio2_3c = ratio1_3c * div2_3c / SmallSinc::MUL;
if (get3ChainCost(ratio, rollOff, ratio1_3c, ratio2_3c) < cost_2c) {
list.push_front(new SmallSinc(div1_3c, typename SmallSinc::RollOff(0.5f / ratio1_3c, (ratio1_3c - 1) / ratio1_3c), 1.0));
ratio = ratio1_3c;
div_2c = div2_3c;
ratio_2c = ratio2_3c;
}
list.push_front(new SmallSinc(div_2c, typename SmallSinc::RollOff(0.5f / ratio_2c, (ratio_2c - 1) / ratio_2c), 1.0));
ratio = ratio_2c;
}
}*/
list.push_front(bigSinc = new BigSinc(static_cast<int>(BigSinc::MUL / ratio + 0.5),
typename BigSinc::RollOff(0.5f * (1 - rollOff), 0.5f * rollOff), 1.0));
return reallocateBuffer();
}

View File

@ -22,7 +22,7 @@
#include "subresampler.h"
#include "rshift16_round.h"
template<unsigned channels>
template<unsigned channels>
class Cic2Core {
// enum { BUFLEN = 64 };
// unsigned long buf[BUFLEN];
@ -33,10 +33,10 @@ class Cic2Core {
unsigned div_;
unsigned nextdivn;
// unsigned bufpos;
// trouble if div is too large, may be better to only support power of 2 div
static long mulForDiv(unsigned div) { return 0x10000 / (div * div); }
public:
explicit Cic2Core(const unsigned div = 2) { reset(div); }
unsigned div() const { return div_; }
@ -45,7 +45,7 @@ public:
static double gain(unsigned div) { return rshift16_round(-32768l * (div * div) * mulForDiv(div)) / -32768.0; }
};
template<unsigned channels>
template<unsigned channels>
void Cic2Core<channels>::reset(const unsigned div) {
sum2 = sum1 = 0;
/*prev2 = */prev1 = 0;
@ -60,15 +60,15 @@ std::size_t Cic2Core<channels>::filter(short *out, const short *const in, std::s
const std::size_t produced = (inlen + div_ - nextdivn) / div_;
const long mul = mulForDiv(div_);
const short *s = in;
/*unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
while (inlen >> 2) {
unsigned n = (inlen < BUFLEN ? inlen >> 2 : BUFLEN >> 2);
const unsigned end = n * 4;
unsigned i = 0;
do {
unsigned long s1 = sm1 += static_cast<long>(*s);
s += channels;
@ -83,74 +83,74 @@ std::size_t Cic2Core<channels>::filter(short *out, const short *const in, std::s
buf[i++] = sm2 += s1;
buf[i++] = sm2 += sm1;
} while (--n);
while (bufpos < end) {
const unsigned long out2 = buf[bufpos] - prev2;
prev2 = buf[bufpos];
bufpos += div_;
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
prev1 = out2;
out += channels;
}
bufpos -= end;
inlen -= end;
}
if (inlen) {
unsigned n = inlen;
unsigned i = 0;
do {
sm1 += static_cast<long>(*s);
s += channels;
buf[i++] = sm2 += sm1;
} while (--n);
while (bufpos < inlen) {
const unsigned long out2 = buf[bufpos] - prev2;
prev2 = buf[bufpos];
bufpos += div_;
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
prev1 = out2;
out += channels;
}
bufpos -= inlen;
}
sum1 = sm1;
sum2 = sm2;*/
unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
if (inlen >= nextdivn) {
{
unsigned divn = nextdivn;
do {
sm1 += static_cast<long>(*s);
s += channels;
sm2 += sm1;
} while (--divn);
const unsigned long out2 = sm2;
sm2 = 0;
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
prev1 = out2;
out += channels;
}
if (div_ & 1) {
std::size_t n = produced;
while (--n) {
unsigned divn = div_ >> 1;
do {
sm1 += static_cast<long>(*s);
s += channels;
@ -159,11 +159,11 @@ std::size_t Cic2Core<channels>::filter(short *out, const short *const in, std::s
s += channels;
sm2 += sm1;
} while (--divn);
sm1 += static_cast<long>(*s);
s += channels;
sm2 += sm1;
*out = rshift16_round(static_cast<long>(sm2 - prev1) * mul);
out += channels;
prev1 = sm2;
@ -171,10 +171,10 @@ std::size_t Cic2Core<channels>::filter(short *out, const short *const in, std::s
}
} else {
std::size_t n = produced;
while (--n) {
unsigned divn = div_ >> 1;
do {
sm1 += static_cast<long>(*s);
s += channels;
@ -183,38 +183,38 @@ std::size_t Cic2Core<channels>::filter(short *out, const short *const in, std::s
s += channels;
sm2 += sm1;
} while (--divn);
*out = rshift16_round(static_cast<long>(sm2 - prev1) * mul);
out += channels;
prev1 = sm2;
sm2 = 0;
}
}
nextdivn = div_;
}
{
unsigned divn = (in + inlen * channels - s) / channels;
nextdivn -= divn;
while (divn--) {
sm1 += static_cast<long>(*s);
s += channels;
sm2 += sm1;
}
}
sum1 = sm1;
sum2 = sm2;
return produced;
}
template<unsigned channels>
class Cic2 : public SubResampler {
Cic2Core<channels> cics[channels];
public:
enum { MAX_DIV = 64 };
explicit Cic2(unsigned div);
@ -233,11 +233,11 @@ Cic2<channels>::Cic2(const unsigned div) {
template<unsigned channels>
std::size_t Cic2<channels>::resample(short *const out, const short *const in, const std::size_t inlen) {
std::size_t samplesOut;
for (unsigned i = 0; i < channels; ++i) {
samplesOut = cics[i].filter(out + i, in + i, inlen);
}
return samplesOut;
}

View File

@ -22,7 +22,7 @@
#include "subresampler.h"
#include "rshift16_round.h"
template<unsigned channels>
template<unsigned channels>
class Cic3Core {
// enum { BUFLEN = 64 };
// unsigned long buf[BUFLEN];
@ -34,10 +34,10 @@ class Cic3Core {
unsigned div_;
unsigned nextdivn;
// unsigned bufpos;
// trouble if div is too large, may be better to only support power of 2 div
static long mulForDiv(unsigned div) { return 0x10000 / (div * div * div); }
public:
explicit Cic3Core(const unsigned div = 1) { reset(div); }
unsigned div() const { return div_; }
@ -46,7 +46,7 @@ public:
static double gain(unsigned div) { return rshift16_round(-32768l * (div * div * div) * mulForDiv(div)) / -32768.0; }
};
template<unsigned channels>
template<unsigned channels>
void Cic3Core<channels>::reset(const unsigned div) {
sum3 = sum2 = sum1 = 0;
prev2 = prev1 = 0;
@ -60,16 +60,16 @@ std::size_t Cic3Core<channels>::filter(short *out, const short *const in, std::s
// const std::size_t produced = (inlen + div_ - (bufpos + 1)) / div_;
const std::size_t produced = (inlen + div_ - nextdivn) / div_;
const short *s = in;
/*unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
unsigned long sm3 = sum3;
while (inlen >> 1) {
unsigned n = (inlen < BUFLEN ? inlen >> 1 : BUFLEN >> 1);
const unsigned end = n * 2;
unsigned i = 0;
do {
unsigned long s1 = sm1 += static_cast<long>(*s);
s += channels;
@ -80,65 +80,65 @@ std::size_t Cic3Core<channels>::filter(short *out, const short *const in, std::s
buf[i++] = sm3 += s2;
buf[i++] = sm3 += sm2;
} while (--n);
while (bufpos < end) {
const unsigned long out3 = buf[bufpos] - prev3;
prev3 = buf[bufpos];
bufpos += div_;
const unsigned long out2 = out3 - prev2;
prev2 = out3;
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
prev1 = out2;
out += channels;
}
bufpos -= end;
inlen -= end;
}
if (inlen) {
unsigned n = inlen;
unsigned i = 0;
do {
sm1 += static_cast<long>(*s);
s += channels;
sm2 += sm1;
buf[i++] = sm3 += sm2;
} while (--n);
while (bufpos < inlen) {
const unsigned long out3 = buf[bufpos] - prev3;
prev3 = buf[bufpos];
bufpos += div_;
const unsigned long out2 = out3 - prev2;
prev2 = out3;
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
prev1 = out2;
out += channels;
}
bufpos -= inlen;
}
sum1 = sm1;
sum2 = sm2;
sum3 = sm3;*/
unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
unsigned long sm3 = sum3;
if (inlen >= nextdivn) {
const long mul = mulForDiv(div_);
unsigned divn = nextdivn;
std::size_t n = produced;
do {
do {
sm1 += static_cast<long>(*s);
@ -146,7 +146,7 @@ std::size_t Cic3Core<channels>::filter(short *out, const short *const in, std::s
sm3 += sm2;
s += channels;
} while (--divn);
const unsigned long out2 = sm3 - prev2;
prev2 = sm3;
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
@ -155,14 +155,14 @@ std::size_t Cic3Core<channels>::filter(short *out, const short *const in, std::s
divn = div_;
sm3 = 0;
} while (--n);
nextdivn = div_;
}
{
unsigned divn = (in + inlen * channels - s) / channels;
nextdivn -= divn;
while (divn--) {
sm1 += static_cast<long>(*s);
sm2 += sm1;
@ -170,15 +170,15 @@ std::size_t Cic3Core<channels>::filter(short *out, const short *const in, std::s
s += channels;
}
}
sum1 = sm1;
sum2 = sm2;
sum3 = sm3;
return produced;
}
/*template<unsigned channels>
/*template<unsigned channels>
class Cic3EvenOddCore {
unsigned long sum1;
unsigned long sum2;
@ -188,25 +188,25 @@ class Cic3EvenOddCore {
unsigned long prev3;
unsigned div_;
unsigned nextdivn;
static int getMul(unsigned div) {
return 0x10000 / (div * div * div); // trouble if div is too large, may be better to only support power of 2 div
}
void filterEven(short *out, const short *s, std::size_t n);
void filterOdd(short *out, const short *s, std::size_t n);
public:
Cic3EvenOddCore(const unsigned div = 2) {
reset(div);
}
unsigned div() const { return div_; }
std::size_t filter(short *out, const short *in, std::size_t inlen);
void reset(unsigned div);
};
template<unsigned channels>
template<unsigned channels>
void Cic3EvenOddCore<channels>::reset(const unsigned div) {
sum3 = sum2 = sum1 = 0;
prev3 = prev2 = prev1 = 0;
@ -220,11 +220,11 @@ void Cic3EvenOddCore<channels>::filterEven(short *out, const short *s, std::size
unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
unsigned long sm3 = sum3;
while (n--) {
{
unsigned sn = div_ >> 1;
do {
unsigned long s1 = sm1 += static_cast<long>(*s);
s += channels;
@ -236,7 +236,7 @@ void Cic3EvenOddCore<channels>::filterEven(short *out, const short *s, std::size
sm3 += sm2;
} while (--sn);
}
const unsigned long out3 = sm3 - prev3;
prev3 = sm3;
const unsigned long out2 = out3 - prev2;
@ -245,7 +245,7 @@ void Cic3EvenOddCore<channels>::filterEven(short *out, const short *s, std::size
prev1 = out2;
out += channels;
}
sum1 = sm1;
sum2 = sm2;
sum3 = sm3;
@ -257,11 +257,11 @@ void Cic3EvenOddCore<channels>::filterOdd(short *out, const short *s, std::size_
unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
unsigned long sm3 = sum3;
while (n--) {
{
unsigned sn = div_ >> 1;
do {
unsigned long s1 = sm1 += static_cast<long>(*s);
s += channels;
@ -273,12 +273,12 @@ void Cic3EvenOddCore<channels>::filterOdd(short *out, const short *s, std::size_
sm3 += sm2;
} while (--sn);
}
sm1 += static_cast<long>(*s);
s += channels;
sm2 += sm1;
sm3 += sm2;
const unsigned long out3 = sm3 - prev3;
prev3 = sm3;
const unsigned long out2 = out3 - prev2;
@ -287,7 +287,7 @@ void Cic3EvenOddCore<channels>::filterOdd(short *out, const short *s, std::size_
prev1 = out2;
out += channels;
}
sum1 = sm1;
sum2 = sm2;
sum3 = sm3;
@ -297,12 +297,12 @@ template<unsigned channels>
std::size_t Cic3EvenOddCore<channels>::filter(short *out, const short *const in, std::size_t inlen) {
short *const outStart = out;
const short *s = in;
if (inlen >= nextdivn) {
{
{
unsigned divn = nextdivn;
do {
sum1 += static_cast<long>(*s);
s += channels;
@ -310,7 +310,7 @@ std::size_t Cic3EvenOddCore<channels>::filter(short *out, const short *const in,
sum3 += sum2;
} while (--divn);
}
const unsigned long out3 = sum3 - prev3;
prev3 = sum3;
const unsigned long out2 = out3 - prev2;
@ -319,23 +319,23 @@ std::size_t Cic3EvenOddCore<channels>::filter(short *out, const short *const in,
prev1 = out2;
out += channels;
}
std::size_t n = (inlen - nextdivn) / div_;
if (div_ & 1)
filterOdd(out, s, n);
else
filterEven(out, s, n);
s += n * div_ * channels;
out += n * channels;
nextdivn = div_;
}
{
unsigned divn = inlen - (s - in) / channels;
nextdivn -= divn;
while (divn--) {
sum1 += static_cast<long>(*s);
s += channels;
@ -343,14 +343,14 @@ std::size_t Cic3EvenOddCore<channels>::filter(short *out, const short *const in,
sum3 += sum2;
}
}
return (out - outStart) / channels;
}*/
template<unsigned channels>
class Cic3 : public SubResampler {
Cic3Core<channels> cics[channels];
public:
enum { MAX_DIV = 23 };
explicit Cic3(unsigned div);
@ -369,11 +369,11 @@ Cic3<channels>::Cic3(const unsigned div) {
template<unsigned channels>
std::size_t Cic3<channels>::resample(short *const out, const short *const in, const std::size_t inlen) {
std::size_t samplesOut;
for (unsigned i = 0; i < channels; ++i) {
samplesOut = cics[i].filter(out + i, in + i, inlen);
}
return samplesOut;
}

View File

@ -22,7 +22,7 @@
#include "subresampler.h"
#include "rshift16_round.h"
template<unsigned channels>
template<unsigned channels>
class Cic4Core {
enum { BUFLEN = 64 };
unsigned long buf[BUFLEN];
@ -37,10 +37,10 @@ class Cic4Core {
unsigned div_;
// unsigned nextdivn;
unsigned bufpos;
// trouble if div is too large, may be better to only support power of 2 div
static long mulForDiv(unsigned div) { return 0x10000 / (div * div * div * div); }
public:
explicit Cic4Core(const unsigned div = 1) { reset(div); }
unsigned div() const { return div_; }
@ -49,7 +49,7 @@ public:
static double gain(unsigned div) { return rshift16_round(-32768l * (div * div * div * div) * mulForDiv(div)) / -32768.0; }
};
template<unsigned channels>
template<unsigned channels>
void Cic4Core<channels>::reset(const unsigned div) {
sum4 = sum3 = sum2 = sum1 = 0;
prev4 = prev3 = prev2 = prev1 = 0;
@ -64,7 +64,7 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
// const std::size_t produced = (inlen + div_ - nextdivn) / div_;
const long mul = mulForDiv(div_);
const short *s = in;
unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
unsigned long sm3 = sum3;
@ -73,12 +73,12 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
unsigned long prv2 = prev2;
unsigned long prv3 = prev3;
unsigned long prv4 = prev4;
while (inlen >> 2) {
const unsigned end = inlen < BUFLEN ? inlen & ~3 : BUFLEN & ~3;
unsigned long *b = buf;
unsigned n = end;
do {
unsigned long s1 = sm1 += static_cast<long>(s[0 * channels]);
sm1 += static_cast<long>(s[1 * channels]);
@ -99,30 +99,30 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
s += 4 * channels;
b += 4;
} while (n -= 4);
while (bufpos < end) {
const unsigned long out4 = buf[bufpos] - prv4;
prv4 = buf[bufpos];
bufpos += div_;
const unsigned long out3 = out4 - prv3;
prv3 = out4;
const unsigned long out2 = out3 - prv2;
prv2 = out3;
*out = rshift16_round(static_cast<long>(out2 - prv1) * mul);
prv1 = out2;
out += channels;
}
bufpos -= end;
inlen -= end;
}
if (inlen) {
unsigned n = inlen;
unsigned i = 0;
do {
sm1 += static_cast<long>(*s);
s += channels;
@ -130,25 +130,25 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
sm3 += sm2;
buf[i++] = sm4 += sm3;
} while (--n);
while (bufpos < inlen) {
const unsigned long out4 = buf[bufpos] - prv4;
prv4 = buf[bufpos];
bufpos += div_;
const unsigned long out3 = out4 - prv3;
prv3 = out4;
const unsigned long out2 = out3 - prv2;
prv2 = out3;
*out = rshift16_round(static_cast<long>(out2 - prv1) * mul);
prv1 = out2;
out += channels;
}
bufpos -= inlen;
}
sum1 = sm1;
sum2 = sm2;
sum3 = sm3;
@ -157,16 +157,16 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
prev2 = prv2;
prev3 = prv3;
prev4 = prv4;
/*unsigned long sm1 = sum1;
unsigned long sm2 = sum2;
unsigned long sm3 = sum3;
unsigned long sm4 = sum4;
if (produced) {
unsigned divn = nextdivn;
std::size_t n = produced;
do {
do {
sm1 += static_cast<long>(*s);
@ -175,7 +175,7 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
sm3 += sm2;
sm4 += sm3;
} while (--divn);
const unsigned long out4 = sm4 - prev4;
prev4 = sm4;
const unsigned long out3 = out4 - prev3;
@ -185,17 +185,17 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
*out = rshift16_round(static_cast<long>(out2 - prev1) * mul);
prev1 = out2;
out += channels;
divn = div_;
} while (--n);
nextdivn = div_;
}
{
unsigned divn = (in + inlen * channels - s) / channels;
nextdivn -= divn;
while (divn--) {
sm1 += static_cast<long>(*s);
s += channels;
@ -204,19 +204,19 @@ std::size_t Cic4Core<channels>::filter(short *out, const short *const in, std::s
sm4 += sm3;
}
}
sum1 = sm1;
sum2 = sm2;
sum3 = sm3;
sum4 = sm4;*/
return produced;
}
template<unsigned channels>
class Cic4 : public SubResampler {
Cic4Core<channels> cics[channels];
public:
enum { MAX_DIV = 13 };
explicit Cic4(unsigned div);
@ -235,11 +235,11 @@ Cic4<channels>::Cic4(const unsigned div) {
template<unsigned channels>
std::size_t Cic4<channels>::resample(short *const out, const short *const in, const std::size_t inlen) {
std::size_t samplesOut;
for (unsigned i = 0; i < channels; ++i) {
samplesOut = cics[i].filter(out + i, in + i, inlen);
}
return samplesOut;
}

View File

@ -30,7 +30,7 @@ class PolyPhaseConvoluter {
Array<short> const prevbuf;
unsigned div_;
unsigned x_;
public:
PolyPhaseConvoluter(const short *kernel, unsigned phaseLen, unsigned div);
std::size_t filter(short *out, const short *in, std::size_t inlen);
@ -50,10 +50,10 @@ template<int channels, unsigned phases>
std::size_t PolyPhaseConvoluter<channels, phases>::filter(short *out, const short *const in, std::size_t inlen) {
if (!kernel || !inlen)
return 0;
// The gist of what happens here is given by the commented pseudo-code below.
// Note that the order of the kernel elements has been changed for efficiency in the real implementation.
/*for (std::size_t x = 0; x < inlen + M; ++x) {
const int end = x < inlen ? M + 1 : inlen + M - x;
int j = x < M ? M - x : 0;
@ -63,9 +63,9 @@ std::size_t PolyPhaseConvoluter<channels, phases>::filter(short *out, const shor
buffer[x] += kernel[j] * start[(x - M + j) / phases];
}
}*/
// Slightly more optimized version.
/*for (std::size_t x = 0; x < inlen + M; ++x) {
const int end = x < inlen ? M + 1 : inlen + M - x;
int j = x < M ? M - x : 0;
@ -78,12 +78,12 @@ std::size_t PolyPhaseConvoluter<channels, phases>::filter(short *out, const shor
buffer[x] += *k++ * *s++;
} while (--n);
}*/
const std::size_t phaseLen = prevbuf.size() / channels;
const std::size_t M = phaseLen * phases - 1;
inlen *= phases;
std::size_t x = x_;
for (; x < (M < inlen ? M : inlen); x += div_) {
for (int c = 0; c < channels; ++c) {
const short *k = kernel + ((x + 1) % phases) * phaseLen; // adjust phase so we don't start on a virtual 0 sample
@ -93,18 +93,18 @@ std::size_t PolyPhaseConvoluter<channels, phases>::filter(short *out, const shor
for (; n; n -= channels)
acc += *k++ * *(s-n);
n = (x / phases + 1) * channels;
s = in + n + c;
do {
acc += *k++ * *(s-n);
} while (n -= channels);
*out++ = rshift16_round(acc);
}
}
// We could easily get rid of the division and modulus here by updating the
// k and s pointers incrementally. However, we currently only use powers of 2
// and we would end up referencing more variables which often compiles to bad
@ -115,41 +115,41 @@ std::size_t PolyPhaseConvoluter<channels, phases>::filter(short *out, const shor
const short *const s = in + (x / phases + 1) * channels + c;
long accl = 0, accr = 0;
int i = -static_cast<int>(phaseLen * channels);
do {
accl += *k * s[i ];
accr += *k * s[i+1];
++k;
} while (i += channels);
out[0] = rshift16_round(accl);
out[1] = rshift16_round(accr);
out += 2;
}
if (channels & 1) {
const short *k = kernel + ((x + 1) % phases) * phaseLen; // adjust phase so we don't start on a virtual 0 sample
const short *const s = in + (x / phases + 1) * channels + channels-1;
long acc = 0;
int i = -static_cast<int>(phaseLen * channels);
do {
acc += *k++ * s[i];
} while (i += channels);
*out++ = rshift16_round(acc);
}
}
const std::size_t produced = (x - x_) / div_;
x_ = x - inlen;
inlen /= phases;
{
short *p = prevbuf;
const short *s = in + (inlen - phaseLen) * channels;
unsigned n = phaseLen;
if (inlen < phaseLen) {
const unsigned i = phaseLen - inlen;
std::memmove(p, p + inlen * channels, i * channels * sizeof *p);
@ -157,10 +157,10 @@ std::size_t PolyPhaseConvoluter<channels, phases>::filter(short *out, const shor
n -= i;
s = in;
}
std::memcpy(p, s, n * channels * sizeof *p);
}
return produced;
}

View File

@ -48,27 +48,27 @@ public:
const float widthTimesTaps = 3.0f;
return std::max(static_cast<unsigned>(std::ceil(widthTimesTaps / rollOffWidth)), 4u);
}
static float toFc(const float rollOffStart, const int taps) {
const float startToFcDeltaTimesTaps = 1.27f;
return startToFcDeltaTimesTaps / taps + rollOffStart;
}
public:
const unsigned taps;
const float fc;
RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {}
};
HammingSinc(unsigned div, unsigned phaseLen, double fc)
: kernel(phaseLen * phases), convoluter_(kernel, phaseLen, div)
{ makeSincKernel(kernel, phases, phaseLen, fc, hammingWin, 1.0); }
HammingSinc(unsigned div, RollOff ro, double gain)
: kernel(ro.taps * phases), convoluter_(kernel, ro.taps, div)
{ makeSincKernel(kernel, phases, ro.taps, ro.fc, hammingWin, gain);}
std::size_t resample(short *out, const short *in, std::size_t inlen) { return convoluter_.filter(out, in, inlen); }
void adjustDiv(unsigned div) { convoluter_.adjustDiv(div); }
unsigned mul() const { return MUL; }

View File

@ -23,14 +23,14 @@ double i0(double x) {
double xpm_dmfac = 1.0;
double m = 1.0;
unsigned n = 16;
x = 0.25 * x * x;
do {
xpm_dmfac *= x / (m*m);
sum += xpm_dmfac;
m += 1.0;
} while (--n);
return sum;
}

View File

@ -27,6 +27,6 @@ double kaiser50SincWin(const long n, const long M) {
double x = static_cast<double>(n * 2) / M - 1.0;
x = x * x;
x = beta * std::sqrt(1.0 - x);
return i0(x) * i0beta_rec;
}

View File

@ -45,27 +45,27 @@ public:
const float widthTimesTaps = 2.715f;
return std::max(static_cast<unsigned>(std::ceil(widthTimesTaps / rollOffWidth)), 4u);
}
static float toFc(const float rollOffStart, const int taps) {
const float startToFcDeltaTimesTaps = 1.2f;
return startToFcDeltaTimesTaps / taps + rollOffStart;
}
public:
const unsigned taps;
const float fc;
RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {}
};
Kaiser50Sinc(unsigned div, unsigned phaseLen, double fc)
: kernel(phaseLen * phases), convoluter_(kernel, phaseLen, div)
{ makeSincKernel(kernel, phases, phaseLen, fc, kaiser50SincWin, 1.0); }
Kaiser50Sinc(unsigned div, RollOff ro, double gain)
: kernel(ro.taps * phases), convoluter_(kernel, ro.taps, div)
{ makeSincKernel(kernel, phases, ro.taps, ro.fc, kaiser50SincWin, gain);}
std::size_t resample(short *out, const short *in, std::size_t inlen) { return convoluter_.filter(out, in, inlen); }
void adjustDiv(unsigned div) { convoluter_.adjustDiv(div); }
unsigned mul() const { return MUL; }

View File

@ -23,10 +23,10 @@
double kaiser70SincWin(const long n, const long M) {
const double beta = 6.9;
static const double i0beta_rec = 1.0 / i0(beta);
double x = static_cast<double>(n * 2) / M - 1.0;
x = x * x;
x = beta * std::sqrt(1.0 - x);
return i0(x) * i0beta_rec;
}

View File

@ -45,23 +45,23 @@ public:
const float widthTimesTaps = 3.75f;
return std::max(static_cast<unsigned>(std::ceil(widthTimesTaps / rollOffWidth)), 4u);
}
static float toFc(const float rollOffStart, const int taps) {
const float startToFcDeltaTimesTaps = 1.5f;
return startToFcDeltaTimesTaps / taps + rollOffStart;
}
public:
const unsigned taps;
const float fc;
RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {}
};
Kaiser70Sinc(unsigned div, unsigned phaseLen, double fc)
: kernel(phaseLen * phases), convoluter_(kernel, phaseLen, div)
{ makeSincKernel(kernel, phases, phaseLen, fc, kaiser70SincWin, 1.0); }
Kaiser70Sinc(unsigned div, RollOff ro, double gain)
: kernel(ro.taps * phases), convoluter_(kernel, ro.taps, div)
{ makeSincKernel(kernel, phases, ro.taps, ro.fc, kaiser70SincWin, gain);}

View File

@ -30,7 +30,7 @@ class LinintCore {
std::size_t pos_;
unsigned fracPos_;
int prevSample_;
public:
explicit LinintCore(long inRate = 1, long outRate = 1) { init(inRate, outRate); }
@ -98,7 +98,7 @@ std::size_t LinintCore<channels>::resample(short *const out, const short *const
template<int channels>
class Linint : public Resampler {
LinintCore<channels> cores[channels];
public:
Linint(long inRate, long outRate);
void adjustRate(long inRate, long outRate);
@ -110,7 +110,7 @@ public:
template<int channels>
Linint<channels>::Linint(const long inRate, const long outRate) {
setRate(inRate, outRate);
for (int i = 0; i < channels; ++i)
cores[i].init(inRate, outRate);
}
@ -118,7 +118,7 @@ Linint<channels>::Linint(const long inRate, const long outRate) {
template<int channels>
void Linint<channels>::adjustRate(const long inRate, const long outRate) {
setRate(inRate, outRate);
for (int i = 0; i < channels; ++i)
cores[i].adjustRate(inRate, outRate);
}
@ -126,10 +126,10 @@ void Linint<channels>::adjustRate(const long inRate, const long outRate) {
template<int channels>
std::size_t Linint<channels>::resample(short *const out, const short *const in, const std::size_t inlen) {
std::size_t outlen = 0;
for (int i = 0; i < channels; ++i)
outlen = cores[i].resample(out + i, in + i, inlen);
return outlen;
}

View File

@ -23,119 +23,119 @@ void makeSincKernel(short *const kernel, const unsigned phases,
const unsigned phaseLen, double fc, double (*win)(long m, long M), double const maxAllowedGain) {
static const double PI = 3.14159265358979323846;
fc /= phases;
/*{
const Array<double> dkernel(phaseLen * phases);
const long M = static_cast<long>(phaseLen) * phases - 1;
for (long i = 0; i < M + 1; ++i) {
const double sinc = i * 2 == M ?
PI * fc :
std::sin(PI * fc * (i * 2 - M)) / (i * 2 - M);
dkernel[((phases - (i % phases)) % phases) * phaseLen + i / phases] = win(i, M) * sinc;
}
double maxabsgain = 0;
for (unsigned ph = 0; ph < phases; ++ph) {
double gain = 0;
double absgain = 0;
for (unsigned i = 0; i < phaseLen; ++i) {
gain += dkernel[ph * phaseLen + i];
absgain += std::abs(dkernel[ph * phaseLen + i]);
}
gain = 1.0 / gain;
// Per phase normalization to avoid DC fluctuations.
for (unsigned i = 0; i < phaseLen; ++i)
dkernel[ph * phaseLen + i] *= gain;
absgain *= gain;
if (absgain > maxabsgain)
maxabsgain = absgain;
}
const double gain = (0x10000 - 0.5 * phaseLen) * maxAllowedGain / maxabsgain;
for (long i = 0; i < M + 1; ++i)
kernel[i] = std::floor(dkernel[i] * gain + 0.5);
}*/
// The following is equivalent to the more readable version above
const long M = static_cast<long>(phaseLen) * phases - 1;
const Array<double> dkernel(M / 2 + 1);
{
double *dk = dkernel;
for (unsigned ph = 0; ph < phases; ++ph) {
for (long i = ph; i < M / 2 + 1; i += phases) {
const double sinc = i * 2 == M ?
PI * fc :
std::sin(PI * fc * (i * 2 - M)) / (i * 2 - M);
*dk++ = win(i, M) * sinc;
}
}
}
double maxabsgain = 0.0;
{
double *dkp1 = dkernel;
double *dkp2 = dkernel + M / 2;
for (unsigned ph = 0; ph < (phases + 1) / 2; ++ph) {
double gain = 0.0;
double absgain = 0.0;
{
const double *kp1 = dkp1;
const double *kp2 = dkp2;
long i = ph;
for (; i < M / 2 + 1; i += phases) {
gain += *kp1;
absgain += std::abs(*kp1++);
}
for (; i < M + 1; i += phases) {
gain += *kp2;
absgain += std::abs(*kp2--);
}
}
gain = 1.0 / gain;
long i = ph;
for (; i < M / 2 + 1; i += phases)
*dkp1++ *= gain;
if (dkp1 < dkp2) {
for (; i < M + 1; i += phases)
*dkp2-- *= gain;
}
absgain *= gain;
if (absgain > maxabsgain)
maxabsgain = absgain;
}
}
const double gain = (0x10000 - 0.5 * phaseLen) * maxAllowedGain / maxabsgain;
const double *dk = dkernel;
for (unsigned ph = 0; ph < phases; ++ph) {
short *k = kernel + ((phases - ph) % phases) * phaseLen;
short *km = kernel + phaseLen - 1 + ((ph + 1) % phases) * phaseLen;
for (long i = ph; i < M / 2 + 1; i += phases)
*km-- = *k++ = static_cast<short>(std::floor(*dk++ * gain + 0.5));
}

View File

@ -45,27 +45,27 @@ public:
const float widthTimesTaps = 0.9f;
return std::max(static_cast<unsigned>(std::ceil(widthTimesTaps / rollOffWidth)), 4u);
}
static float toFc(const float rollOffStart, const int taps) {
const float startToFcDeltaTimesTaps = 0.43f;
return startToFcDeltaTimesTaps / taps + rollOffStart;
}
public:
const unsigned taps;
const float fc;
RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {}
};
RectSinc(unsigned div, unsigned phaseLen, double fc)
: kernel(phaseLen * phases), convoluter_(kernel, phaseLen, div)
{ makeSincKernel(kernel, phases, phaseLen, fc, rectWin, 1.0); }
RectSinc(unsigned div, RollOff ro, double gain)
: kernel(ro.taps * phases), convoluter_(kernel, ro.taps, div)
{ makeSincKernel(kernel, phases, ro.taps, ro.fc, rectWin, gain);}
std::size_t resample(short *out, const short *in, std::size_t inlen) { return convoluter_.filter(out, in, inlen); }
void adjustDiv(unsigned div) { convoluter_.adjustDiv(div); }
unsigned mul() const { return MUL; }

View File

@ -21,7 +21,7 @@
unsigned long u48div(unsigned long num1, unsigned num2, const unsigned long den) {
unsigned long res = 0;
unsigned s = 16;
do {
if (num1 < 0x10000) {
num1 <<= s;
@ -33,22 +33,22 @@ unsigned long u48div(unsigned long num1, unsigned num2, const unsigned long den)
num1 <<= maxs;
num1 |= (num2 >> (s -= maxs)) & ((1 << maxs) - 1);
}
if (num1 < 0x10000000) {
const unsigned maxs = s < 4 ? s : 4;
num1 <<= maxs;
num1 |= (num2 >> (s -= maxs)) & ((1 << maxs) - 1);
}
while (num1 < den && s) {
num1 <<= 1; // if this overflows we're screwed
num1 |= num2 >> --s & 1;
}
}
res += (num1 / den) << s;
num1 = (num1 % den);
} while (s);
return res;
}

View File

@ -25,7 +25,7 @@
template<unsigned channels>
class Upsampler : public SubResampler {
unsigned mul_;
public:
Upsampler(const unsigned mul) : mul_(mul) {}
std::size_t resample(short *out, const short *in, std::size_t inlen);
@ -37,14 +37,14 @@ template<unsigned channels>
std::size_t Upsampler<channels>::resample(short *out, const short *in, std::size_t inlen) {
if (inlen) {
std::memset(out, 0, inlen * mul_ * channels * sizeof *out);
do {
std::memcpy(out, in, channels * sizeof *out);
in += channels;
out += mul_ * channels;
} while (--inlen);
}
return inlen * mul_;
}

View File

@ -30,32 +30,32 @@ class RingBuffer {
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;
}
void clear() {
wpos = rpos = 0;
}
void fill(T value);
void read(T *out, std::size_t num);
void reset(std::size_t sz_in);
std::size_t size() const {
return sz - 1;
}
std::size_t used() const {
return (wpos < rpos ? sz : 0) + wpos - rpos;
}
void write(const T *in, std::size_t num);
};
@ -70,16 +70,16 @@ 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;
num -= n;
out += n;
}
std::memcpy(out, buf + rpos, num * sizeof *out);
if ((rpos += num) == sz)
rpos = 0;
}
@ -95,16 +95,16 @@ 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;
num -= n;
in += n;
}
std::memcpy(buf + wpos, in, num * sizeof *buf);
if ((wpos += num) == sz)
wpos = 0;
}

View File

@ -28,12 +28,12 @@ class Rgb32ToUyvy {
gambatte::uint_least32_t rgb32;
gambatte::uint_least32_t uyvy;
};
enum { cache_size = 0x100 };
enum { cache_mask = cache_size - 1 };
CacheUnit cache[cache_size];
public:
Rgb32ToUyvy();
void operator()(const gambatte::uint_least32_t *s, gambatte::uint_least32_t *d,
@ -54,7 +54,7 @@ void Rgb32ToUyvy::operator()(const gambatte::uint_least32_t *s,
{
while (h--) {
unsigned n = w >> 1;
do {
if ((cache[*s & cache_mask].rgb32 - *s) | (cache[*(s+1) & cache_mask].rgb32 - *(s+1))) {
cache[*s & cache_mask].rgb32 = *s;
@ -76,7 +76,7 @@ void Rgb32ToUyvy::operator()(const gambatte::uint_least32_t *s,
cache[*(s+1) & cache_mask].uyvy = (y & 0xFF000000) | (v >> 8 & 0x00FF0000) | (y >> 16 & 0x0000FF00) | u >> 24;
#endif
}
*d = cache[*s & cache_mask].uyvy;
*(d+1) = cache[*(s+1) & cache_mask].uyvy;
s += 2;
@ -118,10 +118,10 @@ public:
height_(height)
{
}
virtual void* inBuf() const { return inbuf_; }
virtual int inPitch() const { return width_; }
virtual void draw(void *dst, int dstpitch) {
rgb32ToUyvy(inbuf_, static_cast<gambatte::uint_least32_t*>(dst), width_, height_, inPitch(), dstpitch);
}
@ -139,10 +139,10 @@ public:
height_(height)
{
}
virtual void* inBuf() const { return inbuf_; }
virtual int inPitch() const { return width_; }
virtual void draw(void *dst, int dstpitch) {
rgb32ToRgb16(inbuf_, static_cast<gambatte::uint_least16_t*>(dst), width_, height_, inPitch(), dstpitch);
}

View File

@ -26,12 +26,12 @@ class VideoLink;
struct VfilterInfo {
enum { IN_WIDTH = 160 };
enum { IN_HEIGHT = 144 };
const char *handle;
unsigned outWidth;
unsigned outHeight;
VideoLink* (*create)();
static const VfilterInfo& get(std::size_t n);
static std::size_t numVfilters();
};

View File

@ -30,129 +30,129 @@ struct Colorsum {
static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums) {
unsigned w = WIDTH;
while (w--) {
{
gambatte::uint_least32_t rsum = sums[1].r;
gambatte::uint_least32_t gsum = sums[1].g;
gambatte::uint_least32_t bsum = sums[1].b;
if (rsum & 0x80000000) rsum = 0;
if (gsum & 0x80000000) gsum = 0;
if (bsum & 0x80000000) bsum = 0;
rsum <<= 12;
rsum += 0x008000;
gsum >>= 4;
gsum += 0x0080;
bsum += 0x0008;
bsum >>= 4;
if (rsum > 0xFF0000) rsum = 0xFF0000;
if (gsum > 0x00FF00) gsum = 0x00FF00;
if (bsum > 0x0000FF) bsum = 0x0000FF;
*dest++ = (rsum & 0xFF0000) | (gsum & 0x00FF00) | bsum;
}
{
gambatte::uint_least32_t rsum = sums[1].r * 9;
gambatte::uint_least32_t gsum = sums[1].g * 9;
gambatte::uint_least32_t bsum = sums[1].b * 9;
rsum -= sums[0].r;
gsum -= sums[0].g;
bsum -= sums[0].b;
rsum += sums[2].r * 9;
gsum += sums[2].g * 9;
bsum += sums[2].b * 9;
rsum -= sums[3].r;
gsum -= sums[3].g;
bsum -= sums[3].b;
if (rsum & 0x80000000) rsum = 0;
if (gsum & 0x80000000) gsum = 0;
if (bsum & 0x80000000) bsum = 0;
rsum <<= 8;
rsum += 0x008000;
gsum >>= 8;
gsum += 0x000080;
bsum += 0x000080;
bsum >>= 8;
if (rsum > 0xFF0000) rsum = 0xFF0000;
if (gsum > 0x00FF00) gsum = 0x00FF00;
if (bsum > 0x0000FF) bsum = 0x0000FF;
*dest++ = (rsum & 0xFF0000) | (gsum & 0x00FF00) | bsum;
}
++sums;
}
}
static void filter(gambatte::uint_least32_t *dline, const int pitch, const gambatte::uint_least32_t *sline) {
Colorsum sums[PITCH];
for (unsigned h = HEIGHT; h--;) {
{
const gambatte::uint_least32_t *s = sline;
Colorsum *sum = sums;
unsigned n = PITCH;
while (n--) {
unsigned long pixel = *s;
sum->r = pixel >> 12 & 0x000FF0 ;
pixel <<= 4;
sum->g = pixel & 0x0FF000;
sum->b = pixel & 0x000FF0;
++s;
++sum;
}
}
merge_columns(dline, sums);
dline += pitch;
{
const gambatte::uint_least32_t *s = sline;
Colorsum *sum = sums;
unsigned n = PITCH;
while (n--) {
unsigned long pixel = *s;
unsigned long rsum = (pixel >> 16) * 9;
unsigned long gsum = (pixel & 0x00FF00) * 9;
unsigned long bsum = (pixel & 0x0000FF) * 9;
pixel = s[-1*PITCH];
rsum -= pixel >> 16;
gsum -= pixel & 0x00FF00;
bsum -= pixel & 0x0000FF;
pixel = s[1*PITCH];
rsum += (pixel >> 16) * 9;
gsum += (pixel & 0x00FF00) * 9;
bsum += (pixel & 0x0000FF) * 9;
pixel = s[2*PITCH];
rsum -= pixel >> 16;
gsum -= pixel & 0x00FF00;
bsum -= pixel & 0x0000FF;
sum->r = rsum;
sum->g = gsum;
sum->b = bsum;
++s;
++sum;
}
}
merge_columns(dline, sums);
dline += pitch;
sline += PITCH;

View File

@ -29,7 +29,7 @@ class Catrom2x : public VideoLink {
public:
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 2 };
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 2 };
Catrom2x();
virtual void* inBuf() const;
virtual int inPitch() const;

View File

@ -30,7 +30,7 @@ struct Colorsum {
static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums) {
unsigned w = WIDTH;
while (w--) {
{
gambatte::uint_least32_t rsum = sums[1].r;
@ -229,7 +229,7 @@ static void filter(gambatte::uint_least32_t *dline, const int pitch, const gamba
const gambatte::uint_least32_t *s = sline;
Colorsum *sum = sums;
unsigned n = PITCH;
while (n--) {
const unsigned long pixel = *s;
sum->r = (pixel >> 16) * 27;
@ -240,7 +240,7 @@ static void filter(gambatte::uint_least32_t *dline, const int pitch, const gamba
++sum;
}
}
merge_columns(dline, sums);
dline += pitch;
@ -248,7 +248,7 @@ static void filter(gambatte::uint_least32_t *dline, const int pitch, const gamba
const gambatte::uint_least32_t *s = sline;
Colorsum *sum = sums;
unsigned n = PITCH;
while (n--) {
unsigned long pixel = *s;
unsigned long rsum = (pixel >> 16) * 21;
@ -279,7 +279,7 @@ static void filter(gambatte::uint_least32_t *dline, const int pitch, const gamba
++sum;
}
}
merge_columns(dline, sums);
dline += pitch;
@ -287,7 +287,7 @@ static void filter(gambatte::uint_least32_t *dline, const int pitch, const gamba
const gambatte::uint_least32_t *s = sline;
Colorsum *sum = sums;
unsigned n = PITCH;
while (n--) {
unsigned long pixel = *s;
unsigned long rsum = (pixel >> 16) * 9;
@ -318,7 +318,7 @@ static void filter(gambatte::uint_least32_t *dline, const int pitch, const gamba
++sum;
}
}
merge_columns(dline, sums);
dline += pitch;
sline += PITCH;

View File

@ -29,7 +29,7 @@ class Catrom3x : public VideoLink {
public:
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 3 };
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 3 };
Catrom3x();
virtual void* inBuf() const;
virtual int inPitch() const;

View File

@ -27,17 +27,17 @@ static inline int getResult1(const unsigned long a, const unsigned long b, const
int x = 0;
int y = 0;
int r = 0;
if (a == c) ++x;
else if (b == c) ++y;
if (a == d) ++x;
else if (b == d) ++y;
if (x <= 1) ++r;
if (y <= 1) --r;
return r;
}
@ -45,17 +45,17 @@ static inline int getResult2(const unsigned long a, const unsigned long b, const
int x = 0;
int y = 0;
int r = 0;
if (a == c) ++x;
else if (b == c) ++y;
if (a == d) ++x;
else if (b == d) ++y;
if (x <= 1) --r;
if (y <= 1) ++r;
return r;
}
@ -65,7 +65,7 @@ static inline unsigned long interpolate(const unsigned long a, const unsigned lo
static inline unsigned long qInterpolate(const unsigned long a, const unsigned long b, const unsigned long c, const unsigned long d) {
const unsigned long lowBits = ((a & 0x030303) + (b & 0x030303) + (c & 0x030303) + (d & 0x030303)) & 0x030303;
return (a + b + c + d - lowBits) >> 2;
}
@ -73,20 +73,20 @@ template<unsigned srcPitch, unsigned width, unsigned height>
static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const gambatte::uint_least32_t *srcPtr)
{
unsigned h = height;
while (h--) {
const gambatte::uint_least32_t *bP = srcPtr;
gambatte::uint_least32_t *dP = dstPtr;
for (unsigned finish = width; finish--;) {
register unsigned long colorA, colorB;
unsigned long colorC, colorD,
colorE, colorF, colorG, colorH,
colorI, colorJ, colorK, colorL,
colorM, colorN, colorO, colorP;
unsigned long product, product1, product2;
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
@ -96,22 +96,22 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
colorE = *(bP - srcPitch);
colorF = *(bP - srcPitch + 1);
colorJ = *(bP - srcPitch + 2);
colorG = *(bP - 1);
colorA = *(bP);
colorB = *(bP + 1);
colorK = *(bP + 2);
colorH = *(bP + srcPitch - 1);
colorC = *(bP + srcPitch);
colorD = *(bP + srcPitch + 1);
colorL = *(bP + srcPitch + 2);
colorM = *(bP + srcPitch * 2 - 1);
colorN = *(bP + srcPitch * 2);
colorO = *(bP + srcPitch * 2 + 1);
colorP = *(bP + srcPitch * 2 + 2);
if (colorA == colorD && colorB != colorC) {
if ((colorA == colorE && colorB == colorL) ||
(colorA == colorC && colorA == colorF
@ -120,7 +120,7 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
} else {
product = interpolate(colorA, colorB);
}
if ((colorA == colorG && colorC == colorO) ||
(colorA == colorB && colorA == colorH
&& colorG != colorC && colorC == colorM)) {
@ -137,7 +137,7 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
} else {
product = interpolate(colorA, colorB);
}
if ((colorC == colorH && colorA == colorF) ||
(colorC == colorG && colorC == colorD
&& colorA != colorH && colorA == colorI)) {
@ -153,15 +153,15 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
product2 = colorA;
} else {
register int r = 0;
product1 = interpolate(colorA, colorC);
product = interpolate(colorA, colorB);
r += getResult1(colorA, colorB, colorG, colorE);
r += getResult2(colorB, colorA, colorK, colorF);
r += getResult2(colorB, colorA, colorH, colorN);
r += getResult1(colorA, colorB, colorL, colorO);
if (r > 0)
product2 = colorA;
else if (r < 0)
@ -172,7 +172,7 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
}
} else {
product2 = qInterpolate(colorA, colorB, colorC, colorD);
if (colorA == colorC && colorA == colorF
&& colorB != colorE && colorB == colorJ) {
product = colorA;
@ -182,7 +182,7 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
} else {
product = interpolate(colorA, colorB);
}
if (colorA == colorB && colorA == colorH
&& colorG != colorC && colorC == colorM) {
product1 = colorA;
@ -197,11 +197,11 @@ static void filter(gambatte::uint_least32_t *dstPtr, const int dstPitch, const g
*(dP + 1) = product;
*(dP + dstPitch) = product1;
*(dP + dstPitch + 1) = product2;
++bP;
dP += 2;
}
srcPtr += srcPitch;
dstPtr += dstPitch * 2;
}

View File

@ -29,7 +29,7 @@ class Kreed2xSaI : public VideoLink {
public:
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 2 };
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 2 };
Kreed2xSaI();
virtual void* inBuf() const;
virtual int inPitch() const;

View File

@ -29,7 +29,7 @@ class MaxStHq2x : public VideoLink {
public:
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 2 };
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 2 };
MaxStHq2x();
virtual void* inBuf() const;
virtual int inPitch() const;

View File

@ -29,7 +29,7 @@ class MaxStHq3x : public VideoLink {
public:
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 3 };
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 3 };
MaxStHq3x();
virtual void* inBuf() const;
virtual int inPitch() const;

View File

@ -44,20 +44,20 @@ struct CheatItemLess {
class CheatListModel : public QAbstractListModel {
std::vector<CheatListItem> items_;
public:
explicit CheatListModel(QObject *parent = 0) : QAbstractListModel(parent) {}
explicit CheatListModel(const std::vector<CheatListItem> &items, QObject *parent = 0)
: QAbstractListModel(parent), items_(items)
{
}
virtual int rowCount(const QModelIndex&) const { return items_.size(); }
virtual Qt::ItemFlags flags(const QModelIndex &index) const {
return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable;
}
virtual QVariant data(const QModelIndex &index, const int role) const {
if (static_cast<std::size_t>(index.row()) < items_.size()) {
switch (role) {
@ -65,19 +65,19 @@ public:
case Qt::CheckStateRole: return items_[index.row()].checked ? Qt::Checked : Qt::Unchecked;
}
}
return QVariant();
}
virtual bool setData(const QModelIndex &index, const QVariant &value, const int role) {
if (static_cast<std::size_t>(index.row()) < items_.size() && role == Qt::CheckStateRole) {
items_[index.row()].checked = value.toBool();
return true;
}
return false;
}
const std::vector<CheatListItem> & items() const { return items_; }
};
@ -95,19 +95,19 @@ GetCheatInput::GetCheatInput(const QString &desc, const QString &code, QWidget *
l->addWidget(descEdit_);
l->addWidget(new QLabel(tr("GG/GS Code:")));
l->addWidget(codeEdit_);
const QString cheatre("((01[0-9a-fA-F]{6,6})|([0-9a-fA-F]{3,3}-[0-9a-fA-F]{3,3}(-[0-9a-fA-F]{3,3})?))");
codeEdit_->setValidator(new QRegExpValidator(QRegExp(cheatre + "(;" + cheatre + ")*"), codeEdit_));
codeEdit_->setToolTip(tr("Game Genie: hhh-hhh-hhh;...\nGame Shark: 01hhhhhh;..."));
codeEdit_->setWhatsThis(codeEdit_->toolTip());
QHBoxLayout *const hl = new QHBoxLayout;
l->addLayout(hl);
l->setAlignment(hl, Qt::AlignBottom | Qt::AlignRight);
hl->addWidget(okButton_);
QPushButton *const cancelButton = new QPushButton(tr("Cancel"));
hl->addWidget(cancelButton);
okButton_->setEnabled(codeEdit_->hasAcceptableInput());
connect(codeEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(codeTextEdited(const QString&)));
connect(okButton_, SIGNAL(clicked()), this, SLOT(accept()));
@ -134,35 +134,35 @@ CheatDialog::CheatDialog(const QString &savefile, QWidget *const parent)
savefile_(savefile)
{
setWindowTitle("Cheats");
QVBoxLayout *const mainLayout = new QVBoxLayout;
setLayout(mainLayout);
QVBoxLayout *const viewLayout = new QVBoxLayout;
mainLayout->addLayout(viewLayout);
viewLayout->addWidget(view_);
resetViewModel(items_);
{
QPushButton *const addButton = new QPushButton("Add...");
viewLayout->addWidget(addButton);
connect(addButton, SIGNAL(clicked()), this, SLOT(addCheat()));
}
viewLayout->addWidget(editButton_);
connect(editButton_, SIGNAL(clicked()), this, SLOT(editCheat()));
viewLayout->addWidget(rmButton_);
connect(rmButton_, SIGNAL(clicked()), this, SLOT(removeCheat()));
{
QPushButton *const okButton = new QPushButton(tr("OK"));
QPushButton *const cancelButton = new QPushButton(tr("Cancel"));
okButton->setDefault(true);
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
QBoxLayout *const hLayout = new QHBoxLayout;
hLayout->addWidget(okButton);
hLayout->addWidget(cancelButton);
@ -177,21 +177,21 @@ CheatDialog::~CheatDialog() {
void CheatDialog::loadFromSettingsFile() {
items_.clear();
if (!gamename_.isEmpty()) {
QSettings settings(savefile_, QSettings::IniFormat);
settings.beginGroup(gamename_);
foreach (const QString &key, settings.childKeys()) {
const QStringList &l = settings.value(key).toStringList();
if (1 < l.size())
items_.push_back(CheatListItem(l[0], l[1], 2 < l.size() && l[2] == "on"));
}
std::sort(items_.begin(), items_.end(), CheatItemLess());
}
resetViewModel(items_);
}
@ -200,15 +200,15 @@ void CheatDialog::saveToSettingsFile() {
QSettings settings(savefile_, QSettings::IniFormat);
settings.beginGroup(gamename_);
settings.remove("");
for (std::size_t i = 0; i < items_.size(); ++i) {
QStringList l;
l.append(items_[i].label);
l.append(items_[i].code);
if (items_[i].checked)
l.append("on");
settings.setValue(QString::number(i), l);
}
}
@ -230,13 +230,13 @@ void CheatDialog::resetViewModel(const std::vector<CheatListItem> &items, const
void CheatDialog::addCheat() {
const scoped_ptr<GetCheatInput> getCheatDialog(new GetCheatInput(QString(), QString(), this));
getCheatDialog->setWindowTitle(tr("Add Cheat"));
if (getCheatDialog->exec()) {
std::vector<CheatListItem> items = reinterpret_cast<CheatListModel*>(view_->model())->items();
const CheatListItem item(getCheatDialog->descText(), getCheatDialog->codeText(), false);
const std::vector<CheatListItem>::iterator it =
items.insert(std::lower_bound(items.begin(), items.end(), item, CheatItemLess()), item);
resetViewModel(items, it - items.begin());
}
}
@ -244,19 +244,19 @@ void CheatDialog::addCheat() {
void CheatDialog::editCheat() {
const std::size_t row = view_->selectionModel()->currentIndex().row();
std::vector<CheatListItem> items = reinterpret_cast<CheatListModel*>(view_->model())->items();
if (row < items.size()) {
const scoped_ptr<GetCheatInput> getCheatDialog(
new GetCheatInput(items[row].label, items[row].code, this));
getCheatDialog->setWindowTitle(tr("Edit Cheat"));
if (getCheatDialog->exec()) {
const CheatListItem item(getCheatDialog->descText(), getCheatDialog->codeText(), items[row].checked);
items.erase(items.begin() + row);
const std::vector<CheatListItem>::iterator it =
items.insert(std::lower_bound(items.begin(), items.end(), item, CheatItemLess()), item);
resetViewModel(items, it - items.begin());
}
}
@ -266,7 +266,7 @@ void CheatDialog::removeCheat() {
if (view_->selectionModel()->currentIndex().isValid()) {
const std::size_t row = view_->selectionModel()->currentIndex().row();
std::vector<CheatListItem> items = reinterpret_cast<CheatListModel*>(view_->model())->items();
if (row < items.size()) {
items.erase(items.begin() + row);
resetViewModel(items, row);
@ -281,12 +281,12 @@ void CheatDialog::selectionChanged(const QModelIndex &current, const QModelIndex
const QString CheatDialog::cheats() const {
QString s;
for (std::size_t i = 0; i < items_.size(); ++i) {
if (items_[i].checked)
s += items_[i].code + ";";
}
return s;
}

View File

@ -27,7 +27,7 @@ struct CheatListItem {
QString label;
QString code;
bool checked;
CheatListItem(const QString &label, const QString &code, const bool checked)
: label(label), code(code), checked(checked)
{
@ -36,14 +36,14 @@ struct CheatListItem {
class GetCheatInput : public QDialog {
Q_OBJECT
class QLineEdit *const codeEdit_;
class QLineEdit *const descEdit_;
class QPushButton *const okButton_;
private slots:
void codeTextEdited(const QString&);
public:
explicit GetCheatInput(const QString &desc, const QString &code, QWidget *parent);
const QString codeText() const;
@ -52,31 +52,31 @@ public:
class CheatDialog : public QDialog {
Q_OBJECT
class QListView *const view_;
class QPushButton *const editButton_;
class QPushButton *const rmButton_;
std::vector<CheatListItem> items_;
const QString savefile_;
QString gamename_;
void loadFromSettingsFile();
void saveToSettingsFile();
void resetViewModel(const std::vector<CheatListItem> &items);
void resetViewModel(const std::vector<CheatListItem> &items, int newCurRow);
private slots:
void addCheat();
void editCheat();
void removeCheat();
void selectionChanged(const class QModelIndex &current, const class QModelIndex &last);
public:
explicit CheatDialog(const QString &savefile, QWidget *parent = 0);
~CheatDialog();
const QString cheats() const;
void setGameName(const QString &name);
public slots:
virtual void accept();
virtual void reject();

View File

@ -27,15 +27,15 @@ static int getCustomIndex(const QComboBox *const comboBox) {
static void setFps(QComboBox *const comboBox, const QSize &value) {
const int valueIndex = comboBox->findData(value);
if (valueIndex < 0) {
comboBox->addItem(QString::number(static_cast<double>(value.width()) / value.height()) + " fps", value);
const int customIndex = getCustomIndex(comboBox);
if (customIndex + 4 < comboBox->count())
comboBox->removeItem(customIndex + 1);
comboBox->setCurrentIndex(comboBox->count() - 1);
} else
comboBox->setCurrentIndex(valueIndex);
@ -47,11 +47,11 @@ FpsSelector::FpsSelector()
{
comboBox_->addItem("GB/GBC (" + QString::number(262144.0 / 4389.0) + " fps)", QSize(262144, 4389));
comboBox_->addItem(QString("Other..."));
const QSize &loadedValue = QSettings().value("misc/fps", value_).toSize();
value_ = loadedValue.width() > 0 && loadedValue.height() > 0
&& loadedValue.width() / loadedValue.height() > 0 ? loadedValue : value_;
reject();
connect(comboBox_, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)));
@ -77,11 +77,11 @@ QWidget * FpsSelector::widget() const {
void FpsSelector::indexChanged(const int index) {
if (getCustomIndex(comboBox_) == index) {
bool ok = false;
const QSize v(static_cast<int>(
QInputDialog::getDouble(comboBox_, tr("Set Frame Rate"), tr("Frame rate (fps):"),
static_cast<double>(value_.width()) / value_.height(), 30.0, 120.0, 4, &ok) * 10000 + 0.5), 10000);
setFps(comboBox_, ok ? v : value_);
}
}

View File

@ -27,13 +27,13 @@ class QWidget;
class FpsSelector : public QObject {
Q_OBJECT
QComboBox *const comboBox_;
QSize value_;
private slots:
void indexChanged(int index);
public:
FpsSelector();
~FpsSelector();

View File

@ -25,27 +25,27 @@ class QWidget;
class ConstAudioEngineConf {
const AudioEngine *const ae;
public:
/*explicit */ConstAudioEngineConf(const AudioEngine *const ae) : ae(ae) {}
const QString& nameString() const;
QWidget* settingsWidget() const;
void rejectSettings() const;
bool operator==(ConstAudioEngineConf r) const { return ae == r.ae; }
bool operator!=(ConstAudioEngineConf r) const { return ae != r.ae; }
};
class AudioEngineConf {
AudioEngine *const ae;
public:
/*explicit */AudioEngineConf(AudioEngine *const ae) : ae(ae) {}
const QString& nameString() const;
QWidget* settingsWidget() const;
void acceptSettings() const;
void rejectSettings() const;
bool operator==(AudioEngineConf r) const { return ae == r.ae; }
bool operator!=(AudioEngineConf r) const { return ae != r.ae; }
operator const ConstAudioEngineConf() const { return ConstAudioEngineConf(ae); }

View File

@ -30,17 +30,17 @@ private:
std::vector<T*, Allocator> v;
explicit released(const std::vector<T*, Allocator> &v): v(v) {}
};
public:
typedef typename std::vector<T*, Allocator>::const_iterator const_iterator;
typedef typename std::vector<T*, Allocator>::iterator iterator;
typedef typename std::vector<T*, Allocator>::size_type size_type;
explicit auto_vector(const Allocator &a = Allocator()) : std::vector<T*, Allocator>(a) {}
explicit auto_vector(size_type n, const Allocator &a = Allocator()) : std::vector<T*, Allocator>(n, 0, a) {}
auto_vector(auto_vector &v) : std::vector<T*, Allocator>() { swap(v); }
auto_vector(const released &v) : std::vector<T*, Allocator>(v.v) {}
template<class InputIterator>
auto_vector(InputIterator first, InputIterator last, const Allocator& a = Allocator())
: std::vector<T*, Allocator>(first, last, a)
@ -48,7 +48,7 @@ public:
}
~auto_vector() { clear(); }
using std::vector<T*, Allocator>::begin;
using std::vector<T*, Allocator>::end;
using std::vector<T*, Allocator>::rbegin;
@ -63,44 +63,44 @@ public:
using std::vector<T*, Allocator>::front;
using std::vector<T*, Allocator>::back;
using std::vector<T*, Allocator>::push_back;
template<class InputIterator>
void assign(InputIterator first, InputIterator last) {
clear();
std::vector<T*, Allocator>::assign(first, last);
}
void assign(size_type n) {
clear();
std::vector<T*, Allocator>::assign(n);
}
void pop_back() {
if (!empty())
defined_delete(back());
std::vector<T*, Allocator>::pop_back();
}
iterator insert(iterator position, T *x) { return std::vector<T*, Allocator>::insert(position, x); }
template<class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
std::vector<T*, Allocator>::insert(position, first, last);
}
iterator erase(iterator position) {
if (position != end())
defined_delete(*position);
return std::vector<T*, Allocator>::erase(position);
}
iterator erase(iterator first, iterator last) {
std::for_each(first, last, defined_delete<T>);
return std::vector<T*, Allocator>::erase(first, last);
}
void swap(auto_vector &vec) { std::vector<T*, Allocator>::swap(vec); }
void clear() { erase(begin(), end()); }
const std::vector<T*,Allocator> get() const { return *this; }

View File

@ -25,21 +25,21 @@ class QWidget;
class ConstBlitterConf {
const BlitterWidget *const blitter;
public:
explicit ConstBlitterConf(const BlitterWidget *const blitter) : blitter(blitter) {}
const QString& nameString() const;
unsigned maxSwapInterval() const;
QWidget* settingsWidget() const;
void rejectSettings() const;
bool operator==(ConstBlitterConf r) const { return blitter == r.blitter; }
bool operator!=(ConstBlitterConf r) const { return blitter != r.blitter; }
};
class BlitterConf {
BlitterWidget *const blitter;
public:
explicit BlitterConf(BlitterWidget *const blitter) : blitter(blitter) {}
const QString& nameString() const;
@ -47,7 +47,7 @@ public:
QWidget* settingsWidget() const;
void acceptSettings() const;
void rejectSettings() const;
bool operator==(BlitterConf r) const { return blitter == r.blitter; }
bool operator!=(BlitterConf r) const { return blitter != r.blitter; }
operator const ConstBlitterConf() const { return ConstBlitterConf(blitter); }

View File

@ -38,30 +38,30 @@ class ParamQueue : Uncopyable {
char *start;
char *end;
std::size_t avail;
template<class T> struct PaddedSize { enum { R = ((sizeof(T) + ALIGN - 1) / ALIGN) * ALIGN }; };
public:
explicit ParamQueue(const std::size_t sz = ALIGN * 2) :
data((char*) std::malloc(sz)), dataend(data + sz), start(data), end(data), avail(sz) {}
~ParamQueue() { free(data); }
template<class T> bool hasSpaceFor() {
return avail > PaddedSize<T>::R * 2 - 2;
}
template<class T> void push(const T &t);
template<class T> T& front() {
return *reinterpret_cast<T*>(dataend - start < PaddedSize<T>::R ? data : start);
}
template<class T> const T& front() const {
return *reinterpret_cast<const T*>(dataend - start < PaddedSize<T>::R ? data : start);
}
template<class T> void pop();
std::size_t size() const { return dataend - data; }
static void swap(ParamQueue &a, ParamQueue &b);
};
@ -72,7 +72,7 @@ template<class T> void ParamQueue<ALIGN>::push(const T &t) {
avail -= dataend - end;
end = data;
}
new (end) T(t);
end += PaddedSize<T>::R;
avail -= PaddedSize<T>::R;
@ -84,7 +84,7 @@ template<class T> void ParamQueue<ALIGN>::pop() {
avail += dataend - start;
start = data;
}
reinterpret_cast<T*>(start)->~T();
start += PaddedSize<T>::R;
avail += PaddedSize<T>::R;
@ -102,7 +102,7 @@ void ParamQueue<ALIGN>::swap(ParamQueue<ALIGN> &a, ParamQueue<ALIGN> &b) {
template<class T, std::size_t ALIGN> void popto(ParamQueue<ALIGN> &pq, ParamQueue<ALIGN> *const pqout) {
if (pqout)
pqout->push(pq.template front<T>());
pq.template pop<T>();
}
@ -112,21 +112,21 @@ struct CallQueueBase {
Callptr call;
void (*popto)(ParamQueue<ALIGN>&, ParamQueue<ALIGN>*);
};
ParamQueue<ALIGN> pq;
std::deque<const Funptrs*> fq;
void popAllTo(ParamQueue<ALIGN> *const pqout);
void incpq();
template<class T> void push(const T &t, const Funptrs *const fptrs) {
while (!pq.template hasSpaceFor<T>())
incpq();
pq.push(t);
fq.push_back(fptrs);
}
~CallQueueBase() { popAllTo(0); }
};
@ -148,28 +148,28 @@ class NoParam;
template<typename Param = NoParam, std::size_t ALIGN = sizeof(DefaultTypeAlignUnion)>
class CallQueue {
CallQueueBase<void (*)(ParamQueue<ALIGN>&, Param), ALIGN> base;
template<class T> static void call(ParamQueue<ALIGN> &pq, Param p) {
pq.template front<T>()(p);
pq.template pop<T>();
}
public:
template<class T> void push(const T &t) {
static const typename CallQueueBase<void (*)(ParamQueue<ALIGN>&, Param), ALIGN>::Funptrs fptrs = { call<T>, popto<T,ALIGN> };
base.push(t, &fptrs);
}
void pop(Param p) {
base.fq.front()->call(base.pq, p);
base.fq.pop_front();
}
void pop_all(Param p) {
while (!base.fq.empty())
pop(p);
}
std::size_t size() const { return base.fq.size(); }
bool empty() const { return base.fq.empty(); }
};
@ -182,23 +182,23 @@ class CallQueue<NoParam, ALIGN> {
pq.template front<T>()();
pq.template pop<T>();
}
public:
template<class T> void push(const T &t) {
static const typename CallQueueBase<void (*)(ParamQueue<ALIGN>&), ALIGN>::Funptrs fptrs = { call<T>, popto<T,ALIGN> };
base.push(t, &fptrs);
}
void pop() {
base.fq.front()->call(base.pq);
base.fq.pop_front();
}
void pop_all() {
while (!base.fq.empty())
pop();
}
std::size_t size() const { return base.fq.size(); }
bool empty() const { return base.fq.empty(); }
};

View File

@ -42,64 +42,64 @@ public:
struct Button {
// Label used in input settings dialog. If this is empty the button won't be configurable, but will use the defaultKey.
QString label;
// Tab label used in input settings dialog.
QString category;
// Default Qt::Key. Use Qt::Key_unknown for none.
int defaultKey;
// Default alternate Qt::Key. Use Qt::Key_unknown for none.
int defaultAltKey;
// called on button press / release
struct Action {
virtual void buttonPressed() {}
virtual void buttonReleased() {}
virtual ~Action() {}
} *action;
// Default number of frames per auto-repeat press. 0 for auto-repeat disabled.
unsigned char defaultFpp;
};
private:
struct KeyMapped {
Button::Action *const action;
const unsigned char fpp;
KeyMapped(Button::Action *action, int fpp) : action(action), fpp(fpp) {}
};
struct JoyMapped {
Button::Action *const action;
const int mask;
const unsigned char fpp;
JoyMapped(Button::Action *action, int mask, int fpp) : action(action), mask(mask), fpp(fpp) {}
};
struct AutoPress {
Button::Action *action;
unsigned char fpp;
unsigned char fcnt;
AutoPress(Button::Action *action, unsigned char fpp, unsigned char fcnt) : action(action), fpp(fpp), fcnt(fcnt) {}
};
struct Config {
SDL_Event event;
unsigned char fpp;
};
template<class Map>
struct Mapping {
Map map;
std::vector<AutoPress> rapidvec;
};
typedef std::multimap<unsigned,KeyMapped> keymap_t;
typedef std::multimap<unsigned,JoyMapped> joymap_t;
typedef Mapping<keymap_t> KeyMapping;
typedef Mapping<joymap_t> JoyMapping;
const std::vector<Button> buttonInfos;
auto_vector<InputBoxPair> inputBoxPairs;
auto_vector<QSpinBox> fppBoxes;
@ -107,25 +107,25 @@ private:
Mutual<KeyMapping> keymapping;
Mutual<JoyMapping> joymapping;
const bool deleteButtonActions;
void resetMapping();
void store();
void restore();
public:
explicit InputDialog(const std::vector<Button> &buttonInfos,
bool deleteButtonActions = true,
QWidget *parent = 0);
~InputDialog();
// These invoke Button::Actions matching the key pressed/released
void keyPressEvent(const QKeyEvent *);
void keyReleaseEvent(const QKeyEvent *);
void joystickEvent(const SDL_Event&);
// Call once every frame to tick auto-repeat pressing.
void consumeAutoPress();
public slots:
void accept();
void reject();

View File

@ -54,7 +54,7 @@ public:
MediaWidget *const mw;
public:
explicit FrameBuffer(MainWindow *const mw) : mw(mw->w_) {}
class Locked : Uncopyable {
MediaWidget *mw;
PixelBuffer pb;
@ -66,80 +66,80 @@ public:
};
explicit MainWindow(MediaSource *source);
/** Sets the duration in seconds of each video frame.
* Eg. use setFrameTime(1, 60) for 60 fps video.
* Can be used to speed things up or slow things down. Audio pitch will change accordingly.
*/
void setFrameTime(long num, long denom);
/** Sets the mean number of audio samples produced by MediaSource::update for each video frame produced.
* So, for instance if you have 60 fps video, and 48 kHz audio, you would use setSamplesPerFrame(48000 / 60);
* or setSamplesPerFrame(48000, 60);
*/
void setSamplesPerFrame(long num, long denom = 1);
/** Advance a single video frame forward. It only makes sense to use this when paused. */
void frameStep();
/** Pauses audio/video production. Will set the pause bits given by bitmask. Pauses when pause is not 0. */
void pause(unsigned bitmask = 1);
/** Resumes audio/video production. Will unset the pause bits given by bitmask. Unpauses when pause is 0. */
void unpause(unsigned bitmask = 1);
/** Pauses audio/video production. Will add inc to pause. Pauses when pause is not 0. */
void incPause(unsigned inc);
/** Resumes audio/video production. Will subtract dec from pause. Unpauses when pause is 0. */
void decPause(unsigned dec);
/** Pauses audio/video production automatically when the central widget of the MainWindow loses focus.
* Calls pause(bitmask) on focusOut, and unpause(bitmask) on focusIn.
*/
void setPauseOnFocusOut(unsigned bitmask);
/** Run must be called once to initialize resources and start audio/video production. */
void run();
/** Stop can be called to release resources and stop audio/video production.
* Run will have to be called again to resume. Blocks until stopped.
*/
void stop();
bool isRunning() const;
/** The video format is the format of the video content produced by MediaSource.
* This will set the "frame buffer" to the requested format.
*/
void setVideoFormat(unsigned w, unsigned h/*, PixelBuffer::PixelFormat pf*/);
void setAspectRatio(const QSize &ar);
void setScalingMethod(ScalingMethod smet);
/** Sets the size of the video area of the MainWindow when not full screen.
* Should be used in place of methods like QMainWindow::resize, because this one doesn't screw up full screen.
* Pass sz = QSize(-1,-1) for a variable size, such that the user may adjust the window size.
* Otherwise a fixed window size equal to sz will be used. This window size does not include window borders or menus.
*/
void setWindowSize(const QSize &sz);
/** Each blitter has some properties that can be accessed through its BlitterConf. */
const BlitterConf blitterConf(std::size_t blitterNo);
const ConstBlitterConf blitterConf(std::size_t blitterNo) const;
std::size_t numBlitters() const;
const BlitterConf currentBlitterConf();
const ConstBlitterConf currentBlitterConf() const;
/** A video blitter is an engine (DirectDraw, Xv, etc.) responsible for putting video content on the screen. */
void setVideoBlitter(std::size_t blitterNo);
void setVideoFormatAndBlitter(unsigned w, unsigned h,
/*PixelBuffer::PixelFormat pf, */std::size_t blitterNo);
/** speed = N, gives N times faster than normal when fastForward is enabled. */
void setFastForwardSpeed(unsigned speed);
/** Sets the video mode that is used for full screen (see toggleFullScreen).
* A screen is basically a monitor. A different full screen mode can be selected for each screen.
* Which screen is used for full screen presentation depends on the location of the window.
@ -148,50 +148,50 @@ public:
* @param rateIndex Index of the selected refresh rate for the selected resolution.
*/
void setFullScreenMode(std::size_t screenNo, std::size_t resIndex, std::size_t rateIndex);
/** Returns the modes supported by each screen. */
const std::vector<ResInfo>& modeVector(std::size_t screen) const;
const QString screenName(std::size_t screen) const;
/** Returns the number of screens. */
std::size_t screens() const;
/** Returns the current full screen resolution index selected for a screen. */
std::size_t currentResIndex(std::size_t screen) const;
/** Returns the current full screen rate index selected for a screen. */
std::size_t currentRateIndex(std::size_t screen) const;
/** Returns the current screen that will be used for full screen. */
std::size_t currentScreen() const;
/** Toggle full screen mode on/off. QMainWindow::isFullScreen() can be used to determine the current state.
* QMainWindow::setFullScreen should not be used.
*/
void toggleFullScreen();
/** Each AudioEngine has some properties that can be accessed through its AudioEngineConf. */
const AudioEngineConf audioEngineConf(std::size_t aeNo);
const ConstAudioEngineConf audioEngineConf(std::size_t aeNo) const;
std::size_t numAudioEngines() const;
/** Audio resamplers of different performance can be selected. */
std::size_t numResamplers() const;
const char* resamplerDesc(std::size_t resamplerNo) const;
/** Sets the AudioEngine (DirectSound, ALSA, etc.) to be used for audio output,
* as well as which output sampling rate, buffer size in milliseconds, and resampler to use.
* The sampling rate does not need to match the sampling rate of the audio content produced
* by the source, as the input will be converted to match the output rate.
*/
void setAudioOut(std::size_t engineNo, unsigned srateHz, unsigned msecLatency, std::size_t resamplerNo);
/** Pause doesn't take effect immediately. Call this to wait until the worker thread is paused.
* Meant as a tool to simplify thread safety.
*/
void waitUntilPaused();
/** Temporarily pauses the worker thread and calls fun once it has paused. Then unpauses.
* Returns before fun is actually called. Fun is called in an event at a later time.
* fun should implement operator() and have a copy-constructor.
@ -199,7 +199,7 @@ public:
*/
template<class T>
void callWhenPaused(const T &fun);
/** Puts fun into a queue of functors that are called in the worker thread at a later time.
* fun should implement operator() and have a copy-constructor.
* Meant as a tool to simplify thread safety.
@ -219,19 +219,19 @@ public:
public slots:
void hideCursor();
void setFastForward(bool enable);
/** Will synchronize frame rate to vertical retrace if the blitter supports a swapInterval of at least 1.
* Picks a swapInterval closest to the current frame rate.
* Literally speeds things up or slows things down to match the swapInterval. Audio pitch will change accordingly.
*/
void setSyncToRefreshRate(bool enable);
signals:
void audioEngineFailure();
void videoBlitterFailure();
void closing();
void dwmCompositionChange();
protected:
virtual void mouseMoveEvent(QMouseEvent*);
virtual void closeEvent(QCloseEvent*);
@ -246,12 +246,12 @@ protected:
#ifdef Q_WS_WIN
virtual bool winEvent(MSG *msg, long *result);
#endif
private:
void correctFullScreenGeometry();
void doSetWindowSize(const QSize &sz);
void doShowFullScreen();
MediaWidget *const w_;
QSize winSize_;
bool fullscreen_;
@ -263,7 +263,7 @@ class CallWhenMediaWorkerPaused : Uncopyable {
public:
explicit CallWhenMediaWorkerPaused(MediaWidget &mw);
~CallWhenMediaWorkerPaused();
template<class T>
void operator()(const T &function) const { callq_.push(function); }
};
@ -280,7 +280,7 @@ class PushMediaWorkerCall : Uncopyable {
public:
explicit PushMediaWorkerCall(MediaWidget &mw);
~PushMediaWorkerCall();
template<class T>
void operator()(const T &function) const { callq_.push(function); }
};

View File

@ -48,14 +48,14 @@ protected:
explicit MediaSource(const unsigned overupdate = 0) : overupdate(overupdate) {}
public:
const unsigned overupdate;
// Reimplement to get input events. The InputDialog class may be useful.
// joystickEvent is called from the worker thread, while keyPress/ReleaseEvent
// are called from the GUI thread.
virtual void keyPressEvent(const QKeyEvent *) {}
virtual void keyReleaseEvent(const QKeyEvent *) {}
virtual void joystickEvent(const SDL_Event&) {}
/**
* Update until a new frame of video, or 'samples' audio samples have been produced.
* May postpone writing to frameBuf until generateVideoFrame is called.
@ -73,7 +73,7 @@ public:
* @return The number of stereo samples that should be output before the video frame is displayed. Or a negative number if no new video frame should be displayed.
*/
virtual long update(const PixelBuffer &frameBuf, qint16 *soundBuf, long &samples) = 0;
/**
* This is called after update returns, but only when it is clear that the frame won't be skipped.
* This gives an opportunity to delay heavy video work until it is clear that it will be used.
@ -82,7 +82,7 @@ public:
* Heavy post-processing of video is a good candidate for this method.
*/
virtual void generateVideoFrame(const PixelBuffer &/*fb*/) {}
virtual ~MediaSource() {}
};

View File

@ -50,7 +50,7 @@ public:
const T* operator->() const { return &lc.t; }
const T& get() const { return lc.t; }
};
class TryLocked : Uncopyable {
Mutual *const lc;
public:

View File

@ -33,7 +33,7 @@ struct PixelBuffer {
* umask: 0x000000ff, ymask: 0xff00ff00, vmask: 0x00ff0000 (little endian)
*/
enum PixelFormat { RGB32, RGB16, UYVY };
void *data;
int pitch; // number of pixels (not bytes) between line N and line N+1
unsigned width, height;

View File

@ -32,7 +32,7 @@ class QSpinBox;
*/
class SoundDialog : public QDialog {
Q_OBJECT
const MainWindow *const mw;
QVBoxLayout *const topLayout;
QComboBox *const engineSelector;
@ -44,14 +44,14 @@ class SoundDialog : public QDialog {
int resamplerNum;
int rate_;
int latency_;
void store();
void restore();
private slots:
void engineChange(int index);
void rateIndexChange(int index);
public:
explicit SoundDialog(const MainWindow *mw, QWidget *parent = 0);
~SoundDialog();
@ -59,9 +59,9 @@ public:
int resamplerNo() const { return resamplerNum; }
int rate() const { return rate_; }
int latency() const { return latency_; };
static void applySettings(MainWindow *mw, const SoundDialog *sd);
public slots:
void accept();
void reject();

View File

@ -45,11 +45,11 @@ public:
struct VideoSourceInfo {
// label used in the video dialog combobox.
QString label;
unsigned width;
unsigned height;
};
private:
class PersistInt {
const QString key_;
@ -60,11 +60,11 @@ private:
PersistInt & operator=(int i) { i_ = i; return *this; }
operator int() const { return i_; }
};
class EngineSelector {
QComboBox *const comboBox_;
PersistInt index_;
public:
explicit EngineSelector(const MainWindow *mw);
void addToLayout(QBoxLayout *topLayout);
@ -73,13 +73,13 @@ private:
void restore();
int index() const { return index_; }
};
class ScalingMethodSelector {
QRadioButton *const unrestrictedScalingButton_;
QRadioButton *const keepRatioButton_;
QRadioButton *const integerScalingButton_;
PersistInt scaling_;
public:
ScalingMethodSelector();
void addToLayout(QLayout *layout);
@ -88,12 +88,12 @@ private:
void restore();
ScalingMethod scalingMethod() const { return static_cast<ScalingMethod>(static_cast<int>(scaling_)); }
};
class SourceSelector {
QLabel *const label_;
QComboBox *const comboBox_;
PersistInt index_;
public:
SourceSelector(const QString &sourcesLabel, const std::vector<VideoSourceInfo> &sourceInfos);
void addToLayout(QBoxLayout *layout);
@ -103,12 +103,12 @@ private:
void restore();
int index() const { return index_; }
};
class FullResSelector {
QComboBox *const comboBox_;
const QString key_;
int index_;
void fillComboBox(const QSize &sourceSize, const std::vector<ResInfo> &resVector);
public:
FullResSelector(const QString &key, int defaultIndex,
@ -121,12 +121,12 @@ private:
void setSourceSize(const QSize &sourceSize, const std::vector<ResInfo> &resVector);
int index() const { return index_; }
};
class FullHzSelector {
QComboBox *const comboBox_;
const QString key_;
int index_;
public:
FullHzSelector(const QString &key, const std::vector<short> &rates, int defaultIndex);
~FullHzSelector();
@ -137,7 +137,7 @@ private:
void setRates(const std::vector<short> &rates);
int index() const { return index_; }
};
const MainWindow *const mw;
QVBoxLayout *const topLayout;
QWidget *engineWidget;
@ -146,7 +146,7 @@ private:
SourceSelector sourceSelector;
const auto_vector<FullResSelector> fullResSelectors;
const auto_vector<FullHzSelector> fullHzSelectors;
static auto_vector<FullResSelector> makeFullResSelectors(const QSize &sourceSize, const MainWindow *mw);
static auto_vector<FullHzSelector> makeFullHzSelectors(
const auto_vector<FullResSelector> &fullResSelectors, const MainWindow *mw);
@ -172,7 +172,7 @@ public:
void setVideoSources(const std::vector<VideoSourceInfo> &sourceInfos);
void setSourceSize(const QSize &sourceSize);
ScalingMethod scalingMethod() const { return scalingMethodSelector.scalingMethod(); }
public slots:
void accept();
void reject();

View File

@ -33,16 +33,16 @@ typedef struct {
uint8_t num;
uint8_t zero;
};
uint32_t id;
};
union {
struct {
int16_t xrel;
int16_t yrel;
};
int32_t value;
};
} SDL_Event;

View File

@ -46,14 +46,14 @@ void SDL_SetEventFilter(const unsigned int f) {
int SDL_PollEvent(SDL_Event *const event) {
if (!event || queue.empty())
return 0;
{
const SDL_Event &front = queue.front();
event->id = front.id;
event->value = front.value;
}
queue.pop_front();
return 1;
}

View File

@ -35,16 +35,16 @@ struct _SDL_Joystick {
int nhats; /* Number of hats on the joystick */
Uint8 *hats; /* Current hat states */
int nballs; /* Number of trackballs on the joystick */
struct balldelta {
int dx;
int dy;
} *balls; /* Current ball motion deltas */
int nbuttons; /* Number of buttons on the joystick */
Uint8 *buttons; /* Current button states */
struct joystick_hwdata *hwdata; /* Driver dependent information */
int ref_count; /* Reference count for multiple opens */

View File

@ -29,7 +29,7 @@ class AudioEngine {
QMutex mut;
const QString nameString_;
int rate_;
protected:
virtual int doInit(int rate, unsigned msLatency) = 0;
virtual void doAcceptSettings() {}
@ -39,10 +39,10 @@ public:
unsigned fromUnderrun;
unsigned fromOverflow;
};
const QString& nameString() const { return nameString_; }
int rate() const { return rate_; }
AudioEngine(const QString &name) : nameString_(name), rate_(0) {}
virtual ~AudioEngine() {}
int init(int rate, unsigned msLatency) { QMutexLocker l(&mut); return rate_ = doInit(rate, msLatency); }
@ -54,14 +54,14 @@ public:
/** @return success */
virtual bool flushPausedBuffers() const { return false; }
virtual int write(void *buffer, unsigned samples, BufferState &preBufState_out, long &rate_out) {
preBufState_out = bufferState();
const int ret = write(buffer, samples);
rate_out = rateEstimate();
return ret;
}
virtual QWidget* settingsWidget() const { return 0; }
void acceptSettings() { QMutexLocker l(&mut); doAcceptSettings(); }
virtual void rejectSettings() const {}

View File

@ -34,77 +34,77 @@ AlsaEngine::~AlsaEngine() {
int AlsaEngine::doInit(const int inrate, const unsigned latency) {
unsigned rate = inrate;
if (snd_pcm_open(&pcm_handle, conf.device(), SND_PCM_STREAM_PLAYBACK, 0) < 0) {
std::fprintf(stderr, "Error opening PCM device %s\n", conf.device());
pcm_handle = 0;
goto fail;
}
{
snd_pcm_hw_params_t *hwparams;
snd_pcm_hw_params_alloca(&hwparams);
if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
std::fprintf(stderr, "Can not configure this PCM device.\n");
goto fail;
}
if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
std::fprintf(stderr, "Error setting access.\n");
goto fail;
}
if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16) < 0) {
std::fprintf(stderr, "Error setting format.\n");
goto fail;
}
if (snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0) < 0) {
std::fprintf(stderr, "Error setting rate.\n");
goto fail;
}
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) {
std::fprintf(stderr, "Error setting channels.\n");
goto fail;
}
{
unsigned ulatency = latency * 1000;
if (snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams, &ulatency, 0) < 0) {
std::fprintf(stderr, "Error setting buffer latency %u.\n", ulatency);
goto fail;
}
}
{
unsigned val = 16;
snd_pcm_hw_params_set_periods_max(pcm_handle, hwparams, &val, 0);
}
if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) {
std::fprintf(stderr, "Error setting HW params.\n");
goto fail;
}
{
snd_pcm_uframes_t bSize = 0;
if (snd_pcm_hw_params_get_buffer_size(hwparams, &bSize) < 0) {
std::fprintf(stderr, "Error getting buffer size\n");
goto fail;
}
bufSize = bSize;
}
}
{
snd_pcm_sw_params_t *swparams;
snd_pcm_sw_params_alloca(&swparams);
if (snd_pcm_sw_params_current(pcm_handle, swparams) < 0) {
std::fprintf(stderr, "Error getting current swparams\n");
} else if (snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, bufSize) < 0) {
@ -113,12 +113,12 @@ int AlsaEngine::doInit(const int inrate, const unsigned latency) {
std::fprintf(stderr, "Error setting swparams\n");
}
}
prevfur = 0;
est.init(rate, rate, bufSize);
return rate;
fail:
uninit();
return -1;
@ -127,29 +127,29 @@ fail:
void AlsaEngine::uninit() {
if (pcm_handle)
snd_pcm_close(pcm_handle);
pcm_handle = 0;
}
int AlsaEngine::write(void *const buffer, const unsigned samples, const BufferState &bstate) {
bool underrun = false;
if (bstate.fromUnderrun == 0 || snd_pcm_state(pcm_handle) != SND_PCM_STATE_RUNNING) {
underrun = true;
} else if (prevfur > bstate.fromUnderrun && bstate.fromUnderrun != BufferState::NOT_SUPPORTED) {
est.feed(prevfur - bstate.fromUnderrun);
}
prevfur = bstate.fromUnderrun + samples;
for (int n = 4; n-- && snd_pcm_writei(pcm_handle, buffer, samples) < 0;) {
snd_pcm_prepare(pcm_handle);
underrun = true;
}
if (underrun)
est.reset();
return 0;
}
@ -166,22 +166,22 @@ int AlsaEngine::write(void *const buffer, const unsigned samples, BufferState &p
const AudioEngine::BufferState AlsaEngine::bufferState() const {
BufferState s;
snd_pcm_sframes_t avail;
snd_pcm_hwsync(pcm_handle);
avail = snd_pcm_avail_update(pcm_handle);
if (avail == -EPIPE)
avail = bufSize;
if (avail < 0) {
s.fromOverflow = s.fromUnderrun = BufferState::NOT_SUPPORTED;
} else {
if (static_cast<unsigned>(avail) > bufSize)
avail = bufSize;
s.fromUnderrun = bufSize - avail;
s.fromOverflow = avail;
}
return s;
}

View File

@ -30,11 +30,11 @@ class AlsaEngine : public AudioEngine {
snd_pcm_t *pcm_handle;
unsigned bufSize;
unsigned prevfur;
int doInit(int rate, unsigned latency);
void doAcceptSettings() { conf.acceptSettings(); }
int write(void *buffer, unsigned samples, const BufferState &bstate);
public:
AlsaEngine();
~AlsaEngine();

View File

@ -26,22 +26,22 @@ AoEngine::~AoEngine() {
int AoEngine::doInit(const int rate, unsigned /*latency*/) {
ao_initialize();
aoDevice = NULL;
ao_sample_format sampleFormat = { 16, rate, 2, AO_FMT_NATIVE };
int aoDriverId = ao_default_driver_id();
if (aoDriverId != -1) {
aoDevice = ao_open_live(aoDriverId, &sampleFormat, NULL);
}
if (aoDevice == NULL) {
ao_shutdown();
return -1;
}
return sampleFormat.rate;
}
@ -49,7 +49,7 @@ void AoEngine::uninit() {
if (aoDevice) {
ao_close(aoDevice);
aoDevice = NULL;
ao_shutdown();
}
}
@ -57,6 +57,6 @@ void AoEngine::uninit() {
int AoEngine::write(void *const buffer, const unsigned samples) {
if (ao_play(aoDevice, reinterpret_cast<char*>(buffer), samples * 4) == 0)
return -1;
return 0;
}

View File

@ -25,9 +25,9 @@
class AoEngine : public AudioEngine {
ao_device *aoDevice;
int doInit(int rate, unsigned latency);
public:
AoEngine();
~AoEngine();

View File

@ -26,12 +26,12 @@ namespace {
static int createMutex(pthread_mutex_t* &mutptr) {
mutptr = new pthread_mutex_t;
const int ret = pthread_mutex_init(mutptr, 0);
if (ret) {
delete mutptr;
mutptr = 0;
}
return ret;
}
@ -47,12 +47,12 @@ static void destroyMutex(pthread_mutex_t* &mutptr) {
static int createCond(pthread_cond_t* &condptr) {
condptr = new pthread_cond_t;
const int ret = pthread_cond_init(condptr, 0);
if (ret) {
delete condptr;
condptr = 0;
}
return ret;
}
@ -66,13 +66,13 @@ static void destroyCond(pthread_cond_t* &condptr) {
class MutexLocker : Uncopyable {
pthread_mutex_t *const mut;
public:
const int err;
explicit MutexLocker(pthread_mutex_t *mut) : mut(mut), err(pthread_mutex_lock(mut)) {
}
~MutexLocker() {
if (!err)
pthread_mutex_unlock(mut);
@ -98,22 +98,22 @@ CoreAudioEngine::~CoreAudioEngine() {
unsigned CoreAudioEngine::read(void *const stream, unsigned frames, const Float64 rateScalar) {
MutexLocker mutlock(mutex);
if (!mutlock.err) {
{
const Float64 rateEst = rate() / rateScalar;
// rateVar = (rateVar * 15 + std::fabs(rateEst - this->rateEst)) * (1.0 / 16.0);
this->rateEst = rateEst;
}
if (frames > rbuf.used() / 2)
frames = rbuf.used() / 2;
rbuf.read(reinterpret_cast<SInt16*>(stream), frames * 2);
pthread_cond_signal(availCond);
}
return frames;
}
@ -122,14 +122,14 @@ OSStatus CoreAudioEngine::renderProc(void *inRefCon, AudioUnitRenderActionFlags
{
ioData->mBuffers[0].mDataByteSize = reinterpret_cast<CoreAudioEngine*>(
inRefCon)->read(ioData->mBuffers[0].mData, inNumFrames, inTimeStamp->mRateScalar) * 4;
return 0;
}
int CoreAudioEngine::doInit(const int rate, const unsigned latency) {
{
Component comp;
{
ComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
@ -137,31 +137,31 @@ int CoreAudioEngine::doInit(const int rate, const unsigned latency) {
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
if ((comp = FindNextComponent(0, &desc)) == 0) {
std::fprintf(stderr, "Failed to find output unit component\n");
goto fail;
}
}
if (ComponentResult err = OpenAComponent(comp, &outUnit)) {
std::fprintf(stderr, "Failed to open output unit component: %d\n", static_cast<int>(err));
goto fail;
}
outUnitState = UNIT_OPENED;
}
if (ComponentResult err = AudioUnitInitialize(outUnit)) {
std::fprintf(stderr, "Failed to initialize output unit component: %d\n", static_cast<int>(err));
goto fail;
}
outUnitState = UNIT_INITED;
{
AudioStreamBasicDescription desc;
desc.mSampleRate = rate;
desc.mFormatID = kAudioFormatLinearPCM;
desc.mChannelsPerFrame = 2;
@ -169,59 +169,59 @@ int CoreAudioEngine::doInit(const int rate, const unsigned latency) {
desc.mFramesPerPacket = 1;
desc.mBytesPerPacket = desc.mBytesPerFrame = 4;
desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
#ifdef WORDS_BIGENDIAN
desc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
#endif
if (ComponentResult err = AudioUnitSetProperty(outUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &desc, sizeof desc)) {
std::fprintf(stderr, "Failed to set the input format: %d\n", static_cast<int>(err));
goto fail;
}
}
{
AURenderCallbackStruct renderCallback;
renderCallback.inputProc = renderProc;
renderCallback.inputProcRefCon = this;
if (ComponentResult err = AudioUnitSetProperty(outUnit,
kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof renderCallback)) {
std::fprintf(stderr, "Failed to set render callback: %d\n", static_cast<int>(err));
goto fail;
}
}
if (int err = createMutex(mutex)) {
std::fprintf(stderr, "Failed to create mutex: %d\n", err);
goto fail;
}
if (int err = createCond(availCond)) {
std::fprintf(stderr, "Failed to create condition variable: %d\n", err);
goto fail;
}
rbuf.reset(((rate * latency + 500) / 1000) * 2);
rbuf.fill(0);
rateEst = rate;
// rateVar = rate >> 12;
return rate;
fail:
uninit();
return -1;
return -1;
}
void CoreAudioEngine::uninit() {
if (outUnitState >= UNIT_INITED)
AudioUnitUninitialize(outUnit);
if (outUnitState >= UNIT_OPENED)
CloseComponent(outUnit);
destroyMutex(mutex);
destroyCond(availCond);
outUnitState = UNIT_CLOSED;
@ -242,15 +242,15 @@ int CoreAudioEngine::doWrite(void *const buffer, unsigned samples) {
std::fprintf(stderr, "Failed to start output unit: %d\n", static_cast<int>(err));
return -1;
}
running = true;
}
SInt16 *inBuf = reinterpret_cast<SInt16*>(buffer);
{
std::size_t avail;
while ((avail = rbuf.avail() / 2) < samples) {
rbuf.write(inBuf, avail * 2);
inBuf += avail * 2;
@ -258,18 +258,18 @@ int CoreAudioEngine::doWrite(void *const buffer, unsigned samples) {
pthread_cond_wait(availCond, mutex);
}
}
rbuf.write(inBuf, samples * 2);
return 0;
}
int CoreAudioEngine::write(void *const buffer, const unsigned samples, BufferState &preBufState_out, long &rate_out) {
MutexLocker mutlock(mutex);
if (mutlock.err)
return -1;
preBufState_out.fromUnderrun = rbuf.used() / 2;
preBufState_out.fromOverflow = rbuf.avail() / 2;
rate_out = rateEst + 0.5;
@ -279,10 +279,10 @@ int CoreAudioEngine::write(void *const buffer, const unsigned samples, BufferSta
int CoreAudioEngine::write(void *const buffer, const unsigned samples) {
MutexLocker mutlock(mutex);
if (mutlock.err)
return -1;
return doWrite(buffer, samples);
}

View File

@ -35,13 +35,13 @@ class CoreAudioEngine : public AudioEngine, private Uncopyable {
pthread_cond_t *availCond;
Float64 rateEst;
bool running;
static OSStatus renderProc(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData);
unsigned read(void *stream, unsigned frames, Float64 rateScalar);
int doInit(int rate, unsigned latency);
int doWrite(void *buffer, unsigned frames);
public:
CoreAudioEngine();
~CoreAudioEngine();

View File

@ -37,7 +37,7 @@ useCustomDev(false)
confWidget->layout()->setMargin(0);
confWidget->layout()->addWidget(customDevBox);
confWidget->layout()->addWidget(customDevEdit);
{
QSettings settings;
settings.beginGroup(confgroup);
@ -45,7 +45,7 @@ useCustomDev(false)
customDevStr = settings.value("customDevStr", customDevStr).toByteArray();
settings.endGroup();
}
customDevBoxChange(customDevBox->isChecked());
connect(customDevBox, SIGNAL(toggled(bool)), this, SLOT(customDevBoxChange(bool)));
rejectSettings();

View File

@ -29,7 +29,7 @@ class QWidget;
class CustomDevConf : public QObject {
Q_OBJECT
const char *const defaultstr;
const char *const confgroup;
const scoped_ptr<QWidget> confWidget;
@ -37,10 +37,10 @@ class CustomDevConf : public QObject {
QLineEdit *const customDevEdit;
QByteArray customDevStr;
bool useCustomDev;
private slots:
void customDevBoxChange(bool checked);
public:
CustomDevConf(const char *desc, const char *defaultstr, const char *confgroup, const char *customdevstr = 0);
~CustomDevConf();

View File

@ -23,7 +23,7 @@
class NullAudioEngine : public AudioEngine {
int doInit(int rate, unsigned /*latency*/) { return rate; }
public:
NullAudioEngine() : AudioEngine("Null") {}
int write(void */*buffer*/, unsigned /*samples*/) { return 0; }

View File

@ -35,15 +35,15 @@ static const char* errorToString(ALenum error) {
case AL_INVALID_OPERATION: return "invalid operation";
case AL_OUT_OF_MEMORY: return "out of memory";
}
return "";
}
static ALint getSourcei(ALuint source, ALenum pname) {
ALint value = 0;
alGetSourcei(source, pname, &value);
return value;
}
@ -66,10 +66,10 @@ OpenAlEngine::~OpenAlEngine() {
void OpenAlEngine::deleteProcessedBufs() const {
ALint processed = getSourcei(source, AL_BUFFERS_PROCESSED);
while (processed--) {
ALuint bid = 0;
alSourceUnqueueBuffers(source, 1, &bid);
alDeleteBuffers(1, &bid);
}
@ -78,52 +78,52 @@ void OpenAlEngine::deleteProcessedBufs() const {
int OpenAlEngine::doInit(const int rate, unsigned latency) {
class FailureCleaner {
OpenAlEngine *const engine;
public:
bool failed;
FailureCleaner(OpenAlEngine *engine) : engine(engine), failed(true) {}
~FailureCleaner() {
if (failed)
engine->uninit();
}
} failureCleaner(this);
ALenum error;
if (!(device = alcOpenDevice(NULL))) {
std::fprintf(stderr, "alcOpenDevice error\n");
return -1;
}
if (!(context = alcCreateContext(device, NULL))) {
std::fprintf(stderr, "alcCreateContext error\n");
return -1;
}
alGetError();
alcMakeContextCurrent(context);
if ((error = alGetError()) != AL_NO_ERROR) {
std::fprintf(stderr, "alcMakeContextCurrent error: %s\n", errorToString(error));
return -1;
}
alGenSources (1, &source);
if ((error = alGetError()) != AL_NO_ERROR) {
std::fprintf(stderr, "alGenSources error: %s\n", errorToString(error));
return -1;
}
failureCleaner.failed = false;
buffers = rate * latency / (BUF_SZ * 1000);
++buffers;
// std::printf("buffers: %u\n", buffers);
buf = new qint16[BUF_SZ * 2];
bufPos = 0;
return rate;
}
@ -131,28 +131,28 @@ void OpenAlEngine::uninit() {
if (context) {
if (alIsSource(source)) {
alSourceStop(source);
ALint queued = getSourcei(source, AL_BUFFERS_QUEUED);
while (queued--) {
ALuint bid = 0;
alSourceUnqueueBuffers(source, 1, &bid);
alDeleteBuffers(1, &bid);
}
alDeleteSources(1, &source);
}
alcMakeContextCurrent(NULL);
alcDestroyContext(context);
}
if (device)
alcCloseDevice(device);
delete []buf;
buf = NULL;
context = NULL;
device = NULL;
@ -163,7 +163,7 @@ int OpenAlEngine::write(void *const data, const unsigned samples) {
{
unsigned total = samples + bufPos;
const qint16 *src = static_cast<const qint16*>(data);
while (total >= BUF_SZ) {
if (getSourcei(source, AL_BUFFERS_QUEUED) >= static_cast<int>(buffers)) {
while (getSourcei(source, AL_BUFFERS_PROCESSED) < 1 && getSourcei(source, AL_SOURCE_STATE) == AL_PLAYING) {
@ -174,17 +174,17 @@ int OpenAlEngine::write(void *const data, const unsigned samples) {
nanosleep(&tspec, NULL);
#endif
}
ALuint bid = 0;
alSourceUnqueueBuffers(source, 1, &bid);
alDeleteBuffers(1, &bid);
}
std::memcpy(buf + bufPos * 2, src, (BUF_SZ - bufPos) * 2 * sizeof *buf);
src += (BUF_SZ - bufPos) * 2;
total -= BUF_SZ;
bufPos = 0;
{
ALuint bufid = 0;
alGenBuffers(1, &bufid);
@ -192,40 +192,40 @@ int OpenAlEngine::write(void *const data, const unsigned samples) {
alSourceQueueBuffers(source, 1, &bufid);
}
}
std::memcpy(buf + bufPos * 2, src, (total - bufPos) * 2 * sizeof *buf);
bufPos = total;
}
if (getSourcei(source, AL_SOURCE_STATE) != AL_PLAYING) {
//std::printf("UNDERRUN!!!!!!!!!!!!!!!!!!!!!!!!!\n");
alSourcePlay(source);
}
//if (alGetError() != AL_NO_ERROR)
// return -1;
return 0;
}
const AudioEngine::BufferState OpenAlEngine::bufferState() const {
deleteProcessedBufs();
unsigned fromUnderrun = 0;
{
const ALint queued = getSourcei(source, AL_BUFFERS_QUEUED);
if (queued > 0)
fromUnderrun = queued * BUF_SZ - (BUF_SZ >> 1);
}
fromUnderrun += bufPos;
const BufferState s = { fromUnderrun: fromUnderrun, fromOverflow: fromUnderrun > (buffers + 1) * BUF_SZ ? 0 : (buffers + 1) * BUF_SZ - fromUnderrun };
//std::printf("fromUnderrun: %u\n", s.fromUnderrun);
return s;
}

View File

@ -40,10 +40,10 @@ class OpenAlEngine : public AudioEngine {
ALuint source;
unsigned buffers;
unsigned bufPos;
void deleteProcessedBufs() const;
int doInit(int rate, unsigned latency);
public:
OpenAlEngine();
~OpenAlEngine();

View File

@ -50,66 +50,66 @@ int OssEngine::doInit(int speed, const unsigned latency) {
std::perror(conf.device());
goto fail;
}
{
int channels = 2;
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
std::perror("SNDCTL_DSP_CHANNELS");
goto fail;
}
if (channels != 2) {
std::fprintf(stderr, "oss: unsupported number of channels\n");
goto fail;
}
}
{
int format = AFMT_S16_NE;
if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
std::perror("SNDCTL_DSP_SETFMT");
goto fail;
}
if (format != AFMT_S16_NE) {
std::fprintf(stderr, "oss: unsupported format\n");
goto fail;
}
}
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed) == -1) {
std::perror("SNDCTL_DSP_SPEED");
goto fail;
}
{
int arg = 0x60000 | static_cast<int>(std::log(speed * latency * 4 / 6000.0) / std::log(2.0) + 0.5);
if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &arg) == -1) {
std::perror("SNDCTL_DSP_SETFRAGMENT");
// goto fail;
}
}
{
audio_buf_info info;
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) {
std::perror("SNDCTL_DSP_GETOSPACE");
goto fail;
}
bufSize = info.bytes >> 2;
fragSize = info.fragsize >> 2;
}
prevbytes = 0;
est.init(speed, speed, bufSize);
return speed;
fail:
uninit();
return -1;
@ -118,14 +118,14 @@ fail:
void OssEngine::uninit() {
if (audio_fd != -1)
close(audio_fd);
audio_fd = -1;
}
int OssEngine::write(void *const buffer, const unsigned samples, const BufferState &bstate) {
if (bstate.fromUnderrun != BufferState::NOT_SUPPORTED) {
count_info ci;
if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &ci) != -1) {
if (static_cast<unsigned>(ci.bytes) > prevbytes) {
if (bstate.fromUnderrun > fragSize)
@ -133,14 +133,14 @@ int OssEngine::write(void *const buffer, const unsigned samples, const BufferSta
else
est.reset();
}
prevbytes = ci.bytes;
}
}
if (::write(audio_fd, buffer, samples * 4) != static_cast<int>(samples * 4))
return -1;
return 0;
}
@ -157,7 +157,7 @@ int OssEngine::write(void *const buffer, const unsigned samples, BufferState &pr
const AudioEngine::BufferState OssEngine::bufferState() const {
BufferState s;
audio_buf_info info;
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) {
s.fromOverflow = s.fromUnderrun = BufferState::NOT_SUPPORTED;
} else {
@ -165,10 +165,10 @@ const AudioEngine::BufferState OssEngine::bufferState() const {
info.bytes = 0;
else if (static_cast<unsigned>(info.bytes >> 2) > bufSize)
info.bytes = bufSize << 2;
s.fromUnderrun = bufSize - (info.bytes >> 2);
s.fromOverflow = info.bytes >> 2;
}
return s;
}

View File

@ -30,11 +30,11 @@ class OssEngine : public AudioEngine {
unsigned bufSize;
unsigned fragSize;
unsigned prevbytes;
int doInit(int rate, unsigned latency);
void doAcceptSettings() { conf.acceptSettings(); }
int write(void *buffer, unsigned samples, const BufferState &bstate);
public:
OssEngine();
~OssEngine();

View File

@ -74,12 +74,12 @@ void BlitterContainer::setBlitter(BlitterWidget *const blitter_in) {
if (blitter_ != blitter_in) {
// if (blitter_)
// blitter_->setParent(0);
blitter_ = blitter_in;
// if (blitter_)
// blitter_->setParent(this);
updateLayout();
testExclusive();
}

View File

@ -32,15 +32,15 @@ class BlitterContainer : public QWidget {
ScalingMethod scalingMethod_;
bool parentExclusive;
bool cursorHidden_;
void doLayout(int w, int h);
void testExclusive();
void updateLayout() { doLayout(width(), height()); }
protected:
void moveEvent(QMoveEvent *event);
void resizeEvent(QResizeEvent *event);
public:
explicit BlitterContainer(QWidget *parent = 0);
~BlitterContainer();

View File

@ -51,15 +51,15 @@ class BlitterWidget : public QWidget {
const QString nameString_;
const unsigned maxSwapInterval_;
bool paused;
protected:
virtual void privSetPaused(const bool paused) { setUpdatesEnabled(paused); }
virtual void setBufferDimensions(unsigned width, unsigned height) = 0;
// use these if modifying pixel buffer in the sync method, or in an event method.
void lockPixelBuffer() { vbl.lock(); }
void unlockPixelBuffer() { vbl.unlock(); }
void setPixelBuffer(void *pixels, PixelBuffer::PixelFormat format, unsigned pitch) {
pixbuf.data = pixels;
pixbuf.pitch = pitch;
@ -82,24 +82,24 @@ public:
virtual void blit() = 0;
virtual void draw() {}
virtual bool isUnusable() const { return false; }
void setVideoFormat(unsigned width, unsigned height/*, PixelBuffer::PixelFormat pf*/) {
pixbuf.width = width;
pixbuf.height = height;
setBufferDimensions(width, height);
// return pf == pixbuf.pixelFormat;
}
virtual void setCorrectedGeometry(int w, int h, int new_w, int new_h) {
setGeometry((w - new_w) >> 1, (h - new_h) >> 1, new_w, new_h);
}
virtual WId hwnd() const { return winId(); }
virtual long frameTimeEst() const { return 0; }
virtual long sync() { return 0; }
virtual void setExclusive(bool) {}
virtual void setSwapInterval(unsigned) {}
virtual QWidget* settingsWidget() const { return 0; }
virtual void acceptSettings() {}
virtual void rejectSettings() const {}

View File

@ -325,7 +325,7 @@ void QGLBlitter::blit() {
void QGLBlitter::draw() {
if (buffer)
subWidget->updateTexture(inBuffer().data == buffer ? buffer + buffer.size() / 2 : buffer);
if (subWidget->doubleBuffer())
subWidget->blit();
}

View File

@ -27,7 +27,7 @@
class QGLBlitter : public BlitterWidget {
class SubWidget;
const DwmControlHwndChange hwndChange_;
FtEst ftEst;
const scoped_ptr<QWidget> confWidget;
@ -37,14 +37,14 @@ class QGLBlitter : public BlitterWidget {
unsigned swapInterval_;
int dhz;
scoped_ptr<SubWidget> subWidget;
void resetSubWidget();
void privSetPaused(const bool /*paused*/) {}
protected:
void setBufferDimensions(unsigned int width, unsigned int height);
void resizeEvent(QResizeEvent *event);
public:
explicit QGLBlitter(VideoBufferLocker vbl, DwmControlHwndChange hwndChange, QWidget *parent = 0);
~QGLBlitter();
@ -57,10 +57,10 @@ public:
void draw();
long sync();
QWidget* settingsWidget() const { return confWidget.get(); }
void acceptSettings();
void rejectSettings() const;
void setSwapInterval(unsigned);
void rateChange(int dhz);
void compositionEnabledChange();

View File

@ -63,7 +63,7 @@ void QPainterBlitter::draw() {
void QPainterBlitter::paintEvent(QPaintEvent *const event) {
if (!image.get())
return;
QImage *const frontImage = image2.get() && backImage == image.get() ? image2.get() : image.get();
QPainter painter(this);
painter.setClipRegion(event->region());
@ -94,13 +94,13 @@ void QPainterBlitter::setBufferDimensions(const unsigned int w, const unsigned i
void QPainterBlitter::uninit() {
image.reset();
if (image2.get()) {
image2.reset();
} else {
delete[] buffer;
}
buffer = NULL;
}

View File

@ -33,12 +33,12 @@ class QPainterBlitter : public BlitterWidget {
scoped_ptr<QImage> image2;
PersistCheckBox bf_;
union { quint32 *buffer; QImage *backImage; };
protected:
void privSetPaused(bool) {}
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
public:
explicit QPainterBlitter(VideoBufferLocker vbl, QWidget *parent = 0);
~QPainterBlitter();

View File

@ -57,7 +57,7 @@ public:
X11Blitter::ShmBlitter::ShmBlitter(const unsigned width, const unsigned height, const VisInfo &visInfo, const bool db) : doubleBuffer(db) {
shminfo.shmaddr = NULL;
ximage = XShmCreateImage(QX11Info::display(), reinterpret_cast<Visual*>(visInfo.visual), visInfo.depth, ZPixmap, NULL, &shminfo, width, height);
if (ximage == NULL) {
std::cerr << "failed to create shm ximage\n";
} else {
@ -75,7 +75,7 @@ X11Blitter::ShmBlitter::~ShmBlitter() {
XSync(QX11Info::display(), 0);
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
XFree(ximage);
}
}
@ -98,7 +98,7 @@ bool X11Blitter::ShmBlitter::failed() const {
void* X11Blitter::ShmBlitter::pixels() const {
if (!ximage)
return 0;
if (!doubleBuffer)
return ximage->data;
@ -112,7 +112,7 @@ unsigned X11Blitter::ShmBlitter::pitch() const {
class X11Blitter::PlainBlitter : public X11Blitter::SubBlitter, Uncopyable {
XImage *const ximage;
char *data;
bool doubleBuffer() const { return data; }
public:
PlainBlitter(unsigned int width, unsigned int height, const VisInfo &visInfo, bool db);
@ -131,7 +131,7 @@ X11Blitter::PlainBlitter::PlainBlitter(const unsigned int width, const unsigned
{
if (ximage) {
ximage->data = new char[ximage->bytes_per_line * ximage->height << db];
if (db)
data = ximage->data;
} else {
@ -145,7 +145,7 @@ X11Blitter::PlainBlitter::~PlainBlitter () {
delete[] data;
} else
delete[] ximage->data;
XFree(ximage);
}
}
@ -169,10 +169,10 @@ bool X11Blitter::PlainBlitter::failed() const {
void* X11Blitter::PlainBlitter::pixels() const {
if (!ximage)
return 0;
if (!doubleBuffer())
return ximage->data;
return ximage->data == data ? data + ximage->bytes_per_line * ximage->height : data;
}
@ -188,16 +188,16 @@ static XVisualInfo* getVisualPtr(unsigned depth, int c_class, unsigned long rmas
vinfo_template.red_mask = rmask;
vinfo_template.green_mask = gmask;
vinfo_template.blue_mask = bmask;
int nitems = 0;
XVisualInfo *vinfos = XGetVisualInfo(QX11Info::display(),
VisualScreenMask|(depth ? VisualDepthMask : 0)|VisualClassMask|VisualRedMaskMask|VisualGreenMaskMask|VisualBlueMaskMask,
&vinfo_template, &nitems);
if (nitems > 0) {
return vinfos;
}
return NULL;
}
@ -205,38 +205,38 @@ static XVisualInfo* getVisualPtr() {
{
XVisualInfo vinfo_template;
vinfo_template.visualid = XVisualIDFromVisual(XDefaultVisual(QX11Info::display(), QX11Info::appScreen()));
int nitems = 0;
XVisualInfo *vinfos = XGetVisualInfo(QX11Info::display(), VisualIDMask, &vinfo_template, &nitems);
if (nitems > 0) {
if ((vinfos->depth == 24 && vinfos->red_mask == 0xFF0000 && vinfos->green_mask == 0x00FF00 && vinfos->blue_mask == 0x0000FF) ||
(vinfos->depth <= 16 && vinfos->red_mask == 0xF800 && vinfos->green_mask == 0x07E0 && vinfos->blue_mask == 0x001F)) {
return vinfos;
}
XFree(vinfos);
}
}
if (XVisualInfo *visual = getVisualPtr(24, TrueColor, 0xFF0000, 0x00FF00, 0x0000FF))
return visual;
if (XVisualInfo *visual = getVisualPtr(16, TrueColor, 0xF800, 0x07E0, 0x001F))
return visual;
if (XVisualInfo *visual = getVisualPtr(0, TrueColor, 0xFF0000, 0x00FF00, 0x0000FF))
return visual;
if (XVisualInfo *visual = getVisualPtr(0, TrueColor, 0xF800, 0x07E0, 0x001F))
return visual;
if (XVisualInfo *visual = getVisualPtr(0, DirectColor, 0xFF0000, 0x00FF00, 0x0000FF))
return visual;
if (XVisualInfo *visual = getVisualPtr(0, DirectColor, 0xF800, 0x07E0, 0x001F))
return visual;
return NULL;
}
@ -247,14 +247,14 @@ bf_(new QCheckBox(QString("Semi-bilinear filtering")), "x11blitter/bf", false)
{
visInfo.visual = NULL;
visInfo.depth = 0;
confWidget->setLayout(new QVBoxLayout);
confWidget->layout()->setMargin(0);
confWidget->layout()->addWidget(bf_.checkBox());
setAttribute(Qt::WA_OpaquePaintEvent, true);
setAttribute(Qt::WA_PaintOnScreen, true);
if (XVisualInfo *v = getVisualPtr()) {
visInfo.visual = v->visual;
visInfo.depth = v->depth;
@ -281,10 +281,10 @@ void X11Blitter::uninit() {
long X11Blitter::sync() {
if (subBlitter->failed())
return -1;
subBlitter->blit(winId(), 0, 0, width(), height());
XSync(QX11Info::display(), 0);
return 0;
}
@ -310,23 +310,23 @@ void X11Blitter::paintEvent(QPaintEvent *event) {
void X11Blitter::setBufferDimensions(const unsigned int w, const unsigned int h) {
uninit();
const bool scale = width() != static_cast<int>(w) || height() != static_cast<int>(h);
bool shm = XShmQueryExtension(QX11Info::display());
std::cout << "shm: " << shm << std::endl;
if (shm) {
subBlitter.reset(new ShmBlitter(width(), height(), visInfo, !scale));
if (subBlitter->failed()) {
shm = false;
subBlitter.reset(); // predestruct previous object to ensure resource availability.
}
}
if (!shm)
subBlitter.reset(new PlainBlitter(width(), height(), visInfo, !scale));
if (scale) {
buffer.reset(w * h * (visInfo.depth <= 16 ? 2 : 4));
setPixelBuffer(buffer, visInfo.depth <= 16 ? PixelBuffer::RGB16 : PixelBuffer::RGB32, w);

View File

@ -28,23 +28,23 @@ class X11Blitter : public BlitterWidget {
class SubBlitter;
class ShmBlitter;
class PlainBlitter;
struct VisInfo {
void *visual;
unsigned depth;
};
const scoped_ptr<QWidget> confWidget;
scoped_ptr<SubBlitter> subBlitter;
PersistCheckBox bf_;
Array<char> buffer;
VisInfo visInfo;
protected:
void setBufferDimensions(const unsigned width, const unsigned height);
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
public:
explicit X11Blitter(VideoBufferLocker vbl, QWidget *parent = 0);
~X11Blitter();
@ -56,7 +56,7 @@ public:
QWidget* settingsWidget() const { return confWidget.get(); }
void acceptSettings();
void rejectSettings() const;
QPaintEngine* paintEngine() const { return 0; }
};

View File

@ -47,7 +47,7 @@ public:
class XvBlitter::ShmBlitter : public SubBlitter {
XShmSegmentInfo shminfo;
XvImage *xvimage;
public:
ShmBlitter(XvPortID xvport, int formatid, unsigned int width, unsigned int height);
void blit(Drawable drawable, XvPortID xvport, unsigned width, unsigned height);
@ -61,7 +61,7 @@ public:
XvBlitter::ShmBlitter::ShmBlitter(const XvPortID xvport, const int formatid, const unsigned int width, const unsigned int height) {
shminfo.shmaddr = NULL;
xvimage = XvShmCreateImage(QX11Info::display(), xvport, formatid, NULL, width << (formatid != 3), height, &shminfo);
if (xvimage == NULL) {
std::cerr << "failed to create xvimage\n";
} else {
@ -80,7 +80,7 @@ XvBlitter::ShmBlitter::~ShmBlitter() {
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
}
if (xvimage != NULL)
XFree(xvimage);
}
@ -116,7 +116,7 @@ unsigned XvBlitter::ShmBlitter::pitch() const {
class XvBlitter::PlainBlitter : public SubBlitter {
XvImage *const xvimage;
char *data;
public:
PlainBlitter(XvPortID xvport, int formatid, unsigned int width, unsigned int height);
void blit(Drawable drawable, XvPortID xvport, unsigned width, unsigned height);
@ -128,7 +128,7 @@ public:
};
XvBlitter::PlainBlitter::PlainBlitter(const XvPortID xvport, const int formatid, const unsigned int width, const unsigned int height)
: xvimage(XvCreateImage(QX11Info::display(), xvport, formatid, 0, width << (formatid != 3), height)),
: xvimage(XvCreateImage(QX11Info::display(), xvport, formatid, 0, width << (formatid != 3), height)),
data(0)
{
if (xvimage) {
@ -184,12 +184,12 @@ public:
num_ = 0;
}
}
~XvAdaptorInfos() {
if (infos_)
XvFreeAdaptorInfo(infos_);
}
unsigned len() const { return num_; }
operator const XvAdaptorInfo*() const { return infos_; }
};
@ -197,48 +197,48 @@ public:
class XvPortImageFormats : Uncopyable {
int num_;
XvImageFormatValues *const formats_;
public:
explicit XvPortImageFormats(const XvPortID baseId)
: num_(0), formats_(XvListImageFormats(QX11Info::display(), baseId, &num_))
{
}
~XvPortImageFormats() {
if (formats_)
XFree(formats_);
}
int len() const { return num_; }
operator const XvImageFormatValues*() const { return formats_; }
};
static int findId(const XvPortImageFormats &formats, const int id) {
int i = 0;
while (i < formats.len() && formats[i].id != id)
++i;
return i;
}
static void addPorts(QComboBox &portSelector) {
XvAdaptorInfos adaptors;
for (unsigned i = 0; i < adaptors.len(); ++i) {
if (!(adaptors[i].type & XvImageMask))
continue;
const XvPortImageFormats formats(adaptors[i].base_id);
int formatId = 0x3;
int j = findId(formats, formatId);
if (j == formats.len()) {
formatId = 0x59565955;
j = findId(formats, formatId);
}
if (j < formats.len()) {
QList<QVariant> l;
l.append(static_cast<uint>(adaptors[i].base_id));
@ -255,12 +255,12 @@ XvBlitter::ConfWidget::ConfWidget()
: widget_(new QWidget), portSelector_(new QComboBox(widget_.get())), portIndex_(0)
{
addPorts(*portSelector_);
if ((portIndex_ = QSettings().value("xvblitter/portIndex", 0).toUInt()) >= static_cast<unsigned>(portSelector_->count()))
portIndex_ = 0;
restore();
widget_->setLayout(new QHBoxLayout);
widget_->layout()->setMargin(0);
widget_->layout()->addWidget(new QLabel(QString(tr("Xv Port:"))));
@ -304,14 +304,14 @@ XvBlitter::PortGrabber::~PortGrabber() {
bool XvBlitter::PortGrabber::grab(const XvPortID basePort, const unsigned numPorts) {
ungrab();
for (XvPortID port = basePort; port < basePort + numPorts; ++port) {
port_ = port;
if ((grabbed_ = XvGrabPort(QX11Info::display(), port, CurrentTime) == Success))
return true;
}
return false;
}
@ -332,10 +332,10 @@ XvBlitter::XvBlitter(VideoBufferLocker vbl, QWidget *parent) :
setPalette(pal);
setBackgroundRole(QPalette::Window);
setAutoFillBackground(true);*/
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_PaintOnScreen, true);
{
XGCValues gcValues;
gcValues.foreground = gcValues.background = 2110;
@ -351,23 +351,23 @@ bool XvBlitter::isUnusable() const {
for (unsigned int i = 0; i < num_adaptors; ++i) {
if (!(adaptor_info[i].type & XvImageMask))
continue;
int numImages;
XvImageFormatValues *const formats = XvListImageFormats(QX11Info::display(), adaptor_info[i].base_id, &numImages);
for (int j = 0; j < numImages; ++j) {
if (formats[j].id == 0x59565955 &&
XvGrabPort(QX11Info::display(), adaptor_info[i].base_id, CurrentTime) == Success) {
*port_out = adaptor_info[i].base_id;
XFree(formats);
return false;
}
}
XFree(formats);
}
return true;
}*/
@ -387,11 +387,11 @@ void XvBlitter::init() {
yuv_table[i] = (y << 24) | (v << 16) | (y << 8) | u;
}
}*/
XSync(QX11Info::display(), 0);
initPort();
initialized = true;
}
@ -408,38 +408,38 @@ XvBlitter::~XvBlitter() {
long XvBlitter::sync() {
if (!portGrabber.grabbed() || subBlitter->failed())
return -1;
subBlitter->blit(winId(), portGrabber.port(), width(), height());
XSync(QX11Info::display(), 0);
return 0;
}
void XvBlitter::paintEvent(QPaintEvent *event) {
const QRect &rect = event->rect();
XFillRectangle(QX11Info::display(), winId(), gc, rect.x(), rect.y(), rect.width(), rect.height());
if (isPaused() && portGrabber.grabbed())
subBlitter->blit(winId(), portGrabber.port(), width(), height());
}
void XvBlitter::setBufferDimensions(const unsigned width, const unsigned height) {
const int formatid = confWidget.formatId();
subBlitter.reset(); // predestruct previous object to ensure resource availability.
bool shm = XShmQueryExtension(QX11Info::display());
std::cout << "shm: " << shm << std::endl;
if (shm) {
subBlitter.reset(new ShmBlitter(portGrabber.port(), formatid, width, height));
if (subBlitter->failed()) {
shm = false;
subBlitter.reset();
}
}
if (!shm)
subBlitter.reset(new PlainBlitter(portGrabber.port(), formatid, width, height));
@ -459,30 +459,30 @@ class XvAttributes : Uncopyable {
const XvPortID xvport_;
int numAttribs_;
XvAttribute *const attribs_;
Atom atomOf(const char *const name) const {
for (int i = 0; i < numAttribs_; ++i) {
if (!strcmp(attribs_[i].name, name))
return XInternAtom(QX11Info::display(), name, True);
}
return None;
}
public:
explicit XvAttributes(const XvPortID xvport)
: xvport_(xvport), numAttribs_(0), attribs_(XvQueryPortAttributes(QX11Info::display(), xvport, &numAttribs_))
{
}
~XvAttributes() {
if (attribs_)
XFree(attribs_);
}
void set(const char *const name, const int value) {
const Atom atom = atomOf(name);
if (atom != None)
XvSetPortAttribute(QX11Info::display(), xvport_, atom, value);
}
@ -500,7 +500,7 @@ void XvBlitter::initPort() {
void XvBlitter::acceptSettings() {
confWidget.store();
if (initialized && !(portGrabber.port() >= confWidget.basePortId()
&& portGrabber.port() < confWidget.basePortId() + confWidget.numPortIds())) {
initPort();

View File

@ -31,12 +31,12 @@ class XvBlitter : public BlitterWidget {
class SubBlitter;
class ShmBlitter;
class PlainBlitter;
class ConfWidget {
const scoped_ptr<QWidget> widget_;
QComboBox *const portSelector_;
unsigned portIndex_;
public:
ConfWidget();
~ConfWidget();
@ -48,7 +48,7 @@ class XvBlitter : public BlitterWidget {
int numAdapters() const;
QWidget * qwidget() const { return widget_.get(); }
};
class PortGrabber : Uncopyable {
XvPortID port_;
bool grabbed_;
@ -60,13 +60,13 @@ class XvBlitter : public BlitterWidget {
bool grabbed() const { return grabbed_; }
XvPortID port() const { return port_; }
};
ConfWidget confWidget;
PortGrabber portGrabber;
scoped_ptr<SubBlitter> subBlitter;
GC gc;
bool initialized;
void initPort();
void privSetPaused(const bool /*paused*/) {}
@ -83,11 +83,11 @@ public:
long sync();
void setBufferDimensions(const unsigned int width, const unsigned int height);
void blit();
QWidget* settingsWidget() const { return confWidget.qwidget(); }
void acceptSettings();
void rejectSettings() const;
QPaintEngine* paintEngine() const { return NULL; }
};

View File

@ -42,7 +42,7 @@ void FrameRateControl::setFrameTime(const Rational frameTime) {
void FrameRateControl::setRefreshRate(int refreshRate) {
if (refreshRate < 1)
refreshRate = 600;
refreshRate_ = refreshRate;
blitter_->rateChange(refreshRate);
update();

View File

@ -39,7 +39,7 @@ public:
void setFrameTime(Rational frameTime);
void setRefreshRate(int refreshRate);
void setRefreshRateSync(bool enable) { refreshRateSync_ = enable; update(); }
};
#endif

View File

@ -36,24 +36,24 @@ static inline bool operator>(const ResInfo &l, const ResInfo &r) {
static void addMode(const DEVMODE &devmode, std::vector<ResInfo> &infoVector, unsigned *resIndex, unsigned *rateIndex) {
ResInfo info;
short rate;
info.w = devmode.dmPelsWidth;
info.h = devmode.dmPelsHeight;
rate = devmode.dmDisplayFrequency * 10;
std::vector<ResInfo>::iterator it = std::lower_bound(infoVector.begin(), infoVector.end(), info, std::greater<ResInfo>());
if (it == infoVector.end() || *it != info)
it = infoVector.insert(it, info);
std::vector<short>::iterator rateIt = std::lower_bound(it->rates.begin(), it->rates.end(), rate, std::greater<short>());
if (rateIt == it->rates.end() || *rateIt != rate)
rateIt = it->rates.insert(rateIt, rate);
if (resIndex)
*resIndex = std::distance(infoVector.begin(), it);
if (rateIndex)
*rateIndex = std::distance(it->rates.begin(), rateIt);
}
@ -61,15 +61,15 @@ static void addMode(const DEVMODE &devmode, std::vector<ResInfo> &infoVector, un
class GdiToggler::MultiMon : Uncopyable {
HMONITOR *devMonitors;
unsigned numDevs;
HMONITOR monitor(int screen) const { return devMonitors ? devMonitors[screen] : NULL; }
public:
MultiMon() : devMonitors(NULL), numDevs(1) {
if (gdiSettings.monitorFromPoint) {
numDevs = QApplication::desktop()->numScreens();
devMonitors = new HMONITOR[numDevs];
for (unsigned i = 0; i < numDevs; ++i) {
const QPoint &qpoint = QApplication::desktop()->screenGeometry(i).center();
POINT point = { x: qpoint.x(), y: qpoint.y() };
@ -77,17 +77,17 @@ public:
}
}
}
~MultiMon() {
delete []devMonitors;
}
unsigned numScreens() const { return numDevs; }
BOOL enumDisplaySettings(unsigned screen, DWORD iModeNum, LPDEVMODE devmode) const {
return gdiSettings.enumDisplaySettings(monitor(screen), iModeNum, devmode);
}
LONG changeDisplaySettings(unsigned screen, LPDEVMODE devmode, DWORD dwflags) const {
return gdiSettings.changeDisplaySettings(monitor(screen), devmode, dwflags);
}
@ -101,24 +101,24 @@ isFull(false)
infoVector.resize(mon->numScreens());
fullResIndex.resize(mon->numScreens());
fullRateIndex.resize(mon->numScreens());
DEVMODE devmode;
devmode.dmSize = sizeof devmode;
devmode.dmDriverExtra = 0;
for (unsigned i = 0; i < mon->numScreens(); ++i) {
mon->enumDisplaySettings(i, ENUM_CURRENT_SETTINGS, &devmode);
const unsigned bpp = devmode.dmBitsPerPel;
int n = 0;
while (mon->enumDisplaySettings(i, n++, &devmode)) {
if (devmode.dmBitsPerPel == bpp)
addMode(devmode, infoVector[i], NULL, NULL);
}
}
for (unsigned i = 0; i < mon->numScreens(); ++i) {
mon->enumDisplaySettings(i, ENUM_CURRENT_SETTINGS, &devmode);
addMode(devmode, infoVector[i], &fullResIndex[i], &fullRateIndex[i]);
@ -136,7 +136,7 @@ GdiToggler::~GdiToggler() {
void GdiToggler::setScreen(const QWidget *widget) {
unsigned n = QApplication::desktop()->screenNumber(widget);
if (n != widgetScreen && n < mon->numScreens()) {
if (isFullMode()) {
setFullMode(false);
@ -152,7 +152,7 @@ void GdiToggler::setScreen(const QWidget *widget) {
void GdiToggler::setMode(const unsigned screen, const unsigned resIndex, const unsigned rateIndex) {
fullResIndex[screen] = resIndex;
fullRateIndex[screen] = rateIndex;
if (isFullMode() && screen == widgetScreen)
setFullMode(true);
}
@ -161,12 +161,12 @@ void GdiToggler::setFullMode(const bool enable) {
DEVMODE devmode;
devmode.dmSize = sizeof devmode;
devmode.dmDriverExtra = 0;
mon->enumDisplaySettings(widgetScreen, ENUM_CURRENT_SETTINGS, &devmode);
const unsigned currentWidth = devmode.dmPelsWidth;
const unsigned currentHeight = devmode.dmPelsHeight;
const unsigned currentRate = devmode.dmDisplayFrequency;
if (enable) {
const ResInfo &info = infoVector[widgetScreen][fullResIndex[widgetScreen]];
devmode.dmPelsWidth = info.w;
@ -175,15 +175,15 @@ void GdiToggler::setFullMode(const bool enable) {
} else if (isFull) {
mon->enumDisplaySettings(widgetScreen, ENUM_REGISTRY_SETTINGS, &devmode);
}
if (devmode.dmPelsWidth != currentWidth || devmode.dmPelsHeight != currentHeight || devmode.dmDisplayFrequency != currentRate) {
devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
mon->changeDisplaySettings(widgetScreen, &devmode, enable ? CDS_FULLSCREEN : 0);
if (devmode.dmDisplayFrequency != currentRate)
emit rateChange(devmode.dmDisplayFrequency * 10);
}
isFull = enable;
}

View File

@ -25,16 +25,16 @@
class GdiToggler : public FullModeToggler, private Uncopyable {
Q_OBJECT
class MultiMon;
MultiMon *const mon;
std::vector<std::vector<ResInfo> > infoVector;
std::vector<unsigned> fullResIndex;
std::vector<unsigned> fullRateIndex;
unsigned widgetScreen;
bool isFull;
public:
GdiToggler();
~GdiToggler();
@ -49,7 +49,7 @@ public:
void setScreen(const QWidget *widget);
unsigned screen() const { return widgetScreen; }
unsigned screens() const { return infoVector.size(); }
signals:
void rateChange(int newHz);
// void modeChange();

View File

@ -25,10 +25,10 @@ class QWidget;
class NullToggler : public FullModeToggler {
Q_OBJECT
const std::vector<ResInfo> nullVector;
bool fullRes;
public:
NullToggler() : fullRes(false) {}
unsigned currentResIndex(unsigned /*screen*/) const { return 0; }
@ -41,7 +41,7 @@ public:
void setScreen(const QWidget */*widget*/) {}
unsigned screen() const { return 0; }
unsigned screens() const { return 0; }
signals:
void rateChange(int newHz);
};

View File

@ -32,34 +32,34 @@ static inline bool operator>(const ResInfo &l, const ResInfo &r) {
static void addMode(CFDictionaryRef mode, std::vector<ResInfo> &infoVector, unsigned *resIndex, unsigned *rateIndex) {
ResInfo info;
short rate = 0;
{
int w = 0;
int h = 0;
double r = 0.0;
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(mode, kCGDisplayWidth)), kCFNumberIntType, &w);
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(mode, kCGDisplayHeight)), kCFNumberIntType, &h);
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(mode, kCGDisplayRefreshRate)), kCFNumberDoubleType, &r);
info.w = w;
info.h = h;
rate = static_cast<short>(r * 10.0 + 0.5);
}
std::vector<ResInfo>::iterator it = std::lower_bound(infoVector.begin(), infoVector.end(), info, std::greater<ResInfo>());
if (it == infoVector.end() || *it != info)
it = infoVector.insert(it, info);
std::vector<short>::iterator rateIt = std::lower_bound(it->rates.begin(), it->rates.end(), rate, std::greater<short>());
if (rateIt == it->rates.end() || *rateIt != rate)
rateIt = it->rates.insert(rateIt, rate);
if (resIndex)
*resIndex = std::distance(infoVector.begin(), it);
if (rateIndex)
*rateIndex = std::distance(it->rates.begin(), rateIt);
}
@ -72,32 +72,32 @@ isFull(false)
{
CGDisplayCount dspyCnt = 0;
CGGetActiveDisplayList(0, 0, &dspyCnt);
activeDspys = new CGDirectDisplayID[dspyCnt];
CGGetActiveDisplayList(dspyCnt, activeDspys, &dspyCnt);
infoVector.resize(dspyCnt);
fullResIndex.resize(dspyCnt);
fullRateIndex.resize(dspyCnt);
for (CGDisplayCount i = 0; i < dspyCnt; ++i) {
CGDirectDisplayID display = activeDspys[i];
CFDictionaryRef currentMode = CGDisplayCurrentMode(display);
CFArrayRef modesArray = CGDisplayAvailableModes(display);
CFIndex numModes = CFArrayGetCount(modesArray);
CFNumberRef bpp = static_cast<CFNumberRef>(CFDictionaryGetValue(currentMode, kCGDisplayBitsPerPixel));
for (CFIndex j = 0; j < numModes; ++j) {
CFDictionaryRef mode = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(modesArray, j));
if (CFNumberCompare(bpp, static_cast<CFNumberRef>(CFDictionaryGetValue(mode, kCGDisplayBitsPerPixel)), NULL) == kCFCompareEqualTo) {
addMode(mode, infoVector[i], NULL, NULL);
}
}
}
originalMode = CGDisplayCurrentMode(activeDspys[widgetScreen]);
for (CGDisplayCount i = 0; i < dspyCnt; ++i) {
unsigned resIndex = 0;
unsigned rateIndex = 0;
@ -114,13 +114,13 @@ QuartzToggler::~QuartzToggler() {
const QRect QuartzToggler::fullScreenRect(const QWidget */*w*/) const {
CGRect r = CGDisplayBounds(activeDspys[widgetScreen]);
return QRectF(r.origin.x, r.origin.y, r.size.width, r.size.height).toRect();
}
void QuartzToggler::setScreen(const QWidget *widget) {
unsigned n = QApplication::desktop()->screenNumber(widget);
if (n != widgetScreen && n < infoVector.size()) {
if (isFullMode()) {
setFullMode(false);
@ -136,7 +136,7 @@ void QuartzToggler::setScreen(const QWidget *widget) {
void QuartzToggler::setMode(const unsigned screen, const unsigned resIndex, const unsigned rateIndex) {
fullResIndex[screen] = resIndex;
fullRateIndex[screen] = rateIndex;
if (isFullMode() && screen == widgetScreen)
setFullMode(true);
}
@ -144,13 +144,13 @@ void QuartzToggler::setMode(const unsigned screen, const unsigned resIndex, cons
void QuartzToggler::setFullMode(const bool enable) {
CGDirectDisplayID display = activeDspys[widgetScreen];
CFDictionaryRef currentMode = CGDisplayCurrentMode(display);
CFDictionaryRef mode = currentMode;
if (enable) {
int bpp = 0;
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(currentMode, kCGDisplayBitsPerPixel)), kCFNumberIntType, &bpp);
mode = CGDisplayBestModeForParametersAndRefreshRate(
display,
bpp,
@ -159,32 +159,32 @@ void QuartzToggler::setFullMode(const bool enable) {
infoVector[widgetScreen][fullResIndex[widgetScreen]].rates[fullRateIndex[widgetScreen]] / 10.0,
NULL
);
if (!isFull)
originalMode = currentMode;
} else if (isFull)
mode = originalMode;
if (mode != currentMode) {
CGDisplaySwitchToMode(display, mode);
double oldRate = 0.0;
double newRate = 0.0;
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(currentMode, kCGDisplayRefreshRate)), kCFNumberDoubleType, &oldRate);
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(mode, kCGDisplayRefreshRate)), kCFNumberDoubleType, &newRate);
if (static_cast<int>(oldRate * 10.0 + 0.5) != static_cast<int>(newRate * 10.0 + 0.5))
emit rateChange(static_cast<int>(newRate * 10.0 + 0.5));
}
isFull = enable;
}
void QuartzToggler::emitRate() {
double rate = 0.0;
CFNumberGetValue(static_cast<CFNumberRef>(CFDictionaryGetValue(CGDisplayCurrentMode(activeDspys[widgetScreen]), kCGDisplayRefreshRate)), kCFNumberDoubleType, &rate);
emit rateChange(static_cast<int>(rate * 10.0 + 0.5));
}

View File

@ -27,7 +27,7 @@ class QWidget;
class QuartzToggler : public FullModeToggler {
Q_OBJECT
CFDictionaryRef originalMode;
CGDirectDisplayID *activeDspys;
std::vector<std::vector<ResInfo> > infoVector;
@ -35,7 +35,7 @@ class QuartzToggler : public FullModeToggler {
std::vector<unsigned> fullRateIndex;
unsigned widgetScreen;
bool isFull;
public:
QuartzToggler();
~QuartzToggler();
@ -50,7 +50,7 @@ public:
void setScreen(const QWidget *widget);
unsigned screen() const { return widgetScreen; }
unsigned screens() const { return infoVector.size(); }
signals:
void rateChange(int newHz);
// void modeChange();

View File

@ -25,25 +25,25 @@
bool Xf86VidModeToggler::isUsable() {
int unused;
if (XF86VidModeQueryExtension(QX11Info::display(), &unused, &unused)) {
XF86VidModeSetClientVersion(QX11Info::display());
if (XF86VidModeQueryVersion(QX11Info::display(), &unused, &unused)) {
if (XineramaQueryVersion(QX11Info::display(), &unused, &unused)) {
int number = 0;
if (XineramaScreenInfo *info = XineramaQueryScreens(QX11Info::display(), &number))
XFree(info);
if (number > 1)
return false;
}
return true;
}
}
return false;
}
@ -58,7 +58,7 @@ static inline bool operator>(const ResInfo &l, const ResInfo &r) {
static unsigned getRate(const unsigned dotclock, const unsigned htotal, const unsigned vtotal) {
if (unsigned long pixels = htotal * vtotal)
return (dotclock * 10000ull + (pixels >> 1)) / pixels;
return 0;
}
@ -69,24 +69,24 @@ static unsigned getRate(const XF86VidModeModeInfo &mode) {
static void addMode(XF86VidModeModeInfo *mode, std::vector<ResInfo> &infoVector, unsigned *resIndex, unsigned *rateIndex) {
ResInfo info;
short rate;
info.w = mode->hdisplay;
info.h = mode->vdisplay;
rate = getRate(*mode);
std::vector<ResInfo>::iterator it = std::lower_bound(infoVector.begin(), infoVector.end(), info, std::greater<ResInfo>());
if (it == infoVector.end() || *it != info)
it = infoVector.insert(it, info);
std::vector<short>::iterator rateIt = std::lower_bound(it->rates.begin(), it->rates.end(), rate, std::greater<short>());
if (rateIt == it->rates.end() || *rateIt != rate)
rateIt = it->rates.insert(rateIt, rate);
if (resIndex)
*resIndex = std::distance(infoVector.begin(), it);
if (rateIndex)
*rateIndex = std::distance(it->rates.begin(), rateIt);
}
@ -102,12 +102,12 @@ winId(winId),
isFull(false)
{
XF86VidModeGetAllModeLines(QX11Info::display(), QX11Info::appScreen(), &modecount, &modesinfo);
if (modecount) {
for (int i = 1; i < modecount; ++i) {
addMode(modesinfo[i], infoVector, NULL, NULL);
}
originalMode = *modesinfo[0];
addMode(modesinfo[0], infoVector, &fullResIndex, &fullRateIndex);
}
@ -115,7 +115,7 @@ isFull(false)
Xf86VidModeToggler::~Xf86VidModeToggler() {
setFullMode(false);
if (modesinfo)
XFree(modesinfo);
}
@ -123,23 +123,23 @@ Xf86VidModeToggler::~Xf86VidModeToggler() {
const QRect Xf86VidModeToggler::fullScreenRect(const QWidget *wdgt) const {
int dotclock = 0;
XF86VidModeModeLine modeline;
if (XF86VidModeGetModeLine(QX11Info::display(), QX11Info::appScreen(), &dotclock, &modeline)) {
int x = 0;
int y = 0;
// XF86VidModeGetViewPort(QX11Info::display(), QX11Info::appScreen(), &x, &y);
return QRect(x, y, modeline.hdisplay, modeline.vdisplay);
}
return wdgt->geometry();
}
void Xf86VidModeToggler::setMode(unsigned /*screen*/, const unsigned resIndex, const unsigned rateIndex) {
fullResIndex = resIndex;
fullRateIndex = rateIndex;
if (isFullMode())
setFullMode(true);
}
@ -147,39 +147,39 @@ void Xf86VidModeToggler::setMode(unsigned /*screen*/, const unsigned resIndex, c
void Xf86VidModeToggler::setFullMode(const bool enable) {
XF86VidModeModeInfo curMode;
bool curModeValid;
{
int dotclock = 0;
XF86VidModeModeLine modeline;
curModeValid = XF86VidModeGetModeLine(QX11Info::display(), QX11Info::appScreen(), &dotclock, &modeline);
curMode.dotclock = dotclock;
std::memcpy(reinterpret_cast<char*>(&curMode) + sizeof curMode.dotclock,
reinterpret_cast<char*>(&modeline),
std::min(sizeof modeline, sizeof curMode - sizeof curMode.dotclock));
}
XF86VidModeModeInfo *newMode = NULL;
int vportx = 0;
int vporty = 0;
if (enable) {
if (!isFull) {
if (curModeValid)
originalMode = curMode;
XF86VidModeGetViewPort(QX11Info::display(), QX11Info::appScreen(), &originalvportx, &originalvporty);
}
int i = 0;
while (i < modecount &&
modesinfo[i]->hdisplay != infoVector[fullResIndex].w ||
modesinfo[i]->vdisplay != infoVector[fullResIndex].h ||
getRate(*modesinfo[i]) != static_cast<unsigned>(infoVector[fullResIndex].rates[fullRateIndex])) {
++i;
}
if (i != modecount) {
newMode = modesinfo[i];
}
@ -187,23 +187,23 @@ void Xf86VidModeToggler::setFullMode(const bool enable) {
if (modecount) {
newMode = &originalMode;
}
vportx = originalvportx;
vporty = originalvporty;
}
if (newMode) {
if (XF86VidModeSwitchToMode(QX11Info::display(), QX11Info::appScreen(), newMode)) {
const unsigned newRate = getRate(*newMode);
if (!curModeValid || newRate != getRate(curMode))
emit rateChange(newRate);
}
}
XF86VidModeSetViewPort(QX11Info::display(), QX11Info::appScreen(), vportx, vporty);
XF86VidModeLockModeSwitch(QX11Info::display(), QX11Info::appScreen(), enable);
if (enable) {
XGrabPointer(QX11Info::display(), QX11Info::appRootWindow(), True, 0,
GrabModeAsync, GrabModeAsync,
@ -213,9 +213,9 @@ void Xf86VidModeToggler::setFullMode(const bool enable) {
XUngrabPointer(QX11Info::display(), CurrentTime);
QCoreApplication::instance()->removeEventFilter(this);
}
// XSync(QX11Info::display(), False);
isFull = enable;
}
@ -229,7 +229,7 @@ bool Xf86VidModeToggler::eventFilter(QObject *obj, QEvent *ev) {
} else if (ev->type() == 9)
XUngrabPointer(QX11Info::display(), CurrentTime);
}*/
if (ev->type() == QEvent::Show || ev->type() == QEvent::Hide) {
XGrabPointer(QX11Info::display(), QX11Info::appRootWindow(), True, 0,
GrabModeAsync, GrabModeAsync,
@ -239,7 +239,7 @@ bool Xf86VidModeToggler::eventFilter(QObject *obj, QEvent *ev) {
}/* else if (ev->type() == QEvent::Leave && obj->isWidgetType() && static_cast<QWidget*>(obj)->winId() == winId && !qApp->activeWindow()) {
XUngrabPointer(QX11Info::display(), CurrentTime);
}*/
return false;
}
@ -247,10 +247,10 @@ void Xf86VidModeToggler::emitRate() {
int rate = 0;
int dotclock = 0;
XF86VidModeModeLine modeline;
if (XF86VidModeGetModeLine(QX11Info::display(), QX11Info::appScreen(), &dotclock, &modeline)) {
rate = getRate(dotclock, modeline.htotal, modeline.vtotal);
}
emit rateChange(rate);
}

View File

@ -26,7 +26,7 @@
class Xf86VidModeToggler : public FullModeToggler {
Q_OBJECT
XF86VidModeModeInfo **modesinfo;
XF86VidModeModeInfo originalMode;
std::vector<ResInfo> infoVector;
@ -37,7 +37,7 @@ class Xf86VidModeToggler : public FullModeToggler {
int originalvporty;
WId winId;
bool isFull;
public:
static bool isUsable();
Xf86VidModeToggler(WId winId);
@ -54,7 +54,7 @@ public:
unsigned screen() const { return 0; }
unsigned screens() const { return 1; }
bool eventFilter(QObject *obj, QEvent *ev);
signals:
void rateChange(int newHz);
// void modeChange();

View File

@ -34,7 +34,7 @@ static inline bool operator>(const ResInfo &l, const ResInfo &r) {
static unsigned getRate(const unsigned long dotclock, const unsigned htotal, const unsigned vtotal) {
if (unsigned long pixels = htotal * vtotal)
return (dotclock * 10ull + (pixels >> 1)) / pixels;
return 0;
}
@ -45,24 +45,24 @@ static unsigned getRate(const XRRModeInfo &mode) {
static void addMode(const XRRModeInfo &mode, std::vector<ResInfo> &infoVector, unsigned *resIndex, unsigned *rateIndex) {
ResInfo info;
short rate;
info.w = mode.width;
info.h = mode.height;
rate = getRate(mode);
std::vector<ResInfo>::iterator it = std::lower_bound(infoVector.begin(), infoVector.end(), info, std::greater<ResInfo>());
if (it == infoVector.end() || *it != info)
it = infoVector.insert(it, info);
std::vector<short>::iterator rateIt = std::lower_bound(it->rates.begin(), it->rates.end(), rate, std::greater<short>());
if (rateIt == it->rates.end() || *rateIt != rate)
rateIt = it->rates.insert(rateIt, rate);
if (resIndex)
*resIndex = std::distance(infoVector.begin(), it);
if (rateIndex)
*rateIndex = std::distance(it->rates.begin(), rateIt);
}
@ -72,14 +72,14 @@ static XRRModeInfo* getModeInfo(const XRRScreenResources *const resources, const
if (resources->modes[m].id == mode)
return resources->modes + m;
}
return NULL;
}
static bool isGood(const RRMode mode, const std::vector<XRROutputInfo*> &outputInfos) {
for (std::size_t o = 0; o < outputInfos.size(); ++o) {
RRMode *const modesEnd = outputInfos[o]->modes + outputInfos[o]->nmode;
if (std::find(outputInfos[o]->modes, modesEnd, mode) == modesEnd)
return false;
}
@ -102,7 +102,7 @@ OutputInfos::OutputInfos(XRRScreenResources *const resources, const XRRCrtcInfo
{
for (std::size_t i = 0; i < v.size();) {
v[i] = XRRGetOutputInfo(QX11Info::display(), resources, crtcInfo->outputs[i]);
if (v[i])
++i;
else
@ -117,7 +117,7 @@ OutputInfos::~OutputInfos() {
class CrtcInfoPtr : Uncopyable {
XRRCrtcInfo *const crtcInfo;
public:
CrtcInfoPtr(XRRScreenResources *const resources, const RRCrtc crtc)
: crtcInfo(XRRGetCrtcInfo(QX11Info::display(), resources, crtc)) {}
@ -134,21 +134,21 @@ static RRMode getMode(XRRScreenResources *const resources, const XRRCrtcInfo *co
if (curMode->width == info.w && curMode->height == info.h && getRate(*curMode) == static_cast<unsigned>(rate))
return crtcInfo->mode;
}
if (XRRModeInfo *prefMode = getModeInfo(resources, preferred)) {
if (prefMode->width == info.w && prefMode->height == info.h && getRate(*prefMode) == static_cast<unsigned>(rate))
return preferred;
}
OutputInfos outputInfos(resources, crtcInfo);
for (int m = 0; m < resources->nmode; ++m) {
if (resources->modes[m].width == info.w && resources->modes[m].height == info.h && getRate(resources->modes[m]) == static_cast<unsigned>(rate)) {
if (isGood(resources->modes[m].id, outputInfos.get()))
return resources->modes[m].id;
}
}
return crtcInfo->mode;
}
@ -158,7 +158,7 @@ bool XRandR12Toggler::isUsable() {
int unused = 0;
int major = 1;
int minor = 1;
return XRRQueryExtension(QX11Info::display(), &unused, &unused) &&
XRRQueryVersion(QX11Info::display(), &major, &minor) &&
major == 1 && minor >= 2;
@ -171,21 +171,21 @@ widgetScreen(0),
isFull(false)
{
resources = XRRGetScreenResources(QX11Info::display(), QX11Info::appRootWindow());
if (resources) {
infoVector.resize(resources->ncrtc);
fullResIndex.resize(resources->ncrtc);
fullRateIndex.resize(resources->ncrtc);
for (int c = 0; c < resources->ncrtc; ++c) {
XRRModeInfo *curMode = NULL;
{
CrtcInfoPtr crtcInfo(resources, resources->crtcs[c]);
if (crtcInfo && (curMode = getModeInfo(resources, crtcInfo->mode))) {
OutputInfos outputInfos(resources, crtcInfo);
for (int m = 0; m < resources->nmode; ++m) {
if (resources->modes[m].width <= curMode->width && resources->modes[m].height <= curMode->height) {
if (isGood(resources->modes[m].id, outputInfos.get()))
@ -194,13 +194,13 @@ isFull(false)
}
}
}
unsigned resIndex = 0;
unsigned rateIndex = 0;
if (curMode)
addMode(*curMode, infoVector[c], &resIndex, &rateIndex);
fullResIndex[c] = resIndex;
fullRateIndex[c] = rateIndex;
}
@ -215,39 +215,39 @@ XRandR12Toggler::~XRandR12Toggler() {
const QRect XRandR12Toggler::fullScreenRect(const QWidget *const w) const {
if (resources) {
CrtcInfoPtr crtcInfo(resources, resources->crtcs[widgetScreen]);
if (crtcInfo)
return QRect(crtcInfo->x, crtcInfo->y, crtcInfo->width, crtcInfo->height);
}
return FullModeToggler::fullScreenRect(w);
}
void XRandR12Toggler::setScreen(const QWidget *const widget) {
unsigned n = widgetScreen;
if (resources) {
int maxIntersect = 0;
const QRect &wrect = widget->geometry();
for (int c = 0; c < resources->ncrtc; ++c) {
CrtcInfoPtr crtcInfo(resources, resources->crtcs[c]);
if (crtcInfo) {
const QRect &r = QRect(crtcInfo->x, crtcInfo->y, crtcInfo->width, crtcInfo->height).intersected(wrect);
const int area = r.width() * r.height();
if (area > maxIntersect) {
maxIntersect = area;
n = c;
if (r == wrect)
break;
}
}
}
}
if (n != widgetScreen && n < infoVector.size()) {
if (isFullMode()) {
setFullMode(false);
@ -263,7 +263,7 @@ void XRandR12Toggler::setScreen(const QWidget *const widget) {
void XRandR12Toggler::setMode(const unsigned screen, const unsigned resIndex, const unsigned rateIndex) {
fullResIndex[screen] = resIndex;
fullRateIndex[screen] = rateIndex;
if (isFullMode() && screen == widgetScreen)
setFullMode(true);
}
@ -271,59 +271,59 @@ void XRandR12Toggler::setMode(const unsigned screen, const unsigned resIndex, co
void XRandR12Toggler::setFullMode(const bool enable) {
if (resources) {
CrtcInfoPtr crtcInfo(resources, resources->crtcs[widgetScreen]);
if (crtcInfo) {
RRMode mode = crtcInfo->mode;
if (enable) {
if (!infoVector[widgetScreen].empty()) {
mode = getMode(resources, crtcInfo, isFull ? originalMode : crtcInfo->mode,
infoVector[widgetScreen][fullResIndex[widgetScreen]],
infoVector[widgetScreen][fullResIndex[widgetScreen]].rates[fullRateIndex[widgetScreen]]);
}
if (!isFull)
originalMode = crtcInfo->mode;
} else if (isFull)
mode = originalMode;
if (mode != crtcInfo->mode) {
if (XRRSetCrtcConfig(QX11Info::display(), resources, resources->crtcs[widgetScreen],
CurrentTime, crtcInfo->x, crtcInfo->y, mode, crtcInfo->rotation,
crtcInfo->outputs, crtcInfo->noutput) == Success) {
const short rate = infoVector[widgetScreen][fullResIndex[widgetScreen]].rates[fullRateIndex[widgetScreen]];
short prevRate = -1;
if (XRRModeInfo *curMode = getModeInfo(resources, crtcInfo->mode))
prevRate = getRate(*curMode);
if (rate != prevRate)
emit rateChange(rate);
}
}
}
}
isFull = enable;
}
void XRandR12Toggler::emitRate() {
const CrtcInfoPtr crtcInfo(resources, resources->crtcs[widgetScreen]);
short rate = 0;
if (crtcInfo) {
if (XRRModeInfo *curMode = getModeInfo(resources, crtcInfo->mode))
rate = getRate(*curMode);
}
emit rateChange(rate);
}
const QString XRandR12Toggler::screenName(const unsigned screen) const {
OutputInfos outputInfos(resources, CrtcInfoPtr(resources, resources->crtcs[screen]));
if (!outputInfos.get().empty())
return QString(outputInfos.get()[0]->name);
return FullModeToggler::screenName(screen);
}

View File

@ -26,7 +26,7 @@
class XRandR12Toggler : public FullModeToggler, Uncopyable {
Q_OBJECT
RRMode originalMode;
XRRScreenResources *resources;
std::vector<std::vector<ResInfo> > infoVector;
@ -34,7 +34,7 @@ class XRandR12Toggler : public FullModeToggler, Uncopyable {
std::vector<unsigned> fullRateIndex;
unsigned widgetScreen;
bool isFull;
public:
static bool isUsable();
XRandR12Toggler();
@ -51,11 +51,11 @@ public:
unsigned screen() const { return widgetScreen; }
unsigned screens() const { return infoVector.size(); }
const QString screenName(unsigned screen) const;
signals:
void rateChange(int newHz);
// void modeChange();
};
#endif

View File

@ -25,7 +25,7 @@ bool XRandRToggler::isUsable() {
int unused = 0;
int major = 1;
int minor = 1;
return XRRQueryExtension(QX11Info::display(), &unused, &unused) &&
XRRQueryVersion(QX11Info::display(), &major, &minor) &&
major == 1 && minor >= 1;
@ -42,33 +42,33 @@ isFull(false)
{
fullResIndex = originalResIndex = XRRConfigCurrentConfiguration(config, &rotation);
originalRate = XRRConfigCurrentRate(config);
int nSizes;
XRRScreenSize *randrSizes = XRRConfigSizes(config, &nSizes);
for (int i = 0; i < nSizes; ++i) {
ResInfo info;
info.w = randrSizes[i].width;
info.h = randrSizes[i].height;
int nHz;
short *rates = XRRConfigRates(config, i, &nHz);
for (int j = 0; j < nHz; ++j)
info.rates.push_back(rates[j] * 10);
infoVector.push_back(info);
}
{
unsigned i = 0;
while (i < infoVector[fullResIndex].rates.size() && infoVector[fullResIndex].rates[i] != originalRate * 10)
++i;
if (i == infoVector[fullResIndex].rates.size())
infoVector[fullResIndex].rates.push_back(originalRate * 10);
fullRateIndex = i;
}
}
@ -80,14 +80,14 @@ XRandRToggler::~XRandRToggler() {
const QRect XRandRToggler::fullScreenRect(const QWidget */*wdgt*/) const {
int w, h;
{
int nSizes = 0;
XRRScreenSize *randrSizes = XRRConfigSizes(config, &nSizes);
Rotation rot = rotation;
SizeID currentID = XRRConfigCurrentConfiguration(config, &rot);
if (currentID < nSizes) {
w = randrSizes[currentID].width;
h = randrSizes[currentID].height;
@ -96,14 +96,14 @@ const QRect XRandRToggler::fullScreenRect(const QWidget */*wdgt*/) const {
h = infoVector[fullResIndex].h;
}
}
return QRect(0, 0, w, h);
}
void XRandRToggler::setMode(unsigned /*screen*/, const unsigned resIndex, const unsigned rateIndex) {
fullResIndex = resIndex;
fullRateIndex = rateIndex;
if (isFullMode())
setFullMode(true);
}
@ -111,14 +111,14 @@ void XRandRToggler::setMode(unsigned /*screen*/, const unsigned resIndex, const
void XRandRToggler::setFullMode(const bool enable) {
SizeID currentID = XRRConfigCurrentConfiguration(config, &rotation);
int currentRate = XRRConfigCurrentRate(config);
SizeID newID;
int newRate;
if (enable) {
newID = fullResIndex;
newRate = infoVector[fullResIndex].rates[fullRateIndex] / 10;
if (!isFull) {
originalResIndex = currentID;
originalRate = currentRate;
@ -127,14 +127,14 @@ void XRandRToggler::setFullMode(const bool enable) {
newID = originalResIndex;
newRate = originalRate;
}
if (newID != currentID || newRate != currentRate) {
XRRSetScreenConfigAndRate(QX11Info::display(), config, QX11Info::appRootWindow(), newID, rotation, newRate, CurrentTime);
if (newRate != currentRate)
emit rateChange(newRate * 10);
}
isFull = enable;
}

View File

@ -27,7 +27,7 @@
class XRandRToggler : public FullModeToggler, Uncopyable {
Q_OBJECT
std::vector<ResInfo> infoVector;
XRRScreenConfiguration *const config;
unsigned originalResIndex;
@ -36,7 +36,7 @@ class XRandRToggler : public FullModeToggler, Uncopyable {
unsigned fullRateIndex;
short originalRate;
bool isFull;
public:
static bool isUsable();
XRandRToggler();
@ -52,7 +52,7 @@ public:
void setScreen(const QWidget */*widget*/) {}
unsigned screen() const { return 0; }
unsigned screens() const { return 1; }
signals:
void rateChange(int newHz);
// void modeChange();

View File

@ -23,10 +23,10 @@ GdiSettings::GdiSettings() : user32handle(NULL), getMonitorInfo(NULL), changeDis
if ((user32handle = LoadLibraryA("user32.dll"))) {
QT_WA({getMonitorInfo = (GetMonInfo)GetProcAddress(user32handle, "GetMonitorInfoW");},
{getMonitorInfo = (GetMonInfo)GetProcAddress(user32handle, "GetMonitorInfoA");});
QT_WA({changeDisplaySettingsEx = (ChangeGdiSettingsEx)GetProcAddress(user32handle, "ChangeDisplaySettingsExW");},
{changeDisplaySettingsEx = (ChangeGdiSettingsEx)GetProcAddress(user32handle, "ChangeDisplaySettingsExA");});
monitorFromWindow = (MonFromWindow)GetProcAddress(user32handle, "MonitorFromWindow");
monitorFromPoint = (MonFromPoint)GetProcAddress(user32handle, "MonitorFromPoint");
}
@ -41,22 +41,22 @@ TCHAR* GdiSettings::getMonitorName(HMONITOR monitor, GdiSettings::MonInfo *minfo
if (getMonitorInfo && monitor) {
minfo->cbSize = sizeof *minfo;
getMonitorInfo(monitor, minfo);
return minfo->szDevice;
}
return NULL;
}
BOOL GdiSettings::enumDisplaySettings(HMONITOR monitor, DWORD iModeNum, LPDEVMODE devmode) const {
MonInfo minfo;
return EnumDisplaySettings(getMonitorName(monitor, &minfo), iModeNum, devmode);
}
LONG GdiSettings::changeDisplaySettings(HMONITOR monitor, LPDEVMODE devmode, DWORD dwflags) const {
MonInfo minfo;
return changeDisplaySettingsEx ?
changeDisplaySettingsEx(getMonitorName(monitor, &minfo), devmode, NULL, dwflags, NULL) :
ChangeDisplaySettings(devmode, dwflags);

View File

@ -23,11 +23,11 @@
#include <windows.h>
class GdiSettings : Uncopyable {
struct MonInfo {
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
struct MonInfo {
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
TCHAR szDevice[CCHDEVICENAME];
};
@ -35,22 +35,22 @@ class GdiSettings : Uncopyable {
typedef HMONITOR (WINAPI *MonFromWindow)(HWND, DWORD);
typedef HMONITOR (WINAPI *MonFromPoint)(POINT pt, DWORD dwFlags);
typedef LONG (WINAPI *ChangeGdiSettingsEx)(LPCTSTR, LPDEVMODE, HWND, DWORD, LPVOID);
public:
enum { MON_DEFAULTTONEAREST = 2 };
private:
HMODULE user32handle;
GetMonInfo getMonitorInfo;
ChangeGdiSettingsEx changeDisplaySettingsEx;
public:
MonFromWindow monitorFromWindow;
MonFromPoint monitorFromPoint;
private:
TCHAR *getMonitorName(HMONITOR monitor, MonInfo *minfo) const;
public:
GdiSettings();
~GdiSettings();

View File

@ -25,12 +25,12 @@
transfer_ptr<FullModeToggler> getFullModeToggler(WId /*winId*/) {
if (XRandR12Toggler::isUsable())
return transfer_ptr<FullModeToggler>(new XRandR12Toggler);
if (XRandRToggler::isUsable())
return transfer_ptr<FullModeToggler>(new XRandRToggler);
// if (Xf86VidModeToggler::isUsable())
// return transfer_ptr<FullModeToggler>(new Xf86VidModeToggler(winId));
return transfer_ptr<FullModeToggler>(new NullToggler);
}

View File

@ -374,7 +374,7 @@ void InputBox::focusInEvent(QFocusEvent *event) {
ignoreCnt = 1;
timerId = startTimer(100);
}
QLineEdit::focusInEvent(event);
}
@ -384,7 +384,7 @@ void InputBox::focusOutEvent(QFocusEvent *event) {
killTimer(timerId);
timerId = 0;
}
QLineEdit::focusOutEvent(event);
}
@ -393,7 +393,7 @@ void InputBox::keyPressEvent(QKeyEvent *e) {
QLineEdit::keyPressEvent(e);
} else {
setData(e->key());
if (nextFocus)
nextFocus->setFocus();
}
@ -404,11 +404,11 @@ void InputBox::timerEvent(QTimerEvent */*event*/) {
return;
SDL_JoystickUpdate();
SDL_Event ev;
int value = 0;
unsigned id = 0;
if (ignoreCnt) {
ignoreCnt--;
} else while (pollJsEvent(&ev, 256)) {
@ -418,20 +418,20 @@ void InputBox::timerEvent(QTimerEvent */*event*/) {
case SDL_JOYBUTTONCHANGE:
if (!ev.value)
continue;
value = ev.value;
break;
default: continue;
}
id = ev.id;
}
SDL_ClearEvents();
if (id) {
setData(id, value);
if (nextFocus)
nextFocus->setFocus();
}
@ -440,7 +440,7 @@ void InputBox::timerEvent(QTimerEvent */*event*/) {
void InputBox::setData(const unsigned id, const int value) {
data.id = id;
data.value = value;
if (value == KBD_VALUE) {
setText(keyToString(id));
} else if (value == NULL_VALUE) {
@ -448,7 +448,7 @@ void InputBox::setData(const unsigned id, const int value) {
} else {
QString str(SDL_JoystickName(data.dev_num));
str.append(' ');
switch (data.type) {
case SDL_JOYAXISMOTION:
str.append("Axis ");
@ -460,7 +460,7 @@ void InputBox::setData(const unsigned id, const int value) {
str.append("Hat ");
str.append(QString::number(data.num));
str.append(' ');
if (data.value & SDL_HAT_UP)
str.append("Up");
if (data.value & SDL_HAT_DOWN)
@ -469,14 +469,14 @@ void InputBox::setData(const unsigned id, const int value) {
str.append("Left");
if (data.value & SDL_HAT_RIGHT)
str.append("Right");
break;
case SDL_JOYBUTTONCHANGE:
str.append("Button ");
str.append(QString::number(data.num));
break;
}
setText(str);
}
}

View File

@ -29,19 +29,19 @@ class InputBox : public QLineEdit {
SDL_Event data;
int timerId;
int ignoreCnt;
private slots:
void textEditedSlot(const QString &) {
setData(data);
}
protected:
void contextMenuEvent(QContextMenuEvent *event);
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
void keyPressEvent(QKeyEvent *e);
void timerEvent(QTimerEvent */*event*/);
public:
enum { NULL_VALUE = 0, KBD_VALUE = 0x7FFFFFFF };
explicit InputBox(QWidget *nextFocus = 0);
@ -60,9 +60,9 @@ class InputBoxPair : public QObject {
public:
InputBox *const mainBox;
InputBox *const altBox;
InputBoxPair(InputBox *mainBox, InputBox *altBox) : mainBox(mainBox), altBox(altBox) {}
public slots:
void clear();
};

View File

@ -48,23 +48,23 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
deleteButtonActions(deleteButtonActions)
{
setWindowTitle(tr("Input Settings"));
QVBoxLayout *mainLayout = new QVBoxLayout;
QPushButton *const okButton = new QPushButton(tr("OK"));
QPushButton *const cancelButton = new QPushButton(tr("Cancel"));
{
QTabWidget *const tabw = new QTabWidget;
for (std::size_t i = 0; i < buttonInfos.size(); ++i) {
if (!buttonInfos[i].label.isEmpty()) {
inputBoxPairs[i] = new InputBoxPair(new InputBox, new InputBox);
int j = tabw->count() - 1;
while (j >= 0 && tabw->tabText(j) != buttonInfos[i].category)
--j;
if (j < 0) {
QWidget *const w = new QWidget;
QBoxLayout *const boxl = new QVBoxLayout;
@ -73,16 +73,16 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
w->setLayout(boxl);
j = tabw->addTab(w, buttonInfos[i].category);
}
QGridLayout *const gLayout = (QGridLayout*) tabw->widget(j)->layout()->itemAt(0);
gLayout->addWidget(new QLabel(buttonInfos[i].label + ":"), i, 0);
if (buttonInfos[i].defaultFpp) {
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(inputBoxPairs[i]->mainBox);
hLayout->addWidget(fppBoxes[i * 2] = makeFppBox(buttonInfos[i].defaultFpp).release());
gLayout->addLayout(hLayout, i, 1);
hLayout = new QHBoxLayout;
hLayout->addWidget(inputBoxPairs[i]->altBox);
hLayout->addWidget(fppBoxes[i * 2 + 1] = makeFppBox(buttonInfos[i].defaultFpp).release());
@ -91,27 +91,27 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
gLayout->addWidget(inputBoxPairs[i]->mainBox, i, 1);
gLayout->addWidget(inputBoxPairs[i]->altBox, i, 2);
}
QPushButton *const clearButton = new QPushButton(tr("Clear"));
gLayout->addWidget(clearButton, i, 3);
connect(clearButton, SIGNAL(clicked()), inputBoxPairs[i], SLOT(clear()));
}
}
for (int tabi = 0; tabi < tabw->count(); ++tabi) {
QWidget *const w = tabw->widget(tabi);
std::size_t i = 0;
while (i < inputBoxPairs.size() && (!inputBoxPairs[i] || inputBoxPairs[i]->mainBox->parentWidget() != w))
++i;
while (i < inputBoxPairs.size()) {
std::size_t j = i + 1;
while (j < inputBoxPairs.size() && (!inputBoxPairs[j] || inputBoxPairs[j]->mainBox->parentWidget() != w))
++j;
if (j < inputBoxPairs.size()) {
inputBoxPairs[i]->mainBox->setNextFocus(inputBoxPairs[j]->mainBox);
inputBoxPairs[i]->altBox->setNextFocus(inputBoxPairs[j]->altBox);
@ -119,29 +119,29 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
inputBoxPairs[i]->mainBox->setNextFocus(okButton);
inputBoxPairs[i]->altBox->setNextFocus(okButton);
}
i = j;
}
}
mainLayout->addWidget(tabw);
}
QHBoxLayout *const hLayout = new QHBoxLayout;
hLayout->addWidget(okButton);
hLayout->addWidget(cancelButton);
mainLayout->addLayout(hLayout);
mainLayout->setAlignment(hLayout, Qt::AlignBottom | Qt::AlignRight);
okButton->setDefault(true);
setLayout(mainLayout);
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
QSettings settings;
settings.beginGroup("input");
for (std::size_t i = 0; i < buttonInfos.size(); ++i) {
if (!buttonInfos[i].label.isEmpty()) {
config[i * 2 ].event.id = settings.value(
@ -151,7 +151,7 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
buttonInfos[i].defaultKey == Qt::Key_unknown ? InputBox::NULL_VALUE : InputBox::KBD_VALUE).toInt();
config[i * 2 ].fpp = buttonInfos[i].defaultFpp ? settings.value(
buttonInfos[i].category + buttonInfos[i].label + "Fpp1", buttonInfos[i].defaultFpp).toInt() : 0;
config[i * 2 + 1].event.id = settings.value(
buttonInfos[i].category + buttonInfos[i].label + "Key2", buttonInfos[i].defaultAltKey).toUInt();
config[i * 2 + 1].event.value = settings.value(
@ -164,16 +164,16 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
config[i * 2 ].event.value =
buttonInfos[i].defaultKey == Qt::Key_unknown ? InputBox::NULL_VALUE : InputBox::KBD_VALUE;
config[i * 2 ].fpp = buttonInfos[i].defaultFpp;
config[i * 2 + 1].event.id = buttonInfos[i].defaultAltKey;
config[i * 2 + 1].event.value =
buttonInfos[i].defaultAltKey == Qt::Key_unknown ? InputBox::NULL_VALUE : InputBox::KBD_VALUE;
config[i * 2 + 1].fpp = buttonInfos[i].defaultFpp;
}
}
settings.endGroup();
restore();
resetMapping();
}
@ -181,23 +181,23 @@ InputDialog::InputDialog(const std::vector<Button> &buttonInfos,
InputDialog::~InputDialog() {
QSettings settings;
settings.beginGroup("input");
for (std::size_t i = 0; i < buttonInfos.size(); ++i) {
if (!buttonInfos[i].label.isEmpty()) {
settings.setValue(buttonInfos[i].category + buttonInfos[i].label + "Key1", config[i * 2].event.id);
settings.setValue(buttonInfos[i].category + buttonInfos[i].label + "Value1", config[i * 2].event.value);
settings.setValue(buttonInfos[i].category + buttonInfos[i].label + "Key2", config[i * 2 + 1].event.id);
settings.setValue(buttonInfos[i].category + buttonInfos[i].label + "Value2", config[i * 2 + 1].event.value);
if (buttonInfos[i].defaultFpp) {
settings.setValue(buttonInfos[i].category + buttonInfos[i].label + "Fpp1", config[i * 2 ].fpp);
settings.setValue(buttonInfos[i].category + buttonInfos[i].label + "Fpp2", config[i * 2 + 1].fpp);
}
}
}
settings.endGroup();
if (deleteButtonActions)
for (std::size_t i = 0; i < buttonInfos.size(); ++i)
delete buttonInfos[i].action;
@ -208,7 +208,7 @@ void InputDialog::resetMapping() {
Mutual<KeyMapping>::Locked lkm(keymapping);
lkm->map.clear();
lkm->rapidvec.clear();
for (std::size_t i = 0; i < config.size(); ++i) {
if (config[i].event.value != InputBox::NULL_VALUE && config[i].event.value == InputBox::KBD_VALUE) {
lkm->map.insert(std::make_pair(config[i].event.id,
@ -216,12 +216,12 @@ void InputDialog::resetMapping() {
}
}
}
{
Mutual<JoyMapping>::Locked ljm(joymapping);
ljm->map.clear();
ljm->rapidvec.clear();
for (std::size_t i = 0; i < config.size(); ++i) {
if (config[i].event.value != InputBox::NULL_VALUE && config[i].event.value != InputBox::KBD_VALUE) {
ljm->map.insert(std::make_pair(config[i].event.id,
@ -238,12 +238,12 @@ void InputDialog::store() {
config[i * 2 + 1].event = inputBoxPairs[i]->altBox->getData();
}
}
for (std::size_t i = 0; i < fppBoxes.size(); ++i) {
if (fppBoxes[i])
config[i].fpp = fppBoxes[i]->value();
}
resetMapping();
}
@ -254,7 +254,7 @@ void InputDialog::restore() {
inputBoxPairs[i]->altBox->setData( config[i * 2 + 1].event);
}
}
for (std::size_t i = 0; i < fppBoxes.size(); ++i) {
if (fppBoxes[i])
fppBoxes[i]->setValue(config[i].fpp);
@ -269,10 +269,10 @@ static void setButtonPressed(AutoPressVec &v, InputDialog::Button::Action *const
if (it->action == action && it->fpp == fpp)
return;
}
v.push_back(typename AutoPressVec::value_type(action, fpp, 0));
}
action->buttonPressed();
}
@ -287,7 +287,7 @@ static void unsetButtonPressed(AutoPressVec &v, InputDialog::Button::Action *con
}
}
}
action->buttonReleased();
}
@ -336,7 +336,7 @@ static void doConsumeAutoPress(AutoPressVec &v) {
void InputDialog::consumeAutoPress() {
if (const Mutual<KeyMapping>::TryLocked &lm = keymapping)
doConsumeAutoPress(lm->rapidvec);
if (const Mutual<JoyMapping>::TryLocked &lm = joymapping)
doConsumeAutoPress(lm->rapidvec);
}

View File

@ -27,14 +27,14 @@ int pollJsEvent(SDL_Event *const ev, const int insensitivity) {
static map_t axisState;
int evValid;
do {
evValid = SDL_PollEvent(ev);
if (evValid && ev->type == SDL_JOYAXISMOTION) {
enum { THRESHOLD = 8192 };
const map_t::iterator it = axisState.insert(map_t::value_type(ev->id, 0)).first;
switch (it->second) {
case 0:
if (ev->value >= THRESHOLD + insensitivity)
@ -62,6 +62,6 @@ int pollJsEvent(SDL_Event *const ev, const int insensitivity) {
it->second = ev->value;
}
} while (false);
return evValid;
}

View File

@ -40,7 +40,7 @@ MainWindow::MainWindow(MediaSource *const source)
setCentralWidget(w_->widget());
setMouseTracking(true);
setFocus();
connect(w_, SIGNAL( audioEngineFailure()), this, SIGNAL( audioEngineFailure()));
connect(w_, SIGNAL(videoBlitterFailure()), this, SIGNAL(videoBlitterFailure()));
}
@ -50,7 +50,7 @@ void MainWindow::stop() { w_->stop(); }
void MainWindow::setWindowSize(const QSize &sz) {
winSize_ = sz;
if (!fullscreen_ && isVisible())
doSetWindowSize(sz);
}
@ -61,14 +61,14 @@ void MainWindow::toggleFullScreen() {
w_->parentExclusiveEvent(false);
w_->setFullMode(false);
showNormal();
if (isVisible())
doSetWindowSize(winSize_);
activateWindow();
} else {
fullscreen_ = true;
if (isVisible())
doShowFullScreen();
}
@ -76,14 +76,14 @@ void MainWindow::toggleFullScreen() {
void MainWindow::setVideoFormat(unsigned w, unsigned h) {
w_->setVideoFormat(w, h);
if (winSize_ == QSize(-1, -1))
centralWidget()->setMinimumSize(w_->videoSize());
}
void MainWindow::setVideoFormatAndBlitter(unsigned w, unsigned h, std::size_t blitterNo) {
w_->setVideoFormatAndBlitter(w, h, blitterNo);
if (winSize_ == QSize(-1, -1))
centralWidget()->setMinimumSize(w_->videoSize());
}
@ -162,7 +162,7 @@ void MainWindow::showEvent(QShowEvent *) {
// some window managers get pissed (xfwm4 breaks, metacity complains) if fixed window size is set too early.
if (!fullscreen_)
doSetWindowSize(winSize_);
w_->showEvent(this);
}
@ -174,7 +174,7 @@ void MainWindow::focusOutEvent(QFocusEvent *) {
void MainWindow::focusInEvent(QFocusEvent *) {
w_->focusInEvent();
w_->parentExclusiveEvent(isFullScreen());
// urk, delay full screen until getting focus if not visible to avoid WMs screwing up.
if (fullscreen_ && !w_->isFullMode())
doShowFullScreen();
@ -200,7 +200,7 @@ void MainWindow::doShowFullScreen() {
const int screen = QApplication::desktop()->screenNumber(this);
w_->setFullMode(true);
doSetWindowSize(QSize(-1, -1));
doSetWindowSize(QSize(-1, -1));
// If the window is outside the screen it will be moved to the primary screen by Qt.
{

View File

@ -69,7 +69,7 @@ struct CustomEvent : QEvent {
struct MediaWidget::Pauser::DoPause {
MediaWidget &mw;
explicit DoPause(MediaWidget &mw) : mw(mw) {}
void operator()() const {
if (mw.running) {
mw.worker->pause();
@ -83,7 +83,7 @@ struct MediaWidget::Pauser::DoPause {
struct MediaWidget::Pauser::DoUnpause {
MediaWidget &mw;
explicit DoUnpause(MediaWidget &mw) : mw(mw) {}
void operator()() const {
if (mw.running) {
mw.jsTimer->stop();
@ -131,16 +131,16 @@ public:
bool cancelBlit();
void paused();
void audioEngineFailure();
bool tryLockVideoBuffer(PixelBuffer &pb) {
if (mw.vbmut.tryLock()) {
pb = mw.blitterContainer->blitter()->inBuffer();
return true;
}
return false;
}
void unlockVideoBuffer() { mw.vbmut.unlock(); }
void consumeBlitRequest();
@ -232,11 +232,11 @@ void MediaWidget::WorkerCallback::consumeBlitRequest() {
static auto_vector<BlitterWidget> makeBlitterWidgets(const VideoBufferLocker vbl, const DwmControlHwndChange hwndc) {
auto_vector<BlitterWidget> blitters;
addBlitterWidgets(blitters, vbl);
blitters.push_back(new QGLBlitter(vbl, hwndc));
blitters.push_back(new QPainterBlitter(vbl));
for (auto_vector<BlitterWidget>::iterator it = blitters.begin(); it != blitters.end();) {
if ((*it)->isUnusable()) {
it = blitters.erase(it);
@ -249,10 +249,10 @@ static auto_vector<BlitterWidget> makeBlitterWidgets(const VideoBufferLocker vbl
static auto_vector<AudioEngine> makeAudioEngines(const WId winId) {
auto_vector<AudioEngine> audioEngines;
addAudioEngines(audioEngines, winId);
audioEngines.push_back(new NullAudioEngine);
return audioEngines;
}
@ -378,7 +378,7 @@ void MediaWidget::setVideo(const unsigned w, const unsigned h, BlitterWidget *co
if (running)
blitterContainer->blitter()->setVideoFormat(w, h);
}
blitterContainer->setSourceSize(QSize(w, h));
}
}
@ -466,7 +466,7 @@ void MediaWidget::setFrameTime(long num, long denom) {
num = 0xFFFF;
denom = 1;
}
frameRateControl.setFrameTime(Rational(num, denom));
}
@ -486,7 +486,7 @@ void MediaWidget::updateJoysticks() {
struct MediaWidget::FrameStepFun {
MediaWidget &mw;
explicit FrameStepFun(MediaWidget &mw) : mw(mw) {}
void operator()() const {
if (mw.running && mw.worker->frameStep()) {
BlitterWidget *const blitter = mw.blitterContainer->blitter();

View File

@ -44,13 +44,13 @@ class QMainWindow;
class MediaWidget : public QObject {
Q_OBJECT
class Pauser {
struct DoPause;
struct DoUnpause;
unsigned paused;
void modifyPaused(unsigned newPaused, MediaWidget &mw);
public:
Pauser() : paused(0) {}
@ -60,17 +60,17 @@ class MediaWidget : public QObject {
void set(unsigned bm, MediaWidget &mw) { modifyPaused(paused | bm, mw); }
void unset(unsigned bm, MediaWidget &mw) { modifyPaused(paused & ~bm, mw); }
};
const class JoystickIniter : Uncopyable {
std::vector<SDL_Joystick*> joysticks;
public:
JoystickIniter();
~JoystickIniter();
} jsInit_;
class WorkerCallback;
struct FrameStepFun;
QMutex vbmut;
BlitterContainer *const blitterContainer;
const auto_vector<AudioEngine> audioEngines;
@ -86,7 +86,7 @@ class MediaWidget : public QObject {
DwmControl dwmControl_;
unsigned focusPauseBit;
bool running;
friend class CallWhenMediaWorkerPaused;
friend class PushMediaWorkerCall;
virtual void customEvent(QEvent*);
@ -96,17 +96,17 @@ class MediaWidget : public QObject {
void updateSwapInterval();
void emitVideoBlitterFailure() { emit videoBlitterFailure(); }
void emitAudioEngineFailure();
private slots:
void refreshRateChange(int refreshRate);
void updateJoysticks();
public:
MediaWidget(MediaSource *source, QWidget &parent);
~MediaWidget();
QWidget* widget() const { return blitterContainer; }
/** @return compositionChange */
bool winEvent(const void *message) { return dwmControl_.winEvent(message); }
void hideEvent() { dwmControl_.hideEvent(); }
@ -118,57 +118,57 @@ public:
void focusInEvent();
void keyPressEvent(QKeyEvent*);
void keyReleaseEvent(QKeyEvent*);
bool tryLockFrameBuf(PixelBuffer &pb) {
if (vbmut.tryLock()) {
pb = running ? blitterContainer->blitter()->inBuffer() : PixelBuffer();
return true;
}
return false;
}
void unlockFrameBuf() { vbmut.unlock(); }
const QSize& videoSize() const { return blitterContainer->sourceSize(); }
void setFrameTime(long num, long denom);
void setSamplesPerFrame(long num, long denom = 1) { worker->setSamplesPerFrame(Rational(num, denom)); }
void frameStep();
void pause(unsigned bitmask = 1) { pauser.set(bitmask, *this); }
void unpause(unsigned bitmask = 1) { pauser.unset(bitmask, *this); }
void incPause(unsigned inc) { pauser.inc(inc, *this); }
void decPause(unsigned dec) { pauser.dec(dec, *this); }
void setPauseOnFocusOut(unsigned bitmask, bool hasFocus);
void run();
void stop();
bool isRunning() const { return running; }
void setAspectRatio(const QSize &ar) { blitterContainer->setAspectRatio(ar); }
void setScalingMethod(ScalingMethod smet) { blitterContainer->setScalingMethod(smet); }
const BlitterConf blitterConf(std::size_t blitterNo) { return BlitterConf(blitters[blitterNo]); }
const ConstBlitterConf blitterConf(std::size_t blitterNo) const { return ConstBlitterConf(blitters[blitterNo]); }
std::size_t numBlitters() const { return blitters.size(); }
const BlitterConf currentBlitterConf() { return BlitterConf(blitterContainer->blitter()); }
const ConstBlitterConf currentBlitterConf() const { return ConstBlitterConf(blitterContainer->blitter()); }
void setVideoBlitter(std::size_t blitterNo) {
setVideoFormatAndBlitter(blitterContainer->sourceSize().width(),
blitterContainer->sourceSize().height(), blitterNo);
}
void setVideoFormat(unsigned w, unsigned h/*, PixelBuffer::PixelFormat pf*/) {
setVideo(w, h, /*pf, */blitterContainer->blitter());
}
void setVideoFormatAndBlitter(unsigned w, unsigned h,
/*PixelBuffer::PixelFormat pf, */std::size_t blitterNo) {
setVideo(w, h,/* pf,*/ blitters[blitterNo]);
}
void setFastForwardSpeed(unsigned speed) { worker->setFastForwardSpeed(speed); }
void setMode(std::size_t screenNo, std::size_t resIndex, std::size_t rateIndex) { fullModeToggler->setMode(screenNo, resIndex, rateIndex); }
const std::vector<ResInfo>& modeVector(std::size_t screen) const { return fullModeToggler->modeVector(screen); }
@ -181,20 +181,20 @@ public:
void setFullMode(bool fullscreen) { fullModeToggler->setFullMode(fullscreen); }
bool isFullMode() const { return fullModeToggler->isFullMode(); }
void parentExclusiveEvent(bool exclusive) { blitterContainer->parentExclusiveEvent(exclusive); }
const AudioEngineConf audioEngineConf(std::size_t aeNo) { return AudioEngineConf(audioEngines[aeNo]); }
const ConstAudioEngineConf audioEngineConf(std::size_t aeNo) const { return ConstAudioEngineConf(audioEngines[aeNo]); }
std::size_t numAudioEngines() const { return audioEngines.size(); }
void setAudioOut(std::size_t engineNo, unsigned srateHz, unsigned msecLatency, std::size_t resamplerNo) {
worker->setAudioOut(audioEngines[engineNo], srateHz, msecLatency, resamplerNo);
}
std::size_t numResamplers() const { return ResamplerInfo::num(); }
const char* resamplerDesc(std::size_t resamplerNo) const { return ResamplerInfo::get(resamplerNo).desc; }
void waitUntilPaused();
template<class T>
void callWhenPaused(const T &fun) {
worker->qPause();
@ -206,10 +206,10 @@ public:
void setDwmTripleBuffer(bool enable) { dwmControl_.setDwmTripleBuffer(enable); }
void setFastForward(bool enable) { worker->setFastForward(enable); }
void setSyncToRefreshRate(bool on) { frameRateControl.setRefreshRateSync(on); }
public slots:
void hideCursor();
signals:
void audioEngineFailure();
void videoBlitterFailure();

Some files were not shown because too many files have changed in this diff Show More