libsidplayfp  1.8.3
EnvelopeGenerator.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright 2004,2010 Dag Lem <resid@nimrod.no>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef ENVELOPEGENERATOR_H
24 #define ENVELOPEGENERATOR_H
25 
26 #include "siddefs-fp.h"
27 
28 namespace reSIDfp
29 {
30 
43 {
44 private:
49  enum State
50  {
51  ATTACK, DECAY_SUSTAIN, RELEASE
52  };
53 
54 private:
56  int lfsr;
57 
59  int rate;
60 
65  int exponential_counter;
66 
71  int exponential_counter_period;
72 
74  int attack;
75 
77  int decay;
78 
80  int sustain;
81 
83  int release;
84 
86  State state;
87 
89  bool hold_zero;
90 
91  bool envelope_pipeline;
92 
94  bool gate;
95 
97  unsigned char envelope_counter;
98 
104  short dac[256];
105 
106 private:
118  static const int adsrtable[16];
119 
120 private:
121  void set_exponential_counter();
122 
123 public:
131  void setChipModel(ChipModel chipModel);
132 
136  void clock();
137 
143  short output() const { return dac[envelope_counter]; }
144 
149  lfsr(0),
150  rate(0),
151  exponential_counter(0),
152  exponential_counter_period(1),
153  attack(0),
154  decay(0),
155  sustain(0),
156  release(0),
157  state(RELEASE),
158  hold_zero(true),
159  envelope_pipeline(false),
160  gate(false),
161  envelope_counter(0) {}
162 
166  void reset();
167 
174  void writeCONTROL_REG(unsigned char control);
175 
182  void writeATTACK_DECAY(unsigned char attack_decay);
183 
190  void writeSUSTAIN_RELEASE(unsigned char sustain_release);
191 
197  unsigned char readENV() const { return envelope_counter; }
198 };
199 
200 } // namespace reSIDfp
201 
202 #if RESID_INLINING || defined(ENVELOPEGENERATOR_CPP)
203 
204 namespace reSIDfp
205 {
206 
207 RESID_INLINE
209 {
210  if (unlikely(envelope_pipeline))
211  {
212  --envelope_counter;
213  envelope_pipeline = false;
214  // Check for change of exponential counter period.
215  set_exponential_counter();
216  }
217 
218  // Check for ADSR delay bug.
219  // If the rate counter comparison value is set below the current value of the
220  // rate counter, the counter will continue counting up until it wraps around
221  // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
222  // envelope can constly be stepped.
223  // This has been verified by sampling ENV3.
224  //
225  // Envelope is now implemented like in the real machine with a shift register
226  // so the ADSR delay bug should be correcly modeled
227 
228  // check to see if LFSR matches table value
229  if (likely(lfsr != rate))
230  {
231  // it wasn't a match, clock the LFSR once
232  // by performing XOR on last 2 bits
233  const int feedback = ((lfsr << 14) ^ (lfsr << 13)) & 0x4000;
234  lfsr = (lfsr >> 1) | feedback;
235  return;
236  }
237 
238  // reset LFSR
239  lfsr = 0x7fff;
240 
241  // The first envelope step in the attack state also resets the exponential
242  // counter. This has been verified by sampling ENV3.
243  //
244  if (state == ATTACK || ++exponential_counter == exponential_counter_period)
245  {
246  // likely (~50%)
247  exponential_counter = 0;
248 
249  // Check whether the envelope counter is frozen at zero.
250  if (unlikely(hold_zero))
251  {
252  return;
253  }
254 
255  switch (state)
256  {
257  case ATTACK:
258  // The envelope counter can flip from 0xff to 0x00 by changing state to
259  // release, then to attack. The envelope counter is then frozen at
260  // zero; to unlock this situation the state must be changed to release,
261  // then to attack. This has been verified by sampling ENV3.
262  //
263  ++envelope_counter;
264 
265  if (unlikely(envelope_counter == 0xff))
266  {
267  state = DECAY_SUSTAIN;
268  rate = adsrtable[decay];
269  }
270 
271  break;
272 
273  case DECAY_SUSTAIN:
274 
275  // From the sustain levels it follows that both the low and high 4 bits
276  // of the envelope counter are compared to the 4-bit sustain value.
277  // This has been verified by sampling ENV3.
278  //
279  // For a detailed description see:
280  // http://ploguechipsounds.blogspot.it/2010/11/new-research-on-sid-adsr.html
281  if (likely(envelope_counter == (sustain << 4 | sustain)))
282  {
283  return;
284  }
285 
286  // fall-through
287 
288  case RELEASE:
289 
290  // The envelope counter can flip from 0x00 to 0xff by changing state to
291  // attack, then to release. The envelope counter will then continue
292  // counting down in the release state.
293  // This has been verified by sampling ENV3.
294  // NB! The operation below requires two's complement integer.
295  //
296  if (unlikely(exponential_counter_period != 1))
297  {
298  // The decrement is delayed one cycle.
299  envelope_pipeline = true;
300  return;
301  }
302 
303  --envelope_counter;
304  break;
305  }
306 
307  // Check for change of exponential counter period.
308  set_exponential_counter();
309  }
310 }
311 
312 } // namespace reSIDfp
313 
314 #endif
315 
316 #endif
void clock()
Definition: EnvelopeGenerator.h:208
void reset()
Definition: EnvelopeGenerator.cpp:120
Definition: Dac.cpp:25
void setChipModel(ChipModel chipModel)
Definition: EnvelopeGenerator.cpp:99
void writeCONTROL_REG(unsigned char control)
Definition: EnvelopeGenerator.cpp:141
short output() const
Definition: EnvelopeGenerator.h:143
unsigned char readENV() const
Definition: EnvelopeGenerator.h:197
EnvelopeGenerator()
Definition: EnvelopeGenerator.h:148
Definition: EnvelopeGenerator.h:42
void writeSUSTAIN_RELEASE(unsigned char sustain_release)
Definition: EnvelopeGenerator.cpp:190
void writeATTACK_DECAY(unsigned char attack_decay)
Definition: EnvelopeGenerator.cpp:175