def _as_graphviz_graph(self): from .nodes import Synth ordered_synths = [] cluster = uqbar.graphs.Graph(is_cluster=True, # attributes={'rank': 'same'}, ) node_mapping = {self.session.root_node: cluster} for parent, child in self._iterate_node_pairs(self.session.root_node, self._nodes_to_children): if isinstance(child, Synth) and child not in ordered_synths: child_node = child._as_graphviz_node(self.offset) ordered_synths.append(child_node) else: child_node = uqbar.graphs.Graph( is_cluster=True, attributes={ "label": child.session_id, "style": ["dashed", "rounded"], }, ) node_mapping[child] = child_node parent_node = node_mapping[parent] parent_node.append(child_node) for synth_a, synth_b in iterate_nwise(ordered_synths): synth_a.attach(synth_b) return cluster, node_mapping, ordered_synths
def __graph__(self): """ Graphs session. TODO: Get graphviz to respect node order or reimplement as pure SVG. :: >>> session = supriya.Session() >>> with session.at(0): ... group = session.add_group() ... synth_a = group.add_synth(duration=15) ... >>> with session.at(5): ... synth_b = group.add_synth(duration=15) ... synth_c = group.add_synth(duration=5) ... >>> with session.at(7.5): ... synth_d = synth_b.add_synth(duration=5, add_action="ADD_BEFORE") ... >>> with session.at(11): ... _ = synth_d.move_node(synth_a, add_action="ADD_AFTER") ... >>> supriya.graph(session) # doctest: +SKIP """ node_mappings = [] graph = uqbar.graphs.Graph( attributes={ "bgcolor": "transparent", "fontname": "Arial", "penwidth": 2, "rankdir": "LR", "ranksep": 1.5, }, edge_attributes={"penwidth": 2}, node_attributes={ "fontname": "Arial", "fontsize": 12, "penwidth": 2, "shape": "Mrecord", "style": ["filled", "rounded"], }, ) for offset, state in sorted(self.states.items()): cluster, node_mapping, _ = state._as_graphviz_graph() cluster.attributes.update( label="[{}]".format(offset), style=["solid", "rounded"] ) graph.append(cluster) node_mappings.append(node_mapping) for first_mapping, second_mapping in iterate_nwise(node_mappings): for nrt_node, graphviz_node_one in first_mapping.items(): if not isinstance(nrt_node, Synth): continue graphviz_node_two = second_mapping.get(nrt_node) if graphviz_node_two is None: continue graphviz_node_one["session_id"].attach(graphviz_node_two["session_id"]) return graph
def _validate(self, new_items, old_items, start_index, stop_index): for new_item in new_items: if new_item._device_type not in self.device_types: raise ValueError("Device mismatch") devices_to_validate = (self[start_index - 1:start_index] + list(new_items) + self[stop_index:stop_index + 1]) for device_one, device_two in iterate_nwise(devices_to_validate): if (device_one._device_type == device_two._device_type == DeviceType.INSTRUMENT): raise ValueError("Only one instrument device permitted") elif device_one._device_type > device_two._device_type: raise ValueError("Device mismatch")
def _decode_parameters(value, index): import supriya.synthdefs sdd = SynthDefDecompiler parameter_values = [] parameter_count, index = sdd._decode_int_32bit(value, index) for _ in range(parameter_count): parameter_value, index = sdd._decode_float(value, index) parameter_values.append(parameter_value) parameter_count, index = sdd._decode_int_32bit(value, index) parameter_names = [] parameter_indices = [] for _ in range(parameter_count): parameter_name, index = sdd._decode_string(value, index) parameter_index, index = sdd._decode_int_32bit(value, index) parameter_names.append(parameter_name) parameter_indices.append(parameter_index) indexed_parameters = [] if parameter_count: pairs = tuple(zip(parameter_indices, parameter_names)) pairs = sorted(pairs, key=lambda x: x[0]) iterator = utils.iterate_nwise(pairs) for (index_one, name_one), (index_two, name_two) in iterator: value = parameter_values[index_one:index_two] if len(value) == 1: value = value[0] parameter = supriya.synthdefs.Parameter( name=name_one, value=value, ) indexed_parameters.append((index_one, parameter)) index_one, name_one = pairs[-1] value = parameter_values[index_one:] if len(value) == 1: value = value[0] parameter = supriya.synthdefs.Parameter( name=name_one, value=value, ) indexed_parameters.append((index_one, parameter)) indexed_parameters.sort( key=lambda x: parameter_names.index(x[1].name), ) indexed_parameters = collections.OrderedDict(indexed_parameters) return indexed_parameters, index
def _decode_parameters(value, index): import supriya.synthdefs sdd = SynthDefDecompiler parameter_values = [] parameter_count, index = sdd._decode_int_32bit(value, index) for _ in range(parameter_count): parameter_value, index = sdd._decode_float(value, index) parameter_values.append(parameter_value) parameter_count, index = sdd._decode_int_32bit(value, index) parameter_names = [] parameter_indices = [] for _ in range(parameter_count): parameter_name, index = sdd._decode_string(value, index) parameter_index, index = sdd._decode_int_32bit(value, index) parameter_names.append(parameter_name) parameter_indices.append(parameter_index) indexed_parameters = [] if parameter_count: pairs = tuple(zip(parameter_indices, parameter_names)) pairs = sorted(pairs, key=lambda x: x[0]) iterator = utils.iterate_nwise(pairs) for (index_one, name_one), (index_two, name_two) in iterator: value = parameter_values[index_one:index_two] if len(value) == 1: value = value[0] parameter = supriya.synthdefs.Parameter(name=name_one, value=value) indexed_parameters.append((index_one, parameter)) index_one, name_one = pairs[-1] value = parameter_values[index_one:] if len(value) == 1: value = value[0] parameter = supriya.synthdefs.Parameter(name=name_one, value=value) indexed_parameters.append((index_one, parameter)) indexed_parameters.sort(key=lambda x: parameter_names.index(x[1].name)) indexed_parameters = collections.OrderedDict(indexed_parameters) return indexed_parameters, index
def add_notes(self, notes): new_notes_by_pitch = self._by_pitch(list(notes)) old_notes_by_pitch = self._by_pitch(list(self)) for pitch, new_notes in new_notes_by_pitch.items(): note_one = new_notes[0] # simultaneous new note starts: longer note wins for note_two in tuple(new_notes[1:]): if note_one.start_offset == note_two.start_offset: new_notes.remove(note_one) # new note overlaps: later notes masks earlier note for i, (note_one, note_two) in enumerate(tuple(iterate_nwise(new_notes))): if note_one.start_offset < note_two.start_offset < note_one.stop_offset: new_notes[i] = dataclasses.replace( note_one, stop_offset=note_two.start_offset) # old note overlaps: new notes delete old notes # TODO: make this more efficient(use an iterator for the new notes) for old_note in tuple(old_notes_by_pitch.get(pitch, ())): for new_note in new_notes: if (new_note.start_offset <= old_note.start_offset < new_note.stop_offset): self._notes.remove(old_note) self._notes.update(new_notes)
def __graph__(self): """ Graphs session. :: >>> session = supriya.Session() >>> with session.at(0): ... group = session.add_group() ... synth_a = group.add_synth(duration=15) ... >>> with session.at(5): ... synth_b = group.add_synth(duration=15) ... synth_c = group.add_synth(duration=5) ... >>> with session.at(7.5): ... synth_d = synth_b.add_synth(duration=5, add_action='ADD_BEFORE') ... >>> with session.at(11): ... synth_d.move_node(synth_a, add_action='ADD_AFTER') ... >>> supriya.graph(session) :: >>> graph = session.__graph__() >>> print(format(graph, 'graphviz')) digraph G { graph [bgcolor=transparent, fontname=Arial, penwidth=2, rankdir=LR, ranksep=1.5, style="dashed, rounded"]; node [fontname=Arial, fontsize=12, penwidth=2, style="filled, rounded"]; edge [penwidth=2]; subgraph cluster_0 { graph [label="[-inf]"]; } subgraph cluster_1 { graph [label="[0.0]"]; subgraph cluster_1_0 { graph [label="1000"]; node_1_0_0 [label="1001"]; } } subgraph cluster_2 { graph [label="[5.0]"]; subgraph cluster_2_0 { graph [label="1000"]; node_2_0_0 [label="1003"]; node_2_0_1 [label="1002"]; node_2_0_2 [label="1001"]; } } subgraph cluster_3 { graph [label="[10.0]"]; subgraph cluster_3_0 { graph [label="1000"]; node_3_0_0 [label="1002"]; node_3_0_1 [label="1001"]; } } subgraph cluster_4 { graph [label="[15.0]"]; subgraph cluster_4_0 { graph [label="1000"]; node_4_0_0 [label="1002"]; } } subgraph cluster_5 { graph [label="[20.0]"]; subgraph cluster_5_0 { graph [label="1000"]; } } subgraph cluster_6 { graph [label="[inf]"]; } node_1_0_0 -> node_2_0_2; node_2_0_1 -> node_3_0_0; node_2_0_2 -> node_3_0_1; node_3_0_0 -> node_4_0_0; } """ node_mappings = [] graph = uqbar.graphs.Graph( attributes={ 'bgcolor': 'transparent', 'fontname': 'Arial', 'penwidth': 2, 'rankdir': 'LR', 'ranksep': 1.5, }, edge_attributes={ 'penwidth': 2, }, node_attributes={ 'fontname': 'Arial', 'fontsize': 12, 'penwidth': 2, 'shape': 'Mrecord', 'style': ['filled', 'rounded'], }, ) for offset, state in sorted(self.states.items()): cluster, node_mapping, _ = state._as_graphviz_graph() cluster.attributes.update( label='[{}]'.format(offset), style=['solid', 'rounded'], ) graph.append(cluster) node_mappings.append(node_mapping) for first_mapping, second_mapping in iterate_nwise(node_mappings): for nrt_node, graphviz_node_one in first_mapping.items(): if not isinstance(nrt_node, Synth): continue graphviz_node_two = second_mapping.get(nrt_node) if graphviz_node_two is None: continue graphviz_node_one['session_id'].attach( graphviz_node_two['session_id']) return graph