Navigation Menu

Skip to content

Commit

Permalink
gambatte_qt/framework/samplebuffer: ensure 32-bit alignment
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sinamas committed Mar 29, 2013
1 parent f5e4f6c commit 013e8f7
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 25 deletions.
34 changes: 20 additions & 14 deletions gambatte_qt/src/framework/src/samplebuffer.cpp
Expand Up @@ -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;
}
Expand All @@ -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;
}
36 changes: 25 additions & 11 deletions gambatte_qt/src/framework/src/samplebuffer.h
Expand Up @@ -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

0 comments on commit 013e8f7

Please sign in to comment.