Unison improvements

(cherry picked from commit 35418bd30b28a1eb5bd842f277a4cc0bfeeb44d5)
This commit is contained in:
Paul
2009-10-01 23:51:47 +03:00
committed by Tobias Doerffel
parent 5eac2629bb
commit c8c6ed648c
5 changed files with 54 additions and 28 deletions

View File

@@ -936,4 +936,10 @@
fields
29 Sep 2009 (Paul Nasca)
- Remove the old (FFT based) Bandwidth effect to Reverb and started rewrite it (based on multivoice chorus/unison effect)
01 Oct 2009 (Paul Nasca)
- Corrected the ADsynth unison LFO rounding function
- Made Unison based on Bandwidth (in cents) parameter

View File

@@ -30,6 +30,7 @@ Unison::Unison(int update_period_samples_,REALTYPE max_delay_sec_){
delay_buffer=new REALTYPE[max_delay];
delay_k=0;
base_freq=1.0;
unison_bandwidth_cents=10.0;
ZERO_REALTYPE(delay_buffer,max_delay);
@@ -60,21 +61,35 @@ void Unison::set_base_frequency(REALTYPE freq){
update_parameters();
};
void Unison::set_bandwidth(REALTYPE bandwidth){
if (bandwidth<0) bandwidth=0.0;
if (bandwidth>1200.0) bandwidth=1200.0;
printf("bandwidth %g\n",bandwidth);
#warning: todo: if bandwidth is too small the audio will be self canceled (because of the sign change of the outputs)
unison_bandwidth_cents=bandwidth;
update_parameters();
};
void Unison::update_parameters(){
if (!uv) return;
REALTYPE increments_per_second=SAMPLE_RATE/(REALTYPE) update_period_samples;
printf("#%g, %g\n",increments_per_second,base_freq);
// printf("#%g, %g\n",increments_per_second,base_freq);
for (int i=0;i<unison_size;i++){
REALTYPE period=pow(2.0,RND*2.0-1.0)/base_freq;
REALTYPE base=pow(UNISON_FREQ_SPAN,RND*2.0-1.0);
uv[i].relative_amplitude=base;
REALTYPE period=base/base_freq;
REALTYPE m=4.0/(period*increments_per_second);
if (RND<0.5) m=-m;
uv[i].step=m;
printf("%g %g\n",period,m);
// printf("%g %g\n",uv[i].relative_amplitude,period);
};
#warning compute unison_amplitude_samples in functie de centi
unison_amplitude_samples=200.0;
REALTYPE max_speed=pow(2.0,unison_bandwidth_cents/1200.0);
unison_amplitude_samples=0.125*(max_speed-1.0)*SAMPLE_RATE/base_freq;
printf("unison_amplitude_samples %g\n",unison_amplitude_samples);
#warning todo: test if unison_amplitude_samples is to big and reallocate bigger memory
if (unison_amplitude_samples>=max_delay-1) unison_amplitude_samples=max_delay-2;
update_unison_data();
@@ -130,8 +145,10 @@ void Unison::update_unison_data(){
pos=1.0;
step=-step;
};
REALTYPE vibratto_val=pos-0.35*pos*pos*pos;//make the vibratto lfo smoother
REALTYPE newval=1.0+0.5*(vibratto_val+1.0)*unison_amplitude_samples;
REALTYPE vibratto_val=(pos-0.333333333*pos*pos*pos)*1.5;//make the vibratto lfo smoother
#warning I will use relative amplitude, so the delay might be bigger than the whole buffer
#warning I have to enlarge (reallocate) the buffer to make place for the whole delay
REALTYPE newval=1.0+0.5*(vibratto_val+1.0)*unison_amplitude_samples*uv[k].relative_amplitude;
if (first_time){
uv[k].realpos1=uv[k].realpos2=newval;

View File

@@ -24,6 +24,8 @@
#include <stdlib.h>
#include "../globals.h"
#define UNISON_FREQ_SPAN 2.0
//how much the unison frequencies varies (always >= 1.0)
class Unison{
public:
@@ -32,8 +34,7 @@ class Unison{
void set_size(int new_size);
void set_base_frequency(REALTYPE freq);
void set_bandwidth(REALTYPE bandwidth_cents){
};
void set_bandwidth(REALTYPE bandwidth_cents);
void process(int bufsize,REALTYPE *inbuf,REALTYPE *outbuf=NULL);
@@ -46,14 +47,14 @@ class Unison{
struct UnisonVoice{
REALTYPE step,position;//base LFO
REALTYPE realpos1,realpos2; //the position regarding samples
int lin_ipos,lin_ifreq;
//#error sa calculez frecventa si pozitia a.i. la inceput sa fie realpos1 si la final sa fie realpos2
REALTYPE relative_amplitude;
REALTYPE lin_fpos,lin_ffreq;
UnisonVoice(){
position=RND*1.8-0.9;
realpos1=0.0;
realpos2=0.0;
step=0.0;
relative_amplitude=1.0;
};
}*uv;
int update_period_samples,update_period_sample_k;
@@ -61,6 +62,7 @@ class Unison{
bool first_time;
REALTYPE *delay_buffer;
REALTYPE unison_amplitude_samples;
REALTYPE unison_bandwidth_cents;
};
#endif

View File

@@ -353,7 +353,7 @@ void Reverb::settype(unsigned char Ptype)
if (bandwidth) delete bandwidth;
bandwidth=NULL;
if (Ptype==2){//bandwidth
bandwidth=new Unison(SOUND_BUFFER_SIZE/4+1,0.5);
bandwidth=new Unison(SOUND_BUFFER_SIZE/4+1,2.0);
bandwidth->set_size(50);
bandwidth->set_base_frequency(1.0);
#warning sa schimb size-ul
@@ -373,7 +373,8 @@ void Reverb::setroomsize(const unsigned char &Proomsize)
void Reverb::setbandwidth(const unsigned char &Pbandwidth){
this->Pbandwidth=Pbandwidth;
if (bandwidth) bandwidth->set_bandwidth(Pbandwidth/127.0*200.0);
REALTYPE v=Pbandwidth/127.0;
if (bandwidth) bandwidth->set_bandwidth(pow(v,2.0)*200.0);
};
void Reverb::setpreset(unsigned char npreset)
@@ -382,31 +383,31 @@ void Reverb::setpreset(unsigned char npreset)
const int NUM_PRESETS=13;
unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
//Cathedral1
{80,64,63,24,0,0,0,85,5,83,1,64,0},
{80,64,63,24,0,0,0,85,5,83,1,64,20},
//Cathedral2
{80,64,69,35,0,0,0,127,0,71,0,64,0},
{80,64,69,35,0,0,0,127,0,71,0,64,20},
//Cathedral3
{80,64,69,24,0,0,0,127,75,78,1,85,0},
{80,64,69,24,0,0,0,127,75,78,1,85,20},
//Hall1
{90,64,51,10,0,0,0,127,21,78,1,64,0},
{90,64,51,10,0,0,0,127,21,78,1,64,20},
//Hall2
{90,64,53,20,0,0,0,127,75,71,1,64,0},
{90,64,53,20,0,0,0,127,75,71,1,64,20},
//Room1
{100,64,33,0,0,0,0,127,0,106,0,30,0},
{100,64,33,0,0,0,0,127,0,106,0,30,20},
//Room2
{100,64,21,26,0,0,0,62,0,77,1,45,0},
{100,64,21,26,0,0,0,62,0,77,1,45,20},
//Basement
{110,64,14,0,0,0,0,127,5,71,0,25,0},
{110,64,14,0,0,0,0,127,5,71,0,25,20},
//Tunnel
{85,80,84,20,42,0,0,51,0,78,1,105,0},
{85,80,84,20,42,0,0,51,0,78,1,105,20},
//Echoed1
{95,64,26,60,71,0,0,114,0,64,1,64,0},
{95,64,26,60,71,0,0,114,0,64,1,64,20},
//Echoed2
{90,64,40,88,71,0,0,114,0,88,1,64,0},
{90,64,40,88,71,0,0,114,0,88,1,64,20},
//VeryLong1
{90,64,93,15,0,0,0,114,0,77,0,95,0},
{90,64,93,15,0,0,0,114,0,77,0,95,20},
//VeryLong2
{90,64,111,30,0,0,0,114,90,74,1,80,0}
{90,64,111,30,0,0,0,114,90,74,1,80,20}
};
if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;

View File

@@ -787,7 +787,7 @@ void ADnote::compute_unison_freq_rap(int nvoice){
pos=1.0;
step=-step;
};
REALTYPE vibratto_val=pos-0.3*pos*pos*pos;//make the vibratto lfo smoother
REALTYPE vibratto_val=(pos-0.333333333*pos*pos*pos)*1.5;//make the vibratto lfo smoother
unison_freq_rap[nvoice][k]=1.0+((unison_base_freq_rap[nvoice][k]-1.0)+vibratto_val*unison_vibratto[nvoice].amplitude)*relbw;
unison_vibratto[nvoice].position[k]=pos;