libsidplayfp  1.4.2
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 
41 {
42 private:
47  enum State
48  {
49  ATTACK, DECAY_SUSTAIN, RELEASE
50  };
51 
53  int lfsr;
54 
56  int rate;
57 
62  int exponential_counter;
63 
68  int exponential_counter_period;
69 
71  int attack;
72 
74  int decay;
75 
77  int sustain;
78 
80  int release;
81 
83  State state;
84 
86  bool hold_zero;
87 
88  bool envelope_pipeline;
89 
91  bool gate;
92 
94  unsigned char envelope_counter;
95 
101  short dac[256];
102 
114  static const int adsrtable[16];
115 
116 private:
117  void set_exponential_counter();
118 
119 public:
127  void setChipModel(ChipModel chipModel);
128 
132  void clock();
133 
139  short output() const { return dac[envelope_counter]; }
140 
145  lfsr(0),
146  rate(0),
147  exponential_counter(0),
148  exponential_counter_period(1),
149  attack(0),
150  decay(0),
151  sustain(0),
152  release(0),
153  state(RELEASE),
154  hold_zero(true),
155  envelope_pipeline(false),
156  gate(false),
157  envelope_counter(0) {}
158 
162  void reset();
163 
170  void writeCONTROL_REG(unsigned char control);
171 
178  void writeATTACK_DECAY(unsigned char attack_decay);
179 
186  void writeSUSTAIN_RELEASE(unsigned char sustain_release);
187 
193  unsigned char readENV() const { return envelope_counter; }
194 };
195 
196 } // namespace reSIDfp
197 
198 #if RESID_INLINING || defined(ENVELOPEGENERATOR_CPP)
199 
200 namespace reSIDfp
201 {
202 
203 RESID_INLINE
205 {
206  if (unlikely(envelope_pipeline))
207  {
208  --envelope_counter;
209  envelope_pipeline = false;
210  // Check for change of exponential counter period.
211  set_exponential_counter();
212  }
213 
214  // Check for ADSR delay bug.
215  // If the rate counter comparison value is set below the current value of the
216  // rate counter, the counter will continue counting up until it wraps around
217  // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
218  // envelope can constly be stepped.
219  // This has been verified by sampling ENV3.
220  //
221  // Envelope is now implemented like in the real machine with a shift register
222  // so the ADSR delay bug should be correcly modeled
223 
224  // check to see if LFSR matches table value
225  if (likely(lfsr != rate))
226  {
227  // it wasn't a match, clock the LFSR once
228  // by performing XOR on last 2 bits
229  const int feedback = ((lfsr << 14) ^ (lfsr << 13)) & 0x4000;
230  lfsr = (lfsr >> 1) | feedback;
231  return;
232  }
233 
234  // reset LFSR
235  lfsr = 0x7fff;
236 
237  // The first envelope step in the attack state also resets the exponential
238  // counter. This has been verified by sampling ENV3.
239  //
240  if (state == ATTACK || ++exponential_counter == exponential_counter_period)
241  {
242  // likely (~50%)
243  exponential_counter = 0;
244 
245  // Check whether the envelope counter is frozen at zero.
246  if (unlikely(hold_zero))
247  {
248  return;
249  }
250 
251  switch (state)
252  {
253  case ATTACK:
254  // The envelope counter can flip from 0xff to 0x00 by changing state to
255  // release, then to attack. The envelope counter is then frozen at
256  // zero; to unlock this situation the state must be changed to release,
257  // then to attack. This has been verified by sampling ENV3.
258  //
259  ++envelope_counter;
260 
261  if (unlikely(envelope_counter == (unsigned char) 0xff))
262  {
263  state = DECAY_SUSTAIN;
264  rate = adsrtable[decay];
265  }
266 
267  break;
268 
269  case DECAY_SUSTAIN:
270 
271  // From the sustain levels it follows that both the low and high 4 bits
272  // of the envelope counter are compared to the 4-bit sustain value.
273  // This has been verified by sampling ENV3.
274  //
275  // For a detailed description see:
276  // http://ploguechipsounds.blogspot.it/2010/11/new-research-on-sid-adsr.html
277  if (likely(envelope_counter == (unsigned char)(sustain << 4 | sustain)))
278  {
279  return;
280  }
281 
282  // fall-through
283 
284  case RELEASE:
285 
286  // The envelope counter can flip from 0x00 to 0xff by changing state to
287  // attack, then to release. The envelope counter will then continue
288  // counting down in the release state.
289  // This has been verified by sampling ENV3.
290  // NB! The operation below requires two's complement integer.
291  //
292  if (unlikely(exponential_counter_period != 1))
293  {
294  // The decrement is delayed one cycle.
295  envelope_pipeline = true;
296  return;
297  }
298 
299  --envelope_counter;
300  break;
301  }
302 
303  // Check for change of exponential counter period.
304  set_exponential_counter();
305  }
306 }
307 
308 } // namespace reSIDfp
309 
310 #endif
311 
312 #endif
void clock()
Definition: EnvelopeGenerator.h:204
void reset()
Definition: EnvelopeGenerator.cpp:120
void setChipModel(ChipModel chipModel)
Definition: EnvelopeGenerator.cpp:99
void writeCONTROL_REG(unsigned char control)
Definition: EnvelopeGenerator.cpp:141
short output() const
Definition: EnvelopeGenerator.h:139
unsigned char readENV() const
Definition: EnvelopeGenerator.h:193
EnvelopeGenerator()
Definition: EnvelopeGenerator.h:144
Definition: EnvelopeGenerator.h:40
void writeSUSTAIN_RELEASE(unsigned char sustain_release)
Definition: EnvelopeGenerator.cpp:186
void writeATTACK_DECAY(unsigned char attack_decay)
Definition: EnvelopeGenerator.cpp:171