Possible Issues with HISE Source Code
-
HISE Startup / Samplemap Threading Notes (2026-01-18)
A year ago, one of the reasons I abandoned HISE was problems where Sample folder, and Samplemaps, either moved or resolved dynamically, within the context of threading. I eventually got it to work with duct tape and glue. I'm now looking at the HISE source, and the model made these suggestions (below). I'll start tinkeringāif anyone wants to help, that would be helpful. I found one bug that prompted @Christoph-Hart to promise me a t-shirt (still waiting, Chris
).Findings (HISE-PRISM)
-
Link file missing folder can still be returned
InFileHandlerBase::checkSubDirectory(), if the Link file points to a path that no longer
exists and the user cancels the dialog, HISE returns the missing path anyway. This can lead to early āsamples not foundā or missing-session problems unless script logic overrides it later.- File:
HISE-PRISM/hi_core/hi_core/PresetHandler.cpp
- File:
-
Default sample location can be auto-created before scripts run
If the Link file is missing,FrontendHandler::getSampleLocationForCompiledPlugin()selects a default location, writes a new Link file, and returns it. This happens early in startup, before your scripts can relocate sample paths.- File:
HISE-PRISM/hi_core/hi_core/PresetHandler.cpp
- File:
-
Preset load compiles scripts while sample preloading is deferred
MainController::loadPresetInternal()setssetShouldSkipPreloading(true), restores the module graph, compiles scripts, prepares audio, and sends the preset-load rebuild message before preloading resumes. This creates a timing window where scripts execute but samples are not yet loaded.
- File:
HISE-PRISM/hi_core/hi_core/MainController.cpp
- User preset restore completes before samples are preloaded
UserPresetHandler::loadUserPresetInternal()also setssetShouldSkipPreloading(true), restores state (including script controls), then callspostPresetLoad()and only afterwards callspreloadEverything().
- File:
HISE-PRISM/hi_core/hi_core/UserPresetHandler.cpp
- SampleMap change message is sent after parse, not after sample I/O
SampleMap::load()parses the ValueTree and then callssendSampleMapChangeMessage(). This notification can fire before actual sample files are fully loaded, so āsamplemap loadedā
signals may not guarantee sample availability.- File:
HISE-PRISM/hi_core/hi_sampler/sampler/ModulatorSamplerData.cpp
- File:
Implications for dynamic sample locations
- If your scripts assume samples are ready in
onInit/ preset callbacks, the above timing
windows can cause failures in workflows that relocate sample folders or load samplemaps
dynamically.
My solutions/work-arounds
Regardless of what AI has to say about it, here is what I did in my old code, that still works, for having Samples referenced dynamically. It's specific to my usage case, but anything you need should be in there. (If not, hit me up.) It should work with the codebase going back at least a year.
The way i made the samplemap dynamic was to encode them in a JSON file (using HISE's API to do that, there and back).
- Restore a known-good sample folder before Session init
Make sure user data is loaded early, and restore the last valid sample folder before
you scan for Sessions.
inline function InitalisePrism() { // ... // ------------- User Data HandleUserDataFileStartup (); // ------------- Session SESSION_SetFrameworkState("init"); }inline function HandleUserDataFileStartup () { // ... // Restore last sample location (avoids startup "samples not found" state). RestoreLastSampleFolderFromUserData(); // ... }- Populate Sessions on init, but suppress errors until startup completes
This avoids noisy error popups while still scanning the Sessions folder at startup.
inline function SESSION_SetFrameworkState (moduleState) { // ... // Populate the Sessions menu on init, but suppress errors until startup completes. if (g_executionFlags.onInitComplete && !g_executionFlags.presetLoading) SetListOfSessionDataFolders (false); else SetListOfSessionDataFolders (true); // ... }- Centralize sample-folder changes and persist them
Avoid redundant Link file writes and keep a single, tested path for recording the
last sample folder.
inline function ApplySampleFolderChange(sampleFolder) { // ... Settings.setSampleFolder(sampleFolder); RecordLastSampleFolderPath(sampleFolder); // ... }- When a Session/Articulation is chosen: set the sample folder, load the map, reload samples
This ensures the Link file is updated before sample IO begins.
if (g_articulationData) { // Load the Samplemap, which should be embedded in the plugin. local sampleMapName = GetSessionDataGenus("samplemap"); // ... mySampler.loadSampleMap(sampleMapName); // ... ApplySampleFolderChange(sampleFolder); Engine.reloadAllSamples (); } -
-
@clevername27 said in Possible Issues with HISE Source Code:
Workarounds generally require gating logic (eg. deferring UI/parameter restores until the
samplemap has fully loaded), or forcing the Link file to a valid location before startup
checks runLoading samples will always be asynchronous. What do you suggest instead?
-
@David-Healey You're right, and HISE already solves that problem quite elegantly. I've removed that text.
-
@clevername27 The same thing applies to the other paragraph. You can't assume at
on initthat samples are loaded, it's an asynchronous process. The best thing would be to have a broadcaster that fires once the samples are loaded. -
Oh actually it looks like there already is one
https://docs.hise.dev/scripting/scripting-api/broadcaster/index.html#attachtosamplemap
-
@David-Healey (Thank you.) Yes, that was one of the nice things that @Christoph-Hart did, and it solved an issue where (as I recall) the old callback would fire before the samplemap actually loaded. (EDIT: It. may have been your idea, lol.)