// -------------------------------------------------------------- // -------------------------------------------------------------- #include #include #include #include "synth_defs.h" #include "env.h" // -------------------------------------------------------------- // Exported functions // -------------------------------------------------------------- void ENV_Init(envgen_t *pObj, synth_float_t fs) { pObj->fs = fs; ENV_Reset(pObj); ENV_Param2Set(pObj, ENV_PARAM2_A, 0.001); ENV_Param2Set(pObj, ENV_PARAM2_D, 1.000); ENV_Param2Set(pObj, ENV_PARAM2_S, 1.000); ENV_Param2Set(pObj, ENV_PARAM2_R, 1.000); pObj->bufsize = 0; pObj->pOut = NULL; ENV_SetBufsize(pObj, SYNTH_MAX_BUFSIZE); } void ENV_Free(envgen_t *pObj) { ENV_SetBufsize(pObj, 0); } void ENV_SetBufsize(envgen_t *pObj, UINT32 size) { if (pObj->bufsize == size) return; pObj->bufsize = size; if (pObj->pOut) free(pObj->pOut); pObj->pOut = NULL; if (!size) return; pObj->pOut = (synth_float_t*)malloc(pObj->bufsize*sizeof(synth_float_t)); } void ENV_SetFS(envgen_t *pObj, synth_float_t fs) { pObj->fs = fs; } void ENV_Reset(envgen_t *pObj) { pObj->state = env_state_idle; pObj->s = 0; pObj->k = (synth_float_t)1/ENV_KE; } void ENV_Event(envgen_t *pObj, UINT32 type) { switch(type) { case env_event_trigger: case env_event_retrigger: // pObj->sr = 0; pObj->state = env_state_attack; // pObj->k = (synth_float_t)1/ENV_KE; // if (type == env_event_retrigger) // { // pObj->a_r = 1.f/(0.001*pObj->fs); // pObj->b_r = 1.f - pObj->a_r; // pObj->state = env_state_attack_retrigger; // // } break; case env_event_release: if (pObj->state == env_state_idle) break; // if (pObj->state == env_state_attack) // pObj->sf = pObj->sr; // if (pObj->state == env_state_sustain) // pObj->sf = pObj->param.Vs/pObj->k; pObj->state = env_state_release; break; default: break; } }; void ENV_Param2Set(envgen_t *pObj, UINT32 type, synth_float_t value) { switch(type) { case ENV_PARAM2_A: pObj->param.Ta = max(ENV_MIN_A, value); pObj->a_a = 1.f/(pObj->param.Ta*pObj->fs); pObj->b_a = 1.f - pObj->a_a; break; case ENV_PARAM2_D: pObj->param.Td = max(ENV_MIN_D, value); pObj->a_d = 5.f/(pObj->param.Td*pObj->fs); pObj->b_d = 1.f - pObj->a_d; break; case ENV_PARAM2_S: pObj->param.Vs = value; break; case ENV_PARAM2_R: pObj->param.Tr = max(ENV_MIN_R, value); pObj->a_r = 5.f/(pObj->param.Tr*pObj->fs); pObj->b_r = 1.f - pObj->a_r; break; default: break; } } UINT32 ENV_ParamGet(envgen_t *pObj, UINT32 type) { return 0; } INT32 ENV_IsIdle(envgen_t *pObj) { return pObj->state == env_state_idle; } synth_float_t* ENV_ProcessDataV(envgen_t *pObj, UINT32 len) { synth_float_t *pX, y; pX = pObj->pOut; while(len) { y = pObj->k*pObj->s; switch (pObj->state) { case env_state_idle: break; case env_state_attack: // y = pObj->k*pObj->sr; if (y >= 1.0) { // pObj->af = 5.f/(pObj->param.Td*pObj->fs); // pObj->bf = 1.f - pObj->af; // pObj->k = (synth_float_t)1/ENV_KE; // pObj->sf = pObj->sr; pObj->state = env_state_decay; } pObj->s = pObj->a_a + pObj->b_a*pObj->s; break; case env_state_attack_retrigger: pObj->sf = pObj->b_r*pObj->sf; if (pObj->sf <= ENV_TOL) { pObj->a_r = 5.f/(pObj->param.Tr*pObj->fs); pObj->b_r = 1.f - pObj->a_r; pObj->state = env_state_attack; } break; case env_state_decay: if (y <= pObj->param.Vs) { pObj->state = env_state_sustain; } pObj->s = pObj->b_d*pObj->s; break; case env_state_sustain: y = pObj->param.Vs; break; case env_state_release: if (y <= ENV_TOL) { pObj->state = env_state_idle; } pObj->s = pObj->b_r*pObj->s; break; default: break; } *(pX++) = y; len--; } return pObj->pOut; }