Browse Source

implement 'highest note wins' mono mode

master
Nils 9 months ago
parent
commit
b0b9c272ff
  1. 3
      TODO
  2. 3
      src/gui.c
  3. 42
      src/jackclient.c
  4. 4
      src/programstate.c
  5. 2
      src/programstate.h

3
TODO

@ -6,9 +6,6 @@ effect.
* Reintroduce the idea of wheel and key sfx. The code for that is currently commented out because
we never were able to record good sfx samples.
* Different Mono Modes: "Highest note wins" but remember what other keys are currently pressed and
fall back when highest not get's released. This can be done with lv2 midi plugins.
* One more autostart mode (radio buttons): Start with the first note on.
* General tuning, different to a' = 440Hz. It looks like the current tuning is hardcoded in the

3
src/gui.c

@ -270,6 +270,9 @@ void gui_process_eventloop() {
nk_layout_row_dynamic(ctx, v_spacing, 1);
programState.autoplayNeedsJackTransportRolling = nk_check_label(ctx, "Autoplay only with Jack Transport", (nk_bool)programState.autoplayNeedsJackTransportRolling);
nk_layout_row_dynamic(ctx, v_spacing, 1);
programState.highestNoteMonoMode = nk_check_label(ctx, "Highest Note Mode", (nk_bool)programState.highestNoteMonoMode);
}
nk_end(ctx);

42
src/jackclient.c

@ -66,6 +66,9 @@ int autoplayMelody_lastNote = -1; // -1 if no note is currently actively played.
bool autoplayDrone_lastState;
int autoplayDrone_lastNote;
int lastHighestNoteOn = -1;
bool noteOns[128] = {false};
jack_nframes_t lastSampleIndex=0;
/*The function called by JACK in it's own realtime thread.
@ -109,10 +112,45 @@ int process (jack_nframes_t frames, void* arg) {
uint8_t type = event.buffer[0] & 0xf0;
//uint8_t channel = event.buffer[0] & 0xf;
if (type == 0x90) {
instrument_setNoteOn(&instrument_melody, event.buffer[1]);
int pitch = event.buffer[1];
if (programState.highestNoteMonoMode) {
if (pitch > lastHighestNoteOn) {
instrument_setNoteOn(&instrument_melody, pitch);
lastHighestNoteOn = pitch;
}
noteOns[pitch] = true;
}
else { //simple mode
instrument_setNoteOn(&instrument_melody, pitch);
}
}
else if (type == 0x80) {
instrument_setNoteOff(&instrument_melody, event.buffer[1]);
int pitch = event.buffer[1];
if (programState.highestNoteMonoMode) {
noteOns[pitch] = false;
//Check if we have a new highest note
bool allOff = true;
for (int checkPitch=92; checkPitch>35; checkPitch--) { //we only play notes from 36 to 92
if (noteOns[checkPitch] == true) {
if (lastHighestNoteOn != checkPitch) {
instrument_setNoteOn(&instrument_melody, checkPitch);
lastHighestNoteOn = checkPitch;
}
allOff = false;
break;
}
}
if (allOff) {
lastHighestNoteOn = -1;
instrument_setNoteOff(&instrument_melody, pitch);
}
}
else { //simple mode
instrument_setNoteOff(&instrument_melody, pitch);
}
}
//Channel Aftertouch. 0 = no pressure, 127 = highest pressure.

4
src/programstate.c

@ -77,6 +77,8 @@ void initProgramState(bool nsm, const char * filePath, const char * programName,
pState->autoplayMelody_fallbackPitch = 62-12; // 0-127. Note d. Octave below the root note.
pState->droneRootMidiPitch = 62-12-12; // 0-127. Note d' two octaves lower.
pState->highestNoteMonoMode = false; //Highest Note wins
pState->wheelSpeedMelody = 0.5; //we got that value from the original project
pState->wheelSpeedDrone = 0.2; //we got that value from the original project
pState->aftertouchRaisesPitch = true;
@ -165,6 +167,7 @@ void loadStateFromFile() {
programState.forceMelody = (float)jRead_double(buffer, "{'forceMelody'", NULL);
programState.forceDrone = (float)jRead_double(buffer, "{'forceDrone'", NULL);
programState.highestNoteMonoMode = (bool)jRead_int(buffer, "{'highestNoteMonoMode'", NULL);
programState.autoplayNeedsJackTransportRolling = (bool)jRead_int(buffer, "{'autoplayNeedsJackTransportRolling'", NULL);
programState.autoplayMelody = (bool)jRead_int(buffer, "{'autoplayMelody'", NULL);
programState.autoplayDrone = (bool)jRead_int(buffer, "{'autoplayDrone'", NULL);
@ -221,6 +224,7 @@ void saveStateToFile() {
jwObj_double( "wheelSpeedMelody", (double)programState.wheelSpeedMelody );
jwObj_double( "wheelSpeedDrone", (double)programState.wheelSpeedDrone );
jwObj_int( "aftertouchRaisesPitch", (int)programState.aftertouchRaisesPitch );
jwObj_int( "highestNoteMonoMode", (int)programState.highestNoteMonoMode );
jwObj_int( "autoplayNeedsJackTransportRolling", (int)programState.autoplayNeedsJackTransportRolling );
jwObj_int( "autoplayMelody", (int)programState.autoplayMelody );
jwObj_int( "autoplayDrone", (int)programState.autoplayDrone );

2
src/programstate.h

@ -56,6 +56,8 @@ typedef struct {
int autoplayMelody_fallbackPitch; //0-127
int droneRootMidiPitch; //0-127
bool highestNoteMonoMode; //Highest Note wins
float wheelSpeedMelody;
float wheelSpeedDrone;
bool aftertouchRaisesPitch;

Loading…
Cancel
Save