00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
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
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
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
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);
00158 if (j == 0)
00159 tmpVol = 0;
00160 if (tmpVol > 255)
00161 tmpVol = 255;
00162 }
00163
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 );
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 );
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
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
00241
00242 const ptr2sidUwordFunc Envelope::enveModeTable[32] =
00243 {
00244
00245 &Envelope::enveEmuStartAttack, &Envelope::enveEmuStartRelease,
00246 &Envelope::enveEmuAttack, &Envelope::enveEmuDecay,
00247 &Envelope::enveEmuSustain, &Envelope::enveEmuRelease,
00248 &Envelope::enveEmuSustainDecay, &Envelope::enveEmuMute,
00249
00250
00251 &Envelope::enveEmuStartShortAttack, &Envelope::enveEmuMute,
00252 &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00253 &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00254 &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00255
00256
00257 &Envelope::enveEmuStartAttack, &Envelope::enveEmuStartRelease,
00258 &Envelope::enveEmuAlterAttack, &Envelope::enveEmuAlterDecay,
00259 &Envelope::enveEmuAlterSustain, &Envelope::enveEmuAlterRelease,
00260 &Envelope::enveEmuAlterSustainDecay, &Envelope::enveEmuMute,
00261
00262
00263 &Envelope::enveEmuStartShortAttack, &Envelope::enveEmuMute,
00264 &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00265 &Envelope::enveEmuMute, &Envelope::enveEmuMute,
00266 &Envelope::enveEmuMute, &Envelope::enveEmuMute
00267 };
00268
00269
00270
00271
00272
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
00289
00290
00291
00292 inline uword Envelope::enveEmuMute(struct sidOperator* ) const
00293 {
00294 return 0;
00295 }
00296
00297
00298
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
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
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
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
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
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);
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
00463 if ( pVoice->enveVol <= pVoice->enveSusVol )
00464 {
00465 pVoice->enveVol = pVoice->enveSusVol;
00466 return enveEmuAlterSustain(pVoice);
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
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
00587
00588
00589
00590
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;
00671 return enveEmuAlterShortAttack(pVoice);
00672 }
00673
00674
00675
00676