gambatte_qt/framework/samplebuffer: ensure 32-bit alignment
in practice this should already be fine, but it's nice to comply with c++98 which only guarantees alignment beyond the type allocated for char arrays. just use quint32 here.
This commit is contained in:
parent
f5e4f6c7ac
commit
013e8f7c59
@ -17,28 +17,31 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "samplebuffer.h"
|
||||
#include "resample/resamplerinfo.h"
|
||||
#include "resample/resampler.h"
|
||||
#include "mediasource.h"
|
||||
#include "resample/resamplerinfo.h"
|
||||
#include <cstring>
|
||||
|
||||
template<class T>
|
||||
static T * ptr_cast(void *p) { return static_cast<T *>(p); }
|
||||
|
||||
void SampleBuffer::reset() {
|
||||
const long insrate = static_cast<long>(ft_.reciprocal().toFloat() * spf_.toFloat() + 0.5f);
|
||||
const long maxin = spf_.ceiled() + source_->overupdate;
|
||||
|
||||
sndInBuffer.reset(0);
|
||||
resampler.reset();
|
||||
sndInBuffer_.reset(0);
|
||||
resampler_.reset();
|
||||
samplesBuffered_ = 0;
|
||||
|
||||
if (insrate > 0 && outsrate > 0) {
|
||||
sndInBuffer.reset(maxin * 2);
|
||||
resampler.reset(ResamplerInfo::get(resamplerNo_).create(insrate, outsrate, maxin));
|
||||
if (insrate > 0 && outsrate_ > 0) {
|
||||
sndInBuffer_.reset(maxin);
|
||||
resampler_.reset(ResamplerInfo::get(resamplerNo_).create(insrate, outsrate_, maxin));
|
||||
}
|
||||
}
|
||||
|
||||
long SampleBuffer::update(const PixelBuffer &pb) {
|
||||
long insamples = size() - samplesBuffered_;
|
||||
const long res = source_->update(pb, sndInBuffer + samplesBuffered_ * 2, insamples);
|
||||
long insamples = sndInBuffer_.size() - samplesBuffered_;
|
||||
const long res = source_->update(pb, ptr_cast<qint16>(sndInBuffer_ + samplesBuffered_),
|
||||
insamples);
|
||||
samplesBuffered_ += insamples;
|
||||
return res < 0 ? res : samplesBuffered_ - insamples + res;
|
||||
}
|
||||
@ -48,13 +51,16 @@ long SampleBuffer::read(const long insamples, qint16 *const out, const bool alwa
|
||||
samplesBuffered_ -= insamples;
|
||||
|
||||
if (out) {
|
||||
if (resampler->inRate() == resampler->outRate() && !alwaysResample) {
|
||||
std::memcpy(out, sndInBuffer, insamples * 2 * sizeof *out);
|
||||
if (resampler_->inRate() == resampler_->outRate() && !alwaysResample) {
|
||||
std::memcpy(out, sndInBuffer_, insamples * sizeof *sndInBuffer_);
|
||||
outsamples = insamples;
|
||||
} else
|
||||
outsamples = resampler->resample(out, sndInBuffer, insamples);
|
||||
} else {
|
||||
outsamples = resampler_->resample(out, ptr_cast<qint16>(sndInBuffer_),
|
||||
insamples);
|
||||
}
|
||||
}
|
||||
|
||||
std::memmove(sndInBuffer, sndInBuffer + insamples * 2, samplesBuffered_ * 2 * sizeof *sndInBuffer);
|
||||
std::memmove(sndInBuffer_, sndInBuffer_ + insamples,
|
||||
samplesBuffered_ * sizeof *sndInBuffer_);
|
||||
return outsamples;
|
||||
}
|
||||
|
@ -30,33 +30,47 @@ struct PixelBuffer;
|
||||
|
||||
class SampleBuffer : Uncopyable {
|
||||
MediaSource *const source_;
|
||||
scoped_ptr<Resampler> resampler;
|
||||
Array<qint16> sndInBuffer;
|
||||
scoped_ptr<Resampler> resampler_;
|
||||
Array<quint32> sndInBuffer_;
|
||||
long samplesBuffered_;
|
||||
Rational spf_;
|
||||
Rational ft_;
|
||||
int outsrate;
|
||||
unsigned resamplerNo_;
|
||||
long outsrate_;
|
||||
std::size_t resamplerNo_;
|
||||
|
||||
unsigned size() const { return sndInBuffer.size() >> 1; }
|
||||
void reset();
|
||||
|
||||
public:
|
||||
explicit SampleBuffer(MediaSource *source) : source_(source), spf_(0), ft_(1, 0), outsrate(0), resamplerNo_(1) { reset(); }
|
||||
explicit SampleBuffer(MediaSource *source)
|
||||
: source_(source)
|
||||
, spf_(0)
|
||||
, ft_(1, 0)
|
||||
, outsrate_(0)
|
||||
, resamplerNo_(1)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
long update(const PixelBuffer &pb);
|
||||
long read(long insamples, qint16 *out, bool alwaysResample);
|
||||
long samplesBuffered() const { return samplesBuffered_; }
|
||||
void setSpf(const Rational &spf) { spf_ = spf; reset(); }
|
||||
void setFt(const Rational &ft) { ft_ = ft; reset(); }
|
||||
void setOutSampleRate(int outsrate, unsigned resamplerNo) { this->outsrate = outsrate; resamplerNo_ = resamplerNo; reset(); }
|
||||
void setOutSampleRate(int outsrate) { setOutSampleRate(outsrate, resamplerNo_); }
|
||||
long maxOut() const { return resampler.get() ? resampler->maxOut(size()) : 0; }
|
||||
|
||||
void setOutSampleRate(long outsrate, std::size_t resamplerNo) {
|
||||
outsrate_ = outsrate;
|
||||
resamplerNo_ = resamplerNo;
|
||||
reset();
|
||||
}
|
||||
|
||||
void setOutSampleRate(long outsrate) { setOutSampleRate(outsrate, resamplerNo_); }
|
||||
long maxOut() const { return resampler_ ? resampler_->maxOut(sndInBuffer_.size()) : 0; }
|
||||
MediaSource* source() { return source_; }
|
||||
const MediaSource* source() const { return source_; }
|
||||
const Rational& spf() const { return spf_; }
|
||||
const Rational& ft() const { return ft_; }
|
||||
long resamplerOutRate() const { return resampler->outRate(); }
|
||||
void adjustResamplerOutRate(long outRate) { resampler->adjustRate(resampler->inRate(), outRate); }
|
||||
long resamplerOutRate() const { return resampler_->outRate(); }
|
||||
void adjustResamplerOutRate(long outRate) { resampler_->adjustRate(resampler_->inRate(), outRate); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user