DecentSampler: File Format Reference Guide
Document Version: 0.8.4
Table of Contents
- DecentSampler: File Format Reference Guide
Introduction
At its core each DecentSampler sample library consists of two things: a folder containing a bunch of assets like audio files and pictures, and a single text file (called a dspreset file) which describes how the engine should use all of those files. This reference document is a guide to creating dspreset files.
dspreset files are just XML files. As such, each one begins with an XML declaration:
<?xml version="1.0" encoding="UTF-8"?>
The top-level <DecentSampler> element (required)
At the top level of every dspreset file is a <DecentSampler>
element. Every file must have one. Here is a list of attributes:
minVersion
(optional): This is the minimum version on which this preset is known to run. As of version 0.7.19, this information is not being used for anything, but the plan is to prevent users from loading presets that won’t actually work on their version of the engine.
Example:
<?xml version="1.0" encoding="UTF-8"?> <DecentSampler> <!-- More tags go here. :) --> </DecentSampler>
Underneath the top-level <DecentSampler>
element you can put any number of other elements, which are described below:
The <ui> element (optional)
The <ui>
element is how you specify a user interface for your instrument. Each dspreset should have at most one <ui>
element. There are several important attributes:
bgImage
(optional): A relative or absolutely path to a background image to use.bgColor
(required): An eight digit hex value indicating the background color to be used for the background of the UI. This color will be drawn underneath any background image specified bybgimage
.width
(required): The width of your user interface. Recommended value: 812.height
(required): The height of your user interface. Recommended value: 375.
Example:
<DecentSampler> <ui bgImage="background.png" width="812" height="375"> <tab name="main"> <labeled-knob x="560" y="0" label="Tone" type="float" minValue="60" maxValue="22000" textColor="FF000000" value="22000.0" uid="y8AA4uuURh3"> <binding type="effect" level="instrument" position="0" parameter="FX_FILTER_FREQUENCY"/> </labeled-knob> </tab> </ui> </DecentSampler>
The <tab> element
The <tab>
element lives underneath the <ui>
element. This architecture was chosen because we may, at some point, we may add support for multiple tabs. At present it is only possible to have a single tab within DecentSampler instruments. As such, every UI must have at most one <tab>
element.
Attributes:
name
(optional): An optional name to be associated with this tab. This is currently not displayed anywhere.
The <labeled-knob> element
The <labeled-knob>
element lives underneath the <tab>
element. These correspond to round radial dials with label above them. Every tab can have many <labeled-knob
> elements underneath it. Attributes:
x
(optional): Thex
position of your control where (0,0) is the top-left cornery
(optional): They
position of your control where (0,0) is the top-left cornerlabel
(optional): The actual text that should be displayed above the knob.minValue
(optional): The minimum value of your control. Default: 0maxValue
(optional): The maximum value of your control. Default: 1value
(optional): The initial value of your control. Default: 0textColor
(optional): An 8 digit hex value indicating the text color to be used for the label. See Appendix A for an explanation on these hex values.textSize
(optional): A font size for the text label. Default: 12trackForegroundColor
(optional): An 8 digit hex value indicating the foreground color to use for the knob track. See Appendix A for an explanation on these hex values.trackBackgroundColor
(optional): An 8 digit hex value indicating the background color to use for the knob track. See Appendix A for an explanation on these hex values.uid
(optional): This is an internally generated value. This can be ignored.width
(required): The width in pixels of the knob + label.height
(required): The height in pixels of the knob + label.
Example:
<DecentSampler> <ui> <tab> <labeled-knob x="560" y="0" label="Tone" type="float" minValue="60" maxValue="22000" textColor="FF000000" value="22000.0" uid="y8AA4uuURh3"> <!-- Your <binding /> elements should go here --> </labeled-knob> </tab> </ui> </DecentSampler>
To learn how to make knobs actually control parameters of your instrument, see “Appendix B: Bindings” section below.
The <groups> element (required)
Every dspreset file should have one and only one <groups>
element. This is where you specify the samples that make up your sample library. This element lives right underneath the top-level <DecentSampler>
element. The basic structure is this:
<DecentSampler> <groups> <group> <sample /> <!-- This is where --> <sample /> <!-- the samples --> <sample /> <!-- get defined --> </group> </groups> </DecentSampler>
Attribute | Description | |
---|---|---|
volume |
(optional) | The volume of the instrument as a whole. This will be reflected in the UI in the top-right corner. Value can be in linear 0.0-1.0 or in decibels. If it’s in decibels you must append dB after the value (example: “3dB”). Default: 1.0 (no volume change) |
The <group> element
Samples live in groups. There can be many group elements under the <groups>
element. It can be useful to sort your samples into groups in order to apply similar settings to them or to control them with a knob. The order of groups in a file matters insofar as bindings will often reference groups by using an index. The first group in a file is group 0, the second is group 1, etc.
Attribute | Description | |
---|---|---|
volume |
(optional) | The volume of the group. Value can be in linear 0.0-1.0 or in decibels. If it’s in decibels you must append dB after the value (example: “3dB”). Default: 1.0 |
ampVelTrack |
(optional) | The degree to which the velocity of the incoming notes affects the volume of the samples in this group. 0 = not at all. 100 = volume is completely determined by incoming velocity. When the value is 100, a velocity of 127 (max velocity) yields a gain 1.0 (full volume), a velocity of 63 (half velocity) yields a gain of 0.5 (half volume), etc. |
The <sample> element
Underneath the <group>
elements are <sample>
elements. Each sample corresponds to a playable “zone” of your instrument. Attributes:
Attribute | Description | |
---|---|---|
path |
(required) | The relative path of the sample file to play for this zone. |
rootNote |
(required) | The MIDI note number (from 1 to 127) of the note. |
loNote |
(optional) | The MIDI note number (from 1 to 127) of the lowest note for which the zone should be triggered. Default: 0. |
hiNote |
(optional) | The MIDI note number (from 1 to 127) of the highest note for which the zone should be triggered. Default: 127. |
loVel |
(optional) | The lowest velocity for which this zone should be triggered. Default: 1 |
hiVel |
(optional) | The highest velocity for which this zone should be triggered. Default: 127 |
start |
(optional) | The frame/sample position of the start of the sample audio. This is useful if the sample starts midway through the audio file. Default: 0 |
end |
(optional) | The frame/sample position of the end of the sample audio. The is useful is the zone ends before the end of the audio file. Default: the file’s length in samples minus 1. |
tuning |
(optional) | A fine-tuning number (in semitones) for changing the note pitch. e.g 1.0 would be a half-step up Default: 0 |
volume |
(optional) | The volume of the sample. Value can be in linear 0.0-1.0 or in decibels. If it’s in decibels you must append dB after the value (example: “3dB”). Default: 1.0 |
pan |
(optional) | A number of -100 to 100. -100 in panned all the way to the left, 100 is panned all the way to the right. This can also be set at the <group> or <groups> levels. Default: 0 |
trigger |
(optional) | Valid values: attack means a sample is played when the note on message is received. release means the sample is played when the note off message is received (aka a release trigger). This can also be set at the <group> level. Default: attack . |
onLoCCN onHiCCN |
(optional) | If you want a sample to be triggered when a MIDI CC controller message comes in, for example for piano pedal down and pedal up samples, you use these attributes to specify the range of values that should trigger the sample. If you use onLoCCN, you must also use a corresponding onHiCCN for the same MIDI CC number. Example: onLoCC64="90" and onLoCC64="127" would mean that values of CC64 (Sustain Pedal) between 90 and 127 will trigger the given sample. This can also be set at the <group> level. Default:-1 (off) |
Looping
Attribute | Description | |
---|---|---|
loopStart |
(optional) | The frame/sample position of the start of the sample’s loop. If this is not specified, but the sample is a wave file with embedded loop markers, those will be used instead. Default: 0 |
loopEnd |
(optional) | The frame/sample position of the end of the sample’s loop. If this is not specified, but the sample is a wave file with embedded loop markers, those will be used instead. Default: the file’s length in samples minus 1. |
loopCrossfade |
(optional) | When loop crossfades are used, instead of simply looping at a specific end point, a portion of the audio from before the loop point is faded in just as the audio from the end of the loop is faded out. In this way, smooth audio loops can be achieved on samples that weren’t specifically prepared as looping. This parameter is used for specifying the length of the crossade region in frames/samples. This can also be set at the <group> level. Default: 0 (crossfades off). |
loopCrossfadeMode |
(optional) | This parameter is used to specify the curve used for crossfading when loop crossfades are turned on. This can also be set at the <group> level. Value values: linear , equal_power . Default: equal_power . |
loopEnabled |
(optional) | A boolean value indicating whether or not the loop should be used. Valid values: true, false |
Amplitude Envelope
Each sample as its own ADSR amplitude envelope.
Attribute | Description | |
---|---|---|
attack |
(optional) | The attack of the amplitude envelope of this zone. This can also be set at the <group> or <groups> levels. |
decay |
(optional) | The decay of the amplitude envelope of this zone. This can also be set at the <group> or <groups> levels. |
sustain |
(optional) | The sustain of the amplitude envelope of this zone. This can also be set at the <group> or <groups> levels. |
release |
(optional) | The release of the amplitude envelope of this zone. This can also be set at the <group> or <groups> levels. |
Round Robins
Round robins allow different samples to be played each time a zone is triggered. This is especially useful with sounds that have short attacks (such as drums), and is a great way to keep your sample libraries from sounding fake. In order for round robins to work, you must specify both a seqMode
and a seqPosition
for all samples. There are several round-robin modes:
round_robin
: This causes samples to be triggered sequentially according to theirseqPosition
values.random
: This causes random samples to be chosen from within the group of samples. If there are more than two round robins, then the algorithm makes sure not to hit the same one twice in a row.true_random
: This causes random samples to be chosen from within the group of samples.always
: This just turns round robins off.
Attribute | Description | |
---|---|---|
seqMode |
(optional) | Valid values are random , true_random , round_robin , and always . A value indicating the desired round robin behavior for this sample or group of samples. This can also be set at the <group> and <groups> levels. Default: always |
seqPosition |
(optional) | A number indicating this zone’s position in the round robin queue. This can also be set at the <group> level. Default: 1 |
The <effects> element
Adding global, instrument-wide effects is easy: just add an <effects>
element right below your top-level <DecentSampler>
element.
The <effect> element
Within the <effects>
you can have any number of <effect>
elements. These specify parameters for each individual effect that you would like to have in your global effects change. There are currently only a handful effects available although more could definitely be added on request:
Low-pass filter
A 4-pole resonance filter
Example:
<DecentSampler> <effects> <effect type="lowpass_4pl" resonance="0.7" frequency="22000" /> </effects> </DecentSampler>
Attributes:
Attribute | Type | Valid Range | Default | |
---|---|---|---|---|
type |
Required | Must be lowpass_4pl |
lowpass_4pl |
|
resonance |
Optional | The filter resonance (Q) | 0 - 1.0, where 1.0 is big, 0 is small. | 0.7 |
frequency |
Optional | The filter frequency | 0 - 1.0, where 0 is not damped, 1.0 is fully damped. | 0.3 |
Reverb effect
Example:
<DecentSampler> <effects> <effect type="reverb" roomSize="" damping="" wetLevel="" /> </effects> </DecentSampler>
Attributes:
Attribute | Type | Valid Range | Default | |
---|---|---|---|---|
type |
Required | Must be reverb |
reverb |
|
roomSize |
Optional | The reverb “room size” | 0 - 1.0, where 1.0 is big, 0 is small. | 0.7 |
damping |
Optional | The reverb damping level | 0 - 1.0, where 0 is not damped, 1.0 is fully damped. | 0.3 |
wetLevel |
Optional | The volume of reverb signal | 0 - 1.0 | 0 |
Appendix A: The Color Format
Colors are represented throughout the dspreset files using an 8-digit ARGB color format. These are identical to web color hex codes except with an additional 2-digit hex number in front of them. The first two digits are a hexadecimal representation of alpha level with 00 being fully transparent, 80 being 50% transparent, and FF being fully opaque.
Examples:
- Black (solid): FF000000
- Black (90% transparency): E6000000
- Red (solid): FFFF0000
- Red (50% transparency): 80FF0000
- Blue (solid): FF0000FF
Appendix B: The <binding> element
Adding a binding to a UI control tells the DecentSampler engine that it should take input from a source and use it to change values in another part of the engine. An example of this would be a knob which controls the volume of a group or a CC controller that changes an effect parameter.
In order to set up a binding for a specific source, create a <binding>
element within the source element.
In this example, a labeled knob is controlling the volume of the first group of samples (group 0):
<DecentSampler> <ui> <tab> <labeled-knob x="420" y="100" label="RT" type="float" minValue="0" maxValue="1" value="0.3" textSize="20"> <binding type="amp" level="group" position="0" parameter="AMP_VOLUME" translation="linear" translationOutputMin="0" translationOutputMax="1.0" /> </labeled-knob> </tab> </ui> </DecentSampler>
Here’s a full list of parameters for the <binding>
element:
Attribute | Description | |
---|---|---|
type |
Required | This tells the engine what type of parameter this is. Valid values are: “amp”, “effect”, “labeled_knob”. |
level |
Required | Valid values are ui , instrument , group |
position |
Required | The specific 0-based index of the element to be modified by this binding. If you are targeting a group, for example, the first group would be 0, the second group would be 1, etc. |
parameter |
Required | A token describing the specific parameter that you wish to change. A list of controller parameters i below. |
translation |
Optional | Valid values are linear and table . Explanation of both translation modes is in a separate section below. Default: linear |
translationOutputMin |
Optional | This is the min value this binding should send to the target parameter. This is only looked at if translation is set to linear . |
translationOutputMax |
Optional | This is the max value this binding should send to the target parameter. This is only looked at if translation is set to linear . |
translationReversed |
Optional | Valid values are true and false . Default: false . This is only looked at if translation is set to linear . |
translationTable |
Optional | A list of input-output pairs that make up the translation table. The input and output are separated by commas. The groups of coordinates themselves are separated by semi-colons. Default: 0,0;1,1 . You must have at least two coordinates in your list. This is only looked at if translation is set to table . |
Controllable Parameters
This is a list of parameters that can be used in conjunction with the <binding>
element above.
Description | type |
level |
position |
parameter |
Valid Range |
---|---|---|---|---|---|
Global Volume | amp |
instrument |
N/A | AMP_VOLUME |
0.0 - 16.0 |
Global Amp Envelope Attack | amp |
instrument |
N/A | ENV_ATTACK |
0.0 - 2.0 |
Global Amp Envelope Decay | amp |
instrument |
N/A | ENV_DECAY |
0.0 - 2.0 |
Global Amp Envelope Sustain | amp |
instrument |
N/A | ENV_SUSTAIN |
0.0 - 2.0 |
Global Amp Envelope Release | amp |
instrument |
N/A | ENV_RELEASE |
0.0 - 2.0 |
Filter Cutoff | amp |
instrument |
N/A | FX_FILTER_FREQUENCY |
0.0 - 22000.0 |
Filter Resonance | amp |
instrument |
N/A | FX_FILTER_RESONANCE |
0.0 - 2.0 |
Reverb Wet Level | amp |
instrument |
N/A | FX_REVERB_WET_LEVEL |
0.0 - 1.0 |
Reverb Room Size | amp |
instrument |
N/A | FX_REVERB_ROOM_SIZE |
0.0 - 1.0 |
Group Volume | amp |
group |
The 0-based index of the group | AMP_VOLUME |
0.0 - 16.0 |
Group Amp Envelope Attack | amp |
group |
The 0-based index of the group | ENV_ATTACK |
0.0 - 2.0 |
Group Amp Envelope Decay | amp |
group |
The 0-based index of the group | ENV_DECAY |
0.0 - 2.0 |
Group Amp Envelope Sustain | amp |
group |
The 0-based index of the group | ENV_SUSTAIN |
0.0 - 2.0 |
Group Amp Envelope Release | amp |
group |
The 0-based index of the group | ENV_RELEASE |
0.0 - 2.0 |
Translation Modes
There are currently two binding translation modes: linear
and table
:
- linear mode allows values that come in to be scaled up or down before they get passed along to the binding’s target. If you set your translation mode to
linear
you should alsotranslationOutputMin
andtranslationOutputMax
. - table mode allows you to transform the binding’s input in a more complex fashion before it gets passed along to the binding’s target. If you set your translation mode to
table
you must define thetranslationTable
parameter as well. This consists of a series of input-output pairs, separated by semi-colons.
Appendix C: Boilerplate .dspreset File
<?xml version="1.0" encoding="UTF-8"?> <DecentSampler> <ui bgImage="background.png" width="812" height="375" layoutMode="relative" bgMode="top_left"> <tab name="main"> <labeled-knob x="560" y="0" label="Tone" type="float" minValue="60" maxValue="22000" textColor="FF000000" value="22000.0" uid="y8AA4uuURh3"> <binding type="effect" level="instrument" position="0" parameter="FX_FILTER_FREQUENCY"/> </labeled-knob> <labeled-knob x="655" y="0" label="Reverb" type="percent" minValue="0" maxValue="100" textColor="FF000000" value="50.0" uid="lKv29kggDro"> <binding type="effect" level="instrument" position="1" parameter="FX_REVERB_WET_LEVEL" factor="0.01"/> </labeled-knob> </tab> </ui> <groups attack="0.000" decay="25" sustain="1.0" release="0.430" volume="-3dB"> <group> <sample loNote="21" hiNote="21" rootNote="21" path="DefaultPiano-21.aif" length="805888"/> <sample loNote="22" hiNote="33" rootNote="33" path="DefaultPiano-33.aif" length="807552"/> <sample loNote="34" hiNote="45" rootNote="45" path="DefaultPiano-45.aif" length="759168"/> <sample loNote="46" hiNote="57" rootNote="57" path="DefaultPiano-57.aif" length="756480"/> <sample loNote="58" hiNote="69" rootNote="69" path="DefaultPiano-69.aif" length="758656"/> <sample loNote="70" hiNote="77" rootNote="77" path="DefaultPiano-77.aif" length="595328"/> <sample loNote="78" hiNote="89" rootNote="89" path="DefaultPiano-89.aif" length="457600"/> <sample loNote="90" hiNote="96" rootNote="96" path="DefaultPiano-96.aif" length="469888"/> <sample loNote="94" hiNote="108" rootNote="108" path="DefaultPiano-108.aif" length="75264"/> </group> </groups> <effects> <effect type="lowpass_4pl" frequency="22000.0"/> <effect type="reverb" wetLevel="0.4999999888241291"/> </effects> </DecentSampler>