Added Vibratto to unison effect
(cherry picked from commit 97013fd5ca25c477d8db76105a22ddd1b8cc6cdd)
This commit is contained in:
@@ -892,6 +892,9 @@
|
||||
|
||||
07 Sep 2009 (Mark McCurry)
|
||||
- Fixed glitch in XMLwrapper, which would prevent file loading
|
||||
|
||||
20 Sep 2009 (Paul Nasca)
|
||||
- Started to implement the Unison effect for ADsynth
|
||||
|
||||
|
||||
22 Sep 2009 (Paul Nasca)
|
||||
- Added vibratto and other features to Unison effect
|
||||
|
||||
@@ -99,8 +99,9 @@ void ADnoteParameters::defaults(int n)
|
||||
VoicePar[nvoice].Enabled=0;
|
||||
|
||||
VoicePar[nvoice].Unison_size=1;
|
||||
VoicePar[nvoice].Unison_frequency_spread=64;
|
||||
VoicePar[nvoice].Unison_frequency_spread=30;
|
||||
VoicePar[nvoice].Unison_stereo_spread=64;
|
||||
VoicePar[nvoice].Unison_vibratto=64;
|
||||
|
||||
VoicePar[nvoice].Type=0;
|
||||
VoicePar[nvoice].Pfixedfreq=0;
|
||||
@@ -283,6 +284,7 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n)
|
||||
xml->addpar("unison_size",VoicePar[nvoice].Unison_size);
|
||||
xml->addpar("unison_frequency_spread",VoicePar[nvoice].Unison_frequency_spread);
|
||||
xml->addpar("unison_stereo_spread",VoicePar[nvoice].Unison_stereo_spread);
|
||||
xml->addpar("unison_vibratto",VoicePar[nvoice].Unison_vibratto);
|
||||
|
||||
xml->addpar("delay",VoicePar[nvoice].PDelay);
|
||||
xml->addparbool("resonance",VoicePar[nvoice].Presonance);
|
||||
@@ -563,6 +565,7 @@ void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n)
|
||||
VoicePar[nvoice].Unison_size=xml->getpar127("unison_size",VoicePar[nvoice].Unison_size);
|
||||
VoicePar[nvoice].Unison_frequency_spread=xml->getpar127("unison_frequency_spread",VoicePar[nvoice].Unison_frequency_spread);
|
||||
VoicePar[nvoice].Unison_stereo_spread=xml->getpar127("unison_stereo_spread",VoicePar[nvoice].Unison_stereo_spread);
|
||||
VoicePar[nvoice].Unison_vibratto=xml->getpar127("unison_vibratto",VoicePar[nvoice].Unison_vibratto);
|
||||
|
||||
VoicePar[nvoice].Type=xml->getpar127("type",VoicePar[nvoice].Type);
|
||||
VoicePar[nvoice].PDelay=xml->getpar127("delay",VoicePar[nvoice].PDelay);
|
||||
|
||||
@@ -124,6 +124,9 @@ struct ADnoteVoiceParam {
|
||||
|
||||
/** Stereo spread of the subvoices*/
|
||||
unsigned char Unison_stereo_spread;
|
||||
|
||||
/** Vibratto of the subvoices (which makes the unison more "natural")*/
|
||||
unsigned char Unison_vibratto;
|
||||
|
||||
/** Type of the voice (0=Sound,1=Noise)*/
|
||||
unsigned char Type;
|
||||
|
||||
@@ -104,18 +104,20 @@ ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE ve
|
||||
//compute unison
|
||||
unison_size[nvoice]=unison;
|
||||
|
||||
unison_base_freq_rap[nvoice]=new REALTYPE[unison];
|
||||
unison_freq_rap[nvoice]=new REALTYPE[unison];
|
||||
REALTYPE unison_spread=pars->VoicePar[nvoice].Unison_frequency_spread/127.0;
|
||||
unison_spread=pow(unison_spread*2.0,2.0)*50.0;//cents
|
||||
unison_spread=pow(unison_spread*2.0,2.0)*100.0;//cents
|
||||
REALTYPE unison_real_spread=pow(2.0,(unison_spread*0.5)/1200.0);
|
||||
REALTYPE unison_vibratto_a=pars->VoicePar[nvoice].Unison_vibratto/127.0;//0.0 .. 1.0
|
||||
|
||||
switch (unison){
|
||||
case 1:
|
||||
unison_freq_rap[nvoice][0]=1.0;//if the unison is not used, always make the only subvoice to have the default note
|
||||
unison_base_freq_rap[nvoice][0]=1.0;//if the unison is not used, always make the only subvoice to have the default note
|
||||
break;
|
||||
case 2:{//unison for 2 subvoices
|
||||
REALTYPE tmp=pow(2.0,(unison_spread*0.5)/1200.0);
|
||||
unison_freq_rap[nvoice][0]=1.0/tmp;
|
||||
unison_freq_rap[nvoice][1]=tmp;
|
||||
unison_base_freq_rap[nvoice][0]=1.0/unison_real_spread;
|
||||
unison_base_freq_rap[nvoice][1]=unison_real_spread;
|
||||
};
|
||||
break;
|
||||
default:{//unison for more than 2 subvoices
|
||||
@@ -131,10 +133,39 @@ ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE ve
|
||||
REALTYPE diff=max-min;
|
||||
for (int k=0;k<unison;k++){
|
||||
unison_values[k]=(unison_values[k]-(max+min)*0.5)/diff;//the lowest value will be -1 and the highest will be 1
|
||||
unison_freq_rap[nvoice][k]=pow(2.0,(unison_spread*unison_values[k]*0.5)/1200);
|
||||
unison_base_freq_rap[nvoice][k]=pow(2.0,(unison_spread*unison_values[k]*0.5)/1200);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
//unison vibrattos
|
||||
|
||||
if (unison>1){
|
||||
for (int k=0;k<unison;k++){//reduce the frequency difference for larger vibrattos
|
||||
unison_base_freq_rap[nvoice][k]=1.0+(unison_base_freq_rap[nvoice][k]-1.0)*(1.0-unison_vibratto_a);
|
||||
};
|
||||
};
|
||||
unison_vibratto[nvoice].step=new REALTYPE[unison];
|
||||
unison_vibratto[nvoice].position=new REALTYPE[unison];
|
||||
unison_vibratto[nvoice].amplitude=(unison_real_spread-1.0)*unison_vibratto_a*0.5;
|
||||
|
||||
REALTYPE increments_per_second=SAMPLE_RATE/(REALTYPE)SOUND_BUFFER_SIZE;
|
||||
for (int k=0;k<unison;k++){
|
||||
unison_vibratto[nvoice].position[k]=RND*0.9-0.45;
|
||||
REALTYPE vibratto_period=0.5+RND*2.5;
|
||||
|
||||
|
||||
unison_vibratto[nvoice].position[k]=0;
|
||||
REALTYPE m=4.0/(vibratto_period*increments_per_second);
|
||||
if (RND<0.5) m=-m;
|
||||
unison_vibratto[nvoice].step[k]=m;
|
||||
};
|
||||
|
||||
if (unison==1) {//no vibratto for a single voice
|
||||
unison_vibratto[nvoice].step[0]=0.0;
|
||||
unison_vibratto[nvoice].position[0]=0.0;
|
||||
unison_vibratto[nvoice].amplitude=0.0;
|
||||
};
|
||||
|
||||
oscfreqhi[nvoice]=new int[unison];
|
||||
oscfreqlo[nvoice]=new REALTYPE[unison];
|
||||
@@ -395,9 +426,6 @@ void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int
|
||||
|
||||
NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE);
|
||||
|
||||
|
||||
#warning TODO: ADD HERE THE CODE FOR UNISON
|
||||
|
||||
};
|
||||
|
||||
/// initparameters();
|
||||
@@ -509,8 +537,11 @@ void ADnote::KillVoice(int nvoice)
|
||||
delete []oscposloFM[nvoice];
|
||||
|
||||
delete []NoteVoicePar[nvoice].OscilSmp;
|
||||
delete []unison_base_freq_rap[nvoice];
|
||||
delete []unison_freq_rap[nvoice];
|
||||
delete []FMoldsmp[nvoice];
|
||||
delete []unison_vibratto[nvoice].step;
|
||||
delete []unison_vibratto[nvoice].position;
|
||||
|
||||
if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) delete(NoteVoicePar[nvoice].FreqEnvelope);
|
||||
NoteVoicePar[nvoice].FreqEnvelope=NULL;
|
||||
@@ -719,6 +750,35 @@ void ADnote::initparameters()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Computes the relative frequency of each unison voice and it's vibratto
|
||||
* This must be called before setfreq* functions
|
||||
*/
|
||||
void ADnote::compute_unison_freq_rap(int nvoice){
|
||||
if (unison_size[nvoice]==1){//no unison
|
||||
unison_freq_rap[nvoice][0]=1.0;
|
||||
return;
|
||||
};
|
||||
for (int k=0;k<unison_size[nvoice];k++){
|
||||
REALTYPE pos=unison_vibratto[nvoice].position[k];
|
||||
REALTYPE step=unison_vibratto[nvoice].step[k];
|
||||
pos+=step;
|
||||
if (pos<=-1.0) {
|
||||
pos=-1.0;
|
||||
step=-step;
|
||||
};
|
||||
if (pos>=1.0){
|
||||
pos=1.0;
|
||||
step=-step;
|
||||
};
|
||||
unison_freq_rap[nvoice][k]=unison_base_freq_rap[nvoice][k]+pos*unison_vibratto[nvoice].amplitude;
|
||||
|
||||
unison_vibratto[nvoice].position[k]=pos;
|
||||
step=unison_vibratto[nvoice].step[k]=step;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@@ -821,6 +881,8 @@ void ADnote::computecurrentparameters()
|
||||
NoteVoicePar[nvoice].DelayTicks-=1;
|
||||
if (NoteVoicePar[nvoice].DelayTicks>0) continue;
|
||||
|
||||
compute_unison_freq_rap(nvoice);
|
||||
|
||||
/*******************/
|
||||
/* Voice Amplitude */
|
||||
/*******************/
|
||||
|
||||
@@ -59,6 +59,7 @@ private:
|
||||
|
||||
void setfreq(int nvoice,REALTYPE in_freq);
|
||||
void setfreqFM(int nvoice,REALTYPE in_freq);
|
||||
void compute_unison_freq_rap(int nvoice);
|
||||
void computecurrentparameters();
|
||||
void initparameters();
|
||||
void KillVoice(int nvoice);
|
||||
@@ -233,9 +234,20 @@ private:
|
||||
//fractional part (skip) of the Modullator
|
||||
REALTYPE *oscposloFM[NUM_VOICES],*oscfreqloFM[NUM_VOICES];
|
||||
|
||||
//the unison base_value
|
||||
REALTYPE *unison_base_freq_rap[NUM_VOICES];
|
||||
|
||||
//how the unison subvoice's frequency is changed (1.0 for no change)
|
||||
REALTYPE *unison_freq_rap[NUM_VOICES];
|
||||
|
||||
//unison vibratto
|
||||
struct {
|
||||
REALTYPE amplitude; //amplitude which be added to unison_freq_rap
|
||||
REALTYPE *step; //value which increments the position
|
||||
REALTYPE *position;//between -1.0 and 1.0
|
||||
}unison_vibratto[NUM_VOICES];
|
||||
|
||||
|
||||
//integer part (skip) of the Modullator
|
||||
unsigned int *oscposhiFM[NUM_VOICES],*oscfreqhiFM[NUM_VOICES];
|
||||
|
||||
|
||||
@@ -571,6 +571,13 @@ voiceonbutton->redraw();} open
|
||||
code0 {o->add("OFF");char tmp[100];for (int i=1;ADnote_unison_sizes[i];i++){snprintf(tmp,100,"size %d",ADnote_unison_sizes[i]);o->add(tmp);};}
|
||||
code1 {o->value(pars->VoicePar[nvoice].PDetuneType);}
|
||||
} {}
|
||||
Fl_Dial {} {
|
||||
label Vibratto
|
||||
callback {pars->VoicePar[nvoice].Unison_vibratto=(int)o->value();} selected
|
||||
tooltip Vibratto xywh {340 540 25 25} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1
|
||||
code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto);}
|
||||
class WidgetPDial
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Group {} {
|
||||
@@ -1015,7 +1022,7 @@ advoice=new ADvoiceUI(0,0,765,585);
|
||||
ADnoteVoice->add(advoice);
|
||||
advoice->init(pars,nvoice,master);
|
||||
advoice->show();
|
||||
ADnoteVoice->redraw();} selected
|
||||
ADnoteVoice->redraw();}
|
||||
xywh {5 585 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13
|
||||
code0 {o->bounds(1,NUM_VOICES);}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user