The <modulators> element ============================== Version 1.6.0 of Decent Sampler officially introduces the new `` section into the `.dspreset` format. This section lives below the top-level `` element and it is where all modulators for the entire sample library live. ```xml ``` ## The <lfo> element Underneath the `` section, you can have any number of different LFOs, which are defined using an `` element, for example: ```xml ``` This element has the following attributes: - **`shape`**: controls the oscillator shape. Possible values are `sine`, `square`, `saw`. - **`frequency`**: The speed of the LFO in cycles per second. For example, a value of 10 would mean that the waveform repeats ten times per second. - **`modAmount`**: This value between 0 and 1 controls how much the modulation affects the things it is targeting. In conventional terms, this is like the modulation depth. Default value: 1.0. - **`scope`**: Whether or not this LFO exists for all notes or whether each keypress gets its own LFO. Possible values are `global` (default for LFOs) and `voice`. If `voice` is chosen, a new LFO is started each time a new note is pressed. - **`modBehavior`**: This attribute controls how the LFO affects the parameter it is targeting. Possible values are `add`, `multiply`, and `set`. If `add` is chosen, the LFO will add its value to the parameter it is targeting. If `multiply` is chosen, the LFO will multiply its value by the parameter it is targeting. If `set` is chosen, the LFO will set the parameter it is targeting to its value. Default value: `set`. ## The <envelope> element In addition to LFOs, you can also have additional ADSR envelopes. These can be useful for controlling group-level effects, such as low-pass filters. If this is what you wish to achieve, make sure you check out the section on group-level effects below. To create an envelope, use an `` element: This element has the following attributes: - **`attack`**: The length in seconds of the attack portion of the ADSR envelope - **`decay`**: The length in seconds of the decay portion of the ADSR envelope - **`sustain`**: The height of the sustain portion of the ADSR envelope. This is expressed as a value between 0 and 1. - **`release`**: The length in seconds of the release portion of the ADSR envelope - **`modAmount`**: This value between 0 and 1 controls how much the modulation affects the things it is targeting. In conventional terms, this is like the modulation depth. Default value: 1.0. - **`scope`**: Whether or not this LFO exists for all notes or whether each keypress gets its own LFO. Possible values are `global` and `voice` (default for envelopes). If `voice` is chosen, a new LFO is started each time a new note is pressed. - **`modBehavior`**: This attribute controls how the envelope affects the parameter it is targeting. Possible values are `add`, `multiply`, and `set`. If `add` is chosen, the envelope will add its value to the parameter it is targeting. If `multiply` is chosen, the envelope will multiply its value by the parameter it is targeting. If `set` is chosen, the envelope will set the parameter it is targeting to its value. Default value: `set`. - **`attackCurve`**: A numeric value from -100 to 100 that determines the shape of the attack portion of the ADSR envelope. Common values are `-100` (logarithmic), `0` (linear), and `100` (exponential). Default value: `-100` (logarithmic). - **`decayCurve`**: A numeric value from -100 to 100 that determines the shape of the decay portion of the ADSR envelope. Common values are `-100` (logarithmic), `0` (linear), and `100` (exponential). Default value: `100` (exponential). - **`releaseCurve`**: A numeric value from -100 to 100 that determines the shape of the release portion of the ADSR envelope. Common values are `-100` (logarithmic), `0` (linear), and `100` (exponential). Default value: `100` (exponential). ## The <mpeTimbre> element The `` element allows users to control the timbre of an instrument in response to MPE messages. NOTE: In order for this to work, the plugin must be in MPE mode. This can be turned on by going into the **File > MIDI Input Settings..** dialog box. The `` element has the following attributes: - **`scope`**: Whether or not this MPE timbre exists for all notes or whether each keypress gets its own MPE timbre. Possible values are `global` and `voice` (default for MPE timbre). If `voice` is chosen, a new MPE timbre is started each time a new note is pressed. - **`risingSmoothingTime`**: The time in milliseconds it takes for the MPE timbre to rise to its target value. Default value: 0 milliseconds. - **`fallingSmoothingTime`**: The time in milliseconds it takes for the MPE timbre to fall to its target value. Default value: 0 milliseconds. Here's a practical example of how to use the `` element: ```xml ``` This example shows an MPE timbre modulator that modifies the frequency of a low-pass filter based on the MPE timbre value. This example uses a translation table to create a non-linear response curve, making the filter frequency changes more musical and intuitive. ## The <mpePressure> element The `` element allows users to control an instrument in response to MPE Pressure messages. NOTE: In order for this to work, the plugin must be in MPE mode. This can be turned on by going into the **File > MIDI Input Settings..** dialog box. The `` element has the following attributes: - **`scope`**: Whether or not this MPE pressure exists for all notes or whether each keypress gets its own MPE pressure. Possible values are `global` and `voice` (default for MPE pressure). If `voice` is chosen, a new MPE pressure is started each time a new note is pressed. - **`risingSmoothingTime`**: The time in milliseconds it takes for the MPE pressure to rise to its target value. Default value: 0 milliseconds. - **`fallingSmoothingTime`**: The time in milliseconds it takes for the MPE pressure to fall to its target value. Default value: 0 milliseconds. Here's a practical example of how to use the `` element: ```xml ``` This example shows an MPE pressure modulator that modifies the volume of a group based on the MPE pressure value. The translation is linear, meaning that the pressure value directly scales the volume between 0.5 and 1. ## How to use <binding>s in conjunction with modulators In order to actually have your LFOs and envelopes do anything, you need to have bindings under them. If you are not familiar with the concept of bindings, you may want to read [this section](https://www.decentsamples.com/wp-content/uploads/2020/06/format-documentation.html#appendix-b-the-binding-element) then return here. Bindings tell the engine which parameters the LFO should be affecting and how. Here is an example: ```xml ``` There are a few differences between bindings as they are used by knobs and the ones used by modulators. Specifically, when you move a UI control that has a binding attached, the engine actually goes out and changes the value of the parameter that is targeted by that binding. For example, if you have a knob that controls a lowpass filter's cutoff frequency, moving that knob will cause that actual frequency of that filter to change. In other words, the changes that the knob is making on the underlying sample library are _permanent_. The same is also true for bindings associated with MIDI continuous controllers. Modulators, on the other hand, are temporary. If a modulator (such as an LFO) changes its value, the engine looks at the bindings associated with that LFO and then makes a list of _temporary_ changes to the underlying data. When it comes time to render out the effect, it consults both the _permanent_ value and the _temporary_ modulation values. As a result of this difference in the way bindings are handled, only some parameters are "modulatable." At time of press, the following parameters are modulatable: - All gain effect parameters - All delay effect parameters - All phaser effect parameters - All filter effect parameters - All reverb effect parameters - All chorus effect parameters - Group Volume - Global Volume - Group Pan - Global Pan - Group Tuning - Global Tuning ## Modulator scope: global or voice-level By default, all modulators will be created at the global level. This means that there will be exactly one modulator that is shared by all voices. In many situations, such as an LFO modulating a single low-pass filter which is shared by all of voices, this is often what we want. But there are other situations where we don’t want our modulator to be global. For example, what if we want to have a unique envelope for each key-press? Well, for that we use the `scope` attribute of the `` or `` element. This attribute can be set to `voice`, which means that each time a new note is pressed, a new modulator will be created for that note. This is particularly useful for envelopes, which are often used to control parameters that are unique to each note, such as the volume or filter cutoff of a note: ```xml ``` For certain parameters, such as **Group Tuning** or **Group Pan**, it may always make sense to have `scope="voice"` set. For others, such as **Global Volume** or **Global Pan**, it may make more sense to have `scope="global"` set. For a full discussion of how to use modulators, check out [this article on the Decent Samples blog](https://www.decentsamples.com/2022/08/19/how-to-add-lfos-and-extra-envelopes-to-your-decent-sampler-instruments).