void eTfEffectDistortionProcess(eTfEffect *fx, eTfSynth &synth, eTfInstrument &instr, eF32 **signal, eU32 len) { eASSERT_ALIGNED16(fx); eTfEffectDistortion *dist = static_cast<eTfEffectDistortion *>(fx); eF32 amount = 1.0f - instr.params[TF_DISTORT_AMOUNT]; if (amount != dist->generatedAmount) { dist->generatedAmount = amount; for (eU32 base = 0; base<32768; base++) dist->powTable[base] = ePow(base/32768.f, amount); } for(eU32 i=0;i<2;i++) { eF32 *in = signal[i]; eU32 len2 = len; while(len2--) { eF32 val = *in; eF32 sign = eSign(val); eF32 abs = eAbs(val); if (abs > 1.0f) abs = 1.0f; eU32 offs = eFtoL(abs * 32767.0f); *in++ = sign * dist->powTable[offs]; } } }
eF32 tfADSR::process(tfADSR::State *state, eU32 len, eF32 a, eF32 d, eF32 s, eF32 r, eF32 slope, eU32 sampleRate) { eF32 attack,decay,sustain,release; eF32 scale = 0.00050f * (sampleRate / 44100.0f) * len; a = ePow(a, 3); d = ePow(d, 3); r = ePow(r, 3); a = eMax(0.000000001f, a); attack = -eLog(a * .94f) * scale; if (d <= 0) decay = -1.0f; else decay = eLog(d * .94f) * 0.25f * scale; sustain = eMax(s, 0.0f); r = eMax(r, 0.000000001f); release = eLog(r * .94f) * 0.25f * scale; eF32 volume = state->volume; switch (state->state) { case ADSR_STATE_ATTACK: volume += attack; if (volume >= 1.0f) { volume = 1.0f; state->state = ADSR_STATE_DECAY; } break; case ADSR_STATE_DECAY: { eF32 diff = 0.01f + (volume - sustain); eF32 range = 1.0f - sustain; eF32 pos = diff / range; eF32 slope_f = ePow(pos, slope); volume += decay * slope_f; if (volume <= sustain) { volume = sustain; state->state = ADSR_STATE_SUSTAIN; } } break; case ADSR_STATE_SUSTAIN: if (volume < sustain) { volume -= decay; if (volume > sustain) { volume = sustain; } } else if (volume > sustain) { volume += decay; if (volume < sustain) { volume = sustain; } } break; case ADSR_STATE_RELEASE: { eF32 slope_f = ePow(volume, slope); volume += release * slope_f; if (volume <= 0.001f) { volume = 0.0f; state->state = ADSR_STATE_FINISHED; } } break; case ADSR_STATE_FINISHED: break; } state->volume = volume; return volume; }
void eTfEffectEqProcess(eTfEffect *fx, eTfSynth &synth, eTfInstrument &instr, eF32 **signal, eU32 len) { eASSERT_ALIGNED16(fx); eTfEffectEq *eq = static_cast<eTfEffectEq *>(fx); eF32 gain[3]; for(eU32 i=0;i<3;i++) { gain[i] = instr.params[TF_EQ_LOW + i]; if (gain[i] <= 0.5f) gain[i] *= 2.0f; else gain[i] = ePow((gain[i] - 0.5f) * 2.0f, 2.0f) * 10.0f + 1.0f; } // Calculate filter cutoff frequencies eF32 m_lf = 2.0f * eSin(ePI * (880.0f / synth.sampleRate)); eF32 m_hf = 2.0f * eSin(ePI * (5000.0f / synth.sampleRate)); eF32 *in1 = signal[0]; eF32 *in2 = signal[1]; eF32x2 lf = eSimdSetAll(m_lf); eF32x2 hf = eSimdSetAll(m_hf); eF32x2 lg = eSimdSetAll(gain[0]); eF32x2 mg = eSimdSetAll(gain[1]); eF32x2 hg = eSimdSetAll(gain[2]); while(len--) { eF32x2 val = eSimdSet2(*in1, *in2); // Locals eF32x2 l,m,h; // Low / Mid / High - Sample Values // Filter #1 (lowpass) //m_f1p0 += (lf * (val - m_f1p0)); eq->m_f1p0 = eSimdFma(eq->m_f1p0, lf, eSimdSub(val, eq->m_f1p0)); //m_f1p1 += (lf * (m_f1p0 - m_f1p1)); eq->m_f1p1 = eSimdFma(eq->m_f1p1, lf, eSimdSub(eq->m_f1p0, eq->m_f1p1)); //m_f1p2 += (lf * (m_f1p1 - m_f1p2)); eq->m_f1p2 = eSimdFma(eq->m_f1p2, lf, eSimdSub(eq->m_f1p1, eq->m_f1p2)); //m_f1p3 += (lf * (m_f1p2 - m_f1p3)); eq->m_f1p3 = eSimdFma(eq->m_f1p3, lf, eSimdSub(eq->m_f1p2, eq->m_f1p3)); l = eq->m_f1p3; // Filter #2 (highpass) //m_f2p0 += (hf * (val - m_f2p0)); eq->m_f2p0 = eSimdFma(eq->m_f2p0, hf, eSimdSub(val, eq->m_f2p0)); //m_f2p1 += (hf * (m_f2p0 - m_f2p1)); eq->m_f2p1 = eSimdFma(eq->m_f2p1, hf, eSimdSub(eq->m_f2p0, eq->m_f2p1)); //m_f2p2 += (hf * (m_f2p1 - m_f2p2)); eq->m_f2p2 = eSimdFma(eq->m_f2p2, hf, eSimdSub(eq->m_f2p1, eq->m_f2p2)); //m_f2p3 += (hf * (m_f2p2 - m_f2p3)); eq->m_f2p3 = eSimdFma(eq->m_f2p3, hf, eSimdSub(eq->m_f2p2, eq->m_f2p3)); h = eSimdSub(eq->m_sdm3, eq->m_f2p3); // Calculate midrange (signal - (low + high)) m = eSimdSub(eq->m_sdm3, eSimdAdd(h, l)); // Scale, Combine and store l = eSimdMul(l, lg); m = eSimdMul(m, mg); h = eSimdMul(h, hg); // Shuffle history buffer eq->m_sdm3 = eq->m_sdm2; eq->m_sdm2 = eq->m_sdm1; eq->m_sdm1 = val; eF32x2 out = eSimdAdd(eSimdAdd(l, m), h); eSimdStore2(out, *in1, *in2); in1++; in2++; } }
// calculates the expression in the string // returns the position after second number eS32 calculateTerm(const eString& s, int start, int end, const eU32* parMap, const eF32* params, eF32& result) { int pos = start; eF32 tuple[] = {0,0}; eU32 tpos = 0; eU32 op = 0; eU32 c; while((pos < end) && ((c = s.at(pos)) != ',') && (c != ')')) { if(c == '(') { pos = calculateTerm(s, pos + 1, end, parMap, params, tuple[tpos]); eASSERT(pos != -1); pos++; } else { eS32 oldPos = pos; // try to read constant eF32 number = 0; eF32 v = 1.0f; while(pos < end) { int cc = s.at(pos) - '0'; if(cc == '.' - '0') v = 0.1f; else if((eU32)cc <= 9) {// is a number if(v >= 1.0f) number = number * 10.0f + cc; else { number += v * cc; v /= 10.0f; } tuple[tpos] = number; } else break; pos++; } // try to read symbol eASSERT(parMap != eNULL); for(eU32 i = 0; i < LSYS_PAR_MAX; i++) if(parMap[i] == c) { tuple[tpos] = params[i]; pos++; } if(pos == oldPos) { // is an operator pos++; op = c; tpos++; }; } } switch(op) { case '+': result = tuple[0] + tuple[1]; break; case '-': result = tuple[0] - tuple[1]; break; case '*': result = tuple[0] * tuple[1]; break; case '/': result = tuple[0] / tuple[1]; break; case '<': result = (tuple[0] < tuple[1]) ? 1.0f : 0.0f; break; case '=': result = (tuple[0] == tuple[1]) ? 1.0f : 0.0f; break; case '>': result = (tuple[0] > tuple[1]) ? 1.0f : 0.0f; break; case '^': result = ePow(tuple[0], tuple[1]); break; default: result = tuple[0]; // single term } return pos; }