Posted on 10 Comments

Dropdown Menus, Colored Keys, and Keyswitches come to Decent Sampler

An example of the key coloring functionality

Version 1.4 of Decent Sampler recently got released: Download it here.

It brings with it a number of under-the-hood features that sample developers can make use of:

Colored Keys

It’s now possible to color the keys of the on-screen keyboard.

This can be useful for showing different ranges of notes that serve different purposes or highlighting notes used as keyswitches. In order to implement colored keys, make use of the new <keyboard> and <color> elements as follows:

        <em><!-- Other stuffhere --></em>
            <color loNote="36" hiNote="50" color="FF2C365E" />
            <color loNote="51" hiNote="57" color="FF6D9DC5" />
            <color loNote="58" hiNote="67" color="FFCCF3F5" />
            <color loNote="68" hiNote="73" color="FFE8DA9B" />
            <color loNote="74" hiNote="84" color="FFD19D61" />
    <em><!-- Other stuff here --></em>
</DecentSampler>Code language: HTML, XML (xml)

By default, Decent Sampler highlights all of the notes that are mapped for a given sample. If you use the color keys feature, this default highlighting will be turned off and it will be up to you to color whatever keys you want.

Full documentation for the new elements is here.

Dropdown Menus

In order to implemented dropdown menus, use the new <menu> and <option> elements. The <menu> element defines where the dropdown menu will show up in the ui, whereas the <option> XML elements determine what menu options it has and what if anything those options actually do:

<menu x="10" y="40" width="120" height="30" value="2">
  <option name="Menu Option 1">
    <!-- Turn on this group -->
    <binding type="general" level="group" position="0" parameter="ENABLED" 
    translation="fixed_value" translationValue="true" />
    <!-- Turn off this group -->
    <binding type="general" level="group" position="1" parameter="ENABLED" 
    translation="fixed_value" translationValue="false" />
  <option name="Menu Option 2">
    <!-- Turn off this group -->
    <binding type="general" level="group" position="0" parameter="ENABLED" 
    translation="fixed_value" translationValue="false" />
    <!-- Turn on this group -->
    <binding type="general" level="group" position="1" parameter="ENABLED" 
    translation="fixed_value" translationValue="true" />
</menu>Code language: HTML, XML (xml)

In this example, a menu is being used to switch between two groups (the first menu option turns group 0 on and group 1 off; the section option turns group 0 off and group 1 on). Full documentation for the new <menu> and <option> elements is here.

The new fixed_value translation type

You’ll note, in the example above, there’s something new in the bindings: the four bindings elements have a translation parameter of type fixed_value. This is a new translation type. Up until now, binding translation has strictly been about taking an input parameter (such as a knob value or continuous controller amount) and translating it so that it is useful for some other purpose (it’s our way of being able to do a little bit of math without having a full-blown scripting language). This new fixed_value binding is different. It ignores the input value completely and instead provides whatever is specified in the translationValue parameter. In this way, each menu option can have hardcoded values that it provides its bindings when it is selected.


It is now possible to implement keyswitches. For a long time, it’s been possible to trigger events when a MIDI continuous controller event is received: using MIDI CCs we can change knob values or group volumes, for example. It is now possible to trigger events using MIDI notes as well. Here’s what the setup for a MIDI note-based event mapping would look like:

  <note note="11">
    <binding type="general" level="group" position="0" parameter="ENABLED" 
             translation="fixed_value" translationValue="true" />
    <binding type="general" level="group" position="1" parameter="ENABLED" 
             translation="fixed_value" translationValue="false" />
  <note note="12">
    <binding type="general" level="group" position="0" parameter="ENABLED" 
             translation="fixed_value" translationValue="false" />
    <binding type="general" level="group" position="1" parameter="ENABLED" 
             translation="fixed_value" translationValue="true" />
</midi>Code language: HTML, XML (xml)

In this example, MIDI note 11 turns on group 0 and turns off group 1, whereas MIDI note 12 does the opposite. Note the use of the fixed_value translation type.

More documentation on this can be found here.

10 thoughts on “Dropdown Menus, Colored Keys, and Keyswitches come to Decent Sampler

  1. Decent Sampler is growing, and it will get better and better. Thank you for this tool

  2. Hi David!
    Do you consider to add keyboard microtuning into Decent Sampler? I don’t know particularities of what would need to be generalized in the code, but it seems not that hard to implement.

    The starting package is a way to parse .scl and .kbm files—.scl for an interval tuning and .kbm a binding of a concrete frequency and a step of the scale to a specific MIDI note. There are other formats for tunings but probably this “dual format” is sufficient for many many purposes, and these formats are pretty simple. (There are protocols to support live retuning, but I don’t know a thing about them so can’t advice. And anyway the first reasonable step which will also leave many people happy is this static retuning.) Using this info, a frequency for each MIDI note is calculated.

    Then a good way to use this frequency data is for each note to pick a sample according to the frequency F of the note; I presume DS uses MIDI note ranges for each sample, in which case you’d just need to calculate a “fractional 12edo MIDI note” N from F, reversing the calculation which is done for the usual 12edo tuning. Then the sample picked for N is tuned to F in a usual manner. The playing range (in terms of MIDI notes) is widened or condensed accordingly, to allow the constant range of playable frequencies and not a constant number of playable notes.

    There is another way which I deem way less useful for tunings with ≠ 12 notes per octave, which are ubiquitous in today’s xenharmonic community. I leave it for comparison, and maybe the previous description will be a bit clearer from it (but I can also write pseudocode later if you’d want). The second and suspicious way is as follows: you probably know that sforzando has microtuning and it does it so: a MIDI note is always mapped to the sample it is mapped in .sfz file—independent of its new retuned frequency—and only after that the sample is retuned according to the tuning. The playing range is always the same range of MIDI notes, too, as are keyswitches. I guess there might be no satisfactory answer to keyswitches, as placing them at different MIDI notes when a different tuning is applied is counterproductive, but if they replace notes of a widened playrange, that’s nonfunctional too. I don’t know what to suggest about keyswitches, probably having two modes of operation (move them or don’t move them and hope they won’t encroach on the playing range if it widens). Probably there is a better solution somewhere.

    (BTW I personally was considering to write a script to “retune” .scl files to make them useful in sforzando for, say, 19edo or 7edo which without that will be mapped awfully and with too small a range in case of instruments where play range is fixed. But I’m lazy to think about that as .sfz is quite a sophisticated format to parse and re-generate without losing something in semantics. And that will still be quite complicated to use.)

    For 12-note-octave tunings these two methods would give different results when there are steps way wider or narrower than a semitone; at the same time, they will give probably the same result for majority of so-called well tunings. But I’d be glad for a more scalable method I proposed at the start, if you would wish to implement it.

    What do you think about this? I can clarify everything or connect you to somebody who has more thoughts about microtuning from xenharmonic community. I don’t leave links to .scl/.kbm format documentation to not accidentally be flagged by a spam filter, but they do google easily (“Scala scale file” and “Scala keyboard mapping”, first introduced by the Scala scale manipulation software). I would be glad for any feedback.

    P. S. I left a less clearly worded version of this suggestion on youtube but that’s probably not a good place to have feedback reliably, so I wrote here as there’s already a general comment present. 🙂

    1. Hi @05degree–Yes, it’s definitely on the roadmap!

      1. Yay! 👏 If you feel you need any advice on this, please write me and I’ll make something, if anything I’ll send you an invite link to Xenharmonic Alliance Discord server.

        BTW thank you for your lovely videos!

      2. Oh, BTW I should’ve mentioned this sooner: there is a relatively new standard (but already quite widely adopted, by forty-ish plugins I think) called MTS-ESP which allows a plugin to support microtuning very cheaply: all scale manipulation is done by the master MTS-ESP plugin which sends information about tuning to aware plugins. Many devs now (like Full Bucket Audio) just add MTS-ESP support to their new or revamped old plugins and call it a day. For a sampler, it still won’t alleviate much of the work but it’ll still make your life a little bit easier when you’ll have time for this project.

        I don’t know what one needs to implement to support MTS-ESP but they say it should be easy (and there are technical details somewhere at their website). At least easier than being in need of parsing SCL and KBM files. I hypothesize that the master plugin just plainly sends frequencies for each of 128 midi notes in some simple format via a function an aware plugin publishes in addition to all the usual ones.

      3. Hi once again!
        I just remembered that a very okay way of microtuning can be achieved via third-party plugins which send pitch-bend messages but the good way is when the receiving synth/sampler implements MPE (MIDI polyphonic expression). It might be simpler for DecentSampler to implement MPE or at least just its parts that relate to pitch-bends.

        There is the specs for MPE:

        What do you think? The way pitch bends work you won’t need to worry about any unusual special sample mapping, a plugin which sends them to DS will do all the work of which note and which pitchbend to use so the sample DS picks will automatically be the best suited one.

        I hope MPE is not too hard to implement, it will be a great boon though only allowing 15 simultaneous retuned notes but that’s still very nice and many would be thankful. 🙂

      4. Oh and another thing: not only MTS-ESP may be an easier option than parsing .scl/.kbm by your own code, but there is also an option to offload that to a library already written (if you use C++): code refactored out of Surge XT synth, made available as a library specifically to handle hairy .scl/.kbm parsing and processing cases:

        Sorry I absolutely forgot to mention this earlier despite I have heard about it for a while now. Using this or MTS-ESP is less time-consuming so when you’re going to feel it’s time to try luck in adding couple new frequencies, these two options should make your day bearable!

        1. Thanks for this! I’m actually going to be adding basic .scl/.kbm support this weekend. I have a proof of concept version working already.

          1. That’s great! Godspeed! 🥳

  3. Hi Dave

    Great product. Really new to sampling and apologies as I originally sent this question in via the contact page rather than the blog.

    So I have a very basic guitar sample I’m looking at and I have a menu option for picked and a menu option for muted sounds. That works fine.
    I also did a Ukulele one without difference in sounds and used the round robin approach with four samples for each note. Again that all works fine and have used it in a small project and am really pleased with how it sounds.

    So to my question. I see the menu option uses the group tag to decide which sound to use.
    But the round robin option also uses the groups to decide which of the round robin sounds to use.

    I’m trying to figure out how to use a menu for different sound select, but also have the round robin approach for a more natural sound. I see the binding in the menu example has a level=”group” and was wondering if I need to change that to another value to make this work how I intend and if that’s the case where in the documentation I could find that.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.