#ifdef DSP_CPP
void DSP::envelope_run(voice_t &v) {
int env = v.env;
if(v.env_mode == env_release) {
env -= 0x8;
if(env < 0) env = 0;
v.env = env;
return;
}
int rate;
int env_data = VREG(adsr1);
if(state.t_adsr0 & 0x80) {
if(v.env_mode >= env_decay) {
env--;
env -= env >> 8;
rate = env_data & 0x1f;
if(v.env_mode == env_decay) {
rate = ((state.t_adsr0 >> 3) & 0x0e) + 0x10;
}
} else {
rate = ((state.t_adsr0 & 0x0f) << 1) + 1;
env += rate < 31 ? 0x20 : 0x400;
}
} else {
env_data = VREG(gain);
int mode = env_data >> 5;
if(mode < 4) {
env = env_data << 4;
rate = 31;
} else {
rate = env_data & 0x1f;
if(mode == 4) {
env -= 0x20;
} else if(mode < 6) {
env--;
env -= env >> 8;
} else {
env += 0x20;
if(mode > 6 && (unsigned)v.hidden_env >= 0x600) {
env += 0x8 - 0x20;
}
}
}
}
if((env >> 8) == (env_data >> 5) && v.env_mode == env_decay) v.env_mode = env_sustain;
v.hidden_env = env;
if((unsigned)env > 0x7ff) {
env = (env < 0 ? 0 : 0x7ff);
if(v.env_mode == env_attack) v.env_mode = env_decay;
}
if(counter_poll(rate) == true) v.env = env;
}
#endif