Skip to content

Commit

Permalink
- added release start mode to streaming engine!
Browse files Browse the repository at this point in the history
  • Loading branch information
christoph-hart committed Sep 24, 2024
1 parent 5d07c8e commit 79019ea
Show file tree
Hide file tree
Showing 33 changed files with 4,583 additions and 3,578 deletions.
2 changes: 1 addition & 1 deletion hi_backend/backend/BackendComponents.h
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ struct EncodedDialogBase: public Component,
{
auto id = simple_css::FlexboxComponent::Helpers::getIdSelectorFromComponentClass(c).name;

if(id == "header")
if(id == "header" && c->isVisible())
{
c->setInterceptsMouseClicks(true, true);
this->dragger = new WindowDragger(rootWindow, this, c);
Expand Down
60 changes: 60 additions & 0 deletions hi_backend/backend/dialog_library/dialog_library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,66 @@ var AboutWindow::showCommit(const var::NativeFunctionArgs& args)
return var();
}

ReleaseStartOptionDialog::ReleaseStartOptionDialog(hise::BackendRootWindow* bpe_, ModulatorSampler* sampler_):
EncodedDialogBase(bpe_, false),
sampler(sampler_),
root(bpe_)
{
setName("Release Start Options");
loadFrom("1934.sNB..D...............35H...oi...hc.........J09R+f09DEqC.ZeEBOrBzPiZCHtoMRIzRYB5R15NI4lNYHWubBXHMsE5DvqD9C3pS2rGYPtZV.x5q6Cf4.PM.Up7PlY0Q+AAhR4789sqdn6P6QB116LyjxbPd8dzdvg1CHbeP9yIgou+ObfHtny4foK+2MZyG8IMiHJmqALkiydPjb5oMWAkITlDQ6L7scL0pq4Zlznoa7pMCPZCiHrmeNwMv142Eg7e5uYg5xVI.W9eqyebDoCKjoOLkUqayBoPDUlnBFIlXalszMZaNCJUtf4Bk2tz8hkwQuLAFKSf.LTbASEKX9P1eBIvLgELfzL6BEWrHAEUrKWgfJWtX4RDTTwxK5LWCDGJSnHhcC7lE7vuciDXqaTvh4UbfHOkEgVIj9qYDIyD4a2AQxLy.vgLSD8UKV1zuIRlAfCQqY9VNsXmPdepjlaE4Bl77OW6RexkSxXrTtPMxoOLB+70nOgKy0TX1btM9yMxwnPgDXnXYec4nvT6aimvtTG7QWiwGxNgH8tV7ESOyXNLj6nCblLVrAFUvgc4Zfajoc7bigEXn5nCdG+TPsiBAHutoIbgdeKFGogBkOBh2KnP4REfblxVv.WB4nOUo+42pTF8ozs.BWMZO9o2Xj+4Nok6X.KzYZFPl4CYa1pZU8t+D8vZsdNyUVhHyrafgqRcPu8Fia5iju8mDDhixkJYlnewRRZtwVNJ668oNXquu8+ibjrLHH+mTIvd9YakWK04Ho1U+aNcLHv+oc7WeX6pIlyoYuZMyle9ys2Xr1ZVgfK+97iORINT1ajT5ZqJtZr9jvzkZOWFGsWnjyXZjegOOQnEYdGsGv19a6aDodUil0GrJ1izjsm+rcTolYH2IcHq.QMr4xhtTkbBzRfbBT98xqTSnlgwdy2J4r744actHb8TI+kVPfYqpOx4oayrTSHm4D+a96AB8mZZgwb67hpr41a+cosl9fIevQZf7ib2.G8u84IxIWpy1mKedq4959dNeOdFyom21V64qTWiy.nCA.CXfsbzL7MzrQo468gL7strABDp4egM+rqL+uk7EHOUC2e0sONe1+FhY5Cmr3i+Jz1DHUo+1MjaG9Yn6x0p5I3Se3mOXTIyz7+cNRZF5oMM9asvpWErAUz5dQ1ggQlJjk.TlLgh9vXSc4xbmjscI8kS7GBHf.hGp4ZWNo+t8UVTwTE66kU7yy5Sn7t21.htbLYR7ys4mT.Yj5oK74sDt1s+cJW62aieeibxjp2nF12S9t+d6C0IU81HHNJhG85Z5JhGoBga+5ckdkwfPntu3qhuGlpmFw1NaANIpQk4PJkglY..BB.A.w.Q.fwxIYbqARCMLIOMDyo.jAB.nB..Afv.RHyxCCz4kQhnpoZU0acRdhqEM0kJ8v8IiI2QGYWJUtOi1XfNGO1QaLuyflQ4ya9eL4OJzyAbXRu8zIyB9Bue14vwyIXFDEjynULa.oZfRJejxOD1yuqtQ1vZl8cDPXQ0feNxllnOU.p+lQlaTgxzRHHXFaB94f17iFhV5knvYRMy8hDTLrOWqFzbI7o+gv6juA1XRpXqxwnNlbmGsH29SG.k5SF+v5ara+53kMrwA7XA6IsCokfdYlpu45E0KGyTnbBg3CADFa6zYaEfqjx1V6FWfREUQUbGfonMfhyTHqVgwFOXRXQmAVnGerW1cnQoaBI4NDCbe80Kk+.iHbMXLkoweqUlaZtZqao8n.aqF.ZRxPHHFfeO2cj+Ye9pMwOWpS+dkHSSCv5kV+08LE1+8OAXT.oQBlmjDLkfQcOP+hQWmkTbiG2Pr.Fa5lN+zIEu..csy+FgsIjcEGKeoE5x7vR1029tSl6AiDJaNwWJYO6dnk1nGkbkP1gl4WVYUlzBmnPtvrS7ZvWg2Jl6nxRXUiEJHz.aQP3VyeBFISMss1juvrYTE.i7PIYWwhWHLrA1NPvIXjE6qCfXzN.zFI.v.C.7rim8O5vvvRjX3CEyGuaDCOEYGNqtQjNzasyV.ya3NnCFf2i2sl5.3rwzx3Px8xrQc0ChNJrsM6owL+Yb.CYc14tH0.etv+jWplWjEA0VdWThRv8OD56+TqxxxL1x8F.nQQciIf1OoRlBzafXaAQj5LrH3g5O+oCCCMOeoDhbth3xUPGvSAb3hmttMXTC0NRhhYoEzEv6sKHLPMWPFOFeGHsMewyOLuLBnvaIgXBp803PxmyqKYBPjXWi41goTKtoCbiwwOYc1XIkS7TcEEREkwMsPJw+J+YCrbT1Q8phY+pv3zjPVefK3Cx+n.DVvyA+kksec9CKNhFG7fIQTkJ6V2POupG+UZeLt50UAG2qwDH5bFN.iqSlExfN5JnA6P5B4nSXbTi1x47bC7eXLO0a8jZ5n1NHrQ++jf2RUV1YACt3VPYRtc0BTqS7eCROoEmZEO.Wv.b227vsNsqvEmPQ2wSrDHhrVTUQ86UAjYOJNdXu+riF4z.hQw2sxsrT7ff7Qy1tC2jN7zhHvQI61X.MAHEtJLenFcz9JDLwEXrUIV8Qlh9cJXGPoi...lNB..v5H...");
}

var ReleaseStartOptionDialog::initValues(const var::NativeFunctionArgs& args)
{
#if HISE_SAMPLER_ALLOW_RELEASE_START
auto options = sampler->getSampleMap()->getReleaseStartOptions();

auto d = options->toJSON();

const auto& obj = d.getDynamicObject()->getProperties();

for(int i = 0; i < obj.size(); i++)
{
auto id = obj.getName(i);
auto value = obj.getValueAt(i);

state->globalState.getDynamicObject()->setProperty(id, value);
}
#endif

return var();
}

var ReleaseStartOptionDialog::onPropertyUpdate(const var::NativeFunctionArgs& args)
{
#if HISE_SAMPLER_ALLOW_RELEASE_START
StreamingHelpers::ReleaseStartOptions::Ptr newData = new StreamingHelpers::ReleaseStartOptions();
newData->fromJSON(state->globalState);
sampler->getSampleMap()->setReleaseStartOptions(newData);

Component::callRecursive<SamplerSoundWaveform>(root, [](SamplerSoundWaveform* w)
{
w->repaint();
return false;
});
#endif

return var();
}

var ReleaseStartOptionDialog::onCreateScriptCode(const var::NativeFunctionArgs& args)
{
String code;

state->globalState.getDynamicObject()->removeProperty("CreateScriptCode");

code << "Synth.getSampler(" << sampler->getId().quoted() << ").setReleaseStartOptions(";
code << JSON::toString(state->globalState) << ");";
SystemClipboard::copyTextToClipboard(code);

return var();
}

WelcomeScreen::WelcomeScreen(BackendRootWindow* bpe_):
EncodedDialogBase(bpe_),
bpe(bpe_)
Expand Down
23 changes: 23 additions & 0 deletions hi_backend/backend/dialog_library/dialog_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,29 @@ struct AboutWindow: public multipage::EncodedDialogBase
JUCE_DECLARE_WEAK_REFERENCEABLE(AboutWindow);
};



struct ReleaseStartOptionDialog: public multipage::EncodedDialogBase

{
ReleaseStartOptionDialog(hise::BackendRootWindow* bpe_, ModulatorSampler* sampler_);

void bindCallbacks() override
{
MULTIPAGE_BIND_CPP(ReleaseStartOptionDialog, initValues);
MULTIPAGE_BIND_CPP(ReleaseStartOptionDialog, onPropertyUpdate);
MULTIPAGE_BIND_CPP(ReleaseStartOptionDialog, onCreateScriptCode);

}

var initValues(const var::NativeFunctionArgs& args);
var onPropertyUpdate(const var::NativeFunctionArgs& args);
var onCreateScriptCode(const var::NativeFunctionArgs& args);

WeakReference<ModulatorSampler> sampler;
Component* root;
};

struct NewProjectCreator: public ImporterBase,
public multipage::EncodedDialogBase

Expand Down
93 changes: 90 additions & 3 deletions hi_core/hi_components/audio_components/SampleComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -816,9 +816,47 @@ void SamplerSoundWaveform::paintOverChildren(Graphics &g)
{
AudioDisplayComponent::paintOverChildren(g);

#if HISE_SAMPLER_ALLOW_RELEASE_START
if(currentSound != nullptr)
{
auto rs = (int)currentSound->getSampleProperty(SampleIds::ReleaseStart);

if(rs != 0)
{
auto xOffset = roundToInt((double)getWidth() * (rs) / (double)getTotalSampleAmount());
auto rc = SampleArea::getReleaseStartColour();

g.setColour(rc.withAlpha(0.7f));
g.drawVerticalLine(xOffset, 0.0f, (float)getHeight());
g.fillRect((float)xOffset, 0.0f, 30.0f, JUCE_LIVE_CONSTANT_OFF(7.0f));

auto options = sampler->getSampleMap()->getReleaseStartOptions();

g.setColour(rc.withAlpha(0.2f));

auto fadeWidth = roundToInt((double)getWidth() * (double)options->releaseFadeTime / (double)getTotalSampleAmount());
Rectangle<float> fadeArea((float)xOffset, 0.0f, (float)fadeWidth, (float)getHeight());
g.fillRect(fadeArea.toFloat());

Path p;

p.startNewSubPath(0.0f, 0.0f);
p.quadraticTo(0.5f, std::pow(0.5f, options->fadeGamma), 1.0f, 1.0f);
p.scaleToFit(fadeArea.getX(), fadeArea.getY(), fadeArea.getWidth(), fadeArea.getHeight(), false);
g.setColour(rc.withAlpha(0.7f));
g.strokePath(p, PathStrokeType(1.0f));
}

}
#endif

if (xPos != -1)
{
if (previewHover)
if(releaseStartIsSelected)
{
g.setColour(SampleArea::getReleaseStartColour());
}
else if (previewHover)
{
g.setColour(Colours::white.withAlpha(0.2f));
g.drawVerticalLine(xPos, 0.0f, (float)getHeight());
Expand Down Expand Up @@ -927,7 +965,33 @@ void SamplerSoundWaveform::mouseDown(const MouseEvent& e)
if (onInterface)
return;



#if USE_BACKEND

if(releaseStartIsSelected)
{
auto n = (double)e.getPosition().getX() / (double)getWidth();

auto value = roundToInt(timeProperties.sampleLength * n);

if(zeroCrossing)
{
value = getThumbnail()->getNextZero(value);
}

if (currentSound == nullptr)
return;

auto r = currentSound->getPropertyRange(SampleIds::ReleaseStart);

if (!r.contains(value))
return;

currentSound->setSampleProperty(SampleIds::ReleaseStart, value, true);
return;
}

if (e.mods.isAnyModifierKeyDown())
{
auto numSamples = getTotalSampleAmount();
Expand Down Expand Up @@ -1000,16 +1064,39 @@ void SamplerSoundWaveform::mouseMove(const MouseEvent& e)

auto timeString = SamplerDisplayWithTimeline::getText(timeProperties, n);

previewHover = e.mods.isAnyModifierKeyDown();


previewHover = !releaseStartIsSelected && e.mods.isAnyModifierKeyDown();

if(releaseStartIsSelected)
{
setTooltip("Click to set release start offset from " + timeString);

setMouseCursor(MouseCursor::CrosshairCursor);
xPos = e.getPosition().getX();

if(zeroCrossing)
{
auto n = (double)xPos / (double)getWidth();
auto value = roundToInt(timeProperties.sampleLength * n);
value = getThumbnail()->getNextZero(value);
n = (double)value / timeProperties.sampleLength;
xPos = roundToInt(n * (double)getWidth());
}

repaint();
return;
}
if (previewHover)
{
setTooltip("Click to preview from " + timeString);

Image icon(Image::ARGB, 30, 30, true);
Graphics g(icon);


Path p;
p.loadPathFromData(LoopIcons::preview, sizeof(LoopIcons::preview));
p.loadPathFromData(LoopIcons::preview, SIZE_OF_PATH(LoopIcons::preview));
PathFactory::scalePath(p, { 0.0f, 0.0f, 30.0f, 30.0f });
g.setColour(Colours::white);
g.fillPath(p);
Expand Down
3 changes: 3 additions & 0 deletions hi_core/hi_components/audio_components/SampleComponents.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ struct SamplerTools
SampleStartArea,
LoopArea,
LoopCrossfadeArea,
ReleaseStart,
GainEnvelope,
PitchEnvelope,
FilterEnvelope,
Expand Down Expand Up @@ -338,6 +339,8 @@ class SamplerSoundWaveform : public AudioDisplayComponent,

AreaTypes currentClickArea = AreaTypes::numAreas;

bool releaseStartIsSelected = false;

bool zeroCrossing = true;

private:
Expand Down
35 changes: 35 additions & 0 deletions hi_core/hi_sampler/sampler/ModulatorSampler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,22 @@ bool ModulatorSampler::checkAndLogIsSoftBypassed(DebugLogger::Location location)
return const_cast<MainController*>(getMainController())->getDebugLogger().checkIsSoftBypassed(this, location);
}

void ModulatorSampler::refreshReleaseStartFlag()
{
#if HISE_SAMPLER_ALLOW_RELEASE_START
ModulatorSampler::SoundIterator sIter(this);
jassert(sIter.canIterate());

soundsHaveReleaseStart = false;

while (auto sound = sIter.getNextSound())
{
auto s = sound->getReferenceToSound();
soundsHaveReleaseStart |= s->isReleaseStartEnabled();
}
#endif
}

void ModulatorSampler::refreshCrossfadeTables()
{
ModulatorSynth::setVoiceLimit(realVoiceAmount * getNumActiveGroups());
Expand Down Expand Up @@ -1277,6 +1293,24 @@ void ModulatorSampler::noteOff(const HiseEvent &m)
{
if (!oneShotEnabled)
{
#if HISE_SAMPLER_ALLOW_RELEASE_START
if(soundsHaveReleaseStart)
{
for (auto v : activeVoices)
{
if(v->getCurrentHiseEvent().getEventId() == m.getEventId())
{
auto s = static_cast<ModulatorSamplerSound*>(v->getCurrentlyPlayingSound().get());

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

ModulatorSynth::noteOff(m);
}
}
Expand Down Expand Up @@ -1843,6 +1877,7 @@ bool ModulatorSampler::preloadAllSamples()
sound->setReversed(isReversed);
}

refreshReleaseStartFlag();
refreshMemoryUsage();
setShouldUpdateUI(true);
setHasPendingSampleLoad(false);
Expand Down
5 changes: 4 additions & 1 deletion hi_core/hi_sampler/sampler/ModulatorSampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,9 @@ class ModulatorSampler: public ModulatorSynth,
double getCurrentTimestretchRatio() const;

PolyHandler& getSyncVoiceHandler() { return syncVoiceHandler; }


void refreshReleaseStartFlag();

private:

scriptnode::PolyHandler syncVoiceHandler;
Expand Down Expand Up @@ -839,6 +841,7 @@ class ModulatorSampler: public ModulatorSynth,
bool crossfadeGroups;
bool purged;
bool deactivateUIUpdate;
bool soundsHaveReleaseStart = false;
int rrGroupAmount;
//int currentRRGroupIndex;

Expand Down
36 changes: 35 additions & 1 deletion hi_core/hi_sampler/sampler/ModulatorSamplerData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ SampleMap::SampleMap(ModulatorSampler *sampler_):
sampleMapId(Identifier()),
data("samplemap"),
mode(data, Identifier("SaveMode"), nullptr, 0)
#if HISE_SAMPLER_ALLOW_RELEASE_START
, releaseStartOptions(new StreamingHelpers::ReleaseStartOptions())
#endif
{
data.addListener(this);

Expand Down Expand Up @@ -391,7 +394,7 @@ void SampleMap::parseValueTree(const ValueTree &v)
if(!sampler->isRoundRobinEnabled()) sampler->refreshRRMap();

sampler->refreshMemoryUsage();

sampler->refreshReleaseStartFlag();
};

const ValueTree SampleMap::getValueTree() const
Expand Down Expand Up @@ -472,6 +475,37 @@ void SampleMap::saveAndReloadMap()
changeWatcher = new ChangeWatcher(data);
}

void SampleMap::suspendInternalTimers(bool shouldBeSuspended)
{
notifier.asyncUpdateCollector.suspend(shouldBeSuspended);
}

#if HISE_SAMPLER_ALLOW_RELEASE_START
void SampleMap::setReleaseStartOptions(StreamingHelpers::ReleaseStartOptions::Ptr newOptions)
{
if(releaseStartOptions != newOptions)
{
releaseStartOptions = newOptions;
ModulatorSampler::SoundIterator iter(getSampler());

while(auto s = iter.getNextSound())
{
auto numMultimics = s->getNumMultiMicSamples();

if(numMultimics == 1)
{
s->getReferenceToSound()->setReleaseStartOptions(newOptions);
}
else
{
for(int i = 0; i < numMultimics; i++)
s->getReferenceToSound(i)->setReleaseStartOptions(newOptions);
}
}
}
}
#endif

void SampleMap::valueTreePropertyChanged(ValueTree& treeWhosePropertyHasChanged, const Identifier& property)
{
if (treeWhosePropertyHasChanged == data)
Expand Down
Loading

0 comments on commit 79019ea

Please sign in to comment.