Skip to content

Instantly share code, notes, and snippets.

@dustractor
Created July 20, 2023 11:44
Show Gist options
  • Save dustractor/c6e4344206e089e13ae45dccfa39647b to your computer and use it in GitHub Desktop.
Save dustractor/c6e4344206e089e13ae45dccfa39647b to your computer and use it in GitHub Desktop.
script i use to turn a folder of samples into a decentsampler dslibrary
import argparse
import pathlib
import os
import sys
import shutil
from xml.dom import minidom
from string import Template
# {{{1 boilerplate
boilerplate = Template(
"""<?xml version="1.0" encoding="UTF-8"?>
<DecentSampler minVersion="1.0.0">
<ui width="812" height="375" layoutMode="relative"
bgMode="top_left"
bgImage="$bg_img">
<tab name="main">
<labeled-knob x="445" y="75" width="90" textSize="16" textColor="AA000000"
trackForegroundColor="CC000000" trackBackgroundColor="66999999"
label="Attack" type="float" minValue="0.0" maxValue="4.0" value="0.01" >
<binding type="amp" level="instrument" position="0" parameter="ENV_ATTACK" />
</labeled-knob>
<labeled-knob x="515" y="75" width="90" textSize="16" textColor="AA000000"
trackForegroundColor="CC000000" trackBackgroundColor="66999999"
label="Release" type="float" minValue="0.0" maxValue="20.0" value="1" >
<binding type="amp" level="instrument" position="0" parameter="ENV_RELEASE" />
</labeled-knob>
<labeled-knob x="585" y="75" width="90" textSize="16" textColor="AA000000"
trackForegroundColor="CC000000" trackBackgroundColor="66999999"
label="Chorus" type="float" minValue="0.0" maxValue="1" value="0" >
<binding type="effect" level="instrument" position="1" parameter="FX_MIX" />
</labeled-knob>
<labeled-knob x="655" y="75" width="90" textSize="16" textColor="FF000000"
trackForegroundColor="CC000000" trackBackgroundColor="66999999"
label="Tone" type="float" minValue="0" maxValue="1" value="1">
<binding type="effect" level="instrument" position="0" parameter="FX_FILTER_FREQUENCY"
translation="table"
translationTable="0,33;0.3,150;0.4,450;0.5,1100;0.7,4100;0.9,11000;1.0001,22000"/>
</labeled-knob>
<labeled-knob x="725" y="75" width="90" textSize="16" textColor="AA000000"
trackForegroundColor="CC000000" trackBackgroundColor="66999999"
label="Reverb" type="percent" minValue="0" maxValue="100"
textColor="FF000000" value="50">
<binding type="effect" level="instrument" position="2"
parameter="FX_REVERB_WET_LEVEL" translation="linear"
translationOutputMin="0" translationOutputMax="1" />
</labeled-knob>
</tab>
</ui>
<groups attack="0.000" decay="25" sustain="1.0" release="0.430" volume="-3dB">
$samples
</groups>
<effects>
<effect type="lowpass" frequency="22000.0"/>
<effect type="chorus" mix="0.0" modDepth="0.2" modRate="0.2" />
<effect type="reverb" wetLevel="0.5"/>
</effects>
<midi>
<!-- This causes MIDI CC 1 to control the 4th knob (cutoff) -->
<cc number="1">
<binding level="ui" type="control" parameter="VALUE" position="3"
translation="linear" translationOutputMin="0"
translationOutputMax="1" />
</cc>
</midi>
</DecentSampler>
""") #}}}1
default_bg = pathlib.Path("bg.png")
args = argparse.ArgumentParser()
args.add_argument("--folder",type=pathlib.Path)
args.add_argument("--startnote",type=int,default=0)
args.add_argument("--bg",type=pathlib.Path,default=default_bg)
args.add_argument("--name",type=str,default="UntitledDecentSamplerLib1")
args.add_argument("--overwrite",choices=["yes","no"],default="no")
ns = args.parse_args()
if not ns.folder:
print("supply --folder arg")
sys.exit()
if not ns.folder.is_dir():
print("--folder arg must point to dir")
sys.exit()
newlibdir = pathlib.Path(ns.name)
overwrite = ns.overwrite == "yes"
if newlibdir.is_dir() and not overwrite:
print(newlibdir,"already exists. use --overwrite=yes to force")
sys.exit()
else:
newlibdir.mkdir(exist_ok=overwrite)
print("created",newlibdir)
for path in ns.folder.iterdir():
if path.suffix == ".wav":
shutil.copy(path,newlibdir)
shutil.copy(ns.bg,newlibdir)
sample_list = [p for p in newlibdir.iterdir() if p.suffix==".wav"]
print("sample_list:",sample_list)
sampledocfrag = minidom.Document()
rootelem = sampledocfrag.createElement("group")
notenum = ns.startnote
for sample in sample_list:
elem = sampledocfrag.createElement("sample")
elem.setAttribute("path",sample.name)
elem.setAttribute("loNote",str(notenum))
elem.setAttribute("hiNote",str(notenum))
elem.setAttribute("rootNote",str(notenum))
notenum += 1
rootelem.appendChild(elem)
samplexml = rootelem.toprettyxml().strip()
mapping = dict(bg_img=str(ns.bg),samples=samplexml)
filecontents = boilerplate.substitute(mapping)
dspresetfile = newlibdir / (ns.name + ".dspreset")
with open(dspresetfile,"w") as f:
f.write(filecontents)
print(filecontents,"written to",dspresetfile)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment