Analog synthesis engine for Klang Modular
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

107 lines
2.6 KiB

#ifndef __FM_H__
#define __FM_H__
#include <array>
#include "../util.h"
class FM {
private:
float phase1 = randPhase(), phase2 = randPhase(), phase3 = randPhase(), phase4 = randPhase(), phase5 = randPhase(), phase6 = randPhase();
float fb1 = 0.f, fb2 = 0.f;
public:
struct Settings {
struct {
float pitch;
float level;
} ops[6];
};
Settings settings;
float tick(float pitch, float fmEnv) {
float step3 = cvToStep(pitch);
float step2 = cvToStep(pitch + 3.807354922057604f); // Frequency Coarse = 14
float step1 = cvToStep(pitch + 0.007195501404204f); // Detune = +7
float step6 = cvToStep(pitch);
float step5 = cvToStep(pitch - 0.007231569231076f); // Detune = -7
float step4 = cvToStep(pitch);
float osc3 = fmEnv * 0.333f * sinf(phase3);
float osc2 = fmEnv * 0.333f * sinf(phase2 + (float) M_PI * osc3);
float osc1 = sinf(phase1 + (float) M_PI * osc2);
float osc6 = fmEnv * 1.0f * sinf(phase6 + 0.0f * (float) M_PI * (fb1 + fb2));
float osc5 = fmEnv * 1.0f * sinf(phase5 + (float) M_PI * osc6);
float osc4 = sinf(phase4 + (float) M_PI * osc5);
fb2 = fb1;
fb1 = osc4;
phase1 += step1;
if(phase1 >= (float) PIx2) {
phase1 -= PIx2;
}
phase2 += step2;
if(phase2 >= (float) PIx2) {
phase2 -= PIx2;
}
phase3 += step3;
if(phase3 >= (float) PIx2) {
phase3 -= PIx2;
}
phase4 += step4;
if(phase4 >= (float) PIx2) {
phase4 -= PIx2;
}
phase5 += step5;
if(phase5 >= (float) PIx2) {
phase5 -= PIx2;
}
phase6 += step6;
if(phase6 >= (float) PIx2) {
phase6 -= PIx2;
}
return osc1 + osc4;
}
};
/*
op6.detune 14
op6.output_level 79
op6.frequency_coarse 1
op5.detune 0
op5.output_level 99
op5.frequency_coarse 1
op4.detune 7
op4.output_level 89
op4.frequency_coarse 1
op3.detune 7
op3.output_level 99
op3.frequency_coarse 1
op2.detune 7
op2.output_level 58
op2.frequency_coarse 14
op1.detune 10
op1.output_level 99
op1.frequency_coarse 1
algorithm 4
feedback 6 [0..7]
RANGES
opx.output_level [0, 99]
opX.frequency_coarse [0, 31] 0.50 - 31.00 X
op6.frequency_fine [0, 99] 1.00 - 1.99 X
opX.detune [0, 14] [-7, +7]
feedback [0, 7]
*/
#endif