Sampler
The Sampler
object can be used to access sampler-specific properties, like loading samplemaps, changing sample properties, setting the current RR index, etc.
If you have a generic reference obtained by calling Synth.getChildSynth()
, you can turn it into a Sampler reference with ChildSynth.asSampler()
:
const var Sampler1 = Synth.getChildSynth("Sampler1");
Sampler1.asSampler().loadSampleMap("My SampleMap");
Be aware that most of the functions that change samples will be executed asynchronously - if you want to keep your UI updated, take a look at ScriptPanel.setLoadingCallback()
Class methods
clearSampleMap
Clears the current samplemap. Edit on GitHub
Sampler.clearSampleMap()
createListFromGUISelection
Returns a list of the sounds selected in the samplemap. Edit on GitHub
Sampler.createListFromGUISelection()
createListFromScriptSelection
Returns a list of the sounds selected by the selectSounds() method. Edit on GitHub
Sampler.createListFromScriptSelection()
createSelection
Returns an array with all samples that match this regex. Edit on GitHub
Sampler.createSelection(String regex)
createSelectionFromIndexes
Returns an array with all samples from the index data (can be either int or array of int, -1 selects all.). Edit on GitHub
Sampler.createSelectionFromIndexes(var indexData)
createSelectionWithFilter
Returns an array with all samples that match the filter function. Edit on GitHub
Sampler.createSelectionWithFilter(var filterFunction)
enableRoundRobin
Enables / Disables the automatic round robin group start logic (works only on samplers). Edit on GitHub
Sampler.enableRoundRobin(bool shouldUseRoundRobin)
getActiveRRGroup
Returns the currently (single) active RR group.
Sampler.getActiveRRGroup()
If you have set the active group using the API call Sampler.setActiveGroupForEventId()
, then you need to use the function Sampler.getActiveGroupForEventId()
to query the specific group for the given event ID.
getActiveRRGroupForEventId
Returns the RR group that is associated with the event ID.
Sampler.getActiveRRGroupForEventId(int eventId)
This returns the group index for the given event ID. Be aware that the lifetime of this information is very short (only between calling the function setActiveGroupForEventId()
and the next audio render callback). If you call this function with a "dangling" event ID (an event ID that was already processed or discarded after the audio render callback), it will simply return the active RR group (so basically the same as getActiveRRGroup()
).
getAttribute
Gets the attribute with the given index (use the constants for clearer code). Edit on GitHub
Sampler.getAttribute(int index)
getAttributeId
Returns the ID of the attribute with the given index. Edit on GitHub
Sampler.getAttributeId(int index)
getAttributeIndex
Returns the index of the attribute with the given ID. Edit on GitHub
Sampler.getAttributeIndex(String id)
getAudioWaveformContentAsBase64
Converts the user preset data of a audio waveform to a base 64 samplemap. Edit on GitHub
Sampler.getAudioWaveformContentAsBase64(var presetObj)
getCurrentSampleMapId
Returns the currently loaded sample map. Edit on GitHub
Sampler.getCurrentSampleMapId()
getMicPositionName
Returns the name of the channel with the given index (Multimic samples only. Edit on GitHub
Sampler.getMicPositionName(int channelIndex)
getNumActiveGroups
Returns the number of currently active groups. Edit on GitHub
Sampler.getNumActiveGroups()
getNumAttributes
Returns the number of attributes. Edit on GitHub
Sampler.getNumAttributes()
getNumMicPositions
Returns the number of mic positions. Edit on GitHub
Sampler.getNumMicPositions()
getNumSelectedSounds
Returns the amount of selected samples. Edit on GitHub
Sampler.getNumSelectedSounds()
getReleaseStartOptions
Returns the current release start options as JSON object. Edit on GitHub
Sampler.getReleaseStartOptions()
getRRGroupsForMessage
Returns the amount of actual RR groups for the notenumber and velocity Edit on GitHub
Sampler.getRRGroupsForMessage(int noteNumber, int velocity)
getSampleMapAsBase64
Returns a base64 compressed string containing the entire samplemap. Edit on GitHub
Sampler.getSampleMapAsBase64()
getSampleMapList
Returns an array with all available sample maps. Edit on GitHub
Sampler.getSampleMapList()
getSoundProperty
Returns the property of the sound with the specified index. Edit on GitHub
Sampler.getSoundProperty(int propertyIndex, int soundIndex)
getTimestretchOptions
Returns the current timestretching options as JSON object. Edit on GitHub
Sampler.getTimestretchOptions()
importSamples
Loads a few samples in the current samplemap and returns a list of references to these samples. Edit on GitHub
Sampler.importSamples(var fileNameList, bool skipExistingSamples)
isMicPositionPurged
Checks if the mic position is purged. Edit on GitHub
Sampler.isMicPositionPurged(int micIndex)
isNoteNumberMapped
Checks whether the note number is mapped to any samples. Edit on GitHub
Sampler.isNoteNumberMapped(int noteNumber)
loadSampleForAnalysis
Loads the content of the given sample into an array of VariantBuffers that can be used for analysis. Edit on GitHub
Sampler.loadSampleForAnalysis(int indexInSelection)
loadSampleMap
Loads a new samplemap into this sampler.
Sampler.loadSampleMap( String fileName)
This method will return immediately and load a new samplemap on a background thread.
If you want to be notified when the sample loading has finished, you will need to create a Panel and add a PreloadingCallback using setLoadingCallback()
loadSampleMapFromBase64
Loads a base64 compressed string with the samplemap.
Sampler.loadSampleMapFromBase64( String b64)
This will load a samplemap that was previously exported with getSampleMapAsBase64()
and is particularly useful if you want to store a custom samplemap in a user preset.
loadSampleMapFromJSON
Loads a samplemap from a list of JSON objects.
Sampler.loadSampleMapFromJSON(var jsonSampleMap)
This function will take an array of JSON objects describing a sample and load it as samplemap. So the days of dragging around a AudioLoop Player just for the user sample import are finally over.The data you need to pass in must have the following format:
[
{
"FileName": "C:\\MyFileName.wav",
"Root": 64
},
{
"FileName": "C:\\AnotherSample.wav",
"SampleStart": 64
}];
You can use every property ID that is used in a standard XML samplemap (take a look at one of your samplemaps for inspiration).
If you want to leverage the relative file format using the {PROJECT_FOLDER}
wildcard when you are trying to load a sample that is in the actual sample folder of your plugin take a look at File.getReferenceString()
Be aware that you are responsible to store and restore this data in a user preset. The most practical way to do this is to use Sampler.getSampleMapAsBase64()
as this will also take into account if you drag the sample range in an audiowaveform - you could also just save and restore that JSON array that you pass in, but then you will lose all changes you might to to the samplemapping afterwards.
loadSfzFile
Loads an SFZ file into the sampler.
Sampler.loadSfzFile(var sfzFile)
This function expects either a String with a full path to the SFZ file or a File
object and will try to parse it and load the multisample set into the Sampler. This finally enables you to offer multisample import on your compiled plugin! Be aware that if you load a SFZ file, the sampler will not store this information automatically, so you need to add a UI component that stores that information and calls this function in its control callback. A suitable candidate for this would be a ScriptPanel with file-drop support using this API function
The SFZ importer is not fully standard compliant (at this point it's just the old HISE SFZ import that has been cleaned up a little bit). However the goal is to offer enough standard compliance so that all mapping information of a SFZ is being imported correctly and without crashing the plugin (obviously stuff like the envelope attack time will never be parsed). If you encounter an issue with a SFZ file, please post it in the forum, then I'll take a look.
parseSampleFile
Creates a JSON object from the sample file that can be used with loadSampleMapFromJSON. Edit on GitHub
Sampler.parseSampleFile(var sampleFile)
purgeMicPosition
Purges all samples of the given mic (Multimic samples only). Edit on GitHub
Sampler.purgeMicPosition(String micName, bool shouldBePurged)
purgeSampleSelection
Purges the array of sampler sounds (and unpurges the rest). Edit on GitHub
Sampler.purgeSampleSelection(var selection)
refreshInterface
Refreshes the interface. Call this after you changed the properties. Edit on GitHub
Sampler.refreshInterface()
refreshRRMap
Recalculates the RR Map. Call this at compile time if you want to use 'getRRGroupForMessage()'. Edit on GitHub
Sampler.refreshRRMap()
saveCurrentSampleMap
Saves (and loads) the current samplemap to the given path (which should be the same string as the ID). Edit on GitHub
Sampler.saveCurrentSampleMap(String relativePathWithoutXml)
selectSounds
Selects samples using the regex string as wildcard and the selectMode ("SELECT", "ADD", "SUBTRACT") Edit on GitHub
Sampler.selectSounds(String regex)
setActiveGroup
Enables the group with the given index (one-based). Works only with samplers and enableRoundRobin(false)
.
Sampler.setActiveGroup(int activeGroupIndex)
Note: if you need to rely on this function to set the event ID for a given note with 100% accuracy, you need to use this method instead .
setActiveGroupForEventId
Enables the group with the given index (one-based) for the given event ID. Works only with samplers and enableRoundRobin(false)
.
Sampler.setActiveGroupForEventId(int eventId, int activeGroupIndex)
Usually the Sampler.setActiveGroup
function is all you need in order to programmatically set the round robin group. However there are a few edge cases where this function leads to inaccurate behaviour: if you play multiple notes pretty fast (we're talking about a few milliseconds between events), the MIDI event queue contains more than one note on message per audio buffer. In this case the internal processing order will override the active group index of the last API call before the voices get started. This might result in voices being started with a different group index than it was set during the MIDI callback execution
.
Usually this isn't problematic because the result is just that it will pick another RR group as desired and if you use this for actual round robin repetitions there is almost no perceivable change in the sound (because chances are great that notes that are being played this fast will be different notes which masks the machine gun effect we're trying to prevent here).
However there are a few use cases where this becomes a problem so in order to ensure that the group index that you've set during the MIDI callback is guaranteed to be the one that is picked up by the voice allocation logic a few CPU cycles down the line, you will have to use this method instead which takes in the event ID of the message that is about to start the next voice and store it in a internal queue until the voice allocator will use it to set it to the exact group index you've specified here.
This queue has a very limited lifetime and will get automatically cleared after each audio render callback of the sampler. This ensures that it won't stack up "unused" notes, but this also means that this procedure does not work with events that are not processed immediately (eg. because you've delayed them using Message.delayEvent()
after calling this method).
The method also works with artificial notes and the internal event queue can store up to 64 note on messages (there's a tradeoff between object size and functionality here but with 64 messages within a single audio callback you should have enough headroom for even the most craziest applications).
setAttribute
Sets a attribute to the given value. Edit on GitHub
Sampler.setAttribute(int index, var newValue)
setGUISelection
Sets the currently selected samples on the interface to the given list. Edit on GitHub
Sampler.setGUISelection(var sampleList, bool addToSelection)
setMultiGroupIndex
Enables the group with the given index (one-based). Allows multiple groups to be active.
Sampler.setMultiGroupIndex(var groupIndex, bool enabled)
This function can be used to enabled multiple groups at once. By default, only one RR group is active at the same time - as long as the Group XF property is disabled, then it will play all groups.
You can define a custom RR behaviour using Sampler.setActiveGroup() , but this function still gives you one exclusively active group.
However there are a few legitimate edge cases where you need multiple, but not all groups enabled - the most common one might be if you want to implement round robin behaviour in combination with Group XF samples.
In order to do so, you can use this function to tell the sampler to allow multiple groups at the same time - you also need to call Sampler.enableRoundRobin(false)
before using this function. The function accepts different types as groupIndex
argument:
- an integer (be aware that it's one based to match the other RR functions).
- an array with integers (also one-based). This can be used to predefine static ranges at initialisation and then just pass those arrays in the function to avoid writing loops in HiseScript
- a MidiList
. In that case, the
enabled
argument will be discarded and it will enable all groups where the MidiList has a valid entry (!= -1
).
Be aware that as soon as you activate this feature by calling this method, the table index used for defining the crossfade gain will be capped to the number of active groups (groupIndex %= numActiveGroups
). The rationale behind this is that if you have 4 dynamic layers and 3 round robin repetitions, you still want only 4 tables to be active (instead of 12). However this means that as soon as you use this feature the amount of dynamic layers must be consistent across RR repetitions
.
// A simple example for 2 dynamic layers with 2 RR repetitions.
Sampler.enableRoundRobin(false);
const var g1 = [1, 2, 3];
const var g2 = [4, 5, 6];
reg on = false;
function onNoteOn()
{
// Calling this function tells the sample to just use
// the first 3 tables for crossfading
Sampler.setMultiGroupIndex(g1, on);
Sampler.setMultiGroupIndex(g2, !on);
on = !on;
}
Note: if you're using this function in the onNoteOn
callback and must ensure that the correct group index state is applied to the current note on message, you will need to use the Sampler.setMultiGroupIndexForEventId()
method which takes in the event ID of the current note. More information about this issue can be found here
.
setMultiGroupIndexForEventId
Enables the group with the given index (one-based) for the given event id. Allows multiple groups to be active.
Sampler.setMultiGroupIndexForEventId(int eventId, var groupIndex, bool enabled)
This function is the event-ID agnostic variant of setMultiGroupIndex()
. In order to find out which function to use, take a look at this function
for a description of the problem.
setReleaseStartOptions
Sets the options for the release start behaviour.
Sampler.setReleaseStartOptions(var newOptions)
This will set the options for the ReleaseStart
playback mode. Usually you will combine this call with getReleaseStartOptions
which returns a JSON object with all properties:
const var obj = Sampler.getReleaseStartOptions();
obj.FadeGamma = 0.5;
Sampler.setReleaseStartOptions(obj);
setRRGroupVolume
Sets the volume of a particular group (use -1 for active group). Only works with disabled crossfade tables. Edit on GitHub
Sampler.setRRGroupVolume(int groupIndex, int gainInDecibels)
setSortByRRGroup
Enables a presorting of the sounds into RR groups. This might improve the performance at voice start if you have a lot of samples (> 20.000) in many RR groups. Edit on GitHub
Sampler.setSortByRRGroup(bool shouldSort)
setSoundProperty
Sets the property for the index within the selection. Edit on GitHub
Sampler.setSoundProperty(int soundIndex, int propertyIndex, var newValue)
setSoundPropertyForAllSamples
Sets the property for all samples of the sampler. Edit on GitHub
Sampler.setSoundPropertyForAllSamples(int propertyIndex, var newValue)
setSoundPropertyForSelection
Sets the property of the sampler sound for the selection. Edit on GitHub
Sampler.setSoundPropertyForSelection(int propertyIndex, var newValue)
setTimestretchOptions
Sets the timestretching options from a JSON object.
Sampler.setTimestretchOptions(var newOptions)
This will set the timestretching
options for the sampler using a JSON object. Usually you would get that object with Sampler.getTimestretchOptions()
, apply your changes and then call this function with the modified object.
setTimestretchRatio
Sets the timestretch ratio for the sampler depending on its timestretch mode.
Sampler.setTimestretchRatio(double newRatio)
This will change the time ratio of the sampler playback when timestretching is enabled.
Depending on the timestretch mode, this value will be applied to new voices or all currently active voices. For an explanation of the different modes, take a look at the Sampler Module Documentation
Currently the time ratio is limited to 50% - 200% of the original time, but that limitation might be lifted at some point.
setUseStaticMatrix
Disables dynamic resizing when a sample map is loaded. Edit on GitHub
Sampler.setUseStaticMatrix(bool shouldUseStaticMatrix)