libsidplayfp  2.3.0
EnvelopeGenerator.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2020 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2018 VICE Project
6  * Copyright 2007-2010 Antti Lankila
7  * Copyright 2004,2010 Dag Lem <resid@nimrod.no>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef ENVELOPEGENERATOR_H
25 #define ENVELOPEGENERATOR_H
26 
27 #include "siddefs-fp.h"
28 
29 namespace reSIDfp
30 {
31 
44 {
45 private:
50  enum State
51  {
52  ATTACK, DECAY_SUSTAIN, RELEASE
53  };
54 
55 private:
57  unsigned int lfsr;
58 
60  unsigned int rate;
61 
66  unsigned int exponential_counter;
67 
72  unsigned int exponential_counter_period;
73  unsigned int new_exponential_counter_period;
74 
75  unsigned int state_pipeline;
76 
78  unsigned int envelope_pipeline;
79 
80  unsigned int exponential_pipeline;
81 
83  State state;
84  State next_state;
85 
87  bool counter_enabled;
88 
90  bool gate;
91 
93  bool resetLfsr;
94 
96  unsigned char envelope_counter;
97 
99  unsigned char attack;
100 
102  unsigned char decay;
103 
105  unsigned char sustain;
106 
108  unsigned char release;
109 
111  unsigned char env3;
112 
114  float* dac; //-V730_NOINIT this is initialized in the SID constructor
115 
116 private:
117  static const unsigned int adsrtable[16];
118 
119 private:
120  void set_exponential_counter();
121 
122  void state_change();
123 
124 public:
132  void setDAC(float* dac) { this->dac = dac; }
133 
137  void clock();
138 
144  float output() const { return dac[envelope_counter]; }
145 
150  lfsr(0x7fff),
151  rate(0),
152  exponential_counter(0),
153  exponential_counter_period(1),
154  new_exponential_counter_period(0),
155  state_pipeline(0),
156  envelope_pipeline(0),
157  exponential_pipeline(0),
158  state(RELEASE),
159  next_state(RELEASE),
160  counter_enabled(true),
161  gate(false),
162  resetLfsr(false),
163  envelope_counter(0xaa),
164  attack(0),
165  decay(0),
166  sustain(0),
167  release(0),
168  env3(0)
169  {}
170 
174  void reset();
175 
182  void writeCONTROL_REG(unsigned char control);
183 
190  void writeATTACK_DECAY(unsigned char attack_decay);
191 
198  void writeSUSTAIN_RELEASE(unsigned char sustain_release);
199 
205  unsigned char readENV() const { return env3; }
206 };
207 
208 } // namespace reSIDfp
209 
210 #if RESID_INLINING || defined(ENVELOPEGENERATOR_CPP)
211 
212 namespace reSIDfp
213 {
214 
215 RESID_INLINE
217 {
218  env3 = envelope_counter;
219 
220  if (unlikely(new_exponential_counter_period > 0))
221  {
222  exponential_counter_period = new_exponential_counter_period;
223  new_exponential_counter_period = 0;
224  }
225 
226  if (unlikely(state_pipeline))
227  {
228  state_change();
229  }
230 
231  if (unlikely(envelope_pipeline != 0) && (--envelope_pipeline == 0))
232  {
233  if (likely(counter_enabled))
234  {
235  if (state == ATTACK)
236  {
237  if (++envelope_counter==0xff)
238  {
239  next_state = DECAY_SUSTAIN;
240  state_pipeline = 3;
241  }
242  }
243  else if ((state == DECAY_SUSTAIN) || (state == RELEASE))
244  {
245  if (--envelope_counter==0x00)
246  {
247  counter_enabled = false;
248  }
249  }
250 
251  set_exponential_counter();
252  }
253  }
254  else if (unlikely(exponential_pipeline != 0) && (--exponential_pipeline == 0))
255  {
256  exponential_counter = 0;
257 
258  if (((state == DECAY_SUSTAIN) && (envelope_counter != sustain))
259  || (state == RELEASE))
260  {
261  // The envelope counter can flip from 0x00 to 0xff by changing state to
262  // attack, then to release. The envelope counter will then continue
263  // counting down in the release state.
264  // This has been verified by sampling ENV3.
265 
266  envelope_pipeline = 1;
267  }
268  }
269  else if (unlikely(resetLfsr))
270  {
271  lfsr = 0x7fff;
272  resetLfsr = false;
273 
274  if (state == ATTACK)
275  {
276  // The first envelope step in the attack state also resets the exponential
277  // counter. This has been verified by sampling ENV3.
278  exponential_counter = 0; // NOTE this is actually delayed one cycle, not modeled
279 
280  // The envelope counter can flip from 0xff to 0x00 by changing state to
281  // release, then to attack. The envelope counter is then frozen at
282  // zero; to unlock this situation the state must be changed to release,
283  // then to attack. This has been verified by sampling ENV3.
284 
285  envelope_pipeline = 2;
286  }
287  else
288  {
289  if (counter_enabled && (++exponential_counter == exponential_counter_period))
290  exponential_pipeline = exponential_counter_period != 1 ? 2 : 1;
291  }
292  }
293 
294  // ADSR delay bug.
295  // If the rate counter comparison value is set below the current value of the
296  // rate counter, the counter will continue counting up until it wraps around
297  // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
298  // envelope can constly be stepped.
299  // This has been verified by sampling ENV3.
300 
301  // check to see if LFSR matches table value
302  if (likely(lfsr != rate))
303  {
304  // it wasn't a match, clock the LFSR once
305  // by performing XOR on last 2 bits
306  const unsigned int feedback = ((lfsr << 14) ^ (lfsr << 13)) & 0x4000;
307  lfsr = (lfsr >> 1) | feedback;
308  }
309  else
310  {
311  resetLfsr = true;
312  }
313 }
314 
354 RESID_INLINE
355 void EnvelopeGenerator::state_change()
356 {
357  state_pipeline--;
358 
359  switch (next_state)
360  {
361  case ATTACK:
362  if (state_pipeline == 1)
363  {
364  // The decay rate is "accidentally" enabled during first cycle of attack phase
365  rate = adsrtable[decay];
366  }
367  else if (state_pipeline == 0)
368  {
369  state = ATTACK;
370  // The attack rate is correctly enabled during second cycle of attack phase
371  rate = adsrtable[attack];
372  counter_enabled = true;
373  }
374  break;
375  case DECAY_SUSTAIN:
376  if (state_pipeline == 0)
377  {
378  state = DECAY_SUSTAIN;
379  rate = adsrtable[decay];
380  }
381  break;
382  case RELEASE:
383  if (((state == ATTACK) && (state_pipeline == 0))
384  || ((state == DECAY_SUSTAIN) && (state_pipeline == 1)))
385  {
386  state = RELEASE;
387  rate = adsrtable[release];
388  }
389  break;
390  }
391 }
392 
393 RESID_INLINE
394 void EnvelopeGenerator::set_exponential_counter()
395 {
396  // Check for change of exponential counter period.
397  //
398  // For a detailed description see:
399  // http://ploguechipsounds.blogspot.it/2010/03/sid-6581r3-adsr-tables-up-close.html
400  switch (envelope_counter)
401  {
402  case 0xff:
403  case 0x00:
404  new_exponential_counter_period = 1;
405  break;
406 
407  case 0x5d:
408  new_exponential_counter_period = 2;
409  break;
410 
411  case 0x36:
412  new_exponential_counter_period = 4;
413  break;
414 
415  case 0x1a:
416  new_exponential_counter_period = 8;
417  break;
418 
419  case 0x0e:
420  new_exponential_counter_period = 16;
421  break;
422 
423  case 0x06:
424  new_exponential_counter_period = 30;
425  break;
426  }
427 }
428 
429 } // namespace reSIDfp
430 
431 #endif
432 
433 #endif
Definition: EnvelopeGenerator.h:44
void writeATTACK_DECAY(unsigned char attack_decay)
Definition: EnvelopeGenerator.cpp:122
void reset()
Definition: EnvelopeGenerator.cpp:62
void writeSUSTAIN_RELEASE(unsigned char sustain_release)
Definition: EnvelopeGenerator.cpp:137
float output() const
Definition: EnvelopeGenerator.h:144
void writeCONTROL_REG(unsigned char control)
Definition: EnvelopeGenerator.cpp:87
unsigned char readENV() const
Definition: EnvelopeGenerator.h:205
void clock()
Definition: EnvelopeGenerator.h:216
EnvelopeGenerator()
Definition: EnvelopeGenerator.h:149
void setDAC(float *dac)
Definition: EnvelopeGenerator.h:132