Up until now, the Delay effect has allowed users to specify the amount of delay in seconds. A brand new feature in version 1.10.0 of Decent Sampler adds the possibility of syncing the delay time to the host clock, and allowing users to specify their delay time in musical time units (eg. quarter notes, eighth notes, etc.). In this article, we’ll talk about how to make use of this new functionality.
1. Getting Started
The patch we are going to be working with is just a basic triangle wave sample library. This is what the code looks like:
<?xml version="1.0" encoding="UTF-8"?>
<DecentSampler>
<ui>
<tab></tab>
</ui>
<effects></effects>
<groups attack="0.0" decay="1.0" sustain="0.0" release="1.75" ampVelTrack="0.3">
<! -- sample definitions are here -->
</groups>
</DecentSampler>
Code language: HTML, XML (xml)
(For the sake of brevity, I’ve removed the portions of the code listings that contain the sample definitions, as they are not important for this tutorial.) As you can see, the UI is blank and there are no effects added yet. By the way, if you wish to follow along, this starting code can be found here in the file labeled Step 1.
2. Adding the Basic Delay Effect
Our first order of business is to add in the delay effect as well as some knobs to control it. Here how that looks:
<?xml version="1.0" encoding="UTF-8"?>
<DecentSampler>
<ui>
<tab>
<labeled-knob x="180" y="40" label="Delay Time" valueType="float" minValue="0" maxValue="5" value="0.5">
<binding type="effect" level="instrument" position="0" parameter="FX_DELAY_TIME" translation="linear"/>
</labeled-knob>
<labeled-knob x="280" y="40" label="Feedback" valueType="float" minValue="0" maxValue="1" value="0.5">
<binding type="effect" level="instrument" position="0" parameter="FX_FEEDBACK" translation="linear"/>
</labeled-knob>
<labeled-knob x="380" y="40" label="Stereo Offset" valueType="float" minValue="0" maxValue="1" value="0.01">
<binding type="effect" level="instrument" position="1" parameter="FX_STEREO_OFFSET" translation="linear"/>
</labeled-knob>
<labeled-knob x="480" y="40" label="Wet Level" valueType="float" minValue="0" maxValue="1" value="1">
<binding type="effect" level="instrument" position="0" parameter="FX_WET_LEVEL" translation="linear"/>
</labeled-knob>
</tab>
</ui>
<effects>
<effect type="delay" delayTime="0.5" stereoOffset="0.01" feedback="0.2" wetLevel="0.5" />
</effects>
<groups attack="0.0" decay="1.0" sustain="0.0" release="1.75" ampVelTrack="0.3">
<! -- sample definitions are here -->
</groups>
</DecentSampler>
Code language: HTML, XML (xml)
As you can see, we’ve added our delay in on line 21. In lines 6 through 17, we’ve added in some controls that let us fine-tune various aspects of our delay effect. In this article, we’re going to be focusing almost exclusively on that first control: Delay Time. Right now, the delay effect is receiving information about how long the delay should be from that first control in seconds. The control has a valueType
of float
, which stands for “floating-point number”, which is the default valueType
. This basically means that the number that control is going to output will be anything between the minimum and the maximum. In other words, it could be a whole number, it could be fractional, float
means that pretty much anything goes.
(If you wish to see this iteration of the code, it can be found here in the file labeled Step 2.)
3. Adding in tempo syncing
Up until now, we’ve been specifying our time in seconds, and, even if the plugin is being run within some host software, the delay time is not being synced to the tempo of that software at all. Let’s change that. Here’s what the new code looks like:
<?xml version="1.0" encoding="UTF-8"?>
<DecentSampler>
<ui>
<tab>
<labeled-knob x="180" y="40" label="Delay Time" valueType="musical_time" value="10">
<binding type="effect" level="instrument" position="0" parameter="FX_DELAY_TIME"/>
</labeled-knob>
<!-- more knob definitions we don't care about right now -->
</tab>
</ui>
<effects>
<effect type="delay" delayTimeFormat="musical_time" delayTime="0.5" stereoOffset="0.01" feedback="0.2" wetLevel="0.5" />
</effects>
<groups attack="0.0" decay="1.0" sustain="0.0" release="1.75" ampVelTrack="0.3">
<! -- sample definitions are here -->
</groups>
</DecentSampler>
Code language: HTML, XML (xml)
There are two important things to note here:
First, on line 6, we’ve changed the valueType
of our Delay Time knob to musical_time
. This is a special, magic value that will cause the control to display a series of standard musical time increments. For those curious, here are the actual time increments that will be used: 1/64 triplet, 1/64, 1/32 triplet, 1/64 dotted, 1/32, 1/16 triplet, 1/32 dotted, 1/16, 1/8 triplet, 1/16 dotted, 1/8, 1/4 triplet, 1/8 dotted, 1/4, 1/2 triplet, 1/4 dotted, 1/2, 1 triplet, 1/2 dotted, 1, 1/1 dotted. On the back end, this will be transmitted out to the delay effect as a whole number from 0 to 20.
Of course, our delay effect was set to expect its time in seconds, right? So if we were to leave the Delay effect alone, it would misinterpret that special magic number coming from the knob as a value in seconds. To fix this, we’ve added a brand new delayTimeFormat="musical_time"
attribute to the <effect>
element on line 13. Now, the Delay effect knows that its time is being set using the special magic array of musical time options. For example, if it receives a value of 4 from a binding, it no knows that that does not mean 0 seconds, it means 1/32 note relative to whatever the host tempo is.
By the way, if you wish to see this iteration of the code, it can be found here in the file labeled Step 3. It already works really nicely.
4. Adding a knob that allows the user to switch between Seconds and Musical Time
So you may be wondering what happens if the plug-in is being run in standalone mode. Well, in such a situation, DecentSampler isn’t able to receive a tempo from the host software, so it defaults to 120 beats per minute. Because of this scenario, it is often wise to include a button that lets users switch between musical time and clock time. Here’s how we do that:
<?xml version="1.0" encoding="UTF-8"?>
<DecentSampler>
<ui>
<tab>
<label x="101" y="57" width="80" height="30" text="Tempo Sync" textSize="15" />
<button x="101" y="90" width="80" height="30" value="0">
<state name="On">
<binding type="effect" level="instrument" position="0" parameter="FX_DELAY_TIME_FORMAT" translation="fixed_value" translationValue="musical_time" />
<binding type="control" level="ui" position="2" parameter="VALUE_TYPE" translation="fixed_value" translationValue="musical_time" />
<binding type="control" level="ui" position="2" parameter="VALUE" translation="fixed_value" translationValue="10" />
</option>
<state name="Off">
<binding type="effect" level="instrument" position="0" parameter="FX_DELAY_TIME_FORMAT" translation="fixed_value" translationValue="seconds" />
<binding type="control" level="ui" position="2" parameter="VALUE_TYPE" translation="fixed_value" translationValue="float" />
<binding type="control" level="ui" position="2" parameter="VALUE" translation="fixed_value" translationValue="0.25" />
<binding type="control" level="ui" position="2" parameter="MIN_VALUE" translation="fixed_value" translationValue="0" />
<binding type="control" level="ui" position="2" parameter="MAX_VALUE" translation="fixed_value" translationValue="5" />
</option>
</button>
<labeled-knob x="180" y="40" label="Delay Time" valueType="musical_time" value="10">
<binding type="effect" level="instrument" position="0" parameter="FX_DELAY_TIME"/>
</labeled-knob>
<!-- a bunch of controls we don't care about right now -->
</tab>
</ui>
<effects>
<effect type="delay" delayTimeFormat="musical_time" delayTime="0.5" stereoOffset="0.01" feedback="0.2" wetLevel="0.5" />
</effects>
<groups attack="0.0" decay="1.0" sustain="0.0" release="1.750873208045959" ampVelTrack="0.3">
<groups attack="0.0" decay="1.0" sustain="0.0" release="1.75" ampVelTrack="0.3">
<! -- sample definitions are here -->
</groups>
</DecentSampler>
Code language: HTML, XML (xml)
Woah, there’s a lot here! Let’s walk through it line by line: On line 6, we’ve added is a label. This is purely for descriptive purposes. Next, we’ve got a button with two states. Each state has a number of different bindings as each time the state gets changed, we are not only going to be changing effect’s settings, but also the settings for the Delay Time knob. Here is what is happening in each of the two states:
In the “On” state, on line 9, we change the delayTimeFormat
setting to musical_time
for the Delay effect. After that, on line 10, we set the valueType
to musical_time
for our Delay Time knob (which has an index of 2). Finally, one line 11, we set a value so that when the user switches states, the control doesn’t get set to some random value. In this case, I’ve decided to set it to 10, which corresponds to eighth notes in the magical musical_time
numbering system.
Moving on, let’s look at the “Off” state. The first thing we do when time sync is switched off is, on line 14, we change the delayTimeFormat
setting to seconds
for the Delay effect. After that, on line 15, we set the valueType
to float
for our Delay Time knob. Next, on line 16, we set a value so that when the user switches states, the control doesn’t get set to some random value. In this case, I’ve decided to set it to 0.25 seconds, which corresponds to eighth notes if the tempo were 120BPM. This was arbitrary decision on my part, but it seems to sound nice. Last but not least, on lines 17 and 18, we set minimum and maximum values for our control. We do this because before, when our control was in musical_time mode, its minimum and maximum values are automatically set to 0 and 20, respectively in order to accommodate the musical time system. We now need to reset them to plausible limits.
This final version of the code can be found here in the labeled Step 4.
Conclusion
I know this last case seems like a lot of code, and it may, at first, be a bit confusing. The good news is that for the most part you can just copy and paste the code above into your projects. Just make sure you change those pesky position
values within the bindings, so that the bindings actual point to the controls and effects you want to change. 😉
Enjoy!
– Dave
Neat!
This is great, but would it be possible to go to values over one bar? E.g. adding values 21, 21, 23, 24 for 2/1, 3/1, 4/1 and 5/1? This would allow loop like behaviour, which I often do with the millisecond based delay values.
Thanks!
That’s a good idea! I will add it into the next version.