#include "sound_engine_adsr.h" int32_t sound_engine_cycle_and_output_adsr( int32_t input, SoundEngine* eng, SoundEngineADSR* adsr, uint16_t* flags) { switch(adsr->envelope_state) { case ATTACK: { adsr->envelope += adsr->envelope_speed; if(adsr->envelope >= MAX_ADSR) { adsr->envelope_state = DECAY; adsr->envelope = MAX_ADSR; adsr->envelope_speed = envspd(eng, adsr->d); } break; } case DECAY: { if(adsr->envelope > ((uint32_t)adsr->s << 17) + adsr->envelope_speed) { adsr->envelope -= adsr->envelope_speed; } else { adsr->envelope = (uint32_t)adsr->s << 17; adsr->envelope_state = (adsr->s == 0) ? RELEASE : SUSTAIN; adsr->envelope_speed = envspd(eng, adsr->r); } break; } case SUSTAIN: case DONE: { break; } case RELEASE: { if(adsr->envelope > adsr->envelope_speed) { adsr->envelope -= adsr->envelope_speed; } else { adsr->envelope_state = DONE; *flags &= ~SE_ENABLE_GATE; adsr->envelope = 0; } break; } } return (int32_t)((int32_t)input * (int32_t)(adsr->envelope >> 10) / (int32_t)(MAX_ADSR >> 10) * (int32_t)adsr->volume / (int32_t)MAX_ADSR_VOLUME); }