(for javascript instrument synthesis, see https://old.reddit.com/r/bytebeat/comments/1vrigu2/synthesizing_instruments/ )
(for C++ output to *.sf2 file containing the instruments, see https://musical-artifacts.com/artifacts/7742 or https://www.polyphone.io/en/soundfonts/instrument-sets/926-synthetic-soundfont-2-0 )
C++ compatible instrument synthesis (floatbeat, 48000Hz):
#pragma comment(lib,"kernel32.lib")
#include <math.h>
#include <vector>
//const unsigned char j[12]={0,1,3,5,6,8,9,11,12,14,16,17,}; double jb=8.25; double je=19.;
//const unsigned char j[12]={0,2,5,8,10,13,15,18,20,23,26,28,}; double jb=8.25; double je=31.;
//const unsigned char j[12]={0,13,28,42,55,71,84,100,113,127,142,155,}; double jb=8.25; double je=171.;
const unsigned char j[12]={0,1,2,3,4,5,6,7,8,9,10,11,}; double jb=27.5*pow(2,-21/12.); double je=12.;
// adjust n for note frequency index
int n=12+12*4+(0x0&0xF);
double ff=pow(2,floor(n/12))*jb*pow(2,j[n-n/12*12]/je);
//double ff=pow(2,floor(n/19))*jb*pow(2,(n-n/19*19)/je);
std::vector<float> eg; long double od=1, ev=1, ex=-1, ea=0, eb=0, ef=-4, vo=1, ep=(sqrt(5.L)-1)/2, v=1, fs=1; int efb=9; int efm=511; bool fft=1;
std::vector<float> s;
int sr=48000;
static const char drumsamples[20] = {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,};
static const char drumpitches[20] = {-48,-36,-24,-12,-12,-24,-36,-48,-12,-12,-12,-8,-5,0,-12,-12,0,-24,0,0,};
static const char drumfades[20] = {9,10,11,12,8,7,6,5,9,11,13,7,7,6,5,3,4,10,12,9,};
static const char drummap[88-27] = {1,3,18,9,9,3,10,8,0,0,3,2,17,2,7,8,6,9,5,11,5,4,13,4,12,16,16,18,15,19,14,12,15,10,9,10,1,0,2,1,17,9,18,10,18,13,18,16,18,9,17,2,1,10,8,18,13,12,10,0,1,};
char instrumentmap[129]={
0,1,1,0,0,0,0,0,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,
6,
};
const long double tau = 6.283185307179586477l;
int bitcount(unsigned a){a=((a&0xAAAAAAAA)>>1)+(a&0x55555555);a=((a&0xCCCCCCCC)>>2)+(a&0x33333333);a=((a&0xF0F0F0F0)>>4)+(a&0x0F0F0F0F);a=((a&0xFF00FF00)>>8)+(a&0x00FF00FF);a=((a&0xFFFF0000)>>16)+(a&0x0000FFFF);return a;}
int log2int(unsigned a){a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;return bitcount(a)-1;}
bool initialized=0;
int __stdcall DllMain(void* hinstDLL, unsigned long fdwReason, unsigned long lpvReserved){
if(initialized) return 1;
bool drummode=0; //0=instrument, 1=drum
int i=0;
/*
instruments:
i=0: piano (1 4-8 97-112)
i=1: bright piano (2-3 33-40)
i=2: guitar (25-32)
i=3: square (81-88 120-128)
i=4: percussive (9-16 89-96 113-119)
i=5: organ (17-24 41-80)
drums:
i>=0&&i<20
*/
if(drummode){
int di=i; if(di<0||di>=sizeof drumsamples/sizeof*drumsamples) di=0;
fft=0; efb=11; int r=1; for(int j=0;j<1<<efb;j++) {s.push_back(((r&0xFFFF)-32768)/32768.); r^=r<<13; r^=r>>17; r^=r<<5;}
if(drumsamples[di]) {std::vector<float> t=s; for(int j=0;j<1<<efb;j++) s[j]=(t[j]+t[(j+1)&((1<<efb)-1)]*-2+t[(j+2)&((1<<efb)-1)])*0.25;}
ff=32000./2048*pow(2,drumpitches[di]/12.); ef=-pow(2.L,drumfades[di]*0.5L);
}
else{
if(i==0||i==1){
//parametric note ranges: 0-17, 18-23, 24-29, 30-35, 36-47, 48-59, 60-71, 72-83, 84-127
static const int eap[]={5,5,6,7,8,10,12,14,16,}; static const int ebp[]={9,9,9,9,8,8,8,8,8,};
static const int efp[]={-8,-7,-6,-5,-4,-2,0,2,4,};
int et=(n<12?0:n>=96?8:n<36?((n-12)/6|0):((n+12)/12|0));
ef=-4*pow(2,efp[et]/8.);
ex=-1; ea=eap[et]/-16.; efb=ebp[et];
if(i==1) {ea=4/-16.; efb=9;}
}
if(i==2) {ex=-1.5; efb=9; static const float egi[]={7,2.5,1.5,}; eg=std::vector<float>(egi,egi+sizeof egi/sizeof*egi);}
if(i==3) {fft=0; ev=0; ep*=0; ef=0; efb=10; for(int j=0;j<1<<efb;j++) s.push_back((j>>(efb-1))&1 ? -0.5 : 0.5);}
if(i==4) {ex=-2.75; eb=1; efb=9; static const float egi[]={3.25,1,-2,}; eg=std::vector<float>(egi,egi+sizeof egi/sizeof*egi);}
if(i==5) {ex=-1.75; ef=0; efb=9; static const float egi[]={2.5,1.5,1,7.5,2,-1,}; eg=std::vector<float>(egi,egi+sizeof egi/sizeof*egi);}
}
if(fft){
const int fftbits = efb;
const int fftsize = 1<<fftbits;
std::vector<float> costable(fftsize);
for(int i=0; i<fftsize; i++) costable[i]=cosl((long double)i/fftsize*tau);
std::vector<float> sintable(fftsize);
for(int i=0; i<fftsize; i++) sintable[i]=sinl((long double)i/fftsize*tau);
std::vector<float> fft1(fftsize), fft2(fftsize);
std::vector<float> tmp1(fftsize), tmp2(fftsize);
for(int i=1;i<=fftsize/2;i++){ //harmonic magnitude adjustment
int la=log2int(i*2-1); int lb=log2int(i);
long double a=pow(2.L,ea*la); long double b=pow(2.L,eb*lb); //ea, eb - octave roll off
long double z=1; for(int j=0;j<eg.size()/3;j++) z*=exp(-exp(-pow((i-eg[j*3+0])/eg[j*3+1],2))*eg[j*3+2]); //eg - fine tuning with gaussian function
long double p=(i&1?od:ev); //od, ev - odd/even harmonic control
fft2[i]=a*b*powl(i,ex)*z*p*vo; //ex - uniform roll off
}
for(int i=1;i<=fftsize/2;i++){ //harmonic phase adjustment
long double a=fft2[i]; int j=i; /*j/=(j^(j-1));*/ long double b=ep*(j*j-1); //ep - harmonic phase shift
fft2[i]=a*cos(b*tau); fft1[i]=a*sin(b*tau);
}
for(int i=1;i<fftsize/2;i++){ //finish fft frequency symmetry
fft2[i]*=0.25; fft2[fftsize-i]+=-fft2[i]; fft1[i]*=0.25; fft1[fftsize-i]+=fft1[i];
}
int pass = fftsize;
int dist = 1;
for(int i=0; i<fftbits; i++){
for(int counter=0; counter<dist; counter++){
for(int counter2=0; counter2<pass; counter2++){
tmp1[counter2]=fft1[counter2*dist+counter];
tmp2[counter2]=fft2[counter2*dist+counter];
}
for(int counter2=0; counter2<(pass>>1); counter2++){
float t1a=tmp1[counter2], t1b=tmp1[counter2+(pass>>1)];
float t2a=tmp2[counter2], t2b=tmp2[counter2+(pass>>1)];
float c=costable[dist*counter2], s=sintable[dist*counter2];
fft1[(counter2*2)*dist+counter] = t1a+t1b;
fft2[(counter2*2)*dist+counter] = t2a+t2b;
fft1[(counter2*2+1)*dist+counter] = (t1a*c+t2a*s)-(t1b*c+t2b*s);
fft2[(counter2*2+1)*dist+counter] = (t2a*c-t1a*s)-(t2b*c-t1b*s);
}
}
pass>>=1; dist<<=1;
}
s.swap(fft1);
}
v=pow(2, ef/sr);
fs=ff*s.size()/sr;
efm=s.size()-1;
return initialized=1;
}
long double o=0, w=1;
extern "C" __declspec(dllexport) float f(int t){
if(!t) w=1;
//o=w*s[(int)(t*fs)&efm];
//o=w*0.5*(s[(int)(t*fs)&efm]+s[(int)((t+0.5)*fs)&efm]);
o=w*0.25*(s[(int)(t*fs)&efm]+s[(int)((t+0.25)*fs)&efm]+s[(int)((t+0.5)*fs)&efm]+s[(int)((t+0.75)*fs)&efm]);
//o=w*(s[(int)(t*fs)&efm]*(1-((t*fs)%1))+(s[(int)(t*fs)+1&efm]*((t*fs)%1)));
w*=v; return o;
}