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:
sinamas 2013-03-29 13:12:23 +01:00
parent f5e4f6c7ac
commit 013e8f7c59
2 changed files with 45 additions and 25 deletions

View File

@ -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;
}

View File

@ -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