voice tuning correct
This commit is contained in:
parent
5c1c79464e
commit
e73914e4ae
@ -30,7 +30,10 @@ Synth::Synth() {
|
||||
|
||||
void Synth::buildTables(double sampleRate) {
|
||||
for (uint8_t i = 0; i < 104; i++) {
|
||||
pitchTable[i] = 440.0f * powf(2, (i - 45) / 12.0f) / sampleRate;
|
||||
// slightly flat middle C from ROM divider table
|
||||
// actually adjusted a little so that the notes are bang on
|
||||
// on the real synth the tuning knob is tweaked a little off to pull it in
|
||||
pitchTable[i] = 260.15f * powf(2, (i - 36) / 12.0f) / sampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,25 +42,22 @@ void Synth::run() {
|
||||
// callled once every 4.3ms block of samples
|
||||
|
||||
for (uint8_t i = 0; i < NUM_VOICES; i++) {
|
||||
ic29.voices[i].env.run();
|
||||
ic29.voices[i].calcPitch();
|
||||
ic29.voices[i].update();
|
||||
}
|
||||
}
|
||||
|
||||
void Synth::voiceOn(uint8_t voice, uint8_t note) {
|
||||
// enable synth voice, start it all running
|
||||
voice &= 0x7f;
|
||||
ic29.voices[voice].env.on();
|
||||
|
||||
// FIXME determine if we need to reset the counter
|
||||
ic29.voices[voice].note = note;
|
||||
ic29.voices[voice].on(note);
|
||||
}
|
||||
|
||||
void Synth::voiceOff(uint8_t voice) {
|
||||
// enable synth voice, start it all running
|
||||
voice &= 0x7f;
|
||||
ic29.voices[voice].env.off();
|
||||
ic29.voices[voice].off();
|
||||
}
|
||||
|
||||
void Synth::basePitch() {
|
||||
uint16_t pitch = 0x1818;
|
||||
|
||||
@ -104,7 +104,7 @@ Voice::Voice() {
|
||||
}
|
||||
|
||||
void Voice::calcPitch() {
|
||||
uint16_t target = (note - 24) << 8;
|
||||
uint16_t target = note << 8;
|
||||
|
||||
if (ic29.portaCoeff != 0) {
|
||||
// porta up
|
||||
@ -121,6 +121,14 @@ void Voice::calcPitch() {
|
||||
pitch = target;
|
||||
}
|
||||
|
||||
pitch += 0x1818; //ic29.masterPitch;
|
||||
|
||||
if (pitch < 0x3000) pitch = 0x3000; // lowest note
|
||||
if (pitch > 0x9700) pitch = 0x6700; // highest note
|
||||
|
||||
pitch -= 0x3000;
|
||||
//pitch &= 0xff00;
|
||||
|
||||
double o1 = ic29.pitchTable[pitch >> 8];
|
||||
double o2 = ic29.pitchTable[(pitch >> 8) + 1];
|
||||
double frac = (pitch & 0xff) / 255.0;
|
||||
@ -128,6 +136,27 @@ void Voice::calcPitch() {
|
||||
omega = ((o2 - o1) * frac) + o1;
|
||||
}
|
||||
|
||||
void Voice::update() {
|
||||
// calculate the once-per-block values
|
||||
env.run();
|
||||
calcPitch();
|
||||
// do filter values
|
||||
}
|
||||
|
||||
void Voice::on(uint8_t key) {
|
||||
voiceState = V_ON;
|
||||
note = key;
|
||||
env.on();
|
||||
}
|
||||
|
||||
void Voice::off() {
|
||||
// I need to rethink this bit FIXME
|
||||
voiceState = V_OFF;
|
||||
if (!ic29.sustained) {
|
||||
env.off();
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::run(float *buffer, uint32_t samples) {
|
||||
float gain = env.level / 16384.0;
|
||||
gain *= 0.125;
|
||||
|
@ -31,6 +31,11 @@ class Envelope {
|
||||
void off() {
|
||||
phase = ENV_RLS;
|
||||
}
|
||||
|
||||
bool inRelease() {
|
||||
return phase == ENV_RLS;
|
||||
}
|
||||
|
||||
uint16_t level;
|
||||
|
||||
// private:
|
||||
@ -45,18 +50,21 @@ class Envelope {
|
||||
class Voice {
|
||||
public:
|
||||
Voice();
|
||||
void run();
|
||||
uint8_t note = 0x3c; // middle C
|
||||
uint8_t note = 0x3c; // middle C
|
||||
void run(float *buffer, uint32_t samples);
|
||||
void update();
|
||||
void on(uint8_t note);
|
||||
void off();
|
||||
|
||||
// private:
|
||||
Envelope env; // calculated envelope value
|
||||
private:
|
||||
Envelope env; // calculated envelope value
|
||||
uint16_t pitch = 0x1818; // calculated pitch value with porta and master pitch etc
|
||||
float phase=0, omega=0;
|
||||
float phase = 0, omega = 0;
|
||||
enum { V_DONE,
|
||||
V_OFF,
|
||||
V_ON } voiceState;
|
||||
void calcPitch();
|
||||
void run(float *buffer, uint32_t samples);
|
||||
|
||||
void calcPitch();
|
||||
};
|
||||
|
||||
class Synth {
|
||||
@ -75,13 +83,13 @@ class Synth {
|
||||
|
||||
double sampleRate;
|
||||
uint16_t masterPitch; // sum of bend and LFO, plus any other pitch-setting value
|
||||
// protected:
|
||||
// protected:
|
||||
uint16_t envAtk, envDcy, envStn, envRls;
|
||||
int16_t portaCoeff;
|
||||
int8_t portaCoeff;
|
||||
bool sustained;
|
||||
double pitchTable[104];
|
||||
|
||||
|
||||
//private:
|
||||
// private:
|
||||
int16_t lfoPitch;
|
||||
int16_t bendPitch;
|
||||
Voice voices[NUM_VOICES];
|
||||
|
Loading…
Reference in New Issue
Block a user