naive saw voice

This commit is contained in:
Gordon JC Pearce 2024-09-03 13:50:46 +01:00
parent ddcdf637fe
commit e48b252a1d
3 changed files with 67 additions and 27 deletions

View File

@ -69,10 +69,9 @@ void Chassis::noteOn(uint8_t note) {
uint32_t i;
for (i = 0; i < NUM_VOICES; i++) {
// printf("note on, finding free voice in %02x for %d\n", assign[i], note);
if (voice[i].state == V_OFF) { // top bit is voice free flag
voice[i].state = V_ON; // enable
voice[i].note = note;
printf("voice %d set to note %d\n", i, note);
if (voice[i].isFree()) { // top bit is voice free flag
voice[i].voiceOn(note);
//printf("voice %d set to note %d\n", i, note);
break;
}
}
@ -80,36 +79,38 @@ void Chassis::noteOn(uint8_t note) {
// Voice v = voice[0];
memmove(voice, voice + 1, sizeof(Voice) * (NUM_VOICES - 1)); // shunt all voices down by one
// lessvoice[NUM_VOICES - 1] = v; // oldest voice goes at the top of the queue
voice[NUM_VOICES - 1].note = note; // set note, assume state is still set
printf("no free voices, reused %d for note %d\n", 0, note);
voice[NUM_VOICES - 1].voiceOn(note); // FIXME distinguish between restarting reused note and stolen note
//printf("no free voices, note %d\n", 0, note);
}
/*
printf("note table is now\n");
for (i = 0; i < NUM_VOICES; i++) {
printf("%2d = %3d %01x\n", i, voice[i].note, voice[i].state);
printf("%2d = %3d %s\n", i, voice[i].note, voice[i].isFree()?"off":"on ");
}
printf("----------------------------\n");
*/
}
void Chassis::noteOff(uint8_t note) {
uint32_t v;
printf("note off called for %3d\n", note);
//printf("note off called for %3d\n", note);
printf("trying voice ");
//printf("trying voice ");
for (uint32_t i = 0; i < NUM_VOICES; i++) {
printf("%02x ", i);
//printf("%02x ", i);
if (voice[i].note == note && voice[i].state != V_OFF) {
printf("note off for %d playing %02x\n", i, note);
if (voice[i].note == note && !voice[i].isFree()) {
// printf("note off for %d playing %3d\n", i, note);
//memmove(voice + i, voice + i + 1, sizeof(Voice) * (NUM_VOICES - i));
voice[i].state = V_OFF;
voice[i].voiceOff();
break;
}
}
/*
printf("\n note table is now\n");
for (uint32_t i = 0; i < NUM_VOICES; i++) {
printf("%2d = %3d %01x\n", i, voice[i].note, voice[i].state);
}
printf("%2d = %3d %s\n", i, voice[i].note, voice[i].isFree()?"off":"on ");
}*/
}
void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *MidiEvents, uint32_t midiEventCount) {
@ -123,6 +124,14 @@ void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEv
noteOff(MidiEvents[i].data[1]);
}
}
// run each synth voice
bzero(outputs[0], sizeof(float)*frames);
for (uint8_t i = 0; i < NUM_VOICES; i++) {
voice[i].run(outputs[0], frames);
}
// copy left to right
memmove(outputs[1], outputs[0], sizeof(float)*frames);
}
// create the plugin

View File

@ -19,12 +19,11 @@
#ifndef _CHASSIS_HPP
#define _CHASSIS_HPP
#define NUM_VOICES 8
#define NUM_VOICES 4
#include "DistrhoPlugin.hpp"
#include "voice.hpp"
START_NAMESPACE_DISTRHO
class Chassis : public Plugin {
@ -65,7 +64,7 @@ class Chassis : public Plugin {
private:
Voice voice[NUM_VOICES];
//uint32_t
// uint32_t
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Chassis);
};

View File

@ -16,21 +16,53 @@
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _VOICE_HPP
#define _VOICE_HPP
#include <cstdint>
enum VoiceState {
V_OFF,
V_ON
};
class Voice {
public:
uint8_t note;
VoiceState state = V_OFF;
void voiceOn(uint32_t key) {
keyState = K_ON;
envState = ATTACK;
note = key;
omega = (261.63 * powf(2, (note - 60)/12.0f))/48000.0f;
target = 1;
}
void voiceOff() {
keyState = K_OFF;
envState = RELEASE;
target = 0;
}
inline bool isFree() {
return keyState == K_OFF;
}
void run(float *buffer, uint32_t samples) {
env = ((target - env)*0.01) + env;
for (uint32_t i = 0; i < samples; i++) {
phase += omega;
if (phase > 1) phase -= 1;
buffer[i] += (0.5-phase) * env;
}
}
private:
enum { ATTACK,
DECAY,
SUSTAIN,
RELEASE } envState = RELEASE;
enum { K_OFF,
K_ON,
K_SUSTAIN } keyState = K_OFF;
float phase, omega;
float env, target;
};
#endif // _VOICE_HPP
#endif // _VOICE_HPP