// 计算点iNext相对中心点iSeed、当前点iCur的正则平滑度函数(3.3.2:公式3.7), preNorm为前一个三角形的法矢 float CPointMesh::computeSeedPointFit(float ptSeed[3], float ptCur[3], size_t iNext, float preNorm[3]){ // 计算三角形最小内角的cosq float* ptNext = m_ps->getPoint(iNext); float eSeedCur[3] = Edge(ptSeed, ptCur), eSeedNext[3] = Edge(ptSeed, ptNext), eCurNext[3] = Edge(ptCur, ptNext); // eUnit(eSeedCur); eUnit(eSeedNext); eUnit(eCurNext); float angelSeed = 1.0f - eCos(eSeedCur, eSeedNext); if (angelSeed > COS160) return FLT_MINN; float angelCur = 1.0f + eCos(eCurNext, eSeedCur); float angelNext = 1.0f - eCos(eSeedCur, eCurNext); float minTriAngel = min(angelSeed, angelCur); // 新三角形的最小内角 minTriAngel = min(minTriAngel, angelNext);//【0,0.5】 if (minTriAngel < COS15) return FLT_MINN+20; float eNorm[3]; // 新三角形面的法矢 eCross(eNorm, eSeedCur, eSeedNext); // eUnit(eNorm); float angleDihe = eCos(eNorm, preNorm); // 二面角大小【-1,1】 float ret = 2*m_A*minTriAngel + m_B* angleDihe; if (getPointStatus(iNext)== PS_FRONTPOINT) ret *= 1.4F; return ret; }
float CPointMesh::computeSeedPointFit(float ptSeed[3], float ptCur[3], size_t iNext){ // 计算三角形最小内角的cosq float* ptNext = m_ps->getPoint(iNext); float eSeedCur[3] = Edge(ptSeed, ptCur), eSeedNext[3] = Edge(ptSeed, ptNext), eCurNext[3] = Edge(ptCur, ptNext); // eUnit(eSeedCur); eUnit(eSeedNext); eUnit(eCurNext); float angelSeed = 1.0f - eCos(eSeedCur, eSeedNext); if (angelSeed > COS150) return FLT_MINN; float angelCur = 1.0f + eCos(eCurNext, eSeedCur); float angelNext = 1.0f - eCos(eSeedCur, eCurNext); float minTriAngel = min(angelSeed, angelCur); // 新三角形的最小内角 minTriAngel = min(minTriAngel, angelNext);//【0,0.5】 return minTriAngel; }
void eTfEffectFlangerProcess(eTfEffect *fx, eTfSynth &synth, eTfInstrument &instr, eF32 **signal, eU32 len) { eTfEffectFlanger *flanger = static_cast<eTfEffectFlanger *>(fx); eF32 *pcmleft = signal[0]; eF32 *pcmright = signal[1]; eF32 amp = instr.params[TF_FLANGER_AMPLITUDE]; eF32 freq = instr.params[TF_FLANGER_FREQUENCY]; eF32 lfo = instr.params[TF_FLANGER_LFO]; eF32 wet = instr.params[TF_FLANGER_WET]; const eF32 DELAYMIN = (eF32)synth.sampleRate * 0.1f / 1000.0f; // 0.1 ms delay min const eF32 DELAYMAX = (eF32)synth.sampleRate *12.1f / 1000.0f; // 12.1 ms delay max eF32 inc = 0.1f*(eF32)len; while(len--) { if (flanger->bidi==0) { flanger->lfocount += lfo * inc; if (flanger->lfocount > freq) { flanger->lfocount = 1.0f; flanger->bidi = 1; } } else { flanger->lfocount -= lfo * inc; if (flanger->lfocount < 0.0f) { flanger->lfocount = 0.01f; flanger->bidi = 0; } } eF32 frequency = flanger->lfocount; if (frequency==0.0) frequency=1.0f; if(flanger->lastBpm != frequency) { flanger->angle0 += (eF32)((eF64)flanger->angle * frequency * 120.0f / (synth.sampleRate * 4.0f * 60.0f / ePI)); flanger->angle1 += (eF32)((eF64)flanger->angle * (1.0f - frequency) * 120.0f / (synth.sampleRate * 4.0f * 60.0f / ePI)); flanger->lastBpm = frequency; flanger->angle = 0; } eInt deltaleft = eFtoL(DELAYMIN + ((DELAYMAX - DELAYMIN) / 8192.0f) * amp * 4096.0f * (1.0f - eCos(flanger->angle0 + flanger->angle * frequency / (synth.sampleRate * 4 * 60 / ePI)))); eInt deltaright = eFtoL(DELAYMIN + ((DELAYMAX - DELAYMIN) / 8192.0f) * amp * 4096.0f * (1.0f - eCos(flanger->angle1 + flanger->angle * frequency / (synth.sampleRate * 4 * 60 / ePI)))); flanger->angle++; eInt ppleft = flanger->buffpos - deltaleft; eInt ppright = flanger->buffpos - deltaright; if(ppleft<0) ppleft += TF_FX_FLANGERBUFFSIZE; if(ppright<0) ppright += TF_FX_FLANGERBUFFSIZE; eF32 l = *pcmleft - wet * flanger->buffleft[ppleft]; if (l<-1.0f) l=-1.0f; else if (l>1.0f) l=1.0f; eF32 r = *pcmright - wet * flanger->buffright[ppright]; if (r<-1.0f) r=-1.0f; else if (r>1.0f) r=1.0f; eUndenormalise(l); eUndenormalise(r); *pcmleft = l; *pcmright = r; flanger->buffleft[flanger->buffpos] = l; flanger->buffright[flanger->buffpos] = r; pcmleft++; pcmright++; flanger->buffpos++; if (flanger->buffpos >= TF_FX_FLANGERBUFFSIZE) flanger->buffpos = 0; } }