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 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