Created
July 20, 2023 11:44
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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