voice tuning correct

This commit is contained in:
Gordon JC Pearce 2024-10-15 22:10:57 +01:00
parent 5c1c79464e
commit e73914e4ae
2 changed files with 57 additions and 20 deletions

View File

@ -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;

View File

@ -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
void run(float *buffer, uint32_t samples);
void update();
void on(uint8_t note);
void off();
// private:
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);
};
class Synth {
@ -77,11 +85,11 @@ class Synth {
uint16_t masterPitch; // sum of bend and LFO, plus any other pitch-setting value
// 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];