00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SOUND_H
00021 #define SOUND_H
00022
00023 #include "psg.h"
00024 #include "types.h"
00025
00026 #define TAPE_VOLUME 32
00027 #define CYCLE_COUNT_INIT 80000 // 4MHz divided by 50Hz = number of CPU cycles per frame
00028
00030 class Sound
00031 {
00032
00033 public:
00034 Sound(Psg* psg=0);
00035 ~Sound() {}
00036
00037 typedef void (Sound::*Synthesizer)(void);
00038 typedef void (Sound::*CaseEnvType)(void);
00039
00040 void init(Psg* psg=0);
00041
00042 void setSynthesizer(Synthesizer syn) {mSynthesizer=syn;}
00043 Synthesizer synthesizer() {return mSynthesizer;}
00044
00045 inline void setMixerRegister(UBYTE value);
00046 inline void setAmplA(UBYTE value);
00047 inline void setAmplB(UBYTE value);
00048 inline void setAmplC(UBYTE value);
00049 void caseEnvType0_3__9();
00050 void caseEnvType4_7__15();
00051 void caseEnvType8();
00052 void caseEnvType10();
00053 void caseEnvType11();
00054 void caseEnvType12();
00055 void caseEnvType13();
00056 void caseEnvType14();
00057 inline void setEnvelopeRegister(UBYTE value);
00058 inline void setAYRegister(int num, UBYTE value);
00059 inline void synthesizerLogicQ();
00060 inline void synthesizerMixerQ();
00061 void synthesizerStereo16();
00062 void synthesizerStereo8();
00063 void synthesizerMixerQMono();
00064 void synthesizerMono16();
00065 void synthesizerMono8();
00066 void calculateLevelTables();
00067 void resetAYChipEmulation();
00068 void initAYCounterVars();
00069 void initAY();
00070
00071 UBYTE* buffer() {return mSndBuffer;}
00072 UBYTE* bufferEnd() {return mSndBufferEnd;}
00073 UBYTE* stream() {return mSndStream;}
00074
00075 void setBuffer (UBYTE* ptr) {mSndBuffer=ptr;}
00076 void setBufferEnd(UBYTE* ptr) {mSndBufferEnd=ptr;}
00077 void setStream (UBYTE* ptr) {mSndStream=ptr;}
00078
00079 DWORD freqTable(int num) {return mFreqTable[num];}
00080
00081 void setEnabled(bool value) {mSndEnabled=value;}
00082 void setPlaybackRate(uint value) {mSndPlaybackRate=value;}
00083 void setBits(uint value) {mSndBits=value;}
00084 void setStereo(uint value) {mSndStereo=value;}
00085 void setVolume(uint value) {mSndVolume=value;}
00086 void setDevice(uint value) {mSndDevice=value;}
00087 void setBufferSize(uint value) {mSndBufferSize=value;}
00088 void setBufferPtr(UBYTE* ptr) {mSndBufferPtr=ptr;}
00089 void setBufferPtrDW(DWORD ptr) {*(DWORD*)mSndBufferPtr=ptr;}
00090 void setBufferPtrW(WORD ptr) {*(WORD*)mSndBufferPtr=ptr;}
00091 void setBufferPtrU(UBYTE ptr) {*(UBYTE*)mSndBufferPtr=ptr;}
00092
00093 void setBufferFull(bool bf) {mBufferFull=bf;}
00094 bool bufferFull() {return mBufferFull;}
00095
00096 bool enabled() {return mSndEnabled;}
00097 uint playbackRate() {return mSndPlaybackRate;}
00098 uint bits() {return mSndBits;}
00099 uint stereo() {return mSndStereo;}
00100 uint volume() {return mSndVolume;}
00101 uint device() {return mSndDevice;}
00102 uint bufferSize() {return mSndBufferSize;}
00103 UBYTE* bufferPtr() {return mSndBufferPtr;}
00104
00105
00106 const INT64 & cycleCountInitBoth() const {return mCycleCountInit.both;}
00107 uint cycleCountInitLow() const {return mCycleCountInit.low;}
00108 uint cycleCountInitHigh() const {return mCycleCountInit.high;}
00109
00110 const INT64 & cycleCountBoth() const {return mCycleCount.both;}
00111 uint cycleCountLow() const {return mCycleCount.low;}
00112 uint cycleCountHigh() const {return mCycleCount.high;}
00113
00114 void setCycleCountInitBoth(const INT64 & value) {mCycleCountInit.both=value;}
00115 void setCycleCountBoth(const INT64 & value) {mCycleCount.both=value;}
00116 void setCycleCountLow (uint value) {mCycleCount.low =value;}
00117 void setCycleCountHigh(uint value) {mCycleCount.high=value;}
00118
00119 private:
00120 Psg* mPsg;
00121
00122 Synthesizer mSynthesizer;
00123
00124 bool mSndEnabled;
00125 uint mSndPlaybackRate;
00126 uint mSndBits;
00127 uint mSndStereo;
00128 uint mSndVolume;
00129 uint mSndDevice;
00130 uint mSndBufferSize;
00131 UBYTE* mSndBufferPtr;
00132
00133
00134
00135
00136 static DWORD mFreqTable[];
00137 UBYTE* mSndBuffer;
00138 UBYTE* mSndBufferEnd;
00139 UBYTE* mSndStream;
00140 UBYTE mTapeLevel;
00141
00142
00143
00144
00145 bool mBufferFull;
00146
00147 union
00148 {
00149 struct
00150 {
00151 uint low;
00152 uint high;
00153 };
00154 INT64 both;
00155 } mCycleCount;
00156
00157 union
00158 {
00159 struct
00160 {
00161 uint low;
00162 uint high;
00163 };
00164 INT64 both;
00165 } mCycleCountInit;
00166
00167
00168 INT64* mLoopCount64;
00169
00170 INT64 mLoopCountInit;
00171
00172 union
00173 {
00174 struct
00175 {
00176 DWORD low;
00177 DWORD high;
00178 };
00179 INT64 both;
00180 } mLoopCount;
00181
00182 union TCounter
00183 {
00184 struct
00185 {
00186 WORD low;
00187 WORD high;
00188 };
00189 DWORD both;
00190 };
00191 TCounter mTonCounterA, mTonCounterB, mTonCounterC, mNoiseCounter;
00192
00193 union
00194 {
00195 struct
00196 {
00197 WORD low;
00198 WORD val;
00199 };
00200 DWORD seed;
00201 } mNoise;
00202
00203 union
00204 {
00205 struct
00206 {
00207 DWORD low;
00208 DWORD high;
00209 };
00210 INT64 both;
00211 } mEnvelopeCounter;
00212
00213 CaseEnvType mCaseEnvType;
00214
00215 int mLevelPP[256];
00216
00217 static UWORD mAmplitudesAY[16];
00218
00219 bool mTonEnA;
00220 bool mTonEnB;
00221 bool mTonEnC;
00222 bool mNoiseEnA;
00223 bool mNoiseEnB;
00224 bool mNoiseEnC;
00225 bool mEnvelopeEnA;
00226 bool mEnvelopeEnB;
00227 bool mEnvelopeEnC;
00228
00229 UBYTE mTonA;
00230 UBYTE mTonB;
00231 UBYTE mTonC;
00232
00233 int mLevelAR[32];
00234 int mLevelAL[32];
00235 int mLevelBR[32];
00236 int mLevelBL[32];
00237 int mLevelCR[32];
00238 int mLevelCL[32];
00239
00240 int mLevelTape;
00241 UBYTE mIndexAL;
00242 UBYTE mIndexAR;
00243 UBYTE mIndexBL;
00244 UBYTE mIndexBR;
00245 UBYTE mIndexCL;
00246 UBYTE mIndexCR;
00247
00248 int mPreAmp;
00249 int mPreAmpMax;
00250 int mLeftChan;
00251 int mRightChan;
00252
00253 };
00254
00255
00256 inline void Sound::setAYRegister(int num, UBYTE value)
00257 {
00258 switch(num)
00259 {
00260 case 13:
00261 setEnvelopeRegister(value & 15);
00262 break;
00263 case 1:
00264 case 3:
00265 case 5:
00266 mPsg->setRegisterAY(num, value & 15);
00267 break;
00268 case 6:
00269 mPsg->setNoise(value & 31);
00270 break;
00271 case 7:
00272 setMixerRegister(value & 63);
00273 break;
00274 case 8:
00275 setAmplA(value & 31);
00276 break;
00277 case 9:
00278 setAmplB(value & 31);
00279 break;
00280 case 10:
00281 setAmplC(value & 31);
00282 break;
00283 case 0:
00284 case 2:
00285 case 4:
00286 case 11:
00287 case 12:
00288 mPsg->setRegisterAY(num, value);
00289 break;
00290 }
00291 }
00292
00293 inline void Sound::setEnvelopeRegister(UBYTE value)
00294 {
00295 mEnvelopeCounter.high = 0;
00296 mPsg->setFirstPeriod(true);
00297 if (!(value & 4))
00298 {
00299 mPsg->setAmplitudeEnv(32);
00300 }
00301 else
00302 {
00303 mPsg->setAmplitudeEnv(-1);
00304 }
00305 mPsg->setEnvType(value);
00306 switch (value)
00307 {
00308 case 0:
00309 case 1:
00310 case 2:
00311 case 3:
00312 case 9:
00313 mCaseEnvType = &Sound::caseEnvType0_3__9;
00314 break;
00315 case 4:
00316 case 5:
00317 case 6:
00318 case 7:
00319 case 15:
00320 mCaseEnvType = &Sound::caseEnvType4_7__15;
00321 break;
00322 case 8:
00323 mCaseEnvType = &Sound::caseEnvType8;
00324 break;
00325 case 10:
00326 mCaseEnvType = &Sound::caseEnvType10;
00327 break;
00328 case 11:
00329 mCaseEnvType = &Sound::caseEnvType11;
00330 break;
00331 case 12:
00332 mCaseEnvType = &Sound::caseEnvType12;
00333 break;
00334 case 13:
00335 mCaseEnvType = &Sound::caseEnvType13;
00336 break;
00337 case 14:
00338 mCaseEnvType = &Sound::caseEnvType14;
00339 break;
00340 }
00341 }
00342
00343 inline void Sound::setMixerRegister(UBYTE value)
00344 {
00345 mPsg->setMixer(value);
00346 mTonEnA = value & 1 ? false : true;
00347 mNoiseEnA = value & 8 ? false : true;
00348 mTonEnB = value & 2 ? false : true;
00349 mNoiseEnB = value & 16 ? false : true;
00350 mTonEnC = value & 4 ? false : true;
00351 mNoiseEnC = value & 32 ? false : true;
00352 }
00353
00354
00355
00356 inline void Sound::setAmplA(UBYTE value)
00357 {
00358 mPsg->setAmplitudeA(value);
00359 mEnvelopeEnA = value & 16 ? false : true;
00360 }
00361
00362
00363
00364 inline void Sound::setAmplB(UBYTE value)
00365 {
00366 mPsg->setAmplitudeB(value);
00367 mEnvelopeEnB = value & 16 ? false : true;
00368 }
00369
00370
00371
00372 inline void Sound::setAmplC(UBYTE value)
00373 {
00374 mPsg->setAmplitudeC(value);
00375 mEnvelopeEnC = value & 16 ? false : true;
00376 }
00377
00378 #endif