libsidplayfp  2.0.2
envelope.h
1 // ---------------------------------------------------------------------------
2 // This file is part of reSID, a MOS6581 SID emulator engine.
3 // Copyright (C) 2010 Dag Lem <resid@nimrod.no>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // ---------------------------------------------------------------------------
19 
20 #ifndef RESID_ENVELOPE_H
21 #define RESID_ENVELOPE_H
22 
23 #include "resid-config.h"
24 
25 namespace reSID
26 {
27 
28 // ----------------------------------------------------------------------------
29 // A 15 bit counter is used to implement the envelope rates, in effect
30 // dividing the clock to the envelope counter by the currently selected rate
31 // period.
32 // In addition, another counter is used to implement the exponential envelope
33 // decay, in effect further dividing the clock to the envelope counter.
34 // The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope
35 // counter values 255, 93, 54, 26, 14, 6, respectively.
36 // ----------------------------------------------------------------------------
38 {
39 public:
41 
42  enum State { ATTACK, DECAY_SUSTAIN, RELEASE, FREEZED };
43 
44  void set_chip_model(chip_model model);
45 
46  void clock();
47  void clock(cycle_count delta_t);
48  void reset();
49 
50  void writeCONTROL_REG(reg8);
51  void writeATTACK_DECAY(reg8);
52  void writeSUSTAIN_RELEASE(reg8);
53  reg8 readENV();
54 
55  // 8-bit envelope output.
56  short output();
57 
58 protected:
59  void set_exponential_counter();
60 
61  void state_change();
62 
63  reg16 rate_counter;
64  reg16 rate_period;
65  reg8 exponential_counter;
66  reg8 exponential_counter_period;
67  reg8 new_exponential_counter_period;
68  reg8 envelope_counter;
69  reg8 env3;
70  // Emulation of pipeline delay for envelope decrement.
71  cycle_count envelope_pipeline;
72  cycle_count exponential_pipeline;
73  cycle_count state_pipeline;
74  bool hold_zero;
75  bool reset_rate_counter;
76 
77  reg4 attack;
78  reg4 decay;
79  reg4 sustain;
80  reg4 release;
81 
82  reg8 gate;
83 
84  State state;
85  State next_state;
86 
87  chip_model sid_model;
88 
89  // Lookup table to convert from attack, decay, or release value to rate
90  // counter period.
91  static reg16 rate_counter_period[];
92 
93  // The 16 selectable sustain levels.
94  static reg8 sustain_level[];
95 
96  // DAC lookup tables.
97  static unsigned short model_dac[2][1 << 8];
98 
99 friend class SID;
100 };
101 
102 
103 // ----------------------------------------------------------------------------
104 // Inline functions.
105 // The following functions are defined inline because they are called every
106 // time a sample is calculated.
107 // ----------------------------------------------------------------------------
108 
109 #if RESID_INLINING || defined(RESID_ENVELOPE_CC)
110 
111 // ----------------------------------------------------------------------------
112 // SID clocking - 1 cycle.
113 // ----------------------------------------------------------------------------
114 RESID_INLINE
115 void EnvelopeGenerator::clock()
116 {
117  // The ENV3 value is sampled at the first phase of the clock
118  env3 = envelope_counter;
119 
120  if (unlikely(state_pipeline)) {
121  state_change();
122  }
123 
124  // If the exponential counter period != 1, the envelope decrement is delayed
125  // 1 cycle. This is only modeled for single cycle clocking.
126  if (unlikely(envelope_pipeline != 0) && (--envelope_pipeline == 0)) {
127  if (likely(!hold_zero)) {
128  if (state == ATTACK) {
129  ++envelope_counter &= 0xff;
130  if (unlikely(envelope_counter == 0xff)) {
131  state = DECAY_SUSTAIN;
132  rate_period = rate_counter_period[decay];
133  }
134  }
135  else if ((state == DECAY_SUSTAIN) || (state == RELEASE)) {
136  --envelope_counter &= 0xff;
137  }
138 
139  set_exponential_counter();
140  }
141  }
142 
143  if (unlikely(exponential_pipeline != 0) && (--exponential_pipeline == 0)) {
144  exponential_counter = 0;
145 
146  if (((state == DECAY_SUSTAIN) && (envelope_counter != sustain_level[sustain]))
147  || (state == RELEASE)) {
148  // The envelope counter can flip from 0x00 to 0xff by changing state to
149  // attack, then to release. The envelope counter will then continue
150  // counting down in the release state.
151  // This has been verified by sampling ENV3.
152 
153  envelope_pipeline = 1;
154  }
155  }
156  else if (unlikely(reset_rate_counter)) {
157  rate_counter = 0;
158  reset_rate_counter = false;
159 
160  if (state == ATTACK) {
161  // The first envelope step in the attack state also resets the exponential
162  // counter. This has been verified by sampling ENV3.
163  exponential_counter = 0; // NOTE this is actually delayed one cycle, not modeled
164 
165  // The envelope counter can flip from 0xff to 0x00 by changing state to
166  // release, then to attack. The envelope counter is then frozen at
167  // zero; to unlock this situation the state must be changed to release,
168  // then to attack. This has been verified by sampling ENV3.
169 
170  envelope_pipeline = 2;
171  }
172  else {
173  if ((!hold_zero) && ++exponential_counter == exponential_counter_period) {
174  exponential_pipeline = exponential_counter_period != 1 ? 2 : 1;
175  }
176  }
177  }
178 
179  // Check for ADSR delay bug.
180  // If the rate counter comparison value is set below the current value of the
181  // rate counter, the counter will continue counting up until it wraps around
182  // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
183  // envelope can finally be stepped.
184  // This has been verified by sampling ENV3.
185  //
186  if (likely(rate_counter != rate_period)) {
187  if (unlikely(++rate_counter & 0x8000)) {
188  ++rate_counter &= 0x7fff;
189  }
190  }
191  else
192  reset_rate_counter = true;
193 }
194 
195 
196 // ----------------------------------------------------------------------------
197 // SID clocking - delta_t cycles.
198 // ----------------------------------------------------------------------------
199 RESID_INLINE
200 void EnvelopeGenerator::clock(cycle_count delta_t)
201 {
202  // NB! Any pipelined envelope counter decrement from single cycle clocking
203  // will be lost. It is not worth the trouble to flush the pipeline here.
204 
205  if (unlikely(state_pipeline)) {
206  if (next_state == ATTACK) {
207  state = ATTACK;
208  hold_zero = false;
209  rate_period = rate_counter_period[attack];
210  } else if (next_state == RELEASE) {
211  state = RELEASE;
212  rate_period = rate_counter_period[release];
213  } else if (next_state == FREEZED) {
214  hold_zero = true;
215  }
216  state_pipeline = 0;
217  }
218 
219  // Check for ADSR delay bug.
220  // If the rate counter comparison value is set below the current value of the
221  // rate counter, the counter will continue counting up until it wraps around
222  // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
223  // envelope can finally be stepped.
224  // This has been verified by sampling ENV3.
225  //
226 
227  // NB! This requires two's complement integer.
228  int rate_step = rate_period - rate_counter;
229  if (unlikely(rate_step <= 0)) {
230  rate_step += 0x7fff;
231  }
232 
233  while (delta_t) {
234  if (delta_t < rate_step) {
235  // likely (~65%)
236  rate_counter += delta_t;
237  if (unlikely(rate_counter & 0x8000)) {
238  ++rate_counter &= 0x7fff;
239  }
240  return;
241  }
242 
243  rate_counter = 0;
244  delta_t -= rate_step;
245 
246  // The first envelope step in the attack state also resets the exponential
247  // counter. This has been verified by sampling ENV3.
248  //
249  if (state == ATTACK || ++exponential_counter == exponential_counter_period) {
250  // likely (~50%)
251  exponential_counter = 0;
252 
253  // Check whether the envelope counter is frozen at zero.
254  if (unlikely(hold_zero)) {
255  rate_step = rate_period;
256  continue;
257  }
258 
259  switch (state) {
260  case ATTACK:
261  // The envelope counter can flip from 0xff to 0x00 by changing state to
262  // release, then to attack. The envelope counter is then frozen at
263  // zero; to unlock this situation the state must be changed to release,
264  // then to attack. This has been verified by sampling ENV3.
265  //
266  ++envelope_counter &= 0xff;
267  if (unlikely(envelope_counter == 0xff)) {
268  state = DECAY_SUSTAIN;
269  rate_period = rate_counter_period[decay];
270  }
271  break;
272  case DECAY_SUSTAIN:
273  if (likely(envelope_counter != sustain_level[sustain])) {
274  --envelope_counter;
275  }
276  break;
277  case RELEASE:
278  // The envelope counter can flip from 0x00 to 0xff by changing state to
279  // attack, then to release. The envelope counter will then continue
280  // counting down in the release state.
281  // This has been verified by sampling ENV3.
282  // NB! The operation below requires two's complement integer.
283  //
284  --envelope_counter &= 0xff;
285  break;
286  case FREEZED:
287  // we should never get here
288  break;
289  }
290 
291  // Check for change of exponential counter period.
292  set_exponential_counter();
293  if (unlikely(new_exponential_counter_period > 0)) {
294  exponential_counter_period = new_exponential_counter_period;
295  new_exponential_counter_period = 0;
296  if (next_state == FREEZED) {
297  hold_zero = true;
298  }
299  }
300  }
301 
302  rate_step = rate_period;
303  }
304 }
305 
345 RESID_INLINE
347 {
348  state_pipeline--;
349 
350  switch (next_state) {
351  case ATTACK:
352  if (state_pipeline == 0) {
353  state = ATTACK;
354  // The attack register is correctly activated during second cycle of attack phase
355  rate_period = rate_counter_period[attack];
356  hold_zero = false;
357  }
358  break;
359  case DECAY_SUSTAIN:
360  break;
361  case RELEASE:
362  if (((state == ATTACK) && (state_pipeline == 0))
363  || ((state == DECAY_SUSTAIN) && (state_pipeline == 1))) {
364  state = RELEASE;
365  rate_period = rate_counter_period[release];
366  }
367  break;
368  case FREEZED:
369  break;
370  }
371 }
372 
373 
374 // ----------------------------------------------------------------------------
375 // Read the envelope generator output.
376 // ----------------------------------------------------------------------------
377 RESID_INLINE
378 short EnvelopeGenerator::output()
379 {
380  // DAC imperfections are emulated by using envelope_counter as an index
381  // into a DAC lookup table. readENV() uses envelope_counter directly.
382  return model_dac[sid_model][envelope_counter];
383 }
384 
385 RESID_INLINE
386 void EnvelopeGenerator::set_exponential_counter()
387 {
388  // Check for change of exponential counter period.
389  switch (envelope_counter) {
390  case 0xff:
391  exponential_counter_period = 1;
392  break;
393  case 0x5d:
394  exponential_counter_period = 2;
395  break;
396  case 0x36:
397  exponential_counter_period = 4;
398  break;
399  case 0x1a:
400  exponential_counter_period = 8;
401  break;
402  case 0x0e:
403  exponential_counter_period = 16;
404  break;
405  case 0x06:
406  exponential_counter_period = 30;
407  break;
408  case 0x00:
409  // TODO write a test to verify that 0x00 really changes the period
410  // e.g. set R = 0xf, gate on to 0x06, gate off to 0x00, gate on to 0x04,
411  // gate off, sample.
412  exponential_counter_period = 1;
413 
414  // When the envelope counter is changed to zero, it is frozen at zero.
415  // This has been verified by sampling ENV3.
416  hold_zero = true;
417  break;
418  }
419 }
420 
421 #endif // RESID_INLINING || defined(RESID_ENVELOPE_CC)
422 
423 } // namespace reSID
424 
425 #endif // not RESID_ENVELOPE_H
reSID::SID
Definition: sid.h:39
reSID::EnvelopeGenerator
Definition: envelope.h:38
reSID::EnvelopeGenerator::state_change
void state_change()
Definition: envelope.h:346