infer-vst / back /models /convert_to_preset.py
Yann
push backend
86694c3
import csv;
import xml.etree.ElementTree as ET
def convert_csv_to_preset(path: str, output_path: str):
daw_to_preset_og = {
'Master Volume': 'volume',
'Filter Type': 'filtertype',
'Filter Cutoff': 'cutoff',
'Filter Resonance': 'resonance',
'Filter Keyfollow': 'keyfollow',
'Filter Contour': 'filtercontour',
'Filter Attack': 'filterattack',
'Filter Decay': 'filterdecay',
'Filter Sustain': 'filtersustain',
'Filter Release': 'filterrelease',
'Amp Attack': 'ampattack',
'Amp Decay': 'ampdecay',
'Amp Sustain': 'ampsustain',
'Amp Release': 'amprelease',
'Osc 1 Volume': 'osc1volume',
'Osc 2 Volume': 'osc2volume',
'Osc 3 Volume': 'osc3volume',
'Osc Mastertune': 'oscmastertune',
'Osc 1 Tune': 'osc1tune',
'Osc 2 Tune': 'osc2tune',
'Osc 1 Fine Tune': 'osc1finetune',
'Osc 2 Fine Tune': 'osc2finetune',
'Osc 1 Waveform': 'osc1waveform',
'Osc 2 Waveform': 'osc2waveform',
'Osc Sync': 'oscsync',
'Lfo 1 Waveform': 'lfo1waveform',
'Lfo 2 Waveform': 'lfo2waveform',
'Lfo 1 Rate': 'lfo1rate',
'Lfo 2 Rate': 'lfo2rate',
'Lfo 1 Amount': 'lfo1amount',
'Lfo 2 Amount': 'lfo2amount',
'Lfo 1 Destination': 'lfo1destination',
'Lfo 2 Destination': 'lfo2destination',
'Lfo 1 Phase': 'lfo1phase',
'Lfo 2 Phase': 'lfo2phase',
'Osc 2 FM': 'osc2fm',
'Osc 2 Phase': 'osc2phase',
'Osc 1 PW': 'osc1pw',
'Osc 1 Phase': 'osc1phase',
'Transpose': 'transpose',
'Free Ad Attack': 'freeadattack',
'Free Ad Decay': 'freeaddecay',
'Free Ad Amount': 'freeadamount',
'Free Ad Destination': 'freeaddestination',
'Lfo 1 Sync': 'lfo1sync',
'Lfo 1 Keytrigger': 'lfo1keytrigger',
'Lfo 2 Sync': 'lfo2sync',
'Lfo 2 Keytrigger': 'lfo2keytrigger',
'Portamento Amount': 'portamento',
'Portamento Mode': 'portamentomode',
'Voices': 'voices',
'Velocity Volume': 'velocityvolume',
'Velocity Contour': 'velocitycontour',
'Velocity Filter': 'velocitycutoff',
'Pitchwheel Cutoff': 'pitchwheelcutoff',
'Pitchwheel Pitch': 'pitchwheelpitch',
'Ringmodulation': 'ringmodulation',
'Chorus 1 Enable': 'chorus1enable',
'Chorus 2 Enable': 'chorus2enable',
'Reverb Wet': 'reverbwet',
'Reverb Decay': 'reverbdecay',
'Reverb Pre Delay': 'reverbpredelay',
'Reverb High Cut': 'reverbhighcut',
'Reverb Low Cut': 'reverblowcut',
'Osc Bitcrusher': 'oscbitcrusher',
'Master High Pass': 'highpass',
'Master Detune': 'detune',
'Vintage Noise': 'vintagenoise',
'Envelope Destination': 'envelopeeditordest1',
'Envelope Speed': 'envelopeeditorspeed',
'Envelope Amount': 'envelopeeditoramount',
'Envelope One Shot Mode': 'envelopeoneshot',
'Envelope Fix Tempo': 'envelopefixtempo',
'Filter Drive': 'filterdrive',
'Delay Wet': 'delaywet',
'Delay Time': 'delaytime',
'Delay Sync': 'delaysync',
'Delay x2 L': 'delayfactorl',
'Delay x2 R': 'delayfactorr',
'Delay High Shelf': 'delayhighshelf',
'Delay Low Shelf': 'delaylowshelf',
'Delay Feedback': 'delayfeedback',
}
daw_to_preset = {v: k for k, v in daw_to_preset_og.items()}
# Read CSV data from file
with open(path, 'r') as csv_file:
csv_reader = csv.DictReader(csv_file)
csv_data = list(csv_reader)
for entry in csv_data:
parameter_name = entry['name']
parameter_value_str = entry['value']
# Check if the name needs mapping
if parameter_name in daw_to_preset_og:
xml_key = daw_to_preset_og[parameter_name]
# Check if the value is numeric
try:
parameter_value = float(parameter_value_str)
except ValueError:
print(f"Skipping non-numeric value for parameter {parameter_name}: {parameter_value_str}")
continue
if xml_key in daw_to_preset:
# Update the corresponding value in the XML dictionary
daw_to_preset[xml_key] = parameter_value
print(daw_to_preset)
# Check for invalid float values and remove them from the dictionary
invalid_values = [key for key, value in daw_to_preset.items() if not isinstance(value, float)]
for key in invalid_values:
print(f"Removing attribute {key} from daw_to_preset due to invalid float value.")
daw_to_preset[key] = 0.0
# Print the updated XML dictionary
print(daw_to_preset)
# Generate XML
root = ET.Element('tal', curprogram="0", version="1.7", presetName="CH Chordionator III FN",
path="Factory Presets/CHORD/CH Chordionator III FN.noisemakerpreset")
programs = ET.SubElement(root, 'programs')
program = ET.SubElement(programs, 'program', programname="CH Chordionator III FN", unknown="0.5", volume="0.5")
# Add parameters to the XML inside the single <program> element
for param_name, param_value in daw_to_preset.items():
program.set(param_name, str(param_value))
ET.SubElement(root, 'midimap')
# Create an ElementTree object
tree = ET.ElementTree(root)
# Save the XML to a file
output_xml_path = output_path
tree.write(output_xml_path)
print(f"XML file written to {output_xml_path}")
return output_xml_path