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) { void Synth::buildTables(double sampleRate) {
for (uint8_t i = 0; i < 104; i++) { 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 // callled once every 4.3ms block of samples
for (uint8_t i = 0; i < NUM_VOICES; i++) { for (uint8_t i = 0; i < NUM_VOICES; i++) {
ic29.voices[i].env.run(); ic29.voices[i].update();
ic29.voices[i].calcPitch();
} }
} }
void Synth::voiceOn(uint8_t voice, uint8_t note) { void Synth::voiceOn(uint8_t voice, uint8_t note) {
// enable synth voice, start it all running // enable synth voice, start it all running
voice &= 0x7f; voice &= 0x7f;
ic29.voices[voice].env.on(); ic29.voices[voice].on(note);
// FIXME determine if we need to reset the counter
ic29.voices[voice].note = note;
} }
void Synth::voiceOff(uint8_t voice) { void Synth::voiceOff(uint8_t voice) {
// enable synth voice, start it all running // enable synth voice, start it all running
voice &= 0x7f; voice &= 0x7f;
ic29.voices[voice].env.off(); ic29.voices[voice].off();
} }
void Synth::basePitch() { void Synth::basePitch() {
uint16_t pitch = 0x1818; uint16_t pitch = 0x1818;
@ -104,7 +104,7 @@ Voice::Voice() {
} }
void Voice::calcPitch() { void Voice::calcPitch() {
uint16_t target = (note - 24) << 8; uint16_t target = note << 8;
if (ic29.portaCoeff != 0) { if (ic29.portaCoeff != 0) {
// porta up // porta up
@ -121,6 +121,14 @@ void Voice::calcPitch() {
pitch = target; 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 o1 = ic29.pitchTable[pitch >> 8];
double o2 = ic29.pitchTable[(pitch >> 8) + 1]; double o2 = ic29.pitchTable[(pitch >> 8) + 1];
double frac = (pitch & 0xff) / 255.0; double frac = (pitch & 0xff) / 255.0;
@ -128,6 +136,27 @@ void Voice::calcPitch() {
omega = ((o2 - o1) * frac) + o1; 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) { void Voice::run(float *buffer, uint32_t samples) {
float gain = env.level / 16384.0; float gain = env.level / 16384.0;
gain *= 0.125; gain *= 0.125;

View File

@ -31,6 +31,11 @@ class Envelope {
void off() { void off() {
phase = ENV_RLS; phase = ENV_RLS;
} }
bool inRelease() {
return phase == ENV_RLS;
}
uint16_t level; uint16_t level;
// private: // private:
@ -45,18 +50,21 @@ class Envelope {
class Voice { class Voice {
public: public:
Voice(); 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: private:
Envelope env; // calculated envelope value Envelope env; // calculated envelope value
uint16_t pitch = 0x1818; // calculated pitch value with porta and master pitch etc 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, enum { V_DONE,
V_OFF, V_OFF,
V_ON } voiceState; V_ON } voiceState;
void calcPitch();
void run(float *buffer, uint32_t samples); void calcPitch();
}; };
class Synth { class Synth {
@ -75,13 +83,13 @@ class Synth {
double sampleRate; double sampleRate;
uint16_t masterPitch; // sum of bend and LFO, plus any other pitch-setting value uint16_t masterPitch; // sum of bend and LFO, plus any other pitch-setting value
// protected: // protected:
uint16_t envAtk, envDcy, envStn, envRls; uint16_t envAtk, envDcy, envStn, envRls;
int16_t portaCoeff; int8_t portaCoeff;
bool sustained;
double pitchTable[104]; double pitchTable[104];
// private:
//private:
int16_t lfoPitch; int16_t lfoPitch;
int16_t bendPitch; int16_t bendPitch;
Voice voices[NUM_VOICES]; Voice voices[NUM_VOICES];