#ifndef _SID_H
#define _SID_H
#define SOUND_FREQ_PAL_C64 985248
enum {
SID6581 = 0,
SID8580,
SID8580DB,
SID6581R1
};
class SIDsound
{
public:
SIDsound(unsigned int model, unsigned int chnlDisableMask);
virtual ~SIDsound();
virtual void reset();
virtual void setReplayFreq() {
calcEnvelopeTable();
};
void setModel(unsigned int model);
void setFrequency(unsigned int sid_frequency);
void setSampleRate(unsigned int sampleRate_);
void calcEnvelopeTable();
unsigned char read(unsigned int adr);
void write(unsigned int adr, unsigned char byte);
void calcSamples(short *buf, long count);
void enableDisableChannel(unsigned int ch, bool enabled) {
voice[ch].disabled = !enabled;
}
private:
enum {
WAVE_NONE, WAVE_TRI, WAVE_SAW, WAVE_TRISAW, WAVE_PULSE,
WAVE_TRIPULSE, WAVE_SAWPULSE, WAVE_TRISAWPULSE, WAVE_NOISE
};
enum {
EG_FROZEN, EG_ATTACK, EG_DECAY, EG_RELEASE
};
enum {
FILTER_NONE, FILTER_LP, FILTER_BP, FILTER_LPBP, FILTER_HP, FILTER_NOTCH, FILTER_HPBP, FILTER_ALL
};
class SIDVoice {
public:
unsigned int index; int wave; int egState; SIDVoice *modulatedBy; SIDVoice *modulatesThis;
unsigned int accu; unsigned int accPrev; unsigned int shiftReg; unsigned int waveNoiseOut;
unsigned int freq; unsigned int pw;
unsigned int envAttackAdd;
unsigned int envDecaySub;
unsigned int envSustainLevel;
unsigned int envReleaseSub;
unsigned int envCurrLevel;
unsigned int envCounter;
unsigned int envExpCounter;
unsigned int envCounterCompare;
unsigned int gate; unsigned int ring; unsigned int test; unsigned int filter; unsigned int muted; bool disabled;
unsigned int sync; } voice[3]; int volume; unsigned int sidBaseFreq; unsigned int sidCyclesPerSampleInt;
unsigned int clockDeltaRemainder; unsigned int clockDeltaFraction; int dcMixer; int dcVoice;
int dcWave;
int dcDigiBlaster;
int extIn;
unsigned int clock();
inline static int waveTriangle(SIDVoice &v);
inline static int waveSaw(SIDVoice &v);
inline static int wavePulse(SIDVoice &v);
inline static int waveTriSaw(SIDVoice &v);
inline static int waveTriPulse(SIDVoice &v);
inline static int waveSawPulse(SIDVoice &v);
inline static int waveTriSawPulse(SIDVoice &v);
inline static int waveNoise(SIDVoice &v);
inline static int getWaveSample(SIDVoice &v);
inline void updateShiftReg(SIDVoice &v);
inline int doEnvelopeGenerator(unsigned int cycles, SIDVoice &v);
static const unsigned int RateCountPeriod[16]; static const unsigned char envGenDRdivisors[256]; static unsigned int masterVolume;
unsigned char filterType; unsigned int filterCutoff; unsigned char filterResonance; double cutOffFreq[2048]; int resonanceCoeffDiv1024; int w0; void setResonance();
void setFilterCutoff();
int filterOutput(unsigned int cycles, int Vi);
int Vhp; int Vbp; int Vlp; unsigned char lastByteWritten; int model_;
bool enableDigiBlaster;
unsigned int sampleRate;
};
inline int SIDsound::waveTriangle(SIDVoice &v)
{
unsigned int msb = (v.ring ? v.accu ^ v.modulatedBy->accu : v.accu)
& 0x800000;
return ((msb ? ~v.accu : v.accu) >> 11) & 0xFFF;
}
inline int SIDsound::waveSaw(SIDVoice &v)
{
return v.accu >> 12;
}
inline int SIDsound::wavePulse(SIDVoice &v)
{
return (v.test | (v.accu >= v.pw ? 0xFFF : 0x000));
}
inline int SIDsound::waveTriSaw(SIDVoice &v)
{
unsigned int sm = (waveTriangle(v)) & (waveSaw(v));
return (sm >> 1) & (sm << 1);
}
inline int SIDsound::waveTriPulse(SIDVoice &v)
{
unsigned int sm = (waveTriangle(v)) & (wavePulse(v));
return (sm >> 1) & (sm << 1);
}
inline int SIDsound::waveSawPulse(SIDVoice &v)
{
unsigned int sm = (waveSaw(v)) & (wavePulse(v));
return (sm >> 1) & (sm << 1);
}
inline int SIDsound::waveTriSawPulse(SIDVoice &v)
{
unsigned int sm = (waveTriangle(v)) & (waveSaw(v)) & (wavePulse(v));
return (sm >> 1) & (sm << 1);
}
#endif