|
|
|
@ -824,7 +824,7 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { |
|
|
|
|
//
|
|
|
|
|
// MIDI learn mode
|
|
|
|
|
//
|
|
|
|
|
if (midi_learn_mode != MIDI_LEARN_MODE_OFF) { |
|
|
|
|
if (midi_learn_mode > MIDI_LEARN_MODE_OFF) { |
|
|
|
|
int8_t tmp_channel = handle_midi_learn(inNumber); |
|
|
|
|
if (tmp_channel >= 0) |
|
|
|
|
inChannel = tmp_channel; |
|
|
|
@ -890,19 +890,22 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { |
|
|
|
|
if (drum_counter >= NUM_DRUMS) |
|
|
|
|
drum_counter = 0; |
|
|
|
|
|
|
|
|
|
if (!(midi_learn_mode & 0x80)) { |
|
|
|
|
if (midi_learn_mode > MIDI_LEARN_MODE_OFF) { |
|
|
|
|
inNumber = configuration.drums.midinote[active_sample]; |
|
|
|
|
} else { |
|
|
|
|
inNumber = midi_learn_mode & 0x7f; |
|
|
|
|
midi_learn_mode = MIDI_LEARN_MODE_DRUM_NOTE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
char note_name[4]; |
|
|
|
|
getNoteName(note_name, inNumber); |
|
|
|
|
if (midi_learn_mode > MIDI_LEARN_MODE_OFF) { |
|
|
|
|
if (midi_learn_mode & 0x80) |
|
|
|
|
Serial.printf_P(PSTR("MIDI LEARN MODE DRUM (%s) for note (%s)\n"), byte_to_binary(midi_learn_mode), note_name); |
|
|
|
|
else |
|
|
|
|
Serial.printf_P(PSTR("MIDI LEARN MODE NOTE (%s) for note (%s)\n"), byte_to_binary(midi_learn_mode), note_name); |
|
|
|
|
} |
|
|
|
|
Serial.print(F("Triggring Drum[")); |
|
|
|
|
Serial.print(drum_counter, DEC); |
|
|
|
|
Serial.print(F("]: with note ")); |
|
|
|
|
Serial.print(F("] with note ")); |
|
|
|
|
Serial.print(note_name); |
|
|
|
|
Serial.print(F("/")); |
|
|
|
|
Serial.println(inNumber, DEC); |
|
|
|
@ -918,43 +921,45 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t slot = drum_get_slot(drum_config[use_drum].drum_class); |
|
|
|
|
float pan = mapfloat(configuration.drums.pan[use_drum], DRUMS_PANORAMA_MIN, DRUMS_PANORAMA_MAX, 0.0, 1.0); |
|
|
|
|
float reverb_send = configuration.drums.reverb_send[use_drum] / 100.0f; |
|
|
|
|
float vol_min = configuration.drums.vol_min[use_drum] / 100.0f; |
|
|
|
|
float vol_max = configuration.drums.vol_max[use_drum] / 100.0f; |
|
|
|
|
|
|
|
|
|
drum_mixer_r.gain(slot, pan * volume_transform(mapfloat(inVelocity, 0, 127, vol_min, vol_max))); |
|
|
|
|
drum_mixer_l.gain(slot, (1.0 - pan) * volume_transform(mapfloat(inVelocity, 0, 127, vol_min, vol_max))); |
|
|
|
|
|
|
|
|
|
drum_reverb_send_mixer_r.gain(slot, pan * volume_transform(reverb_send)); |
|
|
|
|
drum_reverb_send_mixer_l.gain(slot, (1.0 - pan) * volume_transform(reverb_send)); |
|
|
|
|
|
|
|
|
|
if (drum_config[use_drum].drum_data != NULL && drum_config[use_drum].len > 0) { |
|
|
|
|
if (configuration.drums.pitch[use_drum] != 0) { |
|
|
|
|
Drum[slot]->enableInterpolation(true); |
|
|
|
|
Drum[slot]->setPlaybackRate(pow(2, float(configuration.drums.pitch[use_drum]) / 120.0)); |
|
|
|
|
} else { |
|
|
|
|
Drum[slot]->enableInterpolation(false); |
|
|
|
|
Drum[slot]->setPlaybackRate(1.0); |
|
|
|
|
} |
|
|
|
|
Drum[slot]->playRaw((int16_t*)drum_config[use_drum].drum_data, drum_config[use_drum].len, 1); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.printf(PSTR("Playing sample [%s][%c%c] on slot [%d] main volume [%d]: drum_data=%p, len=%d\n"), drum_config[use_drum].name, slot, configuration.drums.main_vol, drum_config[use_drum].drum_data, drum_config[use_drum].len); |
|
|
|
|
|
|
|
|
|
Serial.print(F("Drum Slot [")); |
|
|
|
|
Serial.print(slot); |
|
|
|
|
Serial.print(F("]: Velocity=")); |
|
|
|
|
Serial.print(mapfloat(inVelocity, 0, 127, vol_min, vol_max), 2); |
|
|
|
|
Serial.print(F(" Pan=")); |
|
|
|
|
Serial.print(pan, 2); |
|
|
|
|
Serial.print(F(" ReverbSend=")); |
|
|
|
|
Serial.print(reverb_send, 2); |
|
|
|
|
Serial.print(F(" Pitch=")); |
|
|
|
|
Serial.print(configuration.drums.pitch[use_drum] / 10.0f, 1); |
|
|
|
|
Serial.print(F(" Playback speed=")); |
|
|
|
|
Serial.println(pow(2, float(configuration.drums.pitch[use_drum]) / 120.0)); |
|
|
|
|
if (drum_config[use_drum].midinote > 0) { |
|
|
|
|
uint8_t slot = drum_get_slot(drum_config[use_drum].drum_class); |
|
|
|
|
float pan = mapfloat(configuration.drums.pan[use_drum], DRUMS_PANORAMA_MIN, DRUMS_PANORAMA_MAX, 0.0, 1.0); |
|
|
|
|
float reverb_send = configuration.drums.reverb_send[use_drum] / 100.0f; |
|
|
|
|
float vol_min = configuration.drums.vol_min[use_drum] / 100.0f; |
|
|
|
|
float vol_max = configuration.drums.vol_max[use_drum] / 100.0f; |
|
|
|
|
|
|
|
|
|
drum_mixer_r.gain(slot, pan * volume_transform(mapfloat(inVelocity, 0, 127, vol_min, vol_max))); |
|
|
|
|
drum_mixer_l.gain(slot, (1.0 - pan) * volume_transform(mapfloat(inVelocity, 0, 127, vol_min, vol_max))); |
|
|
|
|
|
|
|
|
|
drum_reverb_send_mixer_r.gain(slot, pan * volume_transform(reverb_send)); |
|
|
|
|
drum_reverb_send_mixer_l.gain(slot, (1.0 - pan) * volume_transform(reverb_send)); |
|
|
|
|
|
|
|
|
|
if (drum_config[use_drum].drum_data != NULL && drum_config[use_drum].len > 0) { |
|
|
|
|
if (configuration.drums.pitch[use_drum] != 0) { |
|
|
|
|
Drum[slot]->enableInterpolation(true); |
|
|
|
|
Drum[slot]->setPlaybackRate(pow(2, float(configuration.drums.pitch[use_drum]) / 120.0)); |
|
|
|
|
} else { |
|
|
|
|
Drum[slot]->enableInterpolation(false); |
|
|
|
|
Drum[slot]->setPlaybackRate(1.0); |
|
|
|
|
} |
|
|
|
|
Drum[slot]->playRaw((int16_t*)drum_config[use_drum].drum_data, drum_config[use_drum].len, 1); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.printf_P(PSTR("Playing sample [%s] on slot [%d] main volume [%d]: drum_data=%p, len=%d\n"), drum_config[use_drum].name, slot, configuration.drums.main_vol, drum_config[use_drum].drum_data, drum_config[use_drum].len); |
|
|
|
|
|
|
|
|
|
Serial.print(F("Drum Slot [")); |
|
|
|
|
Serial.print(slot); |
|
|
|
|
Serial.print(F("]: Velocity=")); |
|
|
|
|
Serial.print(mapfloat(inVelocity, 0, 127, vol_min, vol_max), 2); |
|
|
|
|
Serial.print(F(" Pan=")); |
|
|
|
|
Serial.print(pan, 2); |
|
|
|
|
Serial.print(F(" ReverbSend=")); |
|
|
|
|
Serial.print(reverb_send, 2); |
|
|
|
|
Serial.print(F(" Pitch=")); |
|
|
|
|
Serial.print(configuration.drums.pitch[use_drum] / 10.0f, 1); |
|
|
|
|
Serial.print(F(" Playback speed=")); |
|
|
|
|
Serial.println(pow(2, float(configuration.drums.pitch[use_drum]) / 120.0)); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
@ -964,7 +969,7 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) { |
|
|
|
|
//
|
|
|
|
|
// MIDI learn mode
|
|
|
|
|
//
|
|
|
|
|
if (midi_learn_mode != MIDI_LEARN_MODE_OFF) { |
|
|
|
|
if (midi_learn_mode > MIDI_LEARN_MODE_OFF) { |
|
|
|
|
int8_t tmp_channel = handle_midi_learn(inNumber); |
|
|
|
|
if (tmp_channel >= 0) |
|
|
|
|
inChannel = tmp_channel; |
|
|
|
@ -2215,7 +2220,7 @@ int8_t handle_midi_learn(int8_t note) { |
|
|
|
|
int8_t ret_channel = -1; |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.printf(PSTR("MIDI learning for %d with midi learn mode %d\n"), note, midi_learn_mode); |
|
|
|
|
Serial.printf_P(PSTR("MIDI learning for note %d with midi learn mode %d\n"), note, midi_learn_mode); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_drum_pan)) { |
|
|
|
@ -2232,15 +2237,10 @@ int8_t handle_midi_learn(int8_t note) { |
|
|
|
|
LCDML.OTHER_jumpToFunc(UI_func_drum_vol_min_max); |
|
|
|
|
} else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_drum_midi_note)) { |
|
|
|
|
ret_channel = configuration.drums.midi_channel; |
|
|
|
|
if (midi_learn_mode != MIDI_LEARN_MODE_NOTE && midi_learn_mode != MIDI_LEARN_MODE_DRUM_NOTE) |
|
|
|
|
if (midi_learn_mode & 0x80) |
|
|
|
|
active_sample = get_drums_id_by_note(note); |
|
|
|
|
else { |
|
|
|
|
if (midi_learn_mode != MIDI_LEARN_MODE_DRUM_NOTE) |
|
|
|
|
midi_learn_mode = note; |
|
|
|
|
else |
|
|
|
|
midi_learn_mode = note & 0x80; |
|
|
|
|
LCDML.OTHER_jumpToFunc(UI_func_drum_midi_note); |
|
|
|
|
} |
|
|
|
|
midi_learn_mode |= note; |
|
|
|
|
LCDML.OTHER_jumpToFunc(UI_func_drum_midi_note); |
|
|
|
|
} else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_drum_pitch)) { |
|
|
|
|
ret_channel = configuration.drums.midi_channel; |
|
|
|
|
active_sample = get_drums_id_by_note(note); |
|
|
|
@ -2889,6 +2889,18 @@ void SerialPrintFormatInt3(uint8_t num) { |
|
|
|
|
Serial.print(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* byte_to_binary(int x) { |
|
|
|
|
static char b[9]; |
|
|
|
|
b[0] = '\0'; |
|
|
|
|
|
|
|
|
|
int z; |
|
|
|
|
for (z = 128; z > 0; z >>= 1) { |
|
|
|
|
strcat(b, ((x & z) == z) ? "1" : "0"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return b; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(ARDUINO_TEENSY36) |
|
|
|
|
/* From: https://forum.pjrc.com/threads/33443-How-to-display-free-ram */ |
|
|
|
|
extern "C" char* sbrk(int incr); |
|
|
|
|