Skip to content

Commit

Permalink
- fix release start to not jump back to release
Browse files Browse the repository at this point in the history
- fix release start to properly work with sustain pedals
- added Sampler.setAllowReleaseStart(eventId, shouldBeEnabled)
  • Loading branch information
christoph-hart committed Jan 26, 2025
1 parent ba3e16e commit c06f9f5
Show file tree
Hide file tree
Showing 9 changed files with 3,977 additions and 3,834 deletions.
87 changes: 87 additions & 0 deletions hi_core/hi_sampler/sampler/ModulatorSampler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,90 @@ void ModulatorSampler::setNumChannels(int numNewChannels)

}

bool ModulatorSampler::setAllowReleaseStart(int eventId, bool shouldAllow)
{
#if HISE_SAMPLER_ALLOW_RELEASE_START
if(eventId == -1)
{
for(auto v: voices)
{
auto s = shouldAllow ? ModulatorSamplerVoice::ReleaseStartState::Enabled :
ModulatorSamplerVoice::ReleaseStartState::AlwaysDisabled;

static_cast<ModulatorSamplerVoice*>(v)->setAllowReleaseStart(s);
}

return true;
}

for(auto av: activeVoices)
{
if(av->getCurrentHiseEvent().getEventId() == eventId)
{
auto s = shouldAllow ? ModulatorSamplerVoice::ReleaseStartState::Enabled :
ModulatorSamplerVoice::ReleaseStartState::DisabledOnce;

static_cast<ModulatorSamplerVoice*>(av)->setAllowReleaseStart(s);
return true;
}
}
#endif

return false;
}

void ModulatorSampler::handleSustainPedal(int midiChannel, bool isDown)
{
ModulatorSynth::handleSustainPedal(midiChannel, isDown);

#if HISE_SAMPLER_ALLOW_RELEASE_START
if(!isDown)
{
if(soundsHaveReleaseStart)
{
for (auto v : activeVoices)
{
if (!v->isPlayingChannel (midiChannel))
continue;

if ((v->isKeyDown() || v->isSostenutoPedalDown()))
continue;

auto s = static_cast<ModulatorSamplerSound*>(v->getCurrentlyPlayingSound().get());

if(s->getReferenceToSound()->isReleaseStartEnabled())
static_cast<ModulatorSamplerVoice*>(v)->jumpToRelease();
}
}
}
#endif
}

const ModulatorSampler::ChannelData& ModulatorSampler::getChannelData(int index) const
{
if (index >= 0 && index < getNumMicPositions())
{
return channelData[index];
}
else
{
jassertfalse;
return channelData[0];
}

}

void ModulatorSampler::setMicEnabled(int channelIndex, bool channelIsEnabled) noexcept
{
if (channelIndex >= NUM_MIC_POSITIONS || channelIndex < 0) return;

if(channelData[channelIndex].enabled != channelIsEnabled)
{
channelData[channelIndex].enabled = channelIsEnabled;
asyncPurger.triggerAsyncUpdate(); // will call refreshChannelsForSound asynchronously
}
}

int ModulatorSampler::getNumActiveGroups() const
{
if (crossfadeGroups)
Expand Down Expand Up @@ -1300,6 +1384,9 @@ void ModulatorSampler::noteOff(const HiseEvent &m)
{
if(v->getCurrentHiseEvent().getEventId() == m.getEventId())
{
if(v->isSostenutoPedalDown() || v->isSustainPedalDown())
continue;

auto s = static_cast<ModulatorSamplerSound*>(v->getCurrentlyPlayingSound().get());

if(s->getReferenceToSound()->isReleaseStartEnabled())
Expand Down
27 changes: 4 additions & 23 deletions hi_core/hi_sampler/sampler/ModulatorSampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,9 @@ class ModulatorSampler: public ModulatorSynth,

void setNumChannels(int numChannels);

bool setAllowReleaseStart(int eventId, bool shouldAllow);

void handleSustainPedal(int midiChannel, bool isDown) override;

struct ChannelData: RestorableObject
{
Expand Down Expand Up @@ -608,30 +610,9 @@ class ModulatorSampler: public ModulatorSynth,
String suffix;
};

const ChannelData &getChannelData(int index) const
{
if (index >= 0 && index < getNumMicPositions())
{
return channelData[index];
}
else
{
jassertfalse;
return channelData[0];
}

}

void setMicEnabled(int channelIndex, bool channelIsEnabled) noexcept
{
if (channelIndex >= NUM_MIC_POSITIONS || channelIndex < 0) return;
const ChannelData &getChannelData(int index) const;

if(channelData[channelIndex].enabled != channelIsEnabled)
{
channelData[channelIndex].enabled = channelIsEnabled;
asyncPurger.triggerAsyncUpdate(); // will call refreshChannelsForSound asynchronously
}
}
void setMicEnabled(int channelIndex, bool channelIsEnabled) noexcept;

void refreshChannelsForSounds()
{
Expand Down
12 changes: 9 additions & 3 deletions hi_core/hi_sampler/sampler/ModulatorSamplerVoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ void ModulatorSamplerVoice::startNote(int midiNoteNumber,
{
startVoiceInternal(midiNoteNumber, velocity);
}



#if HISE_SAMPLER_ALLOW_RELEASE_START
if(allowReleaseStart == ReleaseStartState::DisabledOnce)
allowReleaseStart = ReleaseStartState::Enabled;
#endif

if (auto fEnve = currentlyPlayingSamplerSound->getEnvelope(Modulation::Mode::PanMode))
{
Expand Down Expand Up @@ -487,7 +490,10 @@ void MultiMicModulatorSamplerVoice::startNote(int midiNoteNumber, float velocity

midiNoteNumber += transposeAmount;


#if HISE_SAMPLER_ALLOW_RELEASE_START
if(allowReleaseStart == ReleaseStartState::DisabledOnce)
allowReleaseStart = ReleaseStartState::Enabled;
#endif

currentlyPlayingSamplerSound = static_cast<ModulatorSamplerSound*>(s);

Expand Down
33 changes: 30 additions & 3 deletions hi_core/hi_sampler/sampler/ModulatorSamplerVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,31 @@ class ModulatorSamplerVoice : public ModulatorSynthVoice
void calculateBlock(int startSample, int numSamples) override;
void resetVoice() override;

#if HISE_SAMPLER_ALLOW_RELEASE_START
virtual void jumpToRelease()
{
wrappedVoice.jumpToRelease();
if(shouldJumpToRelease())
wrappedVoice.jumpToRelease();
}

enum class ReleaseStartState
{
Enabled,
AlwaysDisabled,
DisabledOnce
};

void setAllowReleaseStart(ReleaseStartState shouldAllow)
{
allowReleaseStart = shouldAllow;
}

bool shouldJumpToRelease() const { return allowReleaseStart == ReleaseStartState::Enabled; }

ReleaseStartState allowReleaseStart = ReleaseStartState::Enabled;

#endif

virtual void setNonRealtime(bool isNonRealtime)
{
nonRealtime = isNonRealtime;
Expand Down Expand Up @@ -214,12 +234,19 @@ class MultiMicModulatorSamplerVoice : public ModulatorSamplerVoice
v->loader.setIsNonRealtime(isNonRealtime);
}

#if HISE_SAMPLER_ALLOW_RELEASE_START

void jumpToRelease() override
{
for(auto v: wrappedVoices)
v->jumpToRelease();
if(shouldJumpToRelease())
{
for(auto v: wrappedVoices)
v->jumpToRelease();
}
}

#endif

// ================================================================================================================

void startVoiceInternal(int midiNoteNumber, float velocity) override;
Expand Down
15 changes: 15 additions & 0 deletions hi_scripting/scripting/api/ScriptingApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3761,6 +3761,7 @@ struct ScriptingApi::Sampler::Wrapper
API_METHOD_WRAPPER_2(Sampler, importSamples);
API_METHOD_WRAPPER_0(Sampler, clearSampleMap);
API_METHOD_WRAPPER_1(Sampler, parseSampleFile);
API_METHOD_WRAPPER_2(Sampler, setAllowReleaseStart);
API_VOID_METHOD_WRAPPER_2(Sampler, setGUISelection);
API_VOID_METHOD_WRAPPER_1(Sampler, setSortByRRGroup);
};
Expand Down Expand Up @@ -3818,6 +3819,7 @@ sampler(sampler_)
ADD_API_METHOD_1(loadSampleMapFromJSON);
ADD_API_METHOD_1(loadSampleMapFromBase64);
ADD_API_METHOD_0(getSampleMapAsBase64);
ADD_API_METHOD_2(setAllowReleaseStart);
ADD_API_METHOD_1(getAudioWaveformContentAsBase64);
ADD_API_METHOD_1(setTimestretchRatio);
ADD_API_METHOD_1(setTimestretchOptions);
Expand Down Expand Up @@ -3943,6 +3945,19 @@ void ScriptingApi::Sampler::setRRGroupVolume(int groupIndex, int gainInDecibels)
s->setRRGroupVolume(groupIndex, Decibels::decibelsToGain((float)gainInDecibels));
}

bool ScriptingApi::Sampler::setAllowReleaseStart(int eventId, bool shouldBeAllowed)
{
ModulatorSampler *s = static_cast<ModulatorSampler*>(sampler.get());

if (s == nullptr)
{
reportScriptError("setAllowReleaseStart() only works with Samplers.");
return false;
}

return s->setAllowReleaseStart(eventId, shouldBeAllowed);
}


int ScriptingApi::Sampler::getActiveRRGroupForEventId(int eventId)
{
Expand Down
3 changes: 3 additions & 0 deletions hi_scripting/scripting/api/ScriptingApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,9 @@ class ScriptingApi
/** Sets the volume of a particular group (use -1 for active group). Only works with disabled crossfade tables. */
void setRRGroupVolume(int groupIndex, int gainInDecibels);

/** Enable / disables the release start feature for the given event. */
bool setAllowReleaseStart(int eventId, bool shouldBeAllowed);

/** Returns the currently (single) active RR group. */
int getActiveRRGroup();

Expand Down
Loading

0 comments on commit c06f9f5

Please sign in to comment.