SID.h
/*
* This file is part of libsidplayfp, a SID player engine.
*
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
* Copyright 2007-2010 Antti Lankila
* Copyright 2004 Dag Lem <resid@nimrod.no>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef SIDFP_H
#define SIDFP_H
#include "siddefs-fp.h"
namespace reSIDfp
{
class Filter;
class Filter6581;
class Filter8580;
class ExternalFilter;
class Potentiometer;
class Voice;
class Resampler;
class SIDError
{
private:
const char* message;
public:
SIDError(const char* msg) :
message(msg) {}
const char* getMessage() { return message; }
};
class SID
{
private:
static const int BUS_TTL;
Filter* filter;
Filter6581* filter6581;
Filter8580* filter8580;
ExternalFilter* externalFilter;
Resampler* resampler;
Potentiometer* potX;
Potentiometer* potY;
Voice* voice[3];
int busValueTtl;
int modelTTL;
int nextVoiceSync;
int delayedOffset;
ChipModel model;
unsigned char delayedValue;
unsigned char busValue;
bool muted[3];
private:
void writeImmediate(int offset, unsigned char value);
void ageBusValue(int n);
int output() const;
void voiceSync(bool sync);
public:
SID();
~SID();
void setChipModel(ChipModel model);
ChipModel getChipModel() const { return model; }
void reset();
void input(int value);
unsigned char read(int offset);
void write(int offset, unsigned char value);
void mute(int channel, bool enable) { muted[channel] = enable; }
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency);
int clock(int cycles, short* buf);
void clockSilent(int cycles);
void setFilter6581Curve(double filterCurve);
void setFilter8580Curve(double filterCurve);
void enableFilter(bool enable);
};
} // namespace reSIDfp
#if RESID_INLINING || defined(SID_CPP)
#include <algorithm>
#include "Filter.h"
#include "ExternalFilter.h"
#include "Voice.h"
#include "resample/Resampler.h"
namespace reSIDfp
{
RESID_INLINE
void SID::ageBusValue(int n)
{
if (likely(busValueTtl != 0))
{
busValueTtl -= n;
if (unlikely(busValueTtl <= 0))
{
busValue = 0;
busValueTtl = 0;
}
}
}
RESID_INLINE
int SID::output() const
{
const int v1 = voice[0]->output(voice[2]->wave());
const int v2 = voice[1]->output(voice[0]->wave());
const int v3 = voice[2]->output(voice[1]->wave());
return externalFilter->clock(filter->clock(v1, v2, v3));
}
RESID_INLINE
int SID::clock(int cycles, short* buf)
{
ageBusValue(cycles);
int s = 0;
while (cycles != 0)
{
int delta_t = std::min(nextVoiceSync, cycles);
if (likely(delta_t > 0))
{
if (unlikely(delayedOffset != -1))
{
delta_t = 1;
}
for (int i = 0; i < delta_t; i++)
{
/* clock waveform generators */
voice[0]->wave()->clock();
voice[1]->wave()->clock();
voice[2]->wave()->clock();
/* clock envelope generators */
voice[0]->envelope()->clock();
voice[1]->envelope()->clock();
voice[2]->envelope()->clock();
if (unlikely(resampler->input(output())))
{
buf[s++] = resampler->getOutput();
}
}
if (unlikely(delayedOffset != -1))
{
writeImmediate(delayedOffset, delayedValue);
delayedOffset = -1;
}
cycles -= delta_t;
nextVoiceSync -= delta_t;
}
if (unlikely(nextVoiceSync == 0))
{
voiceSync(true);
}
}
return s;
}
} // namespace reSIDfp
#endif
#endif
reSIDfp::Resampler
Definition: Resampler.h:32
reSIDfp::SID::getChipModel
ChipModel getChipModel() const
Definition: SID.h:158
reSIDfp::ExternalFilter
Definition: ExternalFilter.h:47
reSIDfp::Filter8580
Definition: Filter8580.h:85
reSIDfp::SID::read
unsigned char read(int offset)
Definition: SID.cpp:308
reSIDfp::SID::enableFilter
void enableFilter(bool enable)
Definition: SID.cpp:93
reSIDfp::SID::write
void write(int offset, unsigned char value)
Definition: SID.cpp:341
reSIDfp::Filter
Definition: Filter.h:32
reSIDfp::Filter::clock
virtual int clock(int v1, int v2, int v3)=0
reSIDfp::Voice::output
RESID_INLINE int output(const WaveformGenerator *ringModulator) const
Definition: Voice.h:59
reSIDfp::Voice
Definition: Voice.h:36
reSIDfp::SID::mute
void mute(int channel, bool enable)
Definition: SID.h:211
reSIDfp::Potentiometer
Definition: Potentiometer.h:37
reSIDfp::SID::setChipModel
void setChipModel(ChipModel model)
Definition: SID.cpp:248
reSIDfp::Resampler::getOutput
short getOutput() const
Definition: Resampler.h:55
reSIDfp::SID::clockSilent
void clockSilent(int cycles)
Definition: SID.cpp:378
reSIDfp::ExternalFilter::clock
int clock(int Vi)
Definition: ExternalFilter.h:94
reSIDfp::SID::reset
void reset()
Definition: SID.cpp:280
reSIDfp::SID::input
void input(int value)
Definition: SID.cpp:302
reSIDfp::SID::setFilter6581Curve
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:83
reSIDfp::WaveformGenerator::clock
void clock()
Definition: WaveformGenerator.h:282
reSIDfp::SID::setFilter8580Curve
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:88
reSIDfp::Filter6581
Definition: Filter6581.h:320
reSIDfp::SIDError
Definition: SID.h:42
reSIDfp::EnvelopeGenerator::clock
void clock()
Definition: EnvelopeGenerator.h:208
reSIDfp::Resampler::input
virtual bool input(int sample)=0
reSIDfp::SID
Definition: SID.h:56
reSIDfp::SID::clock
int clock(int cycles, short *buf)
Definition: SID.h:323
reSIDfp::SID::setSamplingParameters
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency)
Definition: SID.cpp:357