예제 #1
0
 def set_audio_output(self, output_number, element_string):
     """Sets audio output."""
     if output_number not in STEREO_OUTPUTS:
         raise Exception(
             f'{R}Output number invalid!. Available options: \n{STEREO_OUTPUTS}{RST}'
         )
     output_obj = STEREO_OUTPUTS[output_number]
     out_target_element = get_element(
         self.root,
         f'LiveSet.{element_string}.DeviceChain.AudioOutputRouting.Target',
         silent_error=True)
     if not isinstance(out_target_element, ElementTree.Element):
         out_target_element = get_element(  # ableton 8 sets use "MasterChain" for master track.
             self.root,
             f'LiveSet.{element_string}.MasterChain.AudioOutputRouting.Target'
         )
         lower_display_string_element = get_element(
             self.root,
             f'LiveSet.{element_string}.MasterChain.AudioOutputRouting.LowerDisplayString'
         )
     else:
         lower_display_string_element = get_element(
             self.root,
             f'LiveSet.{element_string}.DeviceChain.AudioOutputRouting.LowerDisplayString'
         )
     out_target_element.set('Value', output_obj['target'])
     lower_display_string_element.set('Value',
                                      output_obj['lower_display_string'])
     print(
         f"{G}Set {element_string} to {output_obj['lower_display_string']}")
예제 #2
0
 def list_plugins(self):
     """Iterates through all plugin references and checks paths for VSTs."""
     for plugin_element in self.root.iter('PluginDesc'):
         if plugin_element.findall('./VstPluginInfo'):
             name = get_element(plugin_element,
                                'VstPluginInfo.FileName',
                                attribute='Value')
             path = self._parse_hex_path(
                 get_element(plugin_element, 'VstPluginInfo.Dir.Data').text)
             if not path:
                 print(f"{Y}Couldn't parse absolute path for {name}")
                 continue
             # Some plugin paths end in the os path separator, others don't.
             if path[-1] == os.path.sep:
                 full_path = f'{path}{name}'
             else:
                 full_path = f'{path}{os.path.sep}{name}'
             exists = pathlib.Path(full_path).exists()
             color = G if exists else R
             print(
                 f'{color}Plugin: {name}, {Y}Plugin folder path: {full_path}, {color}Exists: {exists}'
             )
         elif plugin_element.findall('./AuPluginInfo'):
             name = get_element(plugin_element,
                                'AuPluginInfo.Name',
                                attribute='Value')
             manufacturer = get_element(plugin_element,
                                        'AuPluginInfo.Manufacturer',
                                        attribute='Value')
             print(
                 f"{Y}Audio Units do not store paths. Plugin {manufacturer}: {name} cannot be verified."
             )
예제 #3
0
 def get_bpm(self):
     """Gets bpm. Note, float numbers can appear to have trailing digits which can be misleading."""
     ableton_10_bpm = 'LiveSet.MasterTrack.DeviceChain.Mixer.Tempo.Manual'
     ableton_9_bpm = 'LiveSet.MasterTrack.MasterChain.Mixer.Tempo.ArrangerAutomation.Events.FloatEvent'
     bpm_elem = get_element(self.root,
                            ableton_10_bpm,
                            attribute='Value',
                            silent_error=True)
     if not bpm_elem:
         bpm_elem = get_element(self.root, ableton_9_bpm, attribute='Value')
     self.bpm = round(float(bpm_elem), 6)
     return self.bpm
예제 #4
0
 def get_bpm(self):
     """Gets bpm."""
     bpm = 'LiveSet.MasterTrack.DeviceChain.Mixer.Tempo.Manual'
     pre_10_bpm = 'LiveSet.MasterTrack.MasterChain.Mixer.Tempo.ArrangerAutomation.Events.FloatEvent'
     bpm_elem = get_element(self.root,
                            bpm,
                            attribute='Value',
                            silent_error=True)
     if not bpm_elem:
         bpm_elem = get_element(self.root, pre_10_bpm, attribute='Value')
     self.bpm = round(float(bpm_elem), 6)
     return self.bpm
예제 #5
0
    def __init__(self, track_root):
        self.track_root = track_root
        self.type = track_root.tag
        self.name = get_element(track_root, 'Name.UserName', attribute='Value')
        if not self.name:
            self.name = get_element(track_root,
                                    'Name.EffectiveName',
                                    attribute='Value')
        self.id = track_root.get('Id')
        self.group_id = get_element(track_root,
                                    'TrackGroupId',
                                    attribute='Value')

        # Guessing 'Sesstion' was a typo early on and got stuck to not break backwards compatibility
        self.width = get_element(
            track_root,
            'DeviceChain.Mixer.ViewStateSesstionTrackWidth',
            attribute='Value')
        # Lane height in arrangement view will be automation lane 0
        self.height = get_element(
            track_root,
            'DeviceChain.AutomationLanes.AutomationLanes.AutomationLane.LaneHeight',
            attribute='Value')
        self.color = get_element(track_root, 'ColorIndex', attribute='Value')
        self.unfolded = get_element(track_root,
                                    'TrackUnfolded',
                                    attribute='Value',
                                    silent_error=True)  # Ableton 10
        if not self.unfolded:
            folded = get_element(track_root,
                                 'DeviceChain.Mixer.IsFolded',
                                 attribute='Value')  # Ableton 9/8
            self.unfolded = 'false' if folded == 'true' else 'true'
예제 #6
0
 def set_audio_output(self, output_number, element_string):
     """Sets audio output."""
     if output_number not in STEREO_OUTPUTS:
         raise Exception(
             f'{R}Output number invalid!. Available options: \n{STEREO_OUTPUTS}{RST}'
         )
     output_obj = STEREO_OUTPUTS[output_number]
     out_target_element = get_element(
         self.root,
         f'LiveSet.{element_string}.DeviceChain.AudioOutputRouting.Target')
     lower_display_string_element = get_element(
         self.root,
         f'LiveSet.{element_string}.DeviceChain.AudioOutputRouting.LowerDisplayString'
     )
     out_target_element.set('Value', output_obj['target'])
     lower_display_string_element.set('Value',
                                      output_obj['lower_display_string'])
     print(
         f"{G}Set {element_string} to {output_obj['lower_display_string']}")
예제 #7
0
 def list_samples(self):
     """Iterates through all sample references and checks absolute and relative paths."""
     for sample_element in self.root.iter('SampleRef'):
         name = get_element(sample_element,
                            'FileRef.Name',
                            attribute='Value')
         print(f'{C}Sample name: {name}')
         relative_path, from_project_root = self.check_relative_path(
             name, sample_element)
         if relative_path:
             rel_exists = pathlib.Path(relative_path).exists()
             color = G if rel_exists else R
             print(
                 f'\t{color}Relative path: {Y}{self.project_root_folder}{os.path.sep}{M}{from_project_root}, '
                 f'{color}Exists: {rel_exists}')
         abs_path = self._parse_hex_path(
             get_element(sample_element, 'FileRef.Data').text)
         abs_exists = pathlib.Path(abs_path).exists() if abs_path else None
         color = G if abs_exists else R
         print(
             f'\t{color}Absolute path: {Y}{abs_path}, {color}Exists: {abs_exists}'
         )
예제 #8
0
 def check_relative_path(self, name, sample_element):
     """Constructs absolute path from project root and relative path stored in set."""
     if not self.project_root_folder:
         print(
             f'{R}Error, project root folder is undefined, cant find relative paths.'
         )
         return
     relative_path_enabled = get_element(sample_element,
                                         'FileRef.HasRelativePath',
                                         attribute='Value')
     relative_path_type = get_element(sample_element,
                                      'FileRef.RelativePathType',
                                      attribute='Value')
     if relative_path_enabled == 'true' and relative_path_type == '3':
         relative_path_element = get_element(sample_element,
                                             'FileRef.RelativePath')
         sub_directory_path = []
         for path in relative_path_element:
             sub_directory_path.append(path.get('Dir'))
         from_project_root = f'{os.path.sep.join(sub_directory_path)}{os.path.sep}{name}'
         full_path = self.project_root_folder / os.path.sep.join(
             sub_directory_path) / name
         return full_path, from_project_root
     return None, None
예제 #9
0
 def load_tracks(self):
     """Load tracks into AbletonTrack src."""
     tracks = get_element(self.root, 'LiveSet.Tracks')
     for track in tracks:
         self.tracks.append(AbletonTrack(track))