Skip to content

Commit

Permalink
Support Release Velocity in the 16 vintage codebase (#1267)
Browse files Browse the repository at this point in the history
OK so I got a linnstrument, alright? Release velocity is super useful
and I should have done this forever ago. Basically plumb it through as
a modulation source in the DSP engine; hook it up properly in the VST3;
and modify the GUI so the Velocity modulator is an either-or modulator.
This results in the ability to modulate with release velocity just
as you can with anything else, albeit in a bit of a clumsy fashion.

Closes #811
  • Loading branch information
baconpaul authored Nov 2, 2019
1 parent 5072e64 commit 85010dd
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 118 deletions.
13 changes: 8 additions & 5 deletions src/common/ModulationSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ enum modsources
ms_slfo6,
// ms_arpeggiator,
ms_timbre,
ms_releasevelocity,
n_modsources,
/*ms_stepseq1,
ms_stepseq2,
Expand All @@ -60,7 +61,7 @@ const char modsource_abberations_button[n_modsources][32] = {
"Off", "Velocity", "Keytrack", "Poly AT", "Channel AT", "Pitchbend", "Modwheel", "Ctrl 1",
"Ctrl 2", "Ctrl 3", "Ctrl 4", "Ctrl 5", "Ctrl 6", "Ctrl 7", "Ctrl 8", "Amp EG",
"Filter EG", "LFO 1", "LFO 2", "LFO 3", "LFO 4", "LFO 5", "LFO 6", "SLFO 1",
"SLFO 2", "SLFO 3", "SLFO 4", "SLFO 5", "SLFO 6", "Timbre" /*,"Arpeggio"*/};
"SLFO 2", "SLFO 3", "SLFO 4", "SLFO 5", "SLFO 6", "Timbre", "Rel. Velcty" /*,"Arpeggio"*/};

const char modsource_abberations[n_modsources][32] = {"Off",
"Velocity",
Expand Down Expand Up @@ -91,27 +92,29 @@ const char modsource_abberations[n_modsources][32] = {"Off",
"Scene LFO 4",
"Scene LFO 5",
"Scene LFO 6",
"Timbre" /*,"Arpeggio"*/};
"Timbre",
"Release Velocity"
/*,"Arpeggio"*/};

const char modsource_abberations_short[n_modsources][32] = {
"off", "velocity", "keytrack", "Poly AT", "Ch. AT", "Pitch Bend", "Modwheel", "CTRL1",
"CTRL2", "CTRL3", "CTRL4", "CTRL5", "CTRL6", "CTRL7", "CTRL8", "AEG",
"FEG", "LFO1", "LFO2", "LFO3", "LFO4", "LFO5", "LFO6", "SLFO1",
"SLFO2", "SLFO3", "SLFO4", "SLFO5", "SLFO6", "TIMBR" /*,"Arpeggio"*/};
"SLFO2", "SLFO3", "SLFO4", "SLFO5", "SLFO6", "TIMBR", "RELVEL" /*,"Arpeggio"*/};

const int modsource_grid_xy[n_modsources][2] = {
{0, 0}, {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, // vel -> mw
{7, 0}, {8, 0}, {9, 0}, {10, 0}, {7, 3}, {8, 3}, {9, 3}, {10, 3}, // ctrl 1-8
{6, 2}, {6, 4}, // EGs
{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, // LFO
{0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, // SLFO
{6, 0} // Timbre
{6, 0}, {0, 0} // Timbre, relvel is special
};

inline bool isScenelevel(modsources ms)
{
return ((ms <= ms_ctrl8) || ((ms >= ms_slfo1) && (ms <= ms_slfo6))) && (ms != ms_velocity) &&
(ms != ms_keytrack) && (ms != ms_polyaftertouch) && (ms != ms_timbre);
(ms != ms_keytrack) && (ms != ms_polyaftertouch) && (ms != ms_timbre) && (ms != ms_releasevelocity);
}

inline bool canModulateMonophonicTarget(modsources ms)
Expand Down
10 changes: 10 additions & 0 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,15 @@ void SurgeSynthesizer::releaseNote(char channel, char key, char velocity)
int channelmask =
((channel == 0) ? 3 : 0) || ((channel == 1) ? 1 : 0) || ((channel == 2) ? 2 : 0);

for( int s=0; s<2; ++s )
{
for( auto *v : voices[s] )
{
if ((v->state.key == key) && (v->state.channel == channel))
v->state.releasevelocity = velocity;
}
}

// if(channelmask&1)
{
if (!channelState[channel].hold)
Expand All @@ -541,6 +550,7 @@ void SurgeSynthesizer::releaseNote(char channel, char key, char velocity)
else
holdbuffer[1].push_back(key); // hold pedal is down, add to bufffer
}

}

void SurgeSynthesizer::releaseNotePostHoldCheck(int scene, char channel, char key, char velocity)
Expand Down
12 changes: 11 additions & 1 deletion src/common/dsp/SurgeVoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,14 @@ SurgeVoice::SurgeVoice(SurgeStorage* storage,
age = 0;
age_release = 0;
state.key = key;
state.velocity = velocity;
state.channel = channel;

state.velocity = velocity;
state.fvel = velocity / 127.f;

state.releasevelocity = 0;
state.freleasevel = 0;

state.scene_id = scene_id;
state.detune = detune;
state.uberrelease = false;
Expand Down Expand Up @@ -125,11 +130,15 @@ SurgeVoice::SurgeVoice(SurgeStorage* storage,
modsources[ms_lfo1 + i] = &lfo[i];
}
modsources[ms_velocity] = &velocitySource;
modsources[ms_releasevelocity] = &releaseVelocitySource;
modsources[ms_keytrack] = &keytrackSource;
modsources[ms_polyaftertouch] = &polyAftertouchSource;
polyAftertouchSource.init(storage->poly_aftertouch[state.scene_id & 1][state.key & 127]);

velocitySource.output = state.fvel;
releaseVelocitySource.output = state.freleasevel;
keytrackSource.output = 0;

ampEGSource.init(storage, &scene->adsr[0], localcopy, &state);
filterEGSource.init(storage, &scene->adsr[1], localcopy, &state);
modsources[ms_ampeg] = &ampEGSource;
Expand Down Expand Up @@ -302,6 +311,7 @@ void SurgeVoice::release()
lfo[i].release();

state.gate = false;
releaseVelocitySource.output = state.releasevelocity / 127.0f;
}

void SurgeVoice::uber_release()
Expand Down
2 changes: 1 addition & 1 deletion src/common/dsp/SurgeVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class alignas(16) SurgeVoice

std::array<ModulationSource*, n_modsources> modsources;

ModulationSource velocitySource;
ModulationSource velocitySource, releaseVelocitySource;
ModulationSource keytrackSource;
ControllerModulationSource polyAftertouchSource;
ModulationSource monoAftertouchSource;
Expand Down
6 changes: 3 additions & 3 deletions src/common/dsp/SurgeVoiceState.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ struct SurgeVoiceState
{
bool gate;
bool keep_playing, uberrelease;
float pitch, fvel, pkey, detune;
float pitch, fvel, pkey, detune, freleasevel;
MidiKeyState* keyState;
MidiChannelState* mainChannelState;
MidiChannelState* voiceChannelState;
int key, velocity, channel, scene_id;
int key, velocity, channel, scene_id, releasevelocity;
float portasrc_key, portaphase;

float getPitch();
};
};
10 changes: 9 additions & 1 deletion src/common/gui/CModulationSourceButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,15 @@ void CModulationSourceButton::draw(CDrawContext* dc)
dc->drawRect(framer, kDrawFilled);
dc->setFillColor(FillCol);
dc->drawRect(fillr, kDrawFilled);
dc->drawString(label, txtbox, kCenterText, true);

if( hasAlternate && useAlternate )
{
dc->drawString(alternateLabel.c_str(), txtbox, kCenterText, true);
}
else
{
dc->drawString(label, txtbox, kCenterText, true);
}

if (is_metacontroller)
{
Expand Down
14 changes: 14 additions & 0 deletions src/common/gui/CModulationSourceButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#pragma once
#include "vstcontrols.h"
#include "SurgeBitmaps.h"
#include <iostream>


class CModulationSourceButton : public CCursorHidingControl
{
Expand Down Expand Up @@ -52,6 +54,18 @@ class CModulationSourceButton : public CCursorHidingControl
{
return state;
}

bool hasAlternate = false;
int alternateId;
std::string alternateLabel;
virtual void setAlternate( int alt, const std::string &altLabel ) {
hasAlternate = true;
this->alternateId = alt;
this->alternateLabel = altLabel;
}
bool useAlternate = false;
void setUseAlternate( bool f ) { useAlternate = f; if( hasAlternate ) { invalid(); setDirty(); } }

virtual void draw(VSTGUI::CDrawContext* dc);
// virtual void mouse (VSTGUI::CDrawContext *pContext, VSTGUI::CPoint &where, long button = -1);
virtual VSTGUI::CMouseEventResult onMouseDown(VSTGUI::CPoint& where, const VSTGUI::CButtonState& buttons);
Expand Down
Loading

0 comments on commit 85010dd

Please sign in to comment.