示例#1
0
 def allocate(self, desired_block_size=1):
     desired_block_size = int(desired_block_size)
     assert 0 < desired_block_size
     block_id = None
     with self._lock:
         free_block = None
         for block in self._free_heap:
             if desired_block_size <= block.duration:
                 free_block = block
                 break
         if free_block is not None:
             split_offset = free_block.start_offset + desired_block_size
             self._free_heap.remove(free_block)
             if desired_block_size < free_block.duration:
                 new_free_block = utils.new(
                     free_block,
                     start_offset=split_offset,
                     used=False,
                 )
                 self._free_heap.insert(new_free_block)
                 used_block = utils.new(
                     free_block,
                     stop_offset=split_offset,
                     used=True,
                 )
             else:
                 used_block = utils.new(
                     free_block,
                     used=True,
                 )
             self._used_heap.insert(used_block)
             block_id = used_block.start_offset
     return block_id
示例#2
0
 def _render_datagram(self, session, input_file_path, output_file_path,
                      session_osc_file_path, **kwargs):
     relative_session_osc_file_path = session_osc_file_path
     if relative_session_osc_file_path.is_absolute():
         relative_session_osc_file_path = session_osc_file_path.relative_to(
             pathlib.Path.cwd())
     self._report('Rendering {}.'.format(relative_session_osc_file_path))
     if output_file_path.exists():
         self._report('    Skipped {}. Output already exists.'.format(
             relative_session_osc_file_path))
         return 0
     server_options = session._options
     server_options = utils.new(server_options, **kwargs)
     memory_size = server_options.memory_size
     for factor in range(1, 4):
         command = self._build_render_command(
             input_file_path,
             output_file_path,
             session_osc_file_path,
             server_options=server_options,
         )
         self._report('    Command: {}'.format(command))
         exit_code = self._stream_subprocess(command, session.duration)
         server_options = utils.new(
             server_options,
             memory_size=memory_size * (2**factor),
         )
         if exit_code == -6:
             self._report('    Out of memory. Increasing to {}.'.format(
                 server_options.memory_size))
         else:
             self._report('    Rendered {} with exit code {}.'.format(
                 relative_session_osc_file_path, exit_code))
             break
     return exit_code
示例#3
0
 def _apply_iterator_recursively(self, expr, iterator):
     import supriya.patterns
     if isinstance(expr, supriya.patterns.CompositeEvent):
         coerced_events = [
             self._apply_iterator_recursively(child_event, iterator)
             for child_event in expr.get('events') or ()
         ]
         expr = utils.new(expr, events=coerced_events)
     else:
         expr = utils.new(expr, _iterator=iterator)
     return expr
示例#4
0
    def __init__(
        self,
        source,
        target,
        source_range=None,
        target_range=None,
        clip_minimum=None,
        clip_maximum=None,
        exponent=None,
        symmetric=None,
    ):
        import supriya.synthdefs

        # import supriya.system
        # assert isinstance(source, supriya.system.Bindable), source
        # assert isinstance(target, supriya.system.Bindable), target
        # self.source = source
        # self.target = target
        self.source = self.patch(source)
        self.target = self.patch(target)
        if source_range is None:
            if hasattr(self.source.func.__self__, "range_"):
                source_range = self.source.func.__self__.range_
            else:
                source_range = (0.0, 1.0)
        source_range = supriya.synthdefs.Range(source_range)
        if source_range.minimum == float("-inf"):
            source_range = utils.new(source_range, minimum=0.0)
        if source_range.maximum == float("inf"):
            source_range = utils.new(source_range, maximum=1.0)
        self.source_range = supriya.synthdefs.Range(source_range)
        if target_range is None:
            if hasattr(self.target.func, "__self__") and hasattr(
                    self.target.func.__self__, "range_"):
                target_range = self.target.func.__self__.range_
            else:
                target_range = (0.0, 1.0)
        target_range = supriya.synthdefs.Range(target_range)
        if target_range.minimum == float("-inf"):
            target_range = utils.new(target_range, minimum=0.0)
        if target_range.maximum == float("inf"):
            target_range = utils.new(target_range, maximum=1.0)
        self.target_range = supriya.synthdefs.Range(target_range)
        self.clip_maximum = bool(clip_maximum)
        self.clip_minimum = bool(clip_minimum)
        if exponent is None:
            exponent = 1.0
        self.exponent = float(exponent)
        self.symmetric = bool(symmetric)
        self.source.outgoing_bindings.add(self)
        self.target.incoming_bindings.add(self)
示例#5
0
 def _build_render_command(
     self,
     input_file_path,
     output_file_path,
     session_osc_file_path,
     server_options=None,
 ):
     cwd = pathlib.Path.cwd()
     server_options = server_options or supriya.realtime.ServerOptions()
     if os.environ.get("TRAVIS", None):
         server_options = utils.new(server_options, load_synthdefs=True)
     scsynth_path = "scsynth"
     if not uqbar.io.find_executable(scsynth_path):
         raise RuntimeError("Cannot find scsynth")
     if session_osc_file_path.is_absolute():
         session_osc_file_path = session_osc_file_path.relative_to(cwd)
     parts = [scsynth_path, "-N", session_osc_file_path]
     if input_file_path:
         parts.append(input_file_path)
     else:
         parts.append("_")
     if output_file_path.is_absolute() and cwd in output_file_path.parents:
         output_file_path = output_file_path.relative_to(cwd)
     parts.append(output_file_path)
     parts.append(self.sample_rate)
     parts.append(self.header_format.name.lower())  # Must be lowercase.
     parts.append(self.sample_format.name.lower())  # Must be lowercase.
     server_options = server_options.as_options_string(realtime=False)
     if server_options:
         parts.append(server_options)
     command = " ".join(str(_) for _ in parts)
     return command
示例#6
0
 def _coerce_iterator_output(self, expr, state=None):
     import supriya.patterns
     if not isinstance(expr, supriya.patterns.Event):
         expr = supriya.patterns.NoteEvent(**expr)
     if expr.get('uuid') is None:
         expr = utils.new(expr, uuid=uuid.uuid4())
     return expr
示例#7
0
 def _coerce_iterator_output(self, expr, state):
     import supriya.patterns
     expr = super(Pgroup, self)._coerce_iterator_output(expr)
     if (isinstance(expr, supriya.patterns.NoteEvent)
             or not expr.get('is_stop')):
         kwargs = {}
         if expr.get('target_node') is None:
             kwargs['target_node'] = state['group_uuid']
         expr = utils.new(expr, **kwargs)
     return expr
示例#8
0
 def _iterate(self, state=None):
     if self.key:
         for _ in self._loop(self._repetitions):
             for i, x in enumerate(self._pattern):
                 if i == 0:
                     x = utils.new(x, **{self.key: True})
                 yield x
     else:
         for _ in self._loop(self._repetitions):
             yield from self._pattern
示例#9
0
 def _iterate(self, state=None):
     synth_uuid = uuid.uuid4()
     iterator = super(Pmono, self)._iterate(state=state)
     events = []
     try:
         events.append(next(iterator))
     except StopIteration:
         return
     for event in iterator:
         events.append(event)
         event = utils.new(events.pop(0), uuid=synth_uuid, is_stop=False)
         should_stop = yield event
         if should_stop:
             return
     assert len(events) == 1
     if events:
         event = events.pop()
         event = utils.new(event, uuid=synth_uuid, is_stop=True)
         yield event
示例#10
0
    def _coerce_iterator_output(self, expr, state):
        import supriya.patterns

        expr = super(Pgroup, self)._coerce_iterator_output(expr)
        if isinstance(expr,
                      supriya.patterns.NoteEvent) or not expr.get("is_stop"):
            kwargs = {}
            if expr.get("target_node") is None:
                kwargs["target_node"] = state["group_uuid"]
            expr = utils.new(expr, **kwargs)
        return expr
示例#11
0
 def _coerce_iterator_output_recursively(self, expr, state=None):
     import supriya.patterns
     if isinstance(expr, supriya.patterns.CompositeEvent):
         coerced_events = [
             self._coerce_iterator_output(child_event, state=state)
             for child_event in expr.get('events') or ()
         ]
         expr = utils.new(expr, events=coerced_events)
     else:
         expr = self._coerce_iterator_output(expr, state=state)
     return expr
示例#12
0
    def _coerce_iterator_output(self, expr, state):
        import supriya.patterns

        iterator = expr.get("_iterator")
        iterators_to_group_uuids = state["iterators_to_group_uuids"]
        kwargs = {"_iterator": None}
        if isinstance(expr,
                      supriya.patterns.NoteEvent) or not expr.get("is_stop"):
            if expr.get("target_node") is None:
                kwargs["target_node"] = iterators_to_group_uuids[iterator]
            expr = utils.new(expr, **kwargs)
        return expr
示例#13
0
 def _coerce_iterator_output(self, expr, state):
     import supriya.patterns
     iterator = expr.get('_iterator')
     iterators_to_group_uuids = state['iterators_to_group_uuids']
     kwargs = {'_iterator': None}
     if (
         isinstance(expr, supriya.patterns.NoteEvent) or
         not expr.get('is_stop')
         ):
         if expr.get('target_node') is None:
             kwargs['target_node'] = iterators_to_group_uuids[iterator]
         expr = utils.new(expr, **kwargs)
     return expr
示例#14
0
    def boot(self, scsynth_path=None, server_options=None, **kwargs):
        import supriya.realtime

        if self.is_running:
            return self
        scsynth_path = scsynth_path or os.environ.get("SCSYNTH_PATH")
        if not scsynth_path:
            scsynth_path_candidates = uqbar.io.find_executable("scsynth")
            if not scsynth_path_candidates:
                raise RuntimeError("Cannot find scsynth")
            scsynth_path = scsynth_path_candidates[0]
        scsynth_path = pathlib.Path(scsynth_path).absolute()
        if not scsynth_path.exists():
            raise RuntimeError("{} does not exist".format(scsynth_path))

        self._osc_io.boot(ip_address=self.ip_address, port=self.port)
        self._setup_osc_callbacks()

        server_options = server_options or supriya.realtime.ServerOptions()
        assert isinstance(server_options, supriya.realtime.ServerOptions)
        if kwargs:
            server_options = utils.new(server_options, **kwargs)
        options_string = server_options.as_options_string(self.port)
        command = "{} {}".format(scsynth_path, options_string)
        if self.debug_subprocess:
            print("Boot:", command)
        process = self._server_process = subprocess.Popen(
            command,
            shell=True,
            stderr=subprocess.STDOUT,
            stdout=subprocess.PIPE,
            start_new_session=True,
        )
        try:
            self._read_scsynth_boot_output()
        except supriya.exceptions.ServerCannotBoot:
            self._osc_io.quit()
            try:
                process_group = os.getpgid(process.pid)
                os.killpg(process_group, signal.SIGINT)
                process.terminate()
                process.wait()
            except ProcessLookupError:
                pass
            raise
        self._is_running = True
        self._server_options = server_options
        self._setup()
        PubSub.notify("server-booted")
        return self
示例#15
0
 def __call__(self, execution_time, scheduled_time, communicate=True):
     if self._iterator is None:
         self._iterator = self._iterate_outer(
             pattern=self._pattern,
             server=self._server,
             timestamp=scheduled_time,
             uuids=self._uuids,
         )
     event_products, delta = next(self._iterator)
     node_free_ids, requests = set(), []
     for event_product in event_products:
         if not event_product.event:
             continue
         for request in event_product.requests:
             if isinstance(request, supriya.commands.NodeFreeRequest):
                 node_free_ids.update(request.node_ids)
             else:
                 requests.append(request)
         if event_product.is_stop:
             proxies = self._uuids[event_product.uuid]
             for proxy_id, proxy in proxies.items():
                 if isinstance(proxy, (
                         supriya.realtime.Bus,
                         supriya.realtime.BusGroup,
                 )):
                     allocator = supriya.realtime.Bus._get_allocator(
                         calculation_rate=proxy.calculation_rate,
                         server=self._server,
                     )
                     allocator.free(proxy_id)
             self._uuids.pop(event_product.uuid)
     if node_free_ids:
         node_free_ids = sorted(node_free_ids)
         request = supriya.commands.NodeFreeRequest(node_ids=node_free_ids)
         requests.append(request)
     consolidated_bundle = supriya.commands.RequestBundle(
         timestamp=scheduled_time,
         contents=requests,
     )
     if communicate:
         osc_bundle = consolidated_bundle.to_osc_bundle()
         osc_bundle = utils.new(
             osc_bundle,
             timestamp=osc_bundle.timestamp + self._server.latency,
         )
         self._server.send_message(osc_bundle)
         return delta
     return consolidated_bundle, delta
示例#16
0
 def _iterate(self, state=None):
     patterns = [iter(_) for _ in self._patterns]
     while True:
         try:
             event = next(patterns[0])
         except StopIteration:
             return
         for pattern in patterns[1:]:
             try:
                 template_event = next(pattern)
             except StopIteration:
                 return
             template_dict = template_event.as_dict()
             for key, value in tuple(template_dict.items()):
                 if value is None:
                     template_dict.pop(key)
             event = utils.new(event, **template_dict)
         yield event
示例#17
0
 def _add_parameter(self, *args):
     import supriya.synthdefs
     if 3 < len(args):
         raise ValueError(args)
     if len(args) == 1:
         assert isinstance(args[0], supriya.synthdefs.Parameter)
         name, value, parameter_rate = \
             args[0].name, args[0], args[0].parameter_rate
     elif len(args) == 2:
         name, value = args
         if not isinstance(value, supriya.synthdefs.Parameter):
             parameter_rate = supriya.synthdefs.ParameterRate.SCALAR
             if name.startswith('a_'):
                 parameter_rate = supriya.synthdefs.ParameterRate.AUDIO
             elif name.startswith('i_'):
                 parameter_rate = supriya.synthdefs.ParameterRate.SCALAR
             elif name.startswith('t_'):
                 parameter_rate = supriya.synthdefs.ParameterRate.TRIGGER
             else:
                 parameter_rate = supriya.synthdefs.ParameterRate.CONTROL
         else:
             parameter_rate = value.parameter_rate
     elif len(args) == 3:
         name, value, parameter_rate = args
         parameter_rate = supriya.synthdefs.ParameterRate.from_expr(
             parameter_rate, )
     else:
         raise ValueError(args)
     if not isinstance(value, supriya.synthdefs.Parameter):
         parameter = supriya.synthdefs.Parameter(
             name=name,
             parameter_rate=parameter_rate,
             value=value,
         )
     else:
         parameter = utils.new(
             value,
             parameter_rate=parameter_rate,
             name=name,
         )
     assert parameter._uuid is None
     parameter._uuid = self._uuid
     self._parameters[name] = parameter
     return parameter
示例#18
0
 def _coerce_iterator_output(self, expr, state):
     import supriya.assets.synthdefs
     import supriya.patterns
     expr = super(Pbus, self)._coerce_iterator_output(expr)
     if (isinstance(expr, supriya.patterns.NoteEvent)
             or not expr.get('is_stop')):
         kwargs = {}
         if expr.get('target_node') is None:
             kwargs['target_node'] = state['group_uuid']
         prototype = (supriya.patterns.NoteEvent,
                      supriya.patterns.SynthEvent)
         if isinstance(expr, prototype):
             synthdef = expr.get(
                 'synthdef') or supriya.assets.synthdefs.default
             parameter_names = synthdef.parameter_names
             if expr.get('out') is None and 'out' in parameter_names:
                 kwargs['out'] = state['bus_uuid']
             if expr.get('in_') is None and 'in_' in parameter_names:
                 kwargs['in_'] = state['bus_uuid']
         expr = utils.new(expr, **kwargs)
     return expr
示例#19
0
 def _iterate(self, state=None):
     should_stop = self.PatternState.CONTINUE
     event_iterator = iter(self._event_pattern)
     key_iterators = self._coerce_pattern_pairs(self._patterns)
     template_dict = {}
     while True:
         try:
             if not should_stop:
                 expr = next(event_iterator)
             else:
                 expr = event_iterator.send(True)
         except StopIteration:
             return
         expr = self._coerce_iterator_output(expr)
         for name, key_iterator in sorted(key_iterators.items()):
             try:
                 template_dict[name] = next(key_iterator)
             except StopIteration:
                 continue
         expr = utils.new(expr, **template_dict)
         should_stop = yield expr
示例#20
0
 def boot(
     self,
     server_options=None,
     **kwargs
     ):
     import supriya.realtime
     if self.is_running:
         return self
     scsynth_path = 'scsynth'
     if not uqbar.io.find_executable(scsynth_path):
         raise RuntimeError('Cannot find scsynth')
     self._osc_controller.boot()
     server_options = server_options or supriya.realtime.ServerOptions()
     assert isinstance(server_options, supriya.realtime.ServerOptions)
     if kwargs:
         server_options = utils.new(server_options, **kwargs)
     options_string = server_options.as_options_string(self.port)
     command = '{} {}'.format(scsynth_path, options_string)
     if self.debug_subprocess:
         print(command)
     self._server_process = subprocess.Popen(
         command,
         shell=True,
         stdout=subprocess.PIPE,
         stderr=subprocess.STDOUT,
         )
     start_time = time.time()
     while True:
         line = self._server_process.stdout.readline().decode()
         if line.startswith('SuperCollider 3 server ready'):
             break
         elif line.startswith('Exception in World_OpenUDP: bind: Address already in use'):
             raise Exception
         elif (time.time() - start_time) > 1:
             raise Exception
     self._is_running = True
     self._server_options = server_options
     self._setup()
     PubSub.notify('server-booted')
     return self
示例#21
0
    def _coerce_iterator_output(self, expr, state):
        import supriya.assets.synthdefs
        import supriya.patterns

        expr = super(Pbus, self)._coerce_iterator_output(expr)
        if isinstance(expr,
                      supriya.patterns.NoteEvent) or not expr.get("is_stop"):
            kwargs = {}
            if expr.get("target_node") is None:
                kwargs["target_node"] = state["group_uuid"]
            prototype = (supriya.patterns.NoteEvent,
                         supriya.patterns.SynthEvent)
            if isinstance(expr, prototype):
                synthdef = expr.get(
                    "synthdef") or supriya.assets.synthdefs.default
                parameter_names = synthdef.parameter_names
                if expr.get("out") is None and "out" in parameter_names:
                    kwargs["out"] = state["bus_uuid"]
                if expr.get("in_") is None and "in_" in parameter_names:
                    kwargs["in_"] = state["bus_uuid"]
            expr = utils.new(expr, **kwargs)
        return expr
示例#22
0
    def _split(
        self,
        split_offset: float,
        new_nodes=None,
        split_occupiers: bool = True,
        split_traversers: bool = True,
    ) -> List["Node"]:
        import supriya.nonrealtime

        new_nodes = new_nodes or []
        state = self.session.states[split_offset]
        entering, exiting, occupying, starting, _ = self.inspect_children()
        children = state.nodes_to_children.get(self) or ()
        start_offset, stop_offset = self.start_offset, self.stop_offset
        if start_offset < split_offset < stop_offset:
            old_actions = state.transitions
            new_duration = stop_offset - split_offset
            with supriya.nonrealtime.DoNotPropagate():
                if isinstance(self, supriya.nonrealtime.Synth):
                    new_node = self.add_synth(
                        add_action="ADD_BEFORE",
                        duration=new_duration,
                        synthdef=self.synthdef,
                        **self._synth_kwargs,
                    )
                else:
                    new_node = self.add_group(add_action="ADD_BEFORE",
                                              duration=new_duration)
            new_nodes.append(new_node)
            new_actions: Dict["Node",
                              NodeTransition] = collections.OrderedDict()
            for node in new_nodes:
                if node is new_node and self in old_actions:
                    old_actions.pop(node)
                    action = old_actions.pop(self)
                    new_actions[node] = utils.new(action, source=new_node)
                else:
                    new_actions[node] = old_actions.pop(node)
            for child in reversed(children):
                if child in old_actions:
                    old_actions.pop(child)
                action = supriya.nonrealtime.NodeTransition(
                    source=child, target=new_node, action="ADD_TO_TAIL")
                new_actions[child] = action
            new_actions.update(old_actions)
            state._transitions = new_actions
            self._fixup_events(new_node, split_offset)
            self._fixup_duration(split_offset - start_offset)
            self._fixup_node_actions(new_node, split_offset, stop_offset)
            self.session._apply_transitions(
                [new_node.start_offset, new_node.stop_offset])
            result = [self, new_node]
        else:
            return [self]
        for child in children + exiting:
            if ((split_occupiers and child in occupying)
                    or (split_traversers and child in entering)
                    or (split_traversers and child in exiting)):
                child._split(
                    split_offset,
                    new_nodes=new_nodes,
                    split_occupiers=split_occupiers,
                    split_traversers=split_traversers,
                )
        return result
示例#23
0
 def _get_format_specification(self):
     super_class = super(SupriyaValueObject, self)
     format_specification = super_class._get_format_specification()
     return utils.new(format_specification, repr_is_indented=False)
示例#24
0
 def _pre_process_event(self, event_tuple_a, event_tuple_b):
     delta = float(event_tuple_b.offset - event_tuple_a.offset)
     return utils.new(event_tuple_a.event, delta=delta)
示例#25
0
 def _coerce_iterator_output(self, expr, state):
     expr = super(Ppar, self)._coerce_iterator_output(expr, state)
     return utils.new(expr, _iterator=None)
示例#26
0
 def __copy__(self, *args):
     return utils.new(self)