:mod:`sc3nb.sc_objects.node` ============================ .. py:module:: sc3nb.sc_objects.node .. autoapi-nested-parse:: Implements Node and subclasses Synth and Group. .. !! processed by numpydoc !! Module Contents --------------- Class List ~~~~~~~~~~ .. autoapisummary:: :nosignatures: sc3nb.sc_objects.node.GroupReply sc3nb.sc_objects.node.GroupCommand sc3nb.sc_objects.node.SynthCommand sc3nb.sc_objects.node.NodeReply sc3nb.sc_objects.node.NodeCommand sc3nb.sc_objects.node.AddAction sc3nb.sc_objects.node.SynthInfo sc3nb.sc_objects.node.GroupInfo sc3nb.sc_objects.node.Node sc3nb.sc_objects.node.Synth sc3nb.sc_objects.node.Group sc3nb.sc_objects.node.NodeTree Content ~~~~~~~ .. py:data:: _LOGGER .. class:: GroupReply **Bases:** :class:`str`, :class:`enum.Enum` Replies of Group Commands Initialize self. See help(type(self)) for accurate signature. .. !! processed by numpydoc !! .. py:attribute:: QUERY_TREE_REPLY :value: '/g_queryTree.reply' .. class:: GroupCommand **Bases:** :class:`str`, :class:`enum.Enum` OSC Commands for Groups Initialize self. See help(type(self)) for accurate signature. .. !! processed by numpydoc !! .. py:attribute:: QUERY_TREE :value: '/g_queryTree' .. py:attribute:: DUMP_TREE :value: '/g_dumpTree' .. py:attribute:: DEEP_FREE :value: '/g_deepFree' .. py:attribute:: FREE_ALL :value: '/g_freeAll' .. py:attribute:: TAIL :value: '/g_tail' .. py:attribute:: HEAD :value: '/g_head' .. py:attribute:: G_NEW :value: '/g_new' .. py:attribute:: P_NEW :value: '/p_new' .. class:: SynthCommand **Bases:** :class:`str`, :class:`enum.Enum` OSC Commands for Synths Initialize self. See help(type(self)) for accurate signature. .. !! processed by numpydoc !! .. py:attribute:: NEW :value: '/s_new' .. py:attribute:: S_GET :value: '/s_get' .. py:attribute:: S_GETN :value: '/s_getn' .. class:: NodeReply **Bases:** :class:`str`, :class:`enum.Enum` Replies of Node Commands Initialize self. See help(type(self)) for accurate signature. .. !! processed by numpydoc !! .. py:attribute:: INFO :value: '/n_info' .. class:: NodeCommand **Bases:** :class:`str`, :class:`enum.Enum` OSC Commands for Nodes Initialize self. See help(type(self)) for accurate signature. .. !! processed by numpydoc !! .. py:attribute:: ORDER :value: '/n_order' .. py:attribute:: TRACE :value: '/n_trace' .. py:attribute:: QUERY :value: '/n_query' .. py:attribute:: MAP :value: '/n_map' .. py:attribute:: MAPN :value: '/n_mapn' .. py:attribute:: MAPA :value: '/n_mapa' .. py:attribute:: MAPAN :value: '/n_mapan' .. py:attribute:: FILL :value: '/n_fill' .. py:attribute:: SET :value: '/n_set' .. py:attribute:: SETN :value: '/n_setn' .. py:attribute:: RUN :value: '/n_run' .. py:attribute:: FREE :value: '/n_free' .. class:: AddAction(*args, **kwds) **Bases:** :class:`enum.Enum` AddAction of SuperCollider nodes. This Enum contains the codes for the different ways to add a node. .. !! processed by numpydoc !! .. py:attribute:: TO_HEAD :value: 0 .. py:attribute:: TO_TAIL :value: 1 .. py:attribute:: BEFORE :value: 2 .. py:attribute:: AFTER :value: 3 .. py:attribute:: REPLACE :value: 4 .. class:: SynthInfo **Bases:** :class:`NamedTuple` Information about the Synth from /n_info .. !! processed by numpydoc !! .. py:attribute:: nodeid :type: int .. py:attribute:: group :type: int .. py:attribute:: prev_nodeid :type: int .. py:attribute:: next_nodeid :type: int .. class:: GroupInfo **Bases:** :class:`NamedTuple` Information about the Group from /n_info .. !! processed by numpydoc !! .. py:attribute:: nodeid :type: int .. py:attribute:: group :type: int .. py:attribute:: prev_nodeid :type: int .. py:attribute:: next_nodeid :type: int .. py:attribute:: head :type: int .. py:attribute:: tail :type: int .. class:: Node(*, nodeid: Optional[int] = None, add_action: Optional[Union[AddAction, int]] = None, target: Optional[Union[Node, int]] = None, server: Optional[sc3nb.sc_objects.server.SCServer] = None) **Bases:** :class:`abc.ABC` Representation of a Node on SuperCollider. Create a new Node :Parameters: **nodeid** : int or None This Nodes node id or None **add_action** : AddAction or corresponding int, optional This Nodes AddAction when created in Server, by default None **target** : Node or int or None, optional This Nodes AddActions target, by default None **server** : SCServer, optional The Server for this Node, by default use the SC default server .. !! processed by numpydoc !! .. py:attribute:: _server .. py:attribute:: _state_lock .. py:attribute:: _free_event .. py:attribute:: _on_free_callback :value: None .. py:attribute:: _started :value: False .. py:attribute:: _freed :value: False .. py:attribute:: _nodeid .. py:attribute:: _group :value: None .. py:attribute:: _target_id .. py:attribute:: _is_playing :value: None .. py:attribute:: _is_running :value: None .. py:attribute:: _current_controls **Overview:** .. autoapisummary:: :nosignatures: sc3nb.sc_objects.node.Node.new sc3nb.sc_objects.node.Node._get_status_repr sc3nb.sc_objects.node.Node._set_node_attrs sc3nb.sc_objects.node.Node.free sc3nb.sc_objects.node.Node.run sc3nb.sc_objects.node.Node.set sc3nb.sc_objects.node.Node._update_control sc3nb.sc_objects.node.Node._update_controls sc3nb.sc_objects.node.Node.fill sc3nb.sc_objects.node.Node.map sc3nb.sc_objects.node.Node.release sc3nb.sc_objects.node.Node.query sc3nb.sc_objects.node.Node.trace sc3nb.sc_objects.node.Node.move sc3nb.sc_objects.node.Node.register sc3nb.sc_objects.node.Node.unregister sc3nb.sc_objects.node.Node.on_free sc3nb.sc_objects.node.Node.wait sc3nb.sc_objects.node.Node._parse_info sc3nb.sc_objects.node.Node._handle_notification sc3nb.sc_objects.node.Node.__eq__ sc3nb.sc_objects.node.Node._get_nodeid .. py:method:: new(*args, add_action: Optional[Union[AddAction, int]] = None, target: Optional[Union[Node, int]] = None, return_msg: bool = False, **kwargs) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] :abstractmethod: Create a new Node :Parameters: **add_action** : AddAction or int, optional Where the Node should be added, by default AddAction.TO_HEAD (0) **target** : Node or int, optional AddAction target, if None it will be the default group of the server .. !! processed by numpydoc !! .. py:method:: _get_status_repr() -> str .. py:method:: _set_node_attrs(target: Optional[Union[Node, int]] = None, add_action: Optional[Union[AddAction, int]] = None) -> None Derive Node group from addaction and target :Parameters: **target** : int or Node Target nodeid or Target Node of this Node's AddAction **add_action** : AddAction AddAction of this Node, default AddAction.TO_HEAD (0) .. !! processed by numpydoc !! .. py:method:: free(return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Free the node with /n_free. This will set is_running and is_playing to false. Even when the message is returned to mimic the behavior of the SuperCollider Node See https://doc.sccode.org/Classes/Node.html#-freeMsg :Returns: Node or OSCMessage self for chaining or OSCMessage when return_msg=True .. !! processed by numpydoc !! .. py:method:: run(on: bool = True, return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Turn node on or off with /n_run. :Parameters: **on** : bool True for on, False for off, by default True :Returns: Node or OSCMessage self for chaining or OSCMessage when return_msg=True .. !! processed by numpydoc !! .. py:method:: set(argument: Union[str, Dict, List], *values: Any, return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Set a control value(s) of the node with n_set. :Parameters: **argument** : str | dict | list if string: name of control argument if dict: dict with argument, value pairs if list: use list as message content **value** : any, optional only used if argument is string, by default None .. rubric:: Examples >>> synth.set("freq", 400) >>> synth.set({"dur": 1, "freq": 400}) >>> synth.set(["dur", 1, "freq", 400]) .. !! processed by numpydoc !! .. py:method:: _update_control(control: str, value: Any) -> None .. py:method:: _update_controls(controls: Optional[Dict[str, Any]] = None) -> None .. py:method:: fill(control: Union[str, int], num_controls: int, value: Any, return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Fill ranges of control values with n_fill. :Parameters: **control** : int or string control index or name **num_controls** : int number of control values to fill **value** : float or int value to set **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: map(control: Union[str, int], bus: sc3nb.sc_objects.bus.Bus, return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Map a node's control to read from a bus using /n_map or /n_mapa. :Parameters: **control** : int or string control index or name **bus** : Bus control/audio bus **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: release(release_time: Optional[float] = None, return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Set gate as specified. https://doc.sccode.org/Classes/Node.html#-release :Parameters: **release_time** : float, optional amount of time in seconds during which the node will release. If set to a value <= 0, the synth will release immediately. If None using its Envs normal release stage(s) **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: query() -> Union[SynthInfo, GroupInfo] Sends an n_query message to the server. The answer is send to all clients who have registered via the /notify command. Content of answer: node ID the node's parent group ID previous node ID, -1 if no previous node. next node ID, -1 if no next node. 1 if the node is a group, 0 if it is a synth if the node is a group: ID of the head node, -1 if there is no head node. ID of the tail node, -1 if there is no tail node. :Returns: SynthInfo or GroupInfo n_info answer. See above for content description .. !! processed by numpydoc !! .. py:method:: trace(return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Trace a node. Print out values of the inputs and outputs for one control period. If node is a group then print the node IDs and names of each node. :Parameters: **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: Node or OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: move(add_action: AddAction, another_node: Node, return_msg: bool = False) -> Union[Node, sc3nb.osc.osc_communication.OSCMessage] Move this node :Parameters: **add_action** : AddAction [TO_HEAD, TO_TAIL, AFTER, BEFORE] What add action should be done. **another_node** : Node The node which is the target of the add action **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: Node or OSCMessage if return_msg this will be the OSCMessage, else self :Raises: ValueError If a wrong AddAction was provided .. !! processed by numpydoc !! .. py:method:: register() :abstractmethod: Register to be watched. .. !! processed by numpydoc !! .. py:method:: unregister() :abstractmethod: Unregister to stop being watched. .. !! processed by numpydoc !! .. py:method:: on_free(func) Callback that is executed when this Synth is freed .. !! processed by numpydoc !! .. py:method:: wait(timeout: Optional[float] = None) -> None Wait until this Node is freed :Raises: TimeoutError If timeout was provided and wait timed out. .. !! processed by numpydoc !! .. py:method:: _parse_info(nodeid: int, group: int, prev_nodeid: int, next_nodeid: int, *rest: Sequence[int]) -> Union[SynthInfo, GroupInfo] .. py:method:: _handle_notification(kind: str, info) -> None .. py:method:: __eq__(other) .. py:method:: _get_nodeid(value: Union[Node, int]) -> int :staticmethod: Get the corresponding node id :Parameters: **value** : Node or int If a Node is provided it will get its nodeid If a int is provided it will be returned :Returns: int nodeid :Raises: ValueError When neither Node or int was provided .. !! processed by numpydoc !! .. class:: Synth(name: Optional[str] = None, controls: Dict[str, Any] = None, *, nodeid: Optional[int] = None, new: bool = True, add_action: Optional[Union[AddAction, int]] = None, target: Optional[Union[Node, int]] = None, server: Optional[sc3nb.sc_objects.server.SCServer] = None) **Bases:** :class:`Node` Representation of a Synth on SuperCollider. Create a Python representation of a SuperCollider synth. :Parameters: **name** : str, optional name of the synth to be created, by default "default" **controls** : dict, optional synth control arguments, by default None **nodeid** : int, optional ID of the node in SuperCollider, by default sc3nb will create one. Can be set to an existing id to create a Python instance of a running Node. **new** : bool, optional True if synth should be created on the server, by default True Should be False if creating an instance of a running Node. **add_action** : AddAction or int, optional Where the Synth should be added, by default AddAction.TO_HEAD (0) **target** : Node or int, optional AddAction target, if None it will be the default group of the server **server** : SCServer sc3nb SCServer instance :Raises: ValueError Raised when synth can't be found via SynthDescLib.global .. rubric:: Examples >>> scn.Synth(sc, "s1", {"dur": 1, "freq": 400}) .. !! processed by numpydoc !! .. py:attribute:: _server .. py:attribute:: _initialized :value: False **Overview:** .. autoapisummary:: :nosignatures: sc3nb.sc_objects.node.Synth._update_synth_state sc3nb.sc_objects.node.Synth.new sc3nb.sc_objects.node.Synth.get sc3nb.sc_objects.node.Synth.seti sc3nb.sc_objects.node.Synth.__getattr__ sc3nb.sc_objects.node.Synth.__setattr__ sc3nb.sc_objects.node.Synth.__repr__ .. py:method:: _update_synth_state(name: Optional[str], controls: Optional[dict]) .. py:method:: new(controls: Optional[dict] = None, add_action: Optional[Union[AddAction, int]] = None, target: Optional[Union[Node, int]] = None, *, return_msg: bool = False) -> Union[Synth, sc3nb.osc.osc_communication.OSCMessage] Creates the synth on the server with s_new. Attention: Here you create an identical synth! Same nodeID etc. - This will fail if there is already this nodeID on the SuperCollider server! .. !! processed by numpydoc !! .. py:method:: get(control: str) -> Any Get a Synth argument This will request the value from scsynth with /s_get(n). :Parameters: **control** : str name of the Synth control argument .. !! processed by numpydoc !! .. py:method:: seti(*args) :abstractmethod: Set part of an arrayed control. .. !! processed by numpydoc !! .. py:method:: __getattr__(name) .. py:method:: __setattr__(name, value) .. py:method:: __repr__() -> str .. class:: Group(*, nodeid: Optional[int] = None, new: bool = True, parallel: bool = False, add_action: AddAction = AddAction.TO_HEAD, target: Optional[Union[Node, int]] = None, server: Optional[sc3nb.sc_objects.server.SCServer] = None) **Bases:** :class:`Node` Representation of a Group on SuperCollider. Create a Python representation of a SuperCollider group. :Parameters: **nodeid** : int, optional ID of the node in SuperCollider, by default sc3nb will create one. Can be set to an existing id to create a Python instance of a running Node. **new** : bool, optional True if synth should be created on the server, by default True Should be False if creating an instance of a running Node. **parallel** : bool, optional If True create a parallel group, by default False **add_action** : AddAction or int, optional Where the Group should be added, by default AddAction.TO_HEAD (0) **target** : Node or int, optional AddAction target, if None it will be the default group of the server **server** : SCServer, optional Server instance where this Group is located, by default use the SC default server .. !! processed by numpydoc !! .. py:attribute:: _server **Overview:** .. autoapisummary:: :nosignatures: sc3nb.sc_objects.node.Group._update_group_state sc3nb.sc_objects.node.Group.new sc3nb.sc_objects.node.Group.move_node_to_head sc3nb.sc_objects.node.Group.move_node_to_tail sc3nb.sc_objects.node.Group.free_all sc3nb.sc_objects.node.Group.deep_free sc3nb.sc_objects.node.Group.dump_tree sc3nb.sc_objects.node.Group.query_tree sc3nb.sc_objects.node.Group._repr_pretty_ sc3nb.sc_objects.node.Group.__repr__ .. py:method:: _update_group_state(children: Optional[Sequence[Node]] = None) -> None .. py:method:: new(add_action=AddAction.TO_HEAD, target=None, *, parallel=None, return_msg=False) -> Union[Group, sc3nb.osc.osc_communication.OSCMessage] Creates the synth on the server with g_new / p_new. Attention: Here you create an identical group! Same nodeID etc. - This will fail if there is already this nodeID on the SuperCollider server! :Parameters: **add_action** : AddAction or int, optional where the group should be added, by default AddAction.TO_HEAD (0) **target** : Node or int, optional add action target, by default 1 **parallel** : bool, optional If True use p_new, by default False **return_msg** : bool, optional If ture return the OSCMessage instead of sending it, by default False :Returns: Group self .. !! processed by numpydoc !! .. py:method:: move_node_to_head(node, return_msg=False) Move node to this groups head with g_head. :Parameters: **node** : Node node to move **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: Group self .. !! processed by numpydoc !! .. py:method:: move_node_to_tail(node, return_msg=False) Move node to this groups tail with g_tail. :Parameters: **node** : Node node to move **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: Group self .. !! processed by numpydoc !! .. py:method:: free_all(return_msg=False) Frees all nodes in the group with g_freeAll. :Parameters: **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: deep_free(return_msg=False) Free all synths in this group and its sub-groups with g_deepFree. Sub-groups are not freed. :Parameters: **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: dump_tree(post_controls=True, return_msg=False) Posts a representation of this group's node subtree with g_dumpTree. :Parameters: **post_controls** : bool, optional True for control values, by default False **return_msg** : bool, optional If True return msg else send it directly, by default False :Returns: OSCMessage if return_msg else self .. !! processed by numpydoc !! .. py:method:: query_tree(include_controls=False) -> Group Send a g_queryTree message for this group. See https://doc.sccode.org/Reference/Server-Command-Reference.html#/g_queryTree for details. :Parameters: **include_controls** : bool, optional True for control values, by default False :Returns: tuple /g_queryTree.reply .. !! processed by numpydoc !! .. py:method:: _repr_pretty_(printer, cylce) .. py:method:: __repr__() -> str .. class:: NodeTree(info: Sequence[Any], root_nodeid: int, controls_included: bool, start: int = 0, server: Optional[sc3nb.sc_objects.server.SCServer] = None) Node Tree is a class for parsing /g_queryTree.reply .. !! processed by numpydoc !! .. py:attribute:: controls_included .. py:attribute:: root_nodeid **Overview:** .. autoapisummary:: :nosignatures: sc3nb.sc_objects.node.NodeTree.parse_nodes sc3nb.sc_objects.node.NodeTree._repr_pretty_ .. py:method:: parse_nodes(info: Sequence[Any], controls_included: bool = True, start: int = 0, server: Optional[sc3nb.sc_objects.server.SCServer] = None) -> Tuple[int, Node] :staticmethod: Parse Nodes from reply of the /g_queryTree cmd of scsynth. This reads the /g_queryTree.reply and creates the corresponding Nodes in Python. See https://doc.sccode.org/Reference/Server-Command-Reference.html#/g_queryTree :Parameters: **controls_included** : bool If True the current control (arg) values for synths will be included **start** : int starting position of the parsing, used for recursion, default 0 **info** : Sequence[Any] /g_queryTree.reply to be parsed. :Returns: Tuple[int, Node] postion where the parsing ended, resulting Node .. !! processed by numpydoc !! .. py:method:: _repr_pretty_(printer, cylce)