Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

envelope.cpp

Go to the documentation of this file.
00001 //
00002 // 1997/09/27 21:32:09
00003 // 
00004 //=========================================================================
00005 // This source implements the ADSR volume envelope of the SID-chip.
00006 // Two different envelope shapes are implemented, an exponential
00007 // approximation and the linear shape, which can easily be determined 
00008 // by reading the registers of the third SID operator.
00009 //
00010 // Accurate volume envelope times as of November 1994 are used 
00011 // courtesy of George W. Taylor <aa601@cfn.cs.dal.ca>, <yurik@io.org>
00012 // They are slightly modified.
00013 // 
00014 // To use the rounded envelope times from the C64 Programmers Reference
00015 // Book define SID_REFTIMES at the Makefile level.
00016 // 
00017 // To perform realtime calculations with floating point precision define
00018 // SID_FPUENVE at the Makefile level. On high-end FPUs (not Pentium !),
00019 // this can result in speed improvement. Default is integer fixpoint.
00020 // 
00021 // Global Makefile definables:
00022 //
00023 //   DIRECT_FIXPOINT - use a union to access integer fixpoint operands 
00024 //                     in memory. This makes an assumption about the
00025 //                     hardware and software architecture and therefore 
00026 //                     is considered a hack !
00027 //
00028 // Local (or Makefile) definables:
00029 // 
00030 //   SID_LINENVE  - use linear envelope attack shape (default)
00031 //   SID_EXPENVE  - use exponential envelope shape
00032 //   SID_REFTIMES - use rounded envelope times
00033 //   SID_FPUENVE  - use floating point precision for calculations
00034 //                  (will override the global DIRECT_FIXPOINT setting !)
00035 //
00036 //=========================================================================
00037 
00038 #if defined(SID_EXPENVE) && defined(SID_LINENVE)
00039   #error Select either SID_LINENVE or SID_EXPENVE !
00040 #elif !defined(SID_EXPENVE) && !defined(SID_LINENVE)
00041   #define SID_LINENVE 1
00042 #endif
00043 
00044 #include <math.h>
00045 
00046 #include "envelope.h"
00047 //#include "myendian.h"
00048 #if defined(SID_EXPENVE)
00049   #include "enve_ac.h"
00050   #include "enve_dc.h"
00051 #elif defined(SID_LINENVE)
00052   #include "enve_dl.h"
00053 #endif
00054 
00055 
00056 //
00057 // const data
00058 //
00059 extern const ubyte masterVolumeLevels[16] =
00060 {
00061     0,  17,  34,  51,  68,  85, 102, 119,
00062   136, 153, 170, 187, 204, 221, 238, 255
00063 };
00064 
00065 static const float attackTimes[16] =
00066 {
00067   // milliseconds
00068 #if defined(SID_REFTIMES)
00069   2,8,16,24,38,56,68,80,
00070   100,250,500,800,1000,3000,5000,8000
00071 #else
00072   2.2528606f, 8.0099577f, 15.7696042f, 23.7795619f, 37.2963655f, 55.0684591f,
00073   66.8330845f, 78.3473987f,
00074   98.1219818f, 244.554021f, 489.108042f, 782.472742f, 977.715461f, 2933.64701f,
00075   4889.07793f, 7822.72493f
00076 #endif
00077 };
00078 
00079 static const float decayReleaseTimes[16] =
00080 {
00081   // milliseconds
00082 #if defined(SID_REFTIMES)
00083   8,24,48,72,114,168,204,240,
00084   300,750,1500,2400,3000,9000,15000,24000
00085 #else
00086   8.91777693f, 24.594051f, 48.4185907f, 73.0116639f, 114.512475f, 169.078356f,
00087   205.199432f, 240.551975f, 
00088   301.266125f, 750.858245f, 1501.71551f, 2402.43682f, 3001.89298f, 9007.21405f,
00089   15010.998f, 24018.2111f
00090 #endif
00091 };
00092 
00093 
00094 //
00095 // implementation of Envelope
00096 //
00097 
00098 Envelope::Envelope()
00102         {
00103         CTOR(Envelope);
00104         }
00105 
00106 Envelope::~Envelope()
00110         {
00111         DTOR(Envelope);
00112         }
00113 
00114 void Envelope::enveEmuInit( udword updateFreq, bool measuredValues )
00115 {
00116         udword i, j, k;
00117   
00118 #if !defined(SID_LINENVE) && defined(SID_EXPENVE)
00119         attackTabLen = sizeof(attackTab);
00120         for ( i = 0; i < 256; i++ )
00121         {
00122                 j = 0;
00123                 while (( j < attackTabLen ) && (attackTab[j] < i) )
00124                 {
00125                         j++;
00126                 }
00127                 attackPos[i]=j;
00128         }
00129 #endif
00130 
00131         releaseTabLen = sizeof(releaseTab);
00132         for ( i = 0; i < 256; i++ )
00133         {
00134                 j = 0;
00135                 while (( j < releaseTabLen ) && (releaseTab[j] > i) )
00136                 {
00137                         j++;
00138                 }
00139                 if ( j < releaseTabLen )
00140                 {
00141                         releasePos[i] = j;
00142                 }
00143                 else
00144                 {
00145                         releasePos[i] = releaseTabLen -1;
00146                 }
00147         }
00148 
00149         k = 0;
00150         for ( i = 0; i < 16; i++ )
00151         {
00152                 for ( j = 0; j < 256; j++ )
00153                 {
00154                         uword tmpVol = (uword)j;
00155                         if (measuredValues)
00156                         {
00157                                 tmpVol = (sword) ((293.0*(1-exp(j/-130.0)))+4.0); //ALFRED - TODO: check this, possible bug
00158                                 if (j == 0)
00159                                         tmpVol = 0;
00160                                 if (tmpVol > 255)
00161                                         tmpVol = 255;
00162                         }
00163                         // Want the modulated volume value in the high byte.
00164                         masterAmplModTable[k++] = ((tmpVol * masterVolumeLevels[i]) / 255) << 8;
00165                 }
00166         }
00167         
00168         for ( i = 0; i < 16; i++ )
00169         {
00170 #ifdef SID_FPUENVE
00171                 double scaledenvelen = floor(( attackTimes[i] * updateFreq ) / 1000UL );
00172                 if (scaledenvelen == 0)
00173                         scaledenvelen = 1;
00174                 attackRates[i] = attackTabLen / scaledenvelen;
00175 
00176                 scaledenvelen = floor(( decayReleaseTimes[i] * updateFreq ) / 1000UL );
00177                 if (scaledenvelen == 0)
00178                         scaledenvelen = 1;
00179                 decayReleaseRates[i] = releaseTabLen / scaledenvelen;
00180 #elif defined(DIRECT_FIXPOINT)
00181 
00182                 udword scaledenvelen = (sdword) floor( (attackTimes[i]*updateFreq) / 1000UL );
00183 
00184                 if (scaledenvelen == 0)
00185                         scaledenvelen = 1;
00186                 attackRates[i] = (attackTabLen << 16) / scaledenvelen;
00187 
00188                 scaledenvelen = (sdword)floor(( decayReleaseTimes[i] * updateFreq ) / 1000UL );
00189                 if (scaledenvelen == 0)
00190                         scaledenvelen = 1;
00191                 decayReleaseRates[i] = (releaseTabLen << 16) / scaledenvelen;
00192 #else
00193                 udword scaledenvelen = (sdword)floor(( attackTimes[i] * updateFreq ) / 1000UL ); //ALFRED - TODO: check this, possible bug
00194 
00195                 if (scaledenvelen == 0)
00196                         scaledenvelen = 1;
00197                 attackRates[i] = attackTabLen / scaledenvelen;
00198                 attackRatesP[i] = (( attackTabLen % scaledenvelen ) * 65536UL ) / scaledenvelen;
00199                 
00200                 scaledenvelen = (sdword)floor(( decayReleaseTimes[i] * updateFreq ) / 1000UL ); //ALFRED - TODO: check this, possible bug
00201                 if (scaledenvelen == 0)
00202                         scaledenvelen = 1;
00203                 decayReleaseRates[i] = releaseTabLen / scaledenvelen;
00204                 decayReleaseRatesP[i] = (( releaseTabLen % scaledenvelen ) * 65536UL ) / scaledenvelen;
00205 #endif
00206   }
00207 }
00208 
00209 
00210 void Envelope::enveEmuResetOperator(struct sidOperator* pVoice)
00214         {
00215         // mute, end of R-phase
00216         pVoice->ADSRctrl = ENVE_MUTE;
00217         pVoice->gateOnCtrl = (pVoice->gateOffCtrl = false);
00218         
00219 #ifdef SID_FPUENVE
00220         pVoice->fenveStep = (pVoice->fenveStepAdd = 0);
00221         pVoice->enveStep = 0;
00222 #elif defined(DIRECT_FIXPOINT)
00223         pVoice->enveStep.l = (pVoice->enveStepAdd.l = 0);
00224 #else
00225         pVoice->enveStep = (pVoice->enveStepPnt = 0);
00226         pVoice->enveStepAdd = (pVoice->enveStepAddPnt = 0);
00227 #endif
00228         pVoice->enveSusVol = 0;
00229         pVoice->enveVol = 0;
00230         pVoice->enveShortAttackCount = 0;
00231 }
00232 
00233 
00234 const ptr2sidUwordFunc* Envelope::getEnveModeTable() const
00235         {
00236         return enveModeTable;
00237         }
00238 
00239 //
00240 // jump tables
00241 //
00242 const ptr2sidUwordFunc Envelope::enveModeTable[32] =
00243 {
00244 // 0
00245  &Envelope::enveEmuStartAttack, &Envelope::enveEmuStartRelease,
00246    &Envelope::enveEmuAttack, &Envelope::enveEmuDecay,
00247    &Envelope::enveEmuSustain, &Envelope::enveEmuRelease,
00248    &Envelope::enveEmuSustainDecay, &Envelope::enveEmuMute,
00249 
00250    // 16
00251    &Envelope::enveEmuStartShortAttack, &Envelope::enveEmuMute,
00252    &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00253    &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00254    &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00255 
00256    // 32
00257    &Envelope::enveEmuStartAttack, &Envelope::enveEmuStartRelease,
00258    &Envelope::enveEmuAlterAttack, &Envelope::enveEmuAlterDecay,
00259    &Envelope::enveEmuAlterSustain, &Envelope::enveEmuAlterRelease,
00260    &Envelope::enveEmuAlterSustainDecay, &Envelope::enveEmuMute,
00261 
00262    // 48
00263    &Envelope::enveEmuStartShortAttack, &Envelope::enveEmuMute,
00264    &Envelope::enveEmuMute, &Envelope::enveEmuMute, 
00265    &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00266    &Envelope::enveEmuMute, &Envelope::enveEmuMute
00267 };
00268 
00269 // Real-time functions.
00270 // Order is important because of inline optimizations.
00271 //
00272 // ADSRctrl is (index*2) to enveModeTable[], because of KEY-bit.
00273 
00274 inline void enveEmuEnveAdvance(struct sidOperator* pVoice)
00275 {
00276 #ifdef SID_FPUENVE
00277         pVoice->fenveStep += pVoice->fenveStepAdd;
00278 #elif defined(DIRECT_FIXPOINT)
00279         pVoice->enveStep.l += pVoice->enveStepAdd.l;
00280 #else
00281         pVoice->enveStepPnt += pVoice->enveStepAddPnt;
00282         pVoice->enveStep += pVoice->enveStepAdd + ( pVoice->enveStepPnt > 65535 );
00283         pVoice->enveStepPnt &= 0xFFFF;
00284 #endif
00285 }
00286 
00287 //
00288 // Mute/Idle.
00289 //
00290 
00291 // Only used in the beginning.
00292 inline uword Envelope::enveEmuMute(struct sidOperator* /*pVoice*/) const
00293 {
00294         return 0;
00295 }
00296 
00297 //
00298 // Release
00299 //
00300 
00301 inline uword Envelope::enveEmuRelease(struct sidOperator* pVoice) const
00302 {
00303 #ifdef SID_FPUENVE
00304         pVoice->enveStep = (uword)pVoice->fenveStep;
00305 #endif
00306 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00307         if ( pVoice->enveStep.w[HI] >= releaseTabLen )
00308 #else
00309         if ( pVoice->enveStep >= releaseTabLen )
00310 #endif
00311         {
00312                 pVoice->enveVol = releaseTab[releaseTabLen -1];
00313                 return masterAmplModTable[ masterVolumeAmplIndex + pVoice->enveVol ];
00314         }       
00315         else
00316         {
00317 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00318                 pVoice->enveVol = releaseTab[pVoice->enveStep.w[HI]];
00319 #else
00320                 pVoice->enveVol = releaseTab[pVoice->enveStep];
00321 #endif
00322                 enveEmuEnveAdvance(pVoice);
00323                 return masterAmplModTable[ masterVolumeAmplIndex + pVoice->enveVol ];
00324         }
00325 }
00326 
00327 
00328 // This is the same as enveEmuStartSustainDecay().
00329 inline uword Envelope::enveEmuAlterSustainDecay(struct sidOperator* pVoice) const
00330 {
00331         ubyte decay = pVoice->SIDAD & 0x0F ;
00332 #ifdef SID_FPUENVE
00333         pVoice->fenveStepAdd = decayReleaseRates[decay];
00334 #elif defined(DIRECT_FIXPOINT)
00335         pVoice->enveStepAdd.l = decayReleaseRates[decay];
00336 #else
00337         pVoice->enveStepAdd = decayReleaseRates[decay];
00338         pVoice->enveStepAddPnt = decayReleaseRatesP[decay];
00339 #endif
00340         pVoice->ADSRproc = &Envelope::enveEmuSustainDecay;
00341         return enveEmuSustainDecay(pVoice);
00342 }
00343 
00344 
00345 inline uword Envelope::enveEmuAlterRelease(struct sidOperator* pVoice) const
00346 {
00347         ubyte release = pVoice->SIDSR & 0x0F;
00348 #ifdef SID_FPUENVE
00349         pVoice->fenveStepAdd = decayReleaseRates[release];
00350 #elif defined(DIRECT_FIXPOINT)
00351         pVoice->enveStepAdd.l = decayReleaseRates[release];
00352 #else
00353         pVoice->enveStepAdd = decayReleaseRates[release];
00354         pVoice->enveStepAddPnt = decayReleaseRatesP[release];
00355 #endif
00356         pVoice->ADSRproc = &Envelope::enveEmuRelease;
00357         return enveEmuRelease(pVoice);
00358 }
00359 
00360 inline uword Envelope::enveEmuStartRelease(struct sidOperator* pVoice) const
00361 {
00362         pVoice->ADSRctrl = ENVE_RELEASE;
00363 #ifdef SID_FPUENVE
00364         pVoice->fenveStep = releasePos[pVoice->enveVol];
00365 #elif defined(DIRECT_FIXPOINT)
00366         pVoice->enveStep.w[HI] = (uword)releasePos[pVoice->enveVol];
00367         pVoice->enveStep.w[LO] = 0;
00368 #else
00369         pVoice->enveStep = releasePos[pVoice->enveVol];
00370         pVoice->enveStepPnt = 0;
00371 #endif
00372         return enveEmuAlterRelease(pVoice);
00373 }
00374 
00375 //
00376 // Sustain
00377 //
00378 
00379 inline uword Envelope::enveEmuSustain(struct sidOperator* pVoice) const
00380 {
00381         return masterAmplModTable[masterVolumeAmplIndex+pVoice->enveVol];
00382 }
00383 
00384 inline uword Envelope::enveEmuSustainDecay(struct sidOperator* pVoice) const
00385 {
00386 #ifdef SID_FPUENVE
00387         pVoice->enveStep = (uword)pVoice->fenveStep;
00388 #endif
00389 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00390         if ( pVoice->enveStep.w[HI] >= releaseTabLen )
00391 #else
00392         if ( pVoice->enveStep >= releaseTabLen )
00393 #endif
00394         {
00395                 pVoice->enveVol = releaseTab[releaseTabLen-1];
00396                 return enveEmuAlterSustain(pVoice);
00397         }
00398         else
00399         {
00400 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00401                 pVoice->enveVol = releaseTab[pVoice->enveStep.w[HI]];
00402 #else
00403                 pVoice->enveVol = releaseTab[pVoice->enveStep];
00404 #endif
00405                 // Will be controlled from sidEmuSet2().
00406                 if ( pVoice->enveVol <= pVoice->enveSusVol )
00407                 {
00408                         pVoice->enveVol = pVoice->enveSusVol;
00409                         return enveEmuAlterSustain(pVoice);
00410                 }
00411                 else
00412                 {
00413                         enveEmuEnveAdvance(pVoice);
00414                         return masterAmplModTable[ masterVolumeAmplIndex + pVoice->enveVol ];
00415                 }
00416         }
00417 }
00418 
00419 
00420 // This is the same as enveEmuStartSustain().
00421 inline uword Envelope::enveEmuAlterSustain(struct sidOperator* pVoice) const
00422 {
00423         if ( pVoice->enveVol > pVoice->enveSusVol )
00424         {
00425                 pVoice->ADSRctrl = ENVE_SUSTAINDECAY;
00426                 pVoice->ADSRproc = &Envelope::enveEmuSustainDecay;
00427                 return enveEmuAlterSustainDecay(pVoice);
00428         }
00429         else
00430         {
00431                 pVoice->ADSRctrl = ENVE_SUSTAIN;
00432                 pVoice->ADSRproc = &Envelope::enveEmuSustain;
00433                 return enveEmuSustain(pVoice);
00434         }
00435 }
00436 
00437 //
00438 // Decay
00439 //
00440 
00441 inline uword Envelope::enveEmuDecay(struct sidOperator* pVoice) const
00442 {
00443 #ifdef SID_FPUENVE
00444         pVoice->enveStep = (uword)pVoice->fenveStep;
00445 #endif
00446 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00447         if ( pVoice->enveStep.w[HI] >= releaseTabLen )
00448 #else
00449         if ( pVoice->enveStep >= releaseTabLen )
00450 #endif
00451         {
00452                 pVoice->enveVol = pVoice->enveSusVol;
00453                 return enveEmuAlterSustain(pVoice);  // start sustain
00454         }
00455         else
00456         {
00457 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00458                 pVoice->enveVol = releaseTab[pVoice->enveStep.w[HI]];
00459 #else
00460                 pVoice->enveVol = releaseTab[pVoice->enveStep];
00461 #endif
00462                 // Will be controlled from sidEmuSet2().
00463                 if ( pVoice->enveVol <= pVoice->enveSusVol )
00464                 {
00465                         pVoice->enveVol = pVoice->enveSusVol;
00466                         return enveEmuAlterSustain(pVoice);  // start sustain
00467                 }
00468                 else
00469                 {
00470                         enveEmuEnveAdvance(pVoice);
00471                         return masterAmplModTable[ masterVolumeAmplIndex + pVoice->enveVol ];
00472                 }
00473         }
00474 }
00475 
00476 inline uword Envelope::enveEmuAlterDecay(struct sidOperator* pVoice) const
00477 {
00478         ubyte decay = pVoice->SIDAD & 0x0F ;
00479 #ifdef SID_FPUENVE
00480         pVoice->fenveStepAdd = decayReleaseRates[decay];
00481 #elif defined(DIRECT_FIXPOINT)
00482         pVoice->enveStepAdd.l = decayReleaseRates[decay];
00483 #else
00484         pVoice->enveStepAdd = decayReleaseRates[decay];
00485         pVoice->enveStepAddPnt = decayReleaseRatesP[decay];
00486 #endif
00487         pVoice->ADSRproc = &Envelope::enveEmuDecay;
00488         return enveEmuDecay(pVoice);
00489 }
00490 
00491 inline uword Envelope::enveEmuStartDecay(struct sidOperator* pVoice) const
00492 {
00493         pVoice->ADSRctrl = ENVE_DECAY;
00494 #ifdef SID_FPUENVE
00495         pVoice->fenveStep = 0;
00496 #elif defined(DIRECT_FIXPOINT)
00497         pVoice->enveStep.l = 0;
00498 #else
00499         pVoice->enveStep = (pVoice->enveStepPnt = 0);
00500 #endif
00501         return enveEmuAlterDecay(pVoice);
00502 }
00503 
00504 //
00505 // Attack
00506 //
00507 
00508 inline uword Envelope::enveEmuAttack(struct sidOperator* pVoice) const
00509 {
00510 #ifdef SID_FPUENVE
00511         pVoice->enveStep = (uword)pVoice->fenveStep;
00512 #endif
00513 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00514   #if defined(SID_LINENVE)
00515         if ( pVoice->enveStep.w[HI] > attackTabLen )
00516   #else
00517         if ( pVoice->enveStep.w[HI] >= attackTabLen )
00518   #endif
00519 #else
00520         if ( pVoice->enveStep >= attackTabLen )
00521 #endif
00522                 return enveEmuStartDecay(pVoice);
00523         else
00524         {
00525 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00526   #if defined(SID_LINENVE)
00527                 pVoice->enveVol = (ubyte)pVoice->enveStep.w[HI];
00528   #else
00529                 pVoice->enveVol = attackTab[pVoice->enveStep.w[HI]];
00530   #endif
00531 #else
00532   #if defined(SID_LINENVE)
00533                 pVoice->enveVol = pVoice->enveStep;
00534   #else
00535                 pVoice->enveVol = attackTab[pVoice->enveStep];
00536   #endif
00537 #endif
00538                 enveEmuEnveAdvance(pVoice);
00539                 return masterAmplModTable[ masterVolumeAmplIndex + pVoice->enveVol ];
00540         }
00541 }
00542 
00543 inline uword Envelope::enveEmuAlterAttack(struct sidOperator* pVoice) const
00544 {
00545         ubyte attack = pVoice->SIDAD >> 4;
00546 #ifdef SID_FPUENVE
00547         pVoice->fenveStepAdd = attackRates[attack];
00548 #elif defined(DIRECT_FIXPOINT)
00549         pVoice->enveStepAdd.l = attackRates[attack];
00550 #else
00551         pVoice->enveStepAdd = attackRates[attack];
00552         pVoice->enveStepAddPnt = attackRatesP[attack];
00553 #endif
00554         pVoice->ADSRproc = &Envelope::enveEmuAttack;
00555         return enveEmuAttack(pVoice);
00556 }
00557 
00558 inline uword Envelope::enveEmuStartAttack(struct sidOperator* pVoice) const
00559 {
00560         pVoice->ADSRctrl = ENVE_ATTACK;
00561 #ifdef SID_FPUENVE
00562   #if defined(SID_LINENVE)
00563         pVoice->fenveStep = (float)pVoice->enveVol;
00564   #else
00565         pVoice->fenveStep = attackPos[pVoice->enveVol];
00566   #endif
00567 #elif defined(DIRECT_FIXPOINT)
00568   #if defined(SID_LINENVE)
00569         pVoice->enveStep.w[HI] = pVoice->enveVol;
00570   #else
00571         pVoice->enveStep.w[HI] = attackPos[pVoice->enveVol];
00572   #endif
00573         pVoice->enveStep.w[LO] = 0;
00574 #else
00575   #if defined(SID_LINENVE)
00576         pVoice->enveStep = pVoice->enveVol;
00577   #else
00578         pVoice->enveStep = attackPos[pVoice->enveVol];
00579   #endif
00580         pVoice->enveStepPnt = 0;
00581 #endif
00582         return enveEmuAlterAttack(pVoice);
00583 }
00584 
00585 //
00586 // Experimental.
00587 //
00588 
00589 //#include <iostream.h>
00590 //#include <iomanip.h>
00591 
00592 inline uword Envelope::enveEmuShortAttack(struct sidOperator* pVoice) const
00593 {
00594 #ifdef SID_FPUENVE
00595         pVoice->enveStep = (uword)pVoice->fenveStep;
00596 #endif
00597 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00598   #if defined(SID_LINENVE)
00599         if ((pVoice->enveStep.w[HI] > attackTabLen) ||
00600                 (pVoice->enveShortAttackCount == 0))
00601   #else
00602         if ((pVoice->enveStep.w[HI] >= attackTabLen) ||
00603                 (pVoice->enveShortAttackCount == 0))
00604   #endif
00605 #else
00606         if ((pVoice->enveStep >= attackTabLen) ||
00607                 (pVoice->enveShortAttackCount == 0))
00608 #endif
00609                 return enveEmuStartDecay(pVoice);
00610         else
00611         {
00612 #if defined(DIRECT_FIXPOINT) && !defined(SID_FPUENVE)
00613   #if defined(SID_LINENVE)
00614                 pVoice->enveVol = (ubyte)pVoice->enveStep.w[HI];
00615   #else
00616                 pVoice->enveVol = attackTab[pVoice->enveStep.w[HI]];
00617   #endif
00618 #else
00619   #if defined(SID_LINENVE)
00620                 pVoice->enveVol = pVoice->enveStep;
00621   #else
00622                 pVoice->enveVol = attackTab[pVoice->enveStep];
00623   #endif
00624 #endif
00625             pVoice->enveShortAttackCount--;
00626                 enveEmuEnveAdvance(pVoice);
00627                 return masterAmplModTable[ masterVolumeAmplIndex + pVoice->enveVol ];
00628         }
00629 }
00630 
00631 inline uword Envelope::enveEmuAlterShortAttack(struct sidOperator* pVoice) const
00632 {
00633         ubyte attack = pVoice->SIDAD >> 4;
00634 #ifdef SID_FPUENVE
00635         pVoice->fenveStepAdd = attackRates[attack];
00636 #elif defined(DIRECT_FIXPOINT)
00637         pVoice->enveStepAdd.l = attackRates[attack];
00638 #else
00639         pVoice->enveStepAdd = attackRates[attack];
00640         pVoice->enveStepAddPnt = attackRatesP[attack];
00641 #endif
00642         pVoice->ADSRproc = &Envelope::enveEmuShortAttack;
00643         return enveEmuShortAttack(pVoice);
00644 }
00645 
00646 inline uword Envelope::enveEmuStartShortAttack(struct sidOperator* pVoice) const
00647 {
00648         pVoice->ADSRctrl = ENVE_SHORTATTACK;
00649 #ifdef SID_FPUENVE
00650   #if defined(SID_LINENVE)
00651         pVoice->fenveStep = (float)pVoice->enveVol;
00652   #else
00653         pVoice->fenveStep = attackPos[pVoice->enveVol];
00654   #endif
00655 #elif defined(DIRECT_FIXPOINT)
00656   #if defined(SID_LINENVE)
00657         pVoice->enveStep.w[HI] = pVoice->enveVol;
00658   #else
00659         pVoice->enveStep.w[HI] = attackPos[pVoice->enveVol];
00660   #endif
00661         pVoice->enveStep.w[LO] = 0;
00662 #else
00663   #if defined(SID_LINENVE)
00664         pVoice->enveStep = pVoice->enveVol;
00665   #else
00666         pVoice->enveStep = attackPos[pVoice->enveVol];
00667   #endif
00668         pVoice->enveStepPnt = 0;
00669 #endif
00670         pVoice->enveShortAttackCount = 65535;  // unused
00671         return enveEmuAlterShortAttack(pVoice);
00672 }
00673 
00674 
00675 
00676 // EOF - ENVELOPE.CPP

Generated on Tue Feb 8 04:13:57 2005 for Esidplay by doxygen 1.3.3