Continued unison implementation.
(cherry picked from commit 2565eb855025cd3941f272b57b4b93fd86965e79)
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "ADnoteParameters.h"
|
||||
int ADnote_unison_sizes[]={1,2,3,4,6,8,12,16,24,32,48,64,0};
|
||||
|
||||
ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets()
|
||||
{
|
||||
@@ -99,7 +100,7 @@ void ADnoteParameters::defaults(int n)
|
||||
|
||||
VoicePar[nvoice].Unison_size=1;
|
||||
VoicePar[nvoice].Unison_frequency_spread=64;
|
||||
VoicePar[nvoice].Unison_stereo_spread=100;
|
||||
VoicePar[nvoice].Unison_stereo_spread=64;
|
||||
|
||||
VoicePar[nvoice].Type=0;
|
||||
VoicePar[nvoice].Pfixedfreq=0;
|
||||
@@ -235,6 +236,29 @@ ADnoteParameters::~ADnoteParameters()
|
||||
};
|
||||
};
|
||||
|
||||
int ADnoteParameters::get_unison_size_index(int nvoice){
|
||||
int index=0;
|
||||
if (nvoice>=NUM_VOICES) return 0;
|
||||
int unison=VoicePar[nvoice].Unison_size;
|
||||
while(1){
|
||||
if ((ADnote_unison_sizes[index]<=unison)||(ADnote_unison_sizes[index]==0)) return index;
|
||||
index++;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
void ADnoteParameters::set_unison_size_index(int nvoice,int index){
|
||||
int unison=1;
|
||||
for (int i=0;i<=index;i++){
|
||||
unison=ADnote_unison_sizes[i];
|
||||
if (unison==0) {
|
||||
unison=ADnote_unison_sizes[i-1];
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
VoicePar[nvoice].Unison_size=unison;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "Presets.h"
|
||||
|
||||
enum FMTYPE {NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD};
|
||||
extern int ADnote_unison_sizes[];
|
||||
|
||||
/*****************************************************************/
|
||||
/* GLOBAL PARAMETERS */
|
||||
@@ -278,6 +279,8 @@ public:
|
||||
void getfromXML(XMLwrapper *xml);
|
||||
|
||||
REALTYPE getBandwidthDetuneMultiplier();
|
||||
int get_unison_size_index(int nvoice);
|
||||
void set_unison_size_index(int nvoice,int index);
|
||||
private:
|
||||
void defaults(int n);//n is the nvoice
|
||||
|
||||
|
||||
@@ -97,26 +97,44 @@ ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE ve
|
||||
continue; //the voice is disabled
|
||||
};
|
||||
|
||||
unison_stereo_spread[nvoice]=pars->VoicePar[nvoice].Unison_stereo_spread/127.0;
|
||||
int unison=pars->VoicePar[nvoice].Unison_size;
|
||||
if (unison<1) unison=1;
|
||||
|
||||
|
||||
//compute unison
|
||||
unison_size[nvoice]=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,4.0)*50.0;//cents
|
||||
unison_spread=pow(unison_spread*2.0,2.0)*50.0;//cents
|
||||
|
||||
for (int k=0;k<unison;k++){
|
||||
REALTYPE current_rnd=RND*2.0-1.0;
|
||||
|
||||
#warning TODO: make current_rnd to be spread evenly (keep a current_rnd array and fix that)
|
||||
|
||||
|
||||
unison_freq_rap[nvoice][k]=pow(2.0,(unison_spread*current_rnd)/1200);
|
||||
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
|
||||
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;
|
||||
};
|
||||
break;
|
||||
default:{//unison for more than 2 subvoices
|
||||
REALTYPE unison_values[unison];
|
||||
REALTYPE min=-1e-6,max=1e-6;
|
||||
for (int k=0;k<unison;k++){
|
||||
REALTYPE step=(k/(REALTYPE) (unison-1))*2.0-1.0;//this makes the unison spread more uniform
|
||||
REALTYPE val=step+(RND*2.0-1.0)/(unison-1);
|
||||
unison_values[k]=val;
|
||||
if (val>max) max=val;
|
||||
if (val<min) min=val;
|
||||
};
|
||||
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);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if (unison==1) unison_freq_rap[nvoice][0]=1.0;//if the unison is not used, always make the only subvoice to have the default note
|
||||
|
||||
|
||||
oscfreqhi[nvoice]=new int[unison];
|
||||
oscfreqlo[nvoice]=new REALTYPE[unison];
|
||||
@@ -706,12 +724,11 @@ void ADnote::initparameters()
|
||||
/*
|
||||
* Computes the frequency of an oscillator
|
||||
*/
|
||||
void ADnote::setfreq(int nvoice,REALTYPE freq)
|
||||
void ADnote::setfreq(int nvoice,REALTYPE in_freq)
|
||||
{
|
||||
for (int k=0;k<unison_size[nvoice];k++){
|
||||
REALTYPE speed;
|
||||
freq=fabs(freq)*unison_freq_rap[nvoice][k];
|
||||
speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
|
||||
REALTYPE freq=fabs(in_freq)*unison_freq_rap[nvoice][k];
|
||||
REALTYPE speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
|
||||
if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
|
||||
|
||||
F2I(speed,oscfreqhi[nvoice][k]);
|
||||
@@ -722,12 +739,11 @@ void ADnote::setfreq(int nvoice,REALTYPE freq)
|
||||
/*
|
||||
* Computes the frequency of an modullator oscillator
|
||||
*/
|
||||
void ADnote::setfreqFM(int nvoice,REALTYPE freq)
|
||||
void ADnote::setfreqFM(int nvoice,REALTYPE in_freq)
|
||||
{
|
||||
for (int k=0;k<unison_size[nvoice];k++){
|
||||
REALTYPE speed;
|
||||
freq=fabs(freq)*unison_freq_rap[nvoice][k];
|
||||
speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
|
||||
REALTYPE freq=fabs(in_freq)*unison_freq_rap[nvoice][k];
|
||||
REALTYPE speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
|
||||
if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
|
||||
|
||||
F2I(speed,oscfreqhiFM[nvoice][k]);
|
||||
@@ -1247,14 +1263,33 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr)
|
||||
// Voice Processing
|
||||
|
||||
|
||||
//mix subvoices into
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]=0.0;
|
||||
if (stereo) for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]=0.0;
|
||||
for (int k=0;k<unison_size[nvoice];k++){
|
||||
REALTYPE *tw=tmpwave_unison[k];
|
||||
if (stereo){
|
||||
#warning #make stereo mixing
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]+=tw[i];
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]+=tw[i];
|
||||
REALTYPE stereo_pos=0;
|
||||
if (unison_size[nvoice]>1) stereo_pos=k/(REALTYPE)(unison_size[nvoice]-1)*2.0-1.0;
|
||||
REALTYPE stereo_spread=unison_stereo_spread[nvoice]*2.0;//between 0 and 2.0
|
||||
if (stereo_spread>1.0){
|
||||
REALTYPE stereo_pos_1=(stereo_pos>=0.0)?1.0:-1.0;
|
||||
stereo_pos=(2.0-stereo_spread)*stereo_pos+(stereo_spread-1.0)*stereo_pos_1;
|
||||
}else{
|
||||
stereo_pos*=stereo_spread;
|
||||
};
|
||||
if (unison_size[nvoice]==1) stereo_pos=0.0;
|
||||
REALTYPE panning=(stereo_pos+1.0)*0.5;
|
||||
|
||||
|
||||
REALTYPE lvol=(1.0-panning)*2.0;
|
||||
if (lvol>1.0) lvol=1.0;
|
||||
|
||||
REALTYPE rvol=panning*2.0;
|
||||
if (rvol>1.0) rvol=1.0;
|
||||
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]+=tw[i]*lvol;
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]+=tw[i]*rvol;
|
||||
}else{
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]+=tw[i];
|
||||
};
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void setfreq(int nvoice,REALTYPE freq);
|
||||
void setfreqFM(int nvoice,REALTYPE freq);
|
||||
void setfreq(int nvoice,REALTYPE in_freq);
|
||||
void setfreqFM(int nvoice,REALTYPE in_freq);
|
||||
void computecurrentparameters();
|
||||
void initparameters();
|
||||
void KillVoice(int nvoice);
|
||||
@@ -221,6 +221,9 @@ private:
|
||||
//the size of unison for a single voice
|
||||
int unison_size[NUM_VOICES];
|
||||
|
||||
//the stereo spread of the unison subvoices (0.0=mono,1.0=max)
|
||||
REALTYPE unison_stereo_spread[NUM_VOICES];
|
||||
|
||||
//fractional part (skip)
|
||||
REALTYPE *oscposlo[NUM_VOICES],*oscfreqlo[NUM_VOICES];
|
||||
|
||||
|
||||
@@ -548,31 +548,29 @@ voiceonbutton->redraw();} open
|
||||
code1 {char tmp[50]; for (int i=0;i<nvoice;i++) {sprintf(tmp,"Ext.%2d",i+1);o->add(tmp);};}
|
||||
code3 {o->value(pars->VoicePar[nvoice].Pextoscil+1);}
|
||||
} {}
|
||||
Fl_Group {} {
|
||||
label {Unison:} open
|
||||
xywh {5 525 520 45} box UP_FRAME labeltype ENGRAVED_LABEL labelsize 15 align 20
|
||||
Fl_Group {} {open
|
||||
xywh {5 525 475 45} box ENGRAVED_BOX
|
||||
} {
|
||||
Fl_Counter {} {
|
||||
label SIze
|
||||
callback {int k=(int) o->value();
|
||||
|
||||
pars->VoicePar[nvoice].Unison_size=k;}
|
||||
tooltip {Unison Size} xywh {85 540 50 20} type Simple labelsize 10 align 1 minimum 1 maximum 8 step 1 value 1 textfont 1 textsize 12
|
||||
code0 {int k=pars->VoicePar[nvoice].Unison_size;}
|
||||
code2 {o->value(k);}
|
||||
Fl_Dial {} {
|
||||
label Stereo
|
||||
callback {pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value();}
|
||||
tooltip {Stereo Spread} xywh {265 540 25 25} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1
|
||||
code0 {o->value(pars->VoicePar[nvoice].Unison_stereo_spread);}
|
||||
class WidgetPDial
|
||||
}
|
||||
Fl_Value_Slider {} {
|
||||
label {Frequency Spread}
|
||||
callback {pars->VoicePar[nvoice].Unison_frequency_spread=(int)o->value();}
|
||||
tooltip {Frequency Spread of the Unison} xywh {155 543 155 17} type {Horz Knob} box FLAT_BOX labelsize 11 align 5 maximum 127 step 1 value 64
|
||||
tooltip {Frequency Spread of the Unison} xywh {90 548 155 17} type {Horz Knob} box FLAT_BOX labelsize 11 align 5 maximum 127 step 1 value 64
|
||||
code0 {o->value(pars->VoicePar[nvoice].Unison_frequency_spread);}
|
||||
}
|
||||
Fl_Value_Slider {} {
|
||||
label {Stereo Spread}
|
||||
callback {pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value();}
|
||||
tooltip {Stereo Spread of the Unison} xywh {345 543 155 17} type {Horz Knob} box FLAT_BOX labelsize 11 align 5 maximum 127 step 1 value 100
|
||||
code0 {o->value(pars->VoicePar[nvoice].Unison_stereo_spread);}
|
||||
}
|
||||
Fl_Choice {} {
|
||||
label Unison
|
||||
callback {pars->set_unison_size_index(nvoice,(int) o->value());} open
|
||||
tooltip {Unison size} xywh {10 545 75 20} down_box BORDER_BOX labelfont 1 align 5 textfont 1 textsize 10
|
||||
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_Group {} {
|
||||
@@ -754,7 +752,8 @@ o->redraw();}
|
||||
pars=NULL;
|
||||
oscedit=NULL;} {}
|
||||
}
|
||||
Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} {
|
||||
Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {open
|
||||
} {
|
||||
code {pars=parameters;
|
||||
nvoice=nvoice_;
|
||||
master=master_;
|
||||
@@ -992,8 +991,8 @@ resui->resonancewindow->show();}
|
||||
}
|
||||
}
|
||||
Fl_Window ADnoteVoice {
|
||||
label {ADsynth Voice Parameters} selected
|
||||
xywh {53 58 765 620} type Double visible
|
||||
label {ADsynth Voice Parameters}
|
||||
xywh {152 271 765 620} type Double visible
|
||||
} {
|
||||
Fl_Group advoice {
|
||||
xywh {0 0 760 575} box BORDER_BOX
|
||||
@@ -1012,11 +1011,11 @@ resui->resonancewindow->show();}
|
||||
advoice->hide();
|
||||
ADnoteVoice->remove(advoice);
|
||||
delete advoice;
|
||||
advoice=new ADvoiceUI(0,0,765,525);
|
||||
advoice=new ADvoiceUI(0,0,765,585);
|
||||
ADnoteVoice->add(advoice);
|
||||
advoice->init(pars,nvoice,master);
|
||||
advoice->show();
|
||||
ADnoteVoice->redraw();}
|
||||
ADnoteVoice->redraw();} selected
|
||||
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