#ifndef _SID_H
#define _SID_H
#define SOUND_FREQ_PAL_C64 985248
#define TED_SOUND_CLOCK (221680)
enum {
SID6581 = 0,
SID8580,
SID8580DB,
SID6581R1
};
class SIDsound
{
public:
SIDsound(unsigned int model, unsigned int chnlDisableMask);
virtual ~SIDsound();
void reset();
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:
int wave; int egState; SIDVoice *modulatedBy; SIDVoice *modulatesThis;
unsigned int accu; unsigned int accPrev; unsigned int add; unsigned int shiftReg;
unsigned short freq; unsigned short 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; };
int volume; unsigned int sidBaseFreq; unsigned int sidCyclesPerSampleInt;
unsigned int clockDeltaRemainder;
int dcMixer; int dcVoice;
int dcWave;
int dcDigiBlaster;
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]; unsigned int masterVolume;
SIDVoice voice[3];
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)
& 0x8000000;
return ((msb ? ~v.accu : v.accu) >> 15) & 0xFFE;
}
inline int SIDsound::waveSaw(SIDVoice &v)
{
return (v.accu >> 16) & 0xFFF;
}
inline int SIDsound::wavePulse(SIDVoice &v)
{
return (v.test | ((v.accu >> 16) >= 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)
{
return (waveSaw(v)) & (wavePulse(v));
}
inline int SIDsound::waveTriSawPulse(SIDVoice &v)
{
unsigned int sm = (waveTriangle(v)) & (waveSaw(v)) & (wavePulse(v));
return (sm>>1) & (sm<<1);
}
#endif