/* ZynAddSubFX - a software synthesizer FormantFilter.C - formant filters Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2) for more details. You should have received a copy of the GNU General Public License (version 2) along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "FormantFilter.h" FormantFilter::FormantFilter(FilterParams *pars){ numformants=pars->Pnumformants; for (int i=0;iPstages); cleanup(); inbuffer=new REALTYPE [SOUND_BUFFER_SIZE]; tmpbuf=new REALTYPE [SOUND_BUFFER_SIZE]; for (int j=0;jgetformantfreq(pars->Pvowels[j].formants[i].freq); formantpar[j][i].amp=pars->getformantamp(pars->Pvowels[j].formants[i].amp); formantpar[j][i].q=pars->getformantq(pars->Pvowels[j].formants[i].q); }; for (int i=0;iPformantslowness/128.0),3.0); sequencesize=pars->Psequencesize;if (sequencesize==0) sequencesize=1; for (int k=0;kPsequence[k].nvowel; vowelclearness=pow(10.0,(pars->Pvowelclearness-32.0)/48.0); sequencestretch=pow(0.1,(pars->Psequencestretch-32.0)/48.0); if (pars->Psequencereversed) sequencestretch*= -1.0; outgain=dB2rap(pars->getgain()); oldinput=-1.0; Qfactor=1.0;oldQfactor=Qfactor; firsttime=1; }; FormantFilter::~FormantFilter(){ for (int i=0;icleanup(); }; void FormantFilter::setpos(REALTYPE input){ int p1,p2; if (firsttime!=0) slowinput=input; else slowinput=slowinput*(1.0-formantslowness)+input*formantslowness; if ((fabs(oldinput-input)<0.001)&&(fabs(slowinput-input)<0.001)&& (fabs(Qfactor-oldQfactor)<0.001)) { // oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente firsttime=0; return; } else oldinput=input; REALTYPE pos=fmod(input*sequencestretch,1.0);if (pos<0.0) pos+=1.0; F2I(pos*sequencesize,p2); p1=p2-1;if (p1<0) p1+=sequencesize; pos=fmod(pos*sequencesize,1.0); if (pos<0.0) pos=0.0; else if (pos>1.0) pos=1.0; pos=(atan((pos*2.0-1.0)*vowelclearness)/atan(vowelclearness)+1.0)*0.5; p1=sequence[p1].nvowel; p2=sequence[p2].nvowel; if (firsttime!=0) { for (int i=0;isetfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); oldformantamp[i]=currentformants[i].amp; }; firsttime=0; } else { for (int i=0;isetfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); }; }; oldQfactor=Qfactor; }; void FormantFilter::setfreq(REALTYPE frequency){ setpos(frequency); }; void FormantFilter::setq(REALTYPE q_){ Qfactor=q_; for (int i=0;isetq(Qfactor*currentformants[i].q); }; void FormantFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_){ Qfactor=q_; setpos(frequency); }; void FormantFilter::filterout(REALTYPE *smp){ int i,j; for (i=0;ifilterout(tmpbuf); if (ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j],currentformants[j].amp)) for (i=0;i