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;
|
uint32_t i;
|
||||||
for (i = 0; i < NUM_VOICES; i++) {
|
for (i = 0; i < NUM_VOICES; i++) {
|
||||||
// printf("note on, finding free voice in %02x for %d\n", assign[i], note);
|
// 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
|
if (voice[i].isFree()) { // top bit is voice free flag
|
||||||
voice[i].state = V_ON; // enable
|
voice[i].voiceOn(note);
|
||||||
voice[i].note = note;
|
//printf("voice %d set to note %d\n", i, note);
|
||||||
printf("voice %d set to note %d\n", i, note);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,36 +79,38 @@ void Chassis::noteOn(uint8_t note) {
|
|||||||
// Voice v = voice[0];
|
// Voice v = voice[0];
|
||||||
memmove(voice, voice + 1, sizeof(Voice) * (NUM_VOICES - 1)); // shunt all voices down by one
|
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
|
// 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
|
voice[NUM_VOICES - 1].voiceOn(note); // FIXME distinguish between restarting reused note and stolen note
|
||||||
printf("no free voices, reused %d for note %d\n", 0, note);
|
//printf("no free voices, note %d\n", 0, note);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
printf("note table is now\n");
|
printf("note table is now\n");
|
||||||
for (i = 0; i < NUM_VOICES; i++) {
|
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");
|
printf("----------------------------\n");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chassis::noteOff(uint8_t note) {
|
void Chassis::noteOff(uint8_t note) {
|
||||||
uint32_t v;
|
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++) {
|
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) {
|
if (voice[i].note == note && !voice[i].isFree()) {
|
||||||
printf("note off for %d playing %02x\n", i, note);
|
// printf("note off for %d playing %3d\n", i, note);
|
||||||
//memmove(voice + i, voice + i + 1, sizeof(Voice) * (NUM_VOICES - i));
|
//memmove(voice + i, voice + i + 1, sizeof(Voice) * (NUM_VOICES - i));
|
||||||
voice[i].state = V_OFF;
|
voice[i].voiceOff();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
printf("\n note table is now\n");
|
printf("\n note table is now\n");
|
||||||
for (uint32_t i = 0; i < NUM_VOICES; i++) {
|
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) {
|
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]);
|
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
|
// create the plugin
|
||||||
|
@ -19,12 +19,11 @@
|
|||||||
#ifndef _CHASSIS_HPP
|
#ifndef _CHASSIS_HPP
|
||||||
#define _CHASSIS_HPP
|
#define _CHASSIS_HPP
|
||||||
|
|
||||||
#define NUM_VOICES 8
|
#define NUM_VOICES 4
|
||||||
|
|
||||||
#include "DistrhoPlugin.hpp"
|
#include "DistrhoPlugin.hpp"
|
||||||
#include "voice.hpp"
|
#include "voice.hpp"
|
||||||
|
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
class Chassis : public Plugin {
|
class Chassis : public Plugin {
|
||||||
@ -65,7 +64,7 @@ class Chassis : public Plugin {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Voice voice[NUM_VOICES];
|
Voice voice[NUM_VOICES];
|
||||||
//uint32_t
|
// uint32_t
|
||||||
|
|
||||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Chassis);
|
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Chassis);
|
||||||
};
|
};
|
||||||
|
@ -16,21 +16,53 @@
|
|||||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VOICE_HPP
|
#ifndef _VOICE_HPP
|
||||||
#define _VOICE_HPP
|
#define _VOICE_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
enum VoiceState {
|
|
||||||
V_OFF,
|
|
||||||
V_ON
|
|
||||||
};
|
|
||||||
|
|
||||||
class Voice {
|
class Voice {
|
||||||
public:
|
public:
|
||||||
uint8_t note;
|
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