ModulatorChain
A chain of Modulators that can be processed serially.
A ModulatorChain can hold three different types of Modulators:
- VoiceStartModulators that calculate their value only if the voice has been started.
- VariantModulators which calculate their value for each sample
- EnvelopeModulators which calculate their value for each sample and each voice
In order to make a ModulatorChain work, you have to- create one while specifying a Mode and the voice amount.
- populate it with modulators via getHandler()
->addModulator().
- overwrite getNumChildProcessors()
, getNumInternalChains()
and getChildProcessor()
(const and not const)
In your code you have to call all these methods at the appropriate time / place:
- initialize it with the sample rate and the block size via 'prepareToPlay()
'
- initialize a buffer that will store the modulation values.
- call the functions handleMidiEvent() and renderNextBlock() to make sure it gets the midi messages and does its processing.
- call the functions startVoice()
, stopVoice()
, renderVoice(), and reset()
for every voice that should use this chain. (Skip this for monophonic modulation
You might want to use the functions shouldBeProcessed(), isPlaying()
, getVoiceValues()
For an example usage of an polyphonic ModulatorChain, take a look at the WavetableSynth class. For an example usage of an monophonic ModulatorChain, the LfoModulator class is your friend.
Class Hierarchy
Base Classes
- hise::Chain
hise::EnvelopeModulator
Class methods
ModulatorChain
ModulatorChain(MainController *mc, const String &id, int numVoices, Modulation::Mode m, Processor *p)
Creates a new modulator chain. You have to specify the voice amount and the Modulation::Mode
createEditor
ProcessorEditorBody * createEditor(ProcessorEditor *parentEditor) override
Creates a ProcessorEditor for this Processor
and returns the pointer.
If you subclass this, just allocate a ProcessorEditor of the desired type on the heap and return it. Remember to pass the Processor
as parameter to allow asynchronous GUI notification. The concept between Processor
and ProcessorEditor is the same as AudioProcessor and AudioProcessorEditor.
getHandler
Chain::Handler * getHandler() override
Returns the handler that is used to add / delete Modulators in the chain. Use this if you want to change the modulator.
getHandler
const Chain::Handler * getHandler() const override
read only access to the Handler.
getFactoryType
FactoryType * getFactoryType() const override
Returns the Factory type this processor is using.
getColour
Colour getColour() const override
Overwrite this method if you want a special colour.
This colour will be used in the debug console and in the editor.
setFactoryType
void setFactoryType(FactoryType *newFactoryType) override
Sets the FactoryType that will be used.
prepareToPlay
void prepareToPlay(double sampleRate, int samplesPerBlock) override
Sets the sample rate for all modulators in the chain and initialized the UpdateMerger.
getNumChildProcessors
int getNumChildProcessors() const override
Wraps the handlers method.
getChildProcessor
Processor * getChildProcessor(int processorIndex) override
Wraps the handlers method.
getParentProcessor
Processor * getParentProcessor() override
Overwrite this and return the processor that owns this chain if it exists.
getParentProcessor
const Processor * getParentProcessor() const override
Overwrite this and return the processor that owns this chain if it exists.
getChildProcessor
const Processor * getChildProcessor(int processorIndex) const override
Wraps the handlers method.
reset
void reset(int voiceIndex) override
Resets all envelopes. This can be used for envelopes that do not control the main gain value and therefore do not switch back to IDLE if the note stops playing before the envelope is finished.
Also their display is updated to clear remaining tails (that aren't cleared because of a missing update call to UpdateMerger.
handleHiseEvent
void handleHiseEvent(const HiseEvent &m) override
Sends the midi message all modulators.
You can't use the voice index here, since it is not guaranteed if the message starts a note.
isPlaying
bool isPlaying(int voiceIndex) const override
Checks if any of the EnvelopeModulators wants to keep the voice from being killed.
If no envelopes are active, it checks if the voice was recently started or stopped using an internal array.
startVoice
float startVoice(int voiceIndex) override
Calls the start voice function for all voice start modulators and envelope modulators and sends a display message.
stopVoice
void stopVoice(int voiceIndex) override
Calls the stopVoice function for all envelope modulators.
setInternalAttribute
void setInternalAttribute(int, float) override
Changes a Processor
parameter.
Overwrite this method to do your handling. Call the overloaded method with the notification type parameter for external changes.
parameterIndexthe parameter index (use a enum from the derived class)
newValuethe new value between 0.0 and 1.0
getAttribute
float getAttribute(int) const override
returns the attribute with the specified index (use a enum in the derived class).
createSubclassedState
ModulatorState * createSubclassedState(int) const override
Overwrite this method and return a newly created ModulatorState of the desired subclass. It will be owned by the Modulator
.
setIsVoiceStartChain
void setIsVoiceStartChain(bool isVoiceStartChain_)
If you want the chain to only process voice start modulators, set this to true.
newRenderMonophonicValues
void newRenderMonophonicValues(int startSample, int numSamples)
This overrides the TimeVariant::renderNextBlock method and only calculates the TimeVariant modulators.
It assumes that the other modulators are calculated before with renderVoice().
bufferthe buffer that will be filled with the values of the timevariant modulation result.
calculateBlock
void calculateBlock(int, int) override
Does nothing (the complete renderNextBlock method is overwritten.
getConstantVoiceValue
float getConstantVoiceValue(int voiceIndex) const
Iterates all voice start modulators and returns the value either between 0.0 and 1.0 (GainMode) or -1.0 ... 1.0 (Pitch Mode).