Posted on 3 Comments

For Sample Creators: How to Add Tempo-Synced Delay to your Instruments

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

Posted on Leave a comment

For Sample Creators: Changing Sample Start, End, and Loop Points using GUI controls

I have added a few things to the sampler in version 1.9.18:

  1. There’s experimental support for FLAC files.
  2. It’s now possible to assign knobs to the start and end point of samples, as well as their loop points.
  3. It’s now possible to dictate the playback engine that is used by a sample library.

Now, the first item above is probably pretty self-explanatory, this blog post is going to concern itself with items 2 and 3.

How To Manipulate Start, End, and Loop Points

To change a sample’s start, end, loop start, or loop end, simply use the SAMPLE_START, SAMPLE_END, LOOP_START, and LOOP_END parameter names, respectively. Here is some sample code:

<labeled-knob x="445" y="75" width="90" textSize="16" textColor="AA000000" 
                    trackForegroundColor="CC000000" trackBackgroundColor="66999999" 
                    label="Start" type="integer" minValue="0" maxValue="24000" value="0" >
        <binding type="general" level="group" position="0" parameter="SAMPLE_START" />
      </labeled-knob>
      <labeled-knob x="515" y="75" width="90" textSize="16" textColor="AA000000" 
                    trackForegroundColor="CC000000" trackBackgroundColor="66999999" 
                    label="End" type="float" minValue="0.0" maxValue="24000" value="24000" >
        <binding type="general" level="group" position="0" parameter="SAMPLE_END" />
      </labeled-knob>
      <labeled-knob x="585" y="75" width="90" textSize="16" textColor="AA000000" 
                    trackForegroundColor="CC000000" trackBackgroundColor="66999999" 
                    label="Loop Start" type="float" minValue="0.0" maxValue="24000" value="0" >
        <binding type="general" level="group" position="0" parameter="LOOP_START" />
      </labeled-knob>
      <labeled-knob x="655" y="75" width="90" textSize="16" textColor="FF000000"
                    trackForegroundColor="CC000000" trackBackgroundColor="66999999"
                    label="Loop End" type="float" minValue="0" maxValue="24000" value="24000">
        <binding type="general" level="group" position="0" parameter="LOOP_END" />
      </labeled-knob>
Code language: HTML, XML (xml)

In order for this to work properly the sample playback engine must be in RAM/Memory mode (not disk streaming), otherwise you will get very unpredictable results. In order to enforce this, sample creators should use the new playbackMode attribute, which is explained in the next section…

Playback Engines

As you may know, there are two playback modes: the memory mode stores a samples in memory, whereas the disk streaming mode caches only the beginning of each sample, and then uses a series of threads to grab data as needed. Because the memory mode has all of the data it could possible need in its memory already, it is far more flexible in terms of what can be accomplished with it, but, since it loads the entire sample into memory, it can also use up a lot of RAM for large sample libraries. Currently, users can change their playback mode by going into the preferences screen and choosing a new Sample Engine Mode:

97% of the time, this is exactly what you want: the user choosing their own playback system. The problem is that some sample libraries work much better with one mode vs the other. If the sample library has knobs bound to start, end, loopStart, or loopEnd, then being in RAM mode is actually required. Of course, no sample creator wants to have to tell their users “Oh, by the way, make sure you switch playback modes in the preferences before you use my new sample library.” The solution is the playbackMode attribute. It has three possible modes: memory, disk_streaming and auto(default). When a value of memory is used, the sample will be played back using the memory mode as though the user had that playbackEngine selected in the preferences.

OK. I think that’s it. Enjoy!

– Dave

Posted on Leave a comment

For Sample Creators: How to use the Wavefolder and Waveshaper effects

Oscilloscope view of a sawtooth wave form that has been folding back on itself.

Decent Sampler v1.7.3 introduces the new wave folder and wave shaper effects. These can be used to add extra harmonic content to your signals (aka distortion). What both of these effects have in common is that they usually sound much better when applied to a single voice rather than to an entire signal. In Decent Sampler, it is possible to apply effects at the voice level by attaching them to groups. Since each group is triggered independently, they do not share effects. In other words, each time you hit a key, a new copy of that voice will be created.

Wave folder

The wave_folder effect allows you to fold a waveform back on itself. This is very useful for generating additional harmonic content. Here is what that looks like in practice:

Oscilloscope view of a sawtooth wave form before wavefolding
Sawtooth waveform before wavefolding
Oscilloscope view of a sawtooth wave form after wavefolding
The same sawtooth wave form after wavefolding

These are the parameters that can be controlled:

AttributeTypeValid RangeDefault
typeRequiredMust be wave_folderwave_folder
driveOptionalThe volume of the input signal1 – 100, where 100 means the signal is amplified by a factor of 100 and 1 means no amplification is applied1
thresholdOptionalThe amplitude above which wave folding should take place0 – 10.00.25
Wavefolder parameters

Because wave folding tends to sound better when applied on a per-voice basis, it usually makes sense to set up the wave folder at the group level (separate group effects get created for each keypress). Example:

<?xml version="1.0" encoding="UTF-8"?>
<DecentSampler pluginVersion="1">
  <ui>
    <tab>
      <labeled-knob x="180" y="40" label="Drive" type="float" minValue="1" maxValue="100" textColor="FF000000" value="1">
        <binding type="effect" level="group" groupIndex="0" effectIndex="1" parameter="FX_DRIVE" translation="linear" />
      </labeled-knob>
      <labeled-knob x="280" y="40" label="Threshold" type="float" minValue="0" maxValue="1" value="1" textColor="FF000000">
        <binding type="effect" level="group" groupIndex="0" effectIndex="1" parameter="FX_THRESHOLD" translation="linear" />
      </labeled-knob>
    </tab>
  </ui>
  <groups>
    <group>
      <!-- samples go here -->
      <effects>
        <effect type="lowpass_4pl" resonance="1" frequency="500" />
        <effect type="wave_folder" drive="1" threshold="1" />
      </effects>
    </group>
  </groups>
  
</DecentSampler>
Code language: HTML, XML (xml)

Waveshaper

The wave_shaper effect allows you to apply standard tanh waveshaping to your input signal. Here are some examples what that looks like in practice:

An oscilloscope display of an example of sine wave before wave shaping is applied.
A sine wave before wave shaping is applied
An oscilloscope display of a sine wave after wave shaping is applied.
A sine wave after wave shaping is applied

There are a few parameters which can be controlled:

AttributeTypeValid RangeDefault
typeRequiredMust be wave_shaperwave_folder
driveOptionalThe amount of distortion. This really just controls the volume of the input signal.1 to 1000 where 1 means no change to the input signal and 1000 means the amplitude is multiplied by a factor of 1000.1
driveBoostOptionalChanges the character of distortion that gets produced0 – 1.00
outputLevelOptionalThe linear output level of the signal0 – 1.00.1
Waveshaper parameters

Because wave shaping tends to sound better when applied on a per-voice basis, it usually makes sense to set up the wave shaper at the group level (separate group effects get created for each keypress). Example:

<DecentSampler pluginVersion="1">
  <ui>
    <tab>
      <labeled-knob x="180" y="40" label="Drive" type="float" minValue="0" maxValue="1000" textColor="FF000000" value="0.5473124980926514">
        <binding type="effect" level="group" groupIndex="0" effectIndex="0" parameter="FX_DRIVE" translation="linear"/>
      </labeled-knob>
      <labeled-knob x="280" y="40" label="Boost" type="float" minValue="0" maxValue="1" value="0.328312486410141" textColor="FF000000">
        <binding type="effect" level="group" groupIndex="0" effectIndex="0" parameter="FX_DRIVE_BOOST" translation="linear"/>
      </labeled-knob>
      <labeled-knob x="380" y="40" label="Output Lvl" type="float" minValue="0" maxValue="1" value="0.1" textColor="FF000000">
        <binding type="effect" level="group" groupIndex="0" effectIndex="0" parameter="FX_OUTPUT_LEVEL" translation="linear"/>
      </labeled-knob>
    </tab>
  </ui>
  <groups>
    <group>
        <em><!-- Samples go here. --></em>
      <effects>
        <effect type="wave_shaper" drive="0.5473124980926514" driveBoost="0.328312486410141" outputLevel="0.1"/>
      </effects>
    </group>
  </groups>
Code language: HTML, XML (xml)

Examples

The examples from this blog post can be download here.

Posted on 16 Comments

For Sample Creators: How to use Convolution in your Decent Sampler presets

A spectrogram of a convolution reverb impulse response.

Version 1.6.12 of Decent Sampler brings a Convolution effect to the Decent Sampler platform. If you don’t know what Convolution is, you can see a great explanation here. The most common use case for convolution is in creating reverb, and that is the use case that will be demonstrated here.

How to add the Convolution effect to a preset

The convolution effect is invoked in much the same way that any other effect is defined:

<effects>
  <effect type="convolution" mix="0.5" irFile="Samples/Hall_IR.wav" />
</effects>Code language: HTML, XML (xml)

As you can see, other than the required type attribute, there are two other attributes:

  • The mix attribute controls how much of the convolved signal is present in the output. A value of 0 is completely dry whereas a value of 1 is completely wet containing only the convolved signal.
  • The irFile attribute specifies the file that should be used as an impulse response or IR.

How to control the convolution effect using UI controls

Two of the convolution effect’s attributes can be controlled using UI controls. The mix level can be controlled by a knob as follows:

<labeled-knob x="680" y="40" label="Conv Mix" type="float" minValue="0" maxValue="1" value="0.5" textColor="FF000000" >
  <binding type="effect" level="instrument" position="0" parameter="FX_MIX" translation="linear"  />
</labeled-knob>Code language: HTML, XML (xml)

The IR impulse can be changed dynamically using a menu control:

<label text="IR File" x="480" y="40" width="120" height="30"></label>
<menu x="580" y="40"  width="120" height="30" requireSelection="true" placeholderText="Choose..." value="1">
  <option name="long hall.wav">
    <binding type="effect" level="instrument" position="1" parameter="FX_IR_FILE" translation="fixed_value" translationValue="Samples/long hall.wav" />
  </option>
  <option name="ABLCR Chord Vocal.aif">
   <binding type="effect" level="instrument" position="1" parameter="FX_IR_FILE" translation="fixed_value" translationValue="Samples/ABLCR Chord Vocal.aif" />
  </option>
  <option name="Amp Spring High.aif">
    <binding type="effect" level="instrument" position="1" parameter="FX_IR_FILE" translation="fixed_value" translationValue="Samples/Amp Spring High.aif" />
  </option>
  <option name="Swede Plate 3.5s.aif">
    <binding type="effect" level="instrument" position="1" parameter="FX_IR_FILE" translation="fixed_value" translationValue="Samples/Swede Plate 3.5s.aif" />
  </option>
</menu>Code language: HTML, XML (xml)

Examples

An example Decent Sampler preset that uses IR reverb can be downloaded here. (You’ll want to check out the example-003-how-to-use-convolution-reverb folder.)

Performance considerations

While convolution is a powerful tool that can go a long way towards shaping a sample library’s sound, it can also be quite costly in terms of CPU usage. Sample creators would do well to create versions both with and without convolution effect and compare the relative CPU usage of the two versions before opting to use convolution.

Posted on Leave a comment

Kontakt Video Tutorial: How To Remove Unwanted Frequencies + FREE Kontakt Library

Have you ever had an audio file that contained a bunch of extra frequencies in it that you wish you could just remove? Spectral editing may be for you. In this video, I show how to use spectral editing to clean up a sample so that I can make a Kontakt instrument–but not just any instrument:

A few weeks ago, Christian Henson announced a competition: he challenged the internet community to try to turn two oddball samples he’d recorded into true sample-based instruments.

So this video serves two purposes: it’s both a quick introduction to spectral editing as well as my entry into Christian Henson’s Rusty Gate sample competition.

Here’s a link to the free sample (Kontakt 5.3 or higher).

Here’s a link to Christian Henson’s Rusty Gate Sample Competition.

Posted on Leave a comment

New sample library: Melodica!

The melodica is a free-reed instrument that became popular in the 1950s. We’ve sampled it twice and turned it into a Kontakt instrument.

Buy it here: https://www.decentsamples.com/product/melodica-kontakt/

Features:

  • Compatible with the full version of Native Instruments Kontakt 5.3.1 (or later)
  • Two sample sets: Melodica I (4 round robins, 2 velocity layers) and Melodica II (4 round robins, 1 velocity layer)
  • Voice controls allow you to choose between 1, 2, and 4 voices simutaneously
  • ADSR controls
  • EQ controls
  • Custom convolution reverb with reverb level knob
  • Chorus level knob
  • Two versions of each instrument are included: 1) velocity controls dynamics; and 2) modwheel controls dynamics.
  • Sample rate: 24-bit 48khz
  • Library size: 148MB
Posted on Leave a comment

Present in the Box Cello Kontakt Library

In December 2018, Dave Hilowitz built a fully playable cello out of an old silverware box. We spent the month of January sampling the instrument and have no turned it into a feature-packed Kontakt library. Introductory price: $20!

Buy it here: https://www.decentsamples.com/product/box-cello-kontakt/

Features:

  • Three articulations: sustain (both velocity and modwheel), spiccato and pizzicato
  • Up to 8 round robins per note, 2 velocity layers for a maximum total of 16 different samples per note!
  • ADSR controls on all patches (except spiccato)
  • EQ controls on all patches
  • Recorded with three different mics (including a piezo contact mic). Mic levels are controllable after the fact to give maximum sonic flexibility
  • Three experimental patches: Texture I, Open Strings, Open Strings (Ensemble)
  • Requires the full version of Kontakt 5.3.1 or later.
  • Library size: 1.03GB (each articulation is separate patch so you can easily get rid of articulations you don’t need if you find yourself short on disk space)
Posted on Leave a comment

Video Tutorial: How to Make Release Triggers + FREE Tea Kettle Whistle Kontakt Library

In this video, I show how to make release triggers in Kontakt. In the process, I create a full-featured Kontakt library out of the whistle from a Chantal tea kettle.

The instrument that I make in the video can be downloaded for free here.

– Dave