libsidplayfp 1.0.3
|
00001 /* 00002 * This file is part of libsidplayfp, a SID player engine. 00003 * 00004 * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net> 00005 * Copyright 2007-2010 Antti Lankila 00006 * Copyright 2004 Dag Lem <resid@nimrod.no> 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 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 // Register functions. 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 } // namespace reSIDfp 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 // Check for change of exponential counter period. 00218 set_exponential_counter(); 00219 } 00220 00221 // Check for ADSR delay bug. 00222 // If the rate counter comparison value is set below the current value of the 00223 // rate counter, the counter will continue counting up until it wraps around 00224 // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the 00225 // envelope can constly be stepped. 00226 // This has been verified by sampling ENV3. 00227 // 00228 // Envelope is now implemented like in the real machine with a shift register 00229 // so the ADSR delay bug should be correcly modeled 00230 00231 // check to see if LFSR matches table value 00232 if (lfsr != rate) 00233 { 00234 // it wasn't a match, clock the LFSR once 00235 // by performing XOR on last 2 bits 00236 const int feedback = ((lfsr >> 14) ^ (lfsr >> 13)) & 0x01; 00237 lfsr = ((lfsr << 1) & 0x7fff) | feedback; 00238 return; 00239 } 00240 00241 // reset LFSR 00242 lfsr = 0x7fff; 00243 00244 // The first envelope step in the attack state also resets the exponential 00245 // counter. This has been verified by sampling ENV3. 00246 // 00247 if (state == ATTACK || ++exponential_counter == exponential_counter_period) 00248 { 00249 // likely (~50%) 00250 exponential_counter = 0; 00251 00252 // Check whether the envelope counter is frozen at zero. 00253 if (hold_zero) 00254 { 00255 return; 00256 } 00257 00258 switch (state) 00259 { 00260 case ATTACK: 00261 // The envelope counter can flip from 0xff to 0x00 by changing state to 00262 // release, then to attack. The envelope counter is then frozen at 00263 // zero; to unlock this situation the state must be changed to release, 00264 // then to attack. This has been verified by sampling ENV3. 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 // From the sustain levels it follows that both the low and high 4 bits 00279 // of the envelope counter are compared to the 4-bit sustain value. 00280 // This has been verified by sampling ENV3. 00281 // 00282 // For a detailed description see: 00283 // http://ploguechipsounds.blogspot.it/2010/11/new-research-on-sid-adsr.html 00284 if (envelope_counter == (unsigned char)(sustain << 4 | sustain)) 00285 { 00286 return; 00287 } 00288 00289 if (exponential_counter_period != 1) 00290 { 00291 // unlikely (15%) 00292 // The decrement is delayed one cycle. 00293 envelope_pipeline = true; 00294 return; 00295 } 00296 00297 -- envelope_counter; 00298 break; 00299 00300 case RELEASE: 00301 00302 // The envelope counter can flip from 0x00 to 0xff by changing state to 00303 // attack, then to release. The envelope counter will then continue 00304 // counting down in the release state. 00305 // This has been verified by sampling ENV3. 00306 // NB! The operation below requires two's complement integer. 00307 // 00308 if (exponential_counter_period != 1) 00309 { 00310 // likely (~50%) 00311 // The decrement is delayed one cycle. 00312 envelope_pipeline = true; 00313 return; 00314 } 00315 00316 -- envelope_counter; 00317 break; 00318 } 00319 00320 // Check for change of exponential counter period. 00321 set_exponential_counter(); 00322 } 00323 } 00324 00325 } // namespace reSIDfp 00326 00327 #endif 00328 00329 #endif