Skip to content

Commit

Permalink
Merge branch 'aftertouch' (pr mtytel/helm/mtytel#170) into clean-gcc9
Browse files Browse the repository at this point in the history
  • Loading branch information
vmsh0 committed Aug 27, 2021
2 parents 9f1b4bb + 93fb9b3 commit f0fe5eb
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 23 deletions.
40 changes: 34 additions & 6 deletions mopo/src/arpeggiator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,19 @@ namespace mopo {
}

// Check if it's time to play the next note.
// FIXME: handle channel
if (getNumNotes() && new_phase >= 1) {
int offset = utils::iclamp((1 - phase_) / delta_phase, 0, buffer_size_ - 1);
std::pair<mopo_float, mopo_float> note = getNextNote();
note_handler_->noteOn(note.first, note.second, offset);
last_played_note_ = note.first;
std::tuple<mopo_float, mopo_float, int, mopo_float> note = getNextNote();
note_handler_->noteOn(std::get<0>(note), std::get<1>(note), offset, std::get<2>(note), std::get<3>(note));
last_played_note_ = std::get<0>(note);
phase_ = new_phase - 1.0;
}
else
phase_ = new_phase;
}

std::pair<mopo_float, mopo_float> Arpeggiator::getNextNote() {
std::tuple<mopo_float, mopo_float, int, mopo_float> Arpeggiator::getNextNote() {
int octaves = utils::imax(1, input(kOctaves)->at(0));
Pattern type =
static_cast<Pattern>(static_cast<int>(input(kPattern)->at(0)));
Expand Down Expand Up @@ -115,7 +116,10 @@ namespace mopo {
mopo_float base_note = pattern->at(note_index_);
mopo_float note = base_note + mopo::NOTES_PER_OCTAVE * current_octave_;
mopo_float velocity = active_notes_[base_note];
return std::pair<mopo_float, mopo_float>(note, velocity);
int channel = channel_[base_note];
mopo_float aftertouch = aftertouch_[base_note];

return std::tuple<mopo_float, mopo_float, int, mopo_float>(note, velocity, channel, aftertouch);
}

CircularQueue<mopo_float>& Arpeggiator::getPressedNotes() {
Expand Down Expand Up @@ -152,6 +156,8 @@ namespace mopo {

void Arpeggiator::allNotesOff(int sample) {
active_notes_.clear();
channel_.clear();
aftertouch_.clear();
pressed_notes_.clear();
sustained_notes_.clear();
ascending_.clear();
Expand All @@ -160,7 +166,7 @@ namespace mopo {
note_handler_->allNotesOff();
}

void Arpeggiator::noteOn(mopo_float note, mopo_float velocity, int sample, int channel) {
void Arpeggiator::noteOn(mopo_float note, mopo_float velocity, int sample, int channel, mopo_float aftertouch) {
if (active_notes_.count(note))
return;
if (pressed_notes_.size() == 0) {
Expand All @@ -169,6 +175,8 @@ namespace mopo {
phase_ = 1.0;
}
active_notes_[note] = velocity;
channel_[note] = channel;
aftertouch_[note] = aftertouch;
pressed_notes_.push_back(note);
addNoteToPatterns(note);
}
Expand All @@ -181,10 +189,30 @@ namespace mopo {
sustained_notes_.push_back(note);
else {
active_notes_.erase(note);
channel_.erase(note);
aftertouch_.erase(note);
removeNoteFromPatterns(note);
}

pressed_notes_.removeAll(note);
return kVoiceOff;
}

void Arpeggiator::setAftertouch(mopo_float note, mopo_float aftertouch, int sample) {
// TODO: take channel into account
for (const auto &n : pressed_notes_) {
if (n == note) {
aftertouch_[n] = aftertouch;
}
}
}

void Arpeggiator::setPressure(mopo_float pressure, int channel, int sample) {
MOPO_ASSERT(channel >= 0 && channel <= mopo::NUM_MIDI_CHANNELS);
for (const auto &n : pressed_notes_) {
if (channel_[n] == channel) {
aftertouch_[n] = pressure;
}
}
}
} // namespace mopo
13 changes: 11 additions & 2 deletions mopo/src/arpeggiator.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,21 @@ namespace mopo {

int getNumNotes() { return pressed_notes_.size(); }
CircularQueue<mopo_float>& getPressedNotes();
std::pair<mopo_float, mopo_float> getNextNote();
// tuple: note, velocity, channel, aftertouch
std::tuple<mopo_float, mopo_float, int, mopo_float> getNextNote();
void addNoteToPatterns(mopo_float note);
void removeNoteFromPatterns(mopo_float note);

void allNotesOff(int sample = 0) override;
void noteOn(mopo_float note, mopo_float velocity = 1,
int sample = 0, int channel = 0) override;
int sample = 0, int channel = 0, mopo_float aftertouch = 0) override;
VoiceEvent noteOff(mopo_float note, int sample = 0) override;
void sustainOn();
void sustainOff();

void setAftertouch(mopo_float note, mopo_float aftertouch, int sample = 0);
void setPressure(mopo_float pressure, int channel = 0, int sample = 0);


private:
Arpeggiator() : Processor(0, 0) { }
Expand All @@ -89,8 +94,12 @@ namespace mopo {
std::vector<mopo_float> decending_;

std::map<mopo_float, mopo_float> active_notes_;
std::map<mopo_float, int> channel_;
std::map<mopo_float, mopo_float> aftertouch_;

CircularQueue<mopo_float> pressed_notes_;
CircularQueue<mopo_float> sustained_notes_;

};
} // namespace mopo

Expand Down
2 changes: 1 addition & 1 deletion mopo/src/note_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace mopo {
virtual ~NoteHandler() { }
virtual void allNotesOff(int sample = 0) = 0;
virtual void noteOn(mopo_float note, mopo_float velocity = 1,
int sample = 0, int channel = 0) = 0;
int sample = 0, int channel = 0, mopo_float aftertouch = 0) = 0;
virtual VoiceEvent noteOff(mopo_float note, int sample = 0) = 0;
};
} // namespace mopo
Expand Down
14 changes: 11 additions & 3 deletions mopo/src/voice_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ namespace mopo {
return 0;
}

void VoiceHandler::noteOn(mopo_float note, mopo_float velocity, int sample, int channel) {
void VoiceHandler::noteOn(mopo_float note, mopo_float velocity, int sample, int channel, mopo_float aftertouch) {
MOPO_ASSERT(sample >= 0 && sample < buffer_size_);
MOPO_ASSERT(channel >= 0 && channel < NUM_MIDI_CHANNELS);

Expand All @@ -300,7 +300,7 @@ namespace mopo {

if (last_played_note_ < 0)
last_played_note_ = note;
voice->activate(note, velocity, last_played_note_, pressed_notes_.size(), sample, channel);
voice->activate(note, velocity, last_played_note_, pressed_notes_.size(), sample, channel, aftertouch);
active_voices_.push_back(voice);
last_played_note_ = note;
}
Expand All @@ -324,7 +324,7 @@ namespace mopo {
pressed_notes_.pop_back();
pressed_notes_.push_front(old_note);
new_voice->activate(old_note, voice->state().velocity, last_played_note_,
pressed_notes_.size() + 1, sample);
pressed_notes_.size() + 1, sample);
last_played_note_ = old_note;

voice_event = kVoiceReset;
Expand All @@ -343,6 +343,14 @@ namespace mopo {
voice->setAftertouch(aftertouch, sample);
}
}

void VoiceHandler::setPressure(mopo_float pressure, int channel, int sample) {
MOPO_ASSERT(channel >= 0 && channel <= mopo::NUM_MIDI_CHANNELS);
for (Voice* voice : active_voices_) {
if (voice->state().channel == channel)
voice->setAftertouch(pressure, sample);
}
}

void VoiceHandler::setPolyphony(size_t polyphony) {
while (all_voices_.size() < polyphony) {
Expand Down
7 changes: 4 additions & 3 deletions mopo/src/voice_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ namespace mopo {

void activate(mopo_float note, mopo_float velocity,
mopo_float last_note, int note_pressed = 0,
int sample = 0, int channel = 0) {
int sample = 0, int channel = 0, mopo_float aftertouch = 0) {
event_sample_ = sample;
state_.event = kVoiceOn;
state_.note = note;
state_.velocity = velocity;
state_.last_note = last_note;
state_.note_pressed = note_pressed;
state_.channel = channel;
aftertouch_ = velocity;
aftertouch_ = aftertouch;
aftertouch_sample_ = sample;
key_state_ = kHeld;
}
Expand Down Expand Up @@ -143,9 +143,10 @@ namespace mopo {

void allNotesOff(int sample = 0) override;
virtual void noteOn(mopo_float note, mopo_float velocity = 1,
int sample = 0, int channel = 0) override;
int sample = 0, int channel = 0, mopo_float aftertouch = 0) override;
virtual VoiceEvent noteOff(mopo_float note, int sample = 0) override;
void setAftertouch(mopo_float note, mopo_float aftertouch, int sample = 0);
void setPressure(mopo_float pressure, int channel = 0, int sample = 0);
void sustainOn();
void sustainOff(int sample = 0);

Expand Down
11 changes: 10 additions & 1 deletion src/common/midi_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void MidiManager::removeNextBlockOfMessages(MidiBuffer& buffer, int num_samples)
midi_collector_.removeNextBlockOfMessages(buffer, num_samples);
}

void MidiManager::processMidiMessage(const MidiMessage& midi_message, int sample_position) {
void MidiManager::processMidiMessage(const MidiMessage& midi_message, int sample_position) {
if (midi_message.isProgramChange()) {
current_patch_ = midi_message.getProgramChangeNumber();
File patch = LoadSave::loadPatch(current_bank_, current_folder_, current_patch_,
Expand All @@ -118,11 +118,20 @@ void MidiManager::processMidiMessage(const MidiMessage& midi_message, int sample
engine_->sustainOn();
else if (midi_message.isSustainPedalOff())
engine_->sustainOff();
// "aftertouch" is pressure per note
else if (midi_message.isAftertouch()) {
mopo::mopo_float note = midi_message.getNoteNumber();
mopo::mopo_float value = (1.0 * midi_message.getAfterTouchValue()) / mopo::MIDI_SIZE;
engine_->setAftertouch(note, value);
}
// "pressure" is aftertouch for a whole channel (e.g. keyboard send only one value even if several keys are pressed)
// TODO: create a separate modifier
else if (midi_message.isChannelPressure()) {
mopo::mopo_float note = midi_message.getNoteNumber();
mopo::mopo_float value = (1.0 * midi_message.getChannelPressureValue()) / (mopo::MIDI_SIZE - 1.0);
// channel - 1 as with NoteOn above
engine_->setPressure(value, midi_message.getChannel() - 1, sample_position);
}
else if (midi_message.isPitchWheel()) {
double percent = (1.0 * midi_message.getPitchWheelValue()) / PITCH_WHEEL_RESOLUTION;
double value = 2 * percent - 1.0;
Expand Down
15 changes: 12 additions & 3 deletions src/synthesis/helm_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,11 @@ namespace mopo {
arpeggiator_->allNotesOff(sample);
}

void HelmEngine::noteOn(mopo_float note, mopo_float velocity, int sample, int channel) {
void HelmEngine::noteOn(mopo_float note, mopo_float velocity, int sample, int channel, mopo_float aftertouch) {
if (arp_on_->value())
arpeggiator_->noteOn(note, velocity, sample);
arpeggiator_->noteOn(note, velocity, sample, channel, aftertouch);
else
voice_handler_->noteOn(note, velocity, sample, channel);
voice_handler_->noteOn(note, velocity, sample, channel, aftertouch);
}

VoiceEvent HelmEngine::noteOff(mopo_float note, int sample) {
Expand All @@ -401,8 +401,17 @@ namespace mopo {
void HelmEngine::setPitchWheel(mopo_float value, int channel) {
voice_handler_->setPitchWheel(value, channel);
}

void HelmEngine::setPressure(mopo_float value, int channel, int sample) {
if (arp_on_->value())
arpeggiator_->setPressure(value, channel, sample);
voice_handler_->setPressure(value, channel, sample);
}

void HelmEngine::setAftertouch(mopo_float note, mopo_float value, int sample) {
// TODO: take channel into account
if (arp_on_->value())
arpeggiator_->setAftertouch(note, value, sample);
voice_handler_->setAftertouch(note, value, sample);
}

Expand Down
3 changes: 2 additions & 1 deletion src/synthesis/helm_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,14 @@ namespace mopo {
// Keyboard events.
void allNotesOff(int sample = 0) override;
void noteOn(mopo_float note, mopo_float velocity = 1.0,
int sample = 0, int channel = 0) override;
int sample = 0, int channel = 0, mopo_float aftertouch = 0) override;
VoiceEvent noteOff(mopo_float note, int sample = 0) override;
void setModWheel(mopo_float value, int channel = 0);
void setPitchWheel(mopo_float value, int channel = 0);
void setBpm(mopo_float bpm);
void correctToTime(mopo_float samples) override;
void setAftertouch(mopo_float note, mopo_float value, int sample = 0);
void setPressure(mopo_float value, int channel = 0, int sample = 0);

// Sustain pedal events.
void sustainOn();
Expand Down
4 changes: 2 additions & 2 deletions src/synthesis/helm_voice_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,10 +756,10 @@ namespace mopo {
}
}

void HelmVoiceHandler::noteOn(mopo_float note, mopo_float velocity, int sample, int channel) {
void HelmVoiceHandler::noteOn(mopo_float note, mopo_float velocity, int sample, int channel, mopo_float aftertouch) {
if (getPressedNotes().size() < polyphony() || legato_->value() == 0.0)
note_retriggered_.trigger(note, sample);
VoiceHandler::noteOn(note, velocity, sample, channel);
VoiceHandler::noteOn(note, velocity, sample, channel, aftertouch);
}

VoiceEvent HelmVoiceHandler::noteOff(mopo_float note, int sample) {
Expand Down
2 changes: 1 addition & 1 deletion src/synthesis/helm_voice_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ namespace mopo {

void process() override;
void noteOn(mopo_float note, mopo_float velocity = 1,
int sample = 0, int channel = 0) override;
int sample = 0, int channel = 0, mopo_float aftertouch = 0) override;
VoiceEvent noteOff(mopo_float note, int sample = 0) override;
bool shouldAccumulate(Output* output) override;
void setModWheel(mopo_float value, int channel = 0);
Expand Down

0 comments on commit f0fe5eb

Please sign in to comment.