naive saw voice
This commit is contained in:
parent
ddcdf637fe
commit
e48b252a1d
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user