Spaces:
Running
Running
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 | |