Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void PS_SPU::RunEnvelope(SPU_Voice *voice)
- {
- SPU_ADSR *ADSR = &voice->ADSR;
- int increment;
- int divinco;
- int16 uoflow_reset;
- if(ADSR->Phase == ADSR_ATTACK && ADSR->EnvLevel == 0x7FFF)
- ADSR->Phase++;
- //static INLINE void CalcVCDelta(const uint8 zs, uint8 speed, bool log_mode, bool decrement, bool inv_increment, int16 Current, int &increment, int &divinco)
- switch(ADSR->Phase)
- {
- default: assert(0);
- break;
- case ADSR_ATTACK:
- CalcVCDelta(0x7F, ADSR->AttackRate, ADSR->AttackExp, false, false, (int16)ADSR->EnvLevel, increment, divinco);
- uoflow_reset = 0x7FFF;
- break;
- case ADSR_DECAY:
- CalcVCDelta(0x1F << 2, ADSR->DecayRate, true, true, true, (int16)ADSR->EnvLevel, increment, divinco);
- uoflow_reset = 0;
- break;
- case ADSR_SUSTAIN:
- CalcVCDelta(0x7F, ADSR->SustainRate, ADSR->SustainExp, ADSR->SustainDec, ADSR->SustainDec, (int16)ADSR->EnvLevel, increment, divinco);
- uoflow_reset = ADSR->SustainDec ? 0 : 0x7FFF;
- break;
- case ADSR_RELEASE:
- CalcVCDelta(0x1F << 2, ADSR->ReleaseRate, ADSR->ReleaseExp, true, true, (int16)ADSR->EnvLevel, increment, divinco);
- uoflow_reset = 0;
- break;
- }
- ADSR->Divider += divinco;
- if(ADSR->Divider & 0x8000)
- {
- const uint16 prev_level = ADSR->EnvLevel;
- ADSR->Divider = 0;
- ADSR->EnvLevel += increment;
- if(ADSR->Phase == ADSR_ATTACK)
- {
- // If previous the upper bit was 0, but now it's 1, handle overflow.
- if(((prev_level ^ ADSR->EnvLevel) & ADSR->EnvLevel) & 0x8000)
- ADSR->EnvLevel = uoflow_reset;
- }
- else
- {
- if(ADSR->EnvLevel & 0x8000)
- ADSR->EnvLevel = uoflow_reset;
- }
- if(ADSR->Phase == ADSR_DECAY && (uint16)ADSR->EnvLevel < ADSR->SustainLevel)
- ADSR->Phase++;
- }
- }
- static INLINE void CalcVCDelta(const uint8 zs, uint8 speed, bool log_mode, bool dec_mode, bool inv_increment, int16 Current, int &increment, int &divinco)
- {
- increment = (7 - (speed & 0x3));
- if(inv_increment)
- increment = ~increment;
- divinco = 32768;
- if(speed < 0x2C)
- increment = (unsigned)increment << ((0x2F - speed) >> 2);
- if(speed >= 0x30)
- divinco >>= (speed - 0x2C) >> 2;
- if(log_mode)
- {
- if(dec_mode) // Log decrement mode
- increment = (Current * increment) >> 15;
- else // Log increment mode
- {
- if((Current & 0x7FFF) >= 0x6000)
- {
- if(speed < 0x28)
- increment >>= 2;
- else if(speed >= 0x2C)
- divinco >>= 2;
- else // 0x28 ... 0x2B
- {
- increment >>= 1;
- divinco >>= 1;
- }
- }
- }
- } // end if(log_mode)
- if(divinco == 0 && speed < zs) //0x7F)
- divinco = 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement