00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef ENVELOPEGENERATOR_H
00024 #define ENVELOPEGENERATOR_H
00025
00026 #include "siddefs-fp.h"
00027
00028 namespace reSIDfp
00029 {
00030
00044 class EnvelopeGenerator
00045 {
00046 private:
00051 enum State
00052 {
00053 ATTACK, DECAY_SUSTAIN, RELEASE
00054 };
00055
00059 int lfsr;
00060
00064 int rate;
00065
00070 int exponential_counter;
00071
00076 int exponential_counter_period;
00077
00079 int attack;
00080
00082 int decay;
00083
00085 int sustain;
00086
00088 int release;
00089
00091 State state;
00092
00096 bool hold_zero;
00097
00098 bool envelope_pipeline;
00099
00101 bool gate;
00102
00104 unsigned char envelope_counter;
00105
00111 short dac[256];
00112
00113 void set_exponential_counter();
00114
00126 static const int adsrtable[16];
00127
00128 public:
00136 void setChipModel(ChipModel chipModel);
00137
00141 void clock();
00142
00148 short output() const { return dac[envelope_counter]; }
00149
00153 EnvelopeGenerator() :
00154 lfsr(0),
00155 rate(0),
00156 exponential_counter(0),
00157 exponential_counter_period(1),
00158 attack(0),
00159 decay(0),
00160 sustain(0),
00161 release(0),
00162 state(RELEASE),
00163 hold_zero(true),
00164 envelope_pipeline(false),
00165 gate(false),
00166 envelope_counter(0) {}
00167
00171 void reset();
00172
00173
00174
00175
00176
00181 void writeCONTROL_REG(unsigned char control);
00182
00187 void writeATTACK_DECAY(unsigned char attack_decay);
00188
00193 void writeSUSTAIN_RELEASE(unsigned char sustain_release);
00194
00200 unsigned char readENV() const { return envelope_counter; }
00201 };
00202
00203 }
00204
00205 #if RESID_INLINING || defined(ENVELOPEGENERATOR_CPP)
00206
00207 namespace reSIDfp
00208 {
00209
00210 RESID_INLINE
00211 void EnvelopeGenerator::clock()
00212 {
00213 if (envelope_pipeline)
00214 {
00215 -- envelope_counter;
00216 envelope_pipeline = false;
00217
00218 set_exponential_counter();
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 if (lfsr != rate)
00233 {
00234
00235
00236 const int feedback = ((lfsr >> 14) ^ (lfsr >> 13)) & 0x01;
00237 lfsr = ((lfsr << 1) & 0x7fff) | feedback;
00238 return;
00239 }
00240
00241
00242 lfsr = 0x7fff;
00243
00244
00245
00246
00247 if (state == ATTACK || ++exponential_counter == exponential_counter_period)
00248 {
00249
00250 exponential_counter = 0;
00251
00252
00253 if (hold_zero)
00254 {
00255 return;
00256 }
00257
00258 switch (state)
00259 {
00260 case ATTACK:
00261
00262
00263
00264
00265
00266 ++ envelope_counter;
00267
00268 if (envelope_counter == (unsigned char) 0xff)
00269 {
00270 state = DECAY_SUSTAIN;
00271 rate = adsrtable[decay];
00272 }
00273
00274 break;
00275
00276 case DECAY_SUSTAIN:
00277
00278
00279
00280
00281
00282
00283
00284 if (envelope_counter == (unsigned char)(sustain << 4 | sustain))
00285 {
00286 return;
00287 }
00288
00289 if (exponential_counter_period != 1)
00290 {
00291
00292
00293 envelope_pipeline = true;
00294 return;
00295 }
00296
00297 -- envelope_counter;
00298 break;
00299
00300 case RELEASE:
00301
00302
00303
00304
00305
00306
00307
00308 if (exponential_counter_period != 1)
00309 {
00310
00311
00312 envelope_pipeline = true;
00313 return;
00314 }
00315
00316 -- envelope_counter;
00317 break;
00318 }
00319
00320
00321 set_exponential_counter();
00322 }
00323 }
00324
00325 }
00326
00327 #endif
00328
00329 #endif