Source code for reapy.core.fx.fx

"""Define FX and FXParam classes."""

import reapy
from reapy import reascript_api as RPR
from reapy.core import ReapyObject, ReapyObjectList
from reapy.errors import DistError, UndefinedFXParamError


[docs]class FX(ReapyObject): """FX on a Track or a Take.""" _class_name = "FX" functions = { prefix: { name.replace(prefix, ""): function for name, function in RPR.__dict__.items() if name.startswith(prefix) } for prefix in ("TrackFX_", "TakeFX_") } def __init__(self, parent=None, index=None, parent_id=None): if parent_id is None: message = ( "One of `parent` or `parent_id` must be specified." ) assert parent is not None, message parent_id = parent.id self.parent_id = parent_id self.index = index self.functions = self._get_functions() def _get_functions(self): if isinstance(self.parent, reapy.Track): type = "TrackFX_" else: type = "TakeFX_" return self.functions[type] @property def _kwargs(self): return {"parent_id": self.parent_id, "index": self.index}
[docs] def close_chain(self): """Close FX chain.""" self.functions["Show"](self.parent.id, self.index, 0)
[docs] def close_floating_window(self): """Close FX floating window.""" self.functions["Show"](self.parent.id, self.index, 2)
[docs] def close_ui(self): """Close user interface.""" self.is_ui_open = False
[docs] def copy_to_take(self, take, index=0): """ Copy FX to take. Parameters ---------- take : Take Destination take. index : int Index on destination take. See also -------- FX.move_to_take """ self.functions["CopyToTake"]( self.parent_id, self.index, take.id, index, False )
[docs] def copy_to_track(self, track, index=0): """ Copy FX to track. Parameters ---------- track : Track Destination track. index : int Index on destination track. See also -------- FX.move_to_track """ self.functions["CopyToTrack"]( self.parent_id, self.index, track.id, index, False )
[docs] def delete(self): """Delete FX.""" self.functions["Delete"](self.parent_id, self.index)
[docs] def disable(self): """Disable FX.""" self.is_enabled = False
[docs] def enable(self): """Enable FX.""" self.is_enabled = True
@property def is_enabled(self): """ Whether FX is enabled. :type: bool """ is_enabled = bool( self.functions["GetEnabled"](self.parent_id, self.index) ) return is_enabled @is_enabled.setter def is_enabled(self, enabled): self.functions["SetEnabled"](self.parent_id, self.index, enabled) @property def is_online(self): """ Whether FX is online. :type: bool """ is_online = not bool( self.functions["GetOffline"](self.parent_id, self.index) ) return is_online @is_online.setter def is_online(self, online): offline = not online self.functions["SetOffline"](self.parent_id, self.index, offline) @property def is_ui_open(self): """ Whether FX user interface is open. :type: bool """ is_ui_open = bool( self.functions["GetOpen"](self.parent_id, self.index) ) return is_ui_open @is_ui_open.setter def is_ui_open(self, open): self.functions["SetOpen"](self.parent_id, self.index, open)
[docs] def make_offline(self): """Make FX offline.""" self.is_online = False
[docs] def make_online(self): """Make FX online.""" self.is_online = True
[docs] def move_to_take(self, take, index=0): """ Move FX to take. Parameters ---------- take : Take Destination take. index : int Index on destination take. See also -------- FX.copy_to_take """ self.functions["CopyToTake"]( self.parent_id, self.index, take.id, index, True )
[docs] def move_to_track(self, track, index=0): """ Move FX to track. Parameters ---------- track : Track Destination track. index : int Index on destination track. See also -------- FX.copy_to_track """ self.functions["CopyToTrack"]( self.parent_id, self.index, track.id, index, True )
@property def n_inputs(self): """ Number of inputs of FX. :type: int """ return self.functions["GetIOSize"]( self.parent.id, self.index, 0, 0 )[3] @property def n_outputs(self): """ Number of outputs of FX. :type: int """ return self.functions["GetIOSize"]( self.parent.id, self.index, 0, 0 )[4] @property def n_params(self): """ Number of parameters. :type: int """ n_params = self.functions["GetNumParams"](self.parent_id, self.index) return n_params @property def n_presets(self): """ Number of presets. :type: int """ n_presets = self.functions["GetPresetIndex"]( self.parent_id, self.index, 0 )[-1] return n_presets @property def name(self): """ FX name. :type: str """ name = self.functions["GetFXName"]( self.parent_id, self.index, "", 2048 )[3] return name
[docs] def open_chain(self): """Open FX chain with focus on FX.""" self.functions["Show"](self.parent.id, self.index, 1)
[docs] def open_floating_window(self): """Open FX floating window.""" self.functions["Show"](self.parent.id, self.index, 3)
[docs] def open_ui(self): """Open FX user interface.""" self.is_ui_open = True
@property def params(self): """ List of parameters. :type: FXParamsList """ params = reapy.FXParamsList(self) return params @property def parent(self): """ FX parent. :type: Track or Take """ if self.parent_id.startswith("(MediaTrack*)"): return reapy.Track(self.parent_id) return reapy.Take(self.parent_id) @property def preset(self): """ FX preset name. :type: str Attribute can be set by passing a str or int. In the first case, the str can either be a preset name or the path to a .vstpreset file. Otherwise, the int is the preset index. """ preset = self.functions["GetPreset"]( self.parent_id, self.index, "", 2048 )[3] return preset @preset.setter def preset(self, preset): """ Set FX preset. Parameters ---------- preset : str or int If str, preset name or path to .vstpreset file. If int, preset index. Set to -2 for factory preset, and -1 for user default preset. """ if isinstance(preset, str): self.functions["SetPreset"]( self.parent_id, self.index, preset ) elif isinstance(preset, int): self.functions["SetPresetByIndex"]( self.parent_id, self.index, preset ) @property def preset_index(self): """ FX preset index. :type: int """ index = self.functions["GetPresetIndex"]( self.parent_id, self.index, 0 )[0] return index @property def preset_file(self): """ Path to FX preset file. :type: str """ file = self.functions["GetUserPresetFilename"]( self.parent_id, self.index, "", 2048 )[2] return file
[docs] def use_previous_preset(self): """Use previous preset in the presets list.""" self.functions["NavigatePresets"](self.parent_id, self.index, -1)
[docs] def use_next_preset(self): """Use next preset in the presets list.""" self.functions["NavigatePresets"](self.parent_id, self.index, 1)
@property def window(self): """ Floating window associated to FX, if it exists. :type: Window or NoneType """ window = reapy.Window( self.functions["GetFloatingWindow"](self.parent.id, self.index) ) if not window._is_defined: window = None return window
[docs]class FXList(ReapyObjectList): """ Container class for a list of FXs. FXs can be accessed by name or index. Examples -------- >>> fx_list = track.fxs >>> fx_list[0] FX(parent_id="(MediaTrack*)0x0000000006CDEBE0", index=0) >>> len(fx_list) 1 >>> fx_list["VST: ReaComp (Cockos)"] FX(parent_id="(MediaTrack*)0x0000000006CDEBE0", index=0) """ _class_name = "FXList" def __init__(self, parent): self.parent = parent @reapy.inside_reaper() def __delitem__(self, key): fxs = self[key] if isinstance(key, slice) else [self[key]] for fx in fxs: fx.delete() def __getitem__(self, i): if isinstance(i, slice): return self._get_items_from_slice(i) with reapy.inside_reaper(): if isinstance(i, str): i = self._get_fx_index(name=i) n_fxs = self.parent.n_fxs if i >= n_fxs: raise IndexError("{} has only {} fxs".format(self.parent, n_fxs)) i = i % n_fxs # Allows for negative values fx = FX(self.parent, i) return fx def __len__(self): return self.parent.n_fxs @reapy.inside_reaper() def _get_items_from_slice(self, slice): indices = range(*slice.indices(len(self))) return [self[i] for i in indices] def _get_fx_index(self, name): name = name[name.find(': ') + 2:] # Remove FX type prefix if isinstance(self.parent, reapy.Track): prefix = "TrackFX_" args = (self.parent.id, name, False, 0) else: prefix = "TakeFX_" args = (self.parent.id, name, 0) index = getattr(RPR, prefix + "AddByName")(*args) if index == -1: raise KeyError("No FX named {}".format(name)) return index @property def _args(self): return self.parent,