Ejemplo n.º 1
0
 def get_C_process(clazz, obj_type, process_dict, objects):
     if obj_type == "__tabread~if":
         return [
             "__hv_tabread_if(&sTabread_{0}, {1}, {2});".format(
                 process_dict["id"], ", ".join([
                     "VIi({0})".format(HeavyObject._c_buffer(b))
                     for b in process_dict["inputBuffers"]
                 ]), ", ".join([
                     "VOf({0})".format(HeavyObject._c_buffer(b))
                     for b in process_dict["outputBuffers"]
                 ]))
         ]
     elif obj_type == "__tabread~f":
         return [
             "__hv_tabread_f(&sTabread_{0}, {1});".format(
                 process_dict["id"], ", ".join([
                     "VOf({0})".format(HeavyObject._c_buffer(b))
                     for b in process_dict["outputBuffers"]
                 ]))
         ]
     elif obj_type == "__tabreadu~f":
         return [
             "__hv_tabreadu_f(&sTabread_{0}, {1});".format(
                 process_dict["id"], ", ".join([
                     "VOf({0})".format(HeavyObject._c_buffer(b))
                     for b in process_dict["outputBuffers"]
                 ]))
         ]
     else:
         raise Exception()
Ejemplo n.º 2
0
 def get_C_process(clazz, obj_type, process_dict, objects):
     return [
         "__hv_del1_f(&sDel1_{0}, VIf({1}), VOf({2}));".format(
             process_dict["id"],
             HeavyObject._c_buffer(process_dict["inputBuffers"][0]),
             HeavyObject._c_buffer(process_dict["outputBuffers"][0]))
     ]
Ejemplo n.º 3
0
    def get_C_impl(clazz, obj_type, obj_id, on_message_list, obj_class_dict,
                   objects):
        # generate the onMessage implementation
        out_list = [
            "cSwitchcase_{0}_onMessage(HeavyContextInterface *_c, void *o, int letIn, const HvMessage *const m, void *sendMessage) {{"
            .format(obj_id)
        ]
        out_list.append("switch (msg_getHash(m, 0)) {")
        cases = objects[obj_id]["args"]["cases"]
        for i, c in enumerate(cases):
            out_list.append("case {0}: {{ // \"{1}\"".format(
                HeavyObject.get_hash_string(c), c))
            out_list.extend(
                HeavyObject._get_on_message_list(on_message_list[i],
                                                 obj_class_dict, objects))
            out_list.append("break;")
            out_list.append("}")
        out_list.append("default: {")
        out_list.extend(
            HeavyObject._get_on_message_list(on_message_list[-1],
                                             obj_class_dict, objects))
        out_list.append("break;")
        out_list.append("}")  # end default
        out_list.append("}")  # end switch
        out_list.append("}")  # end function

        return out_list
Ejemplo n.º 4
0
 def get_C_process(clazz, obj_type, process_dict, args):
     return [
         "__hv_lorenz_f(&sLorenz_{0}, {1}, {2});".format(
             process_dict["id"],
             ", ".join(["VIf({0})".format(HeavyObject._c_buffer(b)) for b in process_dict["inputBuffers"]]),
             ", ".join(["VOf({0})".format(HeavyObject._c_buffer(b)) for b in process_dict["outputBuffers"]])
         )
     ]
Ejemplo n.º 5
0
 def get_C_process(clazz, obj_type, process_dict, args):
     return [
         "__hv_samphold_f(&sSamphold_{0}, VIf({1}), VIf({2}), VOf({3}));".
         format(process_dict["id"],
                HeavyObject._c_buffer(process_dict["inputBuffers"][0]),
                HeavyObject._c_buffer(process_dict["inputBuffers"][1]),
                HeavyObject._c_buffer(process_dict["outputBuffers"][0]))
     ]
Ejemplo n.º 6
0
 def get_C_process(clazz, obj_type, process_dict, objects):
     return [
         "{0}({1}, {2});".format(
             SignalMath.__OPERATION_DICT[obj_type], ", ".join([
                 "VI{0}({1})".format("i" if b["type"] == "~i>" else "f",
                                     HeavyObject._c_buffer(b))
                 for b in process_dict["inputBuffers"]
             ]), ", ".join([
                 "VO{0}({1})".format("i" if b["type"] == "~i>" else "f",
                                     HeavyObject._c_buffer(b))
                 for b in process_dict["outputBuffers"]
             ]))
     ]
Ejemplo n.º 7
0
 def get_C_process(clazz, obj_type, process_dict, args):
     return [
         "__hv_sample_f(this, &sSample_{0}, VIf({1}), &{2}_{0}_sendMessage);".format(
             process_dict["id"],
             HeavyObject._c_buffer(process_dict["inputBuffers"][0]),
             clazz.preamble
         )
     ]
Ejemplo n.º 8
0
 def get_C_process(clazz, obj_type, process_dict, objects):
     return [
         "__hv_tabhead_f(&sTabhead_{0}, {1});".format(
             process_dict["id"], ", ".join([
                 "VOf({0})".format(HeavyObject._c_buffer(b))
                 for b in process_dict["outputBuffers"]
             ]))
     ]
Ejemplo n.º 9
0
 def get_C_process(clazz, obj_type, process_dict, args):
     if obj_type == "__phasor~f":
         return [
             "__hv_phasor_f(&sPhasor_{0}, VIf({1}), VOf({2}));".format(
                 process_dict["id"],
                 HeavyObject._c_buffer(process_dict["inputBuffers"][0]),
                 HeavyObject._c_buffer(process_dict["outputBuffers"][0])
             )
         ]
     elif obj_type == "__phasor_k~f":
         return [
             "__hv_phasor_k_f(&sPhasor_{0}, VOf({1}));".format(
                 process_dict["id"],
                 HeavyObject._c_buffer(process_dict["outputBuffers"][0])
             )
         ]
     else:
         raise Exception("Unknown object type \"{0}\".".format(obj_type))
Ejemplo n.º 10
0
 def get_C_impl(clazz, obj_type, obj_id, on_message_list, get_obj_class, objects):
     send_message_list = ["cDelay_{0}_sendMessage(HeavyContextInterface *_c, int letIn, const HvMessage *const m) {{".format(
             obj_id)]
     send_message_list.append("cDelay_clearExecutingMessage(&Context(_c)->cDelay_{0}, m);".format(
         obj_id
     ))
     send_message_list.extend(
         HeavyObject._get_on_message_list(on_message_list[0], get_obj_class, objects))
     send_message_list.append("}") # end function
     return send_message_list
Ejemplo n.º 11
0
 def get_C_process(clazz, obj_type, process_dict, objects):
     if obj_type == "__tabwrite~f":
         return [
             "__hv_tabwrite_f(&sTabwrite_{0}, {1});".format(
                 process_dict["id"], ", ".join([
                     "VIf({0})".format(HeavyObject._c_buffer(b))
                     for b in process_dict["inputBuffers"]
                 ]))
         ]
     elif obj_type == "__tabwrite_stoppable~f":
         return [
             "__hv_tabwrite_stoppable_f(&sTabwrite_{0}, {1});".format(
                 process_dict["id"], ", ".join([
                     "VIf({0})".format(HeavyObject._c_buffer(b))
                     for b in process_dict["inputBuffers"]
                 ]))
         ]
     else:
         raise Exception()
Ejemplo n.º 12
0
    def convert_ctrl_to_sig_connections_at_inlet(self, connection_list, inlet_index):
        """ Auto insert heavy var object inbetween control connections.
        """
        sig_obj = HeavyObject(
            obj_type="var",
            obj_args=[0],
            pos_x = int(self.pos_x),
            pos_y = int(self.pos_y-5)) # shift upwards a few points

        # add sig~ object to parent graph
        self.parent_graph.add_object(sig_obj)

        # add connection from sig~ to this object
        c = Connection(sig_obj, 0, self, inlet_index, "~f>")
        self.parent_graph._PdGraph__connections.append(c) # update the local connections list
        sig_obj.add_connection(c)
        self.add_connection(c)

        # retrieve all control connections
        control_conns = [c for c in connection_list if c.conn_type == "-->"]

        for old_conn in control_conns:
            # get from obj
            from_obj = old_conn.from_obj

            # add connection from fromobj to new sig
            new_conn = Connection(from_obj, old_conn.outlet_index, sig_obj, 0, "-->")
            self.parent_graph._PdGraph__connections.append(new_conn)
            sig_obj.add_connection(new_conn)
            from_obj.add_connection(new_conn)

            # remove connection from fromobj
            self.parent_graph._PdGraph__connections.remove(old_conn)
            from_obj.remove_connection(old_conn)
            self.remove_connection(old_conn)
Ejemplo n.º 13
0
 def get_C_process(clazz, obj_type, process_dict, args):
     fmt = obj_type[-1]
     if obj_type in ["__var~f", "__var~i"]:
         # NOTE(mhroth): signal rate variables do not process anything
         return []
     elif obj_type in ["__varwrite~f", "__varwrite~i"]:
         return [
             "__hv_varwrite_{1}(&sVar{1}_{0}, VI{1}({2}));".format(
                 args["var_id"], fmt,
                 HeavyObject._c_buffer(process_dict["inputBuffers"][0]))
         ]
     elif obj_type in ["__var_k~f", "__var_k~i"]:
         if args["k"] == 0.0 and args.get("step", 0.0) == 0.0:
             return [
                 "__hv_zero_{0}(VO{0}({1}));".format(
                     fmt,
                     HeavyObject._c_buffer(
                         process_dict["outputBuffers"][0]))
             ]
         else:
             c = [
                 float(args["k"] + i * args.get("step", 0.0))
                 for i in range(8)
             ]
             cx = ", ".join(["{0}f".format(f)
                             for f in c]) if fmt == "f" else ", ".join(
                                 [str(int(i)) for i in c])
             return [
                 "__hv_var_k_{0}{3}(VO{0}({1}), {2});".format(
                     fmt,
                     HeavyObject._c_buffer(
                         process_dict["outputBuffers"][0]), cx,
                     "_r" if args.get("reverse", False) else "")
             ]
     elif obj_type in ["__varread~f", "__varread~i"]:
         return [
             "__hv_varread_{1}(&sVar{1}_{0}, VO{1}({2}));".format(
                 args["var_id"], fmt,
                 HeavyObject._c_buffer(process_dict["outputBuffers"][0]))
         ]
Ejemplo n.º 14
0
    def get_C_impl(clazz, obj_type, obj_id, on_message_list, get_obj_class,
                   objects):
        # Note(joe): if no corresponding receivers exist and there's no extern indicator
        # then there is not much need to generate code stub
        send_message_list = [
            "{0}_{1}_sendMessage(HeavyContextInterface *_c, int letIn, const HvMessage *m) {{"
            .format(clazz.get_preamble(obj_type), obj_id)
        ]

        if objects[obj_id]["args"].get("extern", False):
            # call the send hook
            send_name = objects[obj_id]["args"]["name"]
            send_message_list.append(
                "if (_c->getSendHook() != nullptr) _c->getSendHook()(_c, \"{0}\", {1}, m);"
                .format(send_name, HeavyObject.get_hash_string(send_name)))

        # a send has only one (implicit!) outlet
        send_message_list.extend(
            HeavyObject._get_on_message_list(on_message_list[0], get_obj_class,
                                             objects))

        send_message_list.append("}")  # end function

        return send_message_list
Ejemplo n.º 15
0
    def __init__(self, hv_path, obj_args=None, pos_x=0, pos_y=0):
        PdObject.__init__(
            self,
            os.path.basename(hv_path).split(".")[0],
            obj_args,
            pos_x, pos_y)

        # read the heavy graph
        with open(hv_path, "r") as f:
            self.hv_json = json.load(f)

        # parse the heavy data structure to determine the outlet connection type
        outlets = [o for o in self.hv_json["objects"].values() if o["type"] == "outlet"]
        sorted(outlets, key=lambda o:o["args"]["index"])
        self.__outlet_connection_types = [o["args"]["type"] for o in outlets]

        # resolve the arguments
        for i,a in enumerate(self.hv_json["args"]):
            if i < len(self.obj_args):
                arg_value = self.obj_args[i]
            elif a["required"]:
                self.add_error("Required argument \"{0}\" not found.".format(a["name"]))
                continue
            else:
                arg_value = a["default"]

            try:
                arg_value = HeavyObject.force_arg_type(arg_value, a["value_type"])
            except Exception as e:
                self.add_error("Heavy {0} cannot convert argument \"{1}\" with value \"{2}\" to type {3}: {4}".format(
                        self.obj_type,
                        a["name"],
                        arg_value,
                        a["value_type"],
                        str(e)))

            # resolve all arguments for each object in the graph
            for o in self.hv_json["objects"].values():
                for k,v in o["args"].items():
                    # TODO(mhroth): make resolution more robust
                    if v == "$"+a["name"]:
                        o["args"][k] = arg_value

        # reset all arguments, as they have all been resolved
        # any required arguments would break hv2ir as they will no longer
        # be supplied (because they are resolved)
        self.hv_json["args"] = []
Ejemplo n.º 16
0
 def get_C_process(clazz, obj_type, process_dict, objects):
     return [
         "__hv_cpole_f(&sCPole_{0}, VIf({1}), VIf({2}), VIf({3}), VIf({4}), VOf({5}), VOf({6}));"
         .format(process_dict["id"],
                 HeavyObject._c_buffer(process_dict["inputBuffers"][0]),
                 HeavyObject._c_buffer(process_dict["inputBuffers"][1]),
                 HeavyObject._c_buffer(process_dict["inputBuffers"][2]),
                 HeavyObject._c_buffer(process_dict["inputBuffers"][3]),
                 HeavyObject._c_buffer(process_dict["outputBuffers"][0]),
                 HeavyObject._c_buffer(process_dict["outputBuffers"][1]))
     ]
Ejemplo n.º 17
0
    def validate_configuration(self):
        """ Auto-detect control only connections to expected signal inlets and
            insert a sig~ (var) object inbetween to ensure it doesn't break.
        """
        # Note(joe): only checking first inlet, should we check all inlets by
        # default? i.e. samphold~ has a 2nd inlet that requires checking
        conns = self._inlet_connections.get("0", [])

        # only do this if no signal connections are present
        if (len([c for c in conns if c.conn_type == "~f>"])
                == 0) and len(conns) > 0:

            # add sig~ object to parent graph
            sig_obj = HeavyObject(obj_type="var",
                                  obj_args=[0],
                                  pos_x=int(self.pos_x),
                                  pos_y=int(self.pos_y -
                                            5))  # shift upwards a few points
            self.parent_graph.add_object(sig_obj)

            # add connection from sig~ to this abstraction
            c = Connection(sig_obj, 0, self, 0, "~f>")
            self.parent_graph._PdGraph__connections.append(
                c)  # update the local connections list
            sig_obj.add_connection(c)
            self.add_connection(c)

            # retrieve all control connections
            control_conns = [c for c in conns if c.conn_type == "-->"]

            for old_conn in control_conns:
                # get from obj
                from_obj = old_conn.from_obj

                # add connection from fromobj to new sig
                new_conn = Connection(from_obj, old_conn.outlet_index, sig_obj,
                                      0, "-->")
                self.parent_graph._PdGraph__connections.append(new_conn)
                sig_obj.add_connection(new_conn)
                from_obj.add_connection(new_conn)

                # remove connection from fromobj
                self.parent_graph._PdGraph__connections.remove(old_conn)
                from_obj.remove_connection(old_conn)
                self.remove_connection(old_conn)

        # make sure to call parent validate_configuration()
        PdGraph.validate_configuration(self)
Ejemplo n.º 18
0
Archivo: ir2c.py Proyecto: ykmm/hvcc
 def filter_hvhash(clazz, x):
     """ Return the hash string of an object.
     """
     return HeavyObject.get_hash_string(x)
Ejemplo n.º 19
0
    def graph_from_object(clazz,
                          obj,
                          obj_id=None,
                          obj_args=None,
                          max_path=None):
        g = MaxGraph(obj_args=obj_args, obj_id=obj_id, max_path=max_path)

        # parse objects
        for o in obj["patcher"]["boxes"]:
            o = o["box"]  # the max object dictionary
            x = None  # a MaxObject

            # read common parameters
            obj_id = o["id"]
            patching_rect = o["patching_rect"]

            if o["maxclass"] == "newobj":
                obj_text = o["text"].split()
                obj_type = obj_text[0]
                obj_args = obj_text[1:] if len(obj_text) > 1 else []

                # resolve object arguments against graph arguments
                for i, a in enumerate(obj_args):
                    if a.startswith("$"):
                        x = int(a[1:]) - 1
                        if len(g.obj_args) > x:
                            obj_args[i] = g.obj_args[x]
                        else:
                            print "WARNING: Can't resolve object argument {0} against graph arguments: {1}".format(
                                a, g.obj_args)

                # are we dealing with a declared Heavy object?
                if obj_type == "patcher":
                    if len(obj_args) > 0 and obj_args[0] == "@hv_obj":
                        if len(obj_args) > 1 and HeavyObject.is_heavy(
                                obj_args[1]):
                            # initialise heavy object
                            x = HeavyObject(obj_args[1],
                                            obj_args[2:],
                                            obj_id,
                                            pos_x=patching_rect[0],
                                            pos_y=patching_rect[1])
                        else:
                            raise Exception(
                                "Max subpatch has @hv_obj annotation but declares no Heavy object."
                            )
                    else:
                        # TODO(mhroth): assume that this is a normal max subpatch
                        raise Exception("Cannot parse Max subpatches yet.")

                # do we have an abstraction for this max object? Is it in the maxlib?
                # TODO(mhroth): are there any other search paths to look through?
                elif os.path.isfile(
                        os.path.join(os.path.dirname(__file__), "maxlib",
                                     obj_type + ".maxpat")):
                    max_path = os.path.join(os.path.dirname(__file__),
                                            "maxlib", obj_type + ".maxpat")
                    x = MaxParser.graph_from_file(max_path, obj_id, obj_args)

                # is this an object that must be programmatically parsed?
                elif obj_type in MaxParser.__MAX_CLASSES:
                    clazz = MaxParser.__MAX_CLASSES[obj_type]
                    x = clazz(obj_type,
                              obj_args,
                              obj_id,
                              pos_x=patching_rect[0],
                              pos_y=patching_rect[1])

                else:
                    raise Exception(
                        "Don't know how to parse object \"{0}\".".format(
                            obj_type))

            elif o["maxclass"] == "inlet":
                outlet_type = o["outlettype"][0]
                x = MaxInletObject(outlet_type,
                                   obj_id,
                                   pos_x=patching_rect[0],
                                   pos_y=patching_rect[1])

            elif o["maxclass"] == "outlet":
                # TODO(mhroth): correctly determine connection type of outlet
                x = MaxOutletObject("signal",
                                    obj_id,
                                    pos_x=patching_rect[0],
                                    pos_y=patching_rect[1])

            else:
                print "WARNING: Ignoring maxclass \"{0}\".".format(
                    o["maxclass"])
                continue  # ignore comments, etc.

            g.add_object(x)

        # parse connections
        for l in obj["patcher"]["lines"]:
            l = l["patchline"]
            if not (bool(l["disabled"]) or bool(l["hidden"])):
                g.add_connection(from_id=l["source"][0],
                                 from_outlet=l["source"][1],
                                 to_id=l["destination"][0],
                                 to_inlet=l["destination"][1])

        return g
Ejemplo n.º 20
0
 def get_C_process(clazz, obj_type, process_dict, args):
     return [
         "sEnv_process(this, &sEnv_{0}, VIf({1}), &sEnv_{0}_sendMessage);".
         format(process_dict["id"],
                HeavyObject._c_buffer(process_dict["inputBuffers"][0]))
     ]
Ejemplo n.º 21
0
    def graph_from_canvas(self,
                          file_iterator,
                          file_hv_arg_dict,
                          canvas_line,
                          graph_args,
                          pd_path,
                          pos_x=0,
                          pos_y=0,
                          is_root=False,
                          pd_graph_class=PdGraph):
        """ Instantiate a PdGraph from an existing canvas.
            Note that graph_args includes $0.
            @param file_hv_arg_dict  A dictionary containing all Heavy argument lines
            for each "#N canvas" in this file.
            @param canvas_line  The "#N canvas" which initiates this canvas.
            @param pd_graph_class  The python class to handle specific graph types
        """
        obj_array = None  # an #A (table) object which is currently being parsed

        g = pd_graph_class(graph_args, pd_path, pos_x, pos_y)

        # parse and add all Heavy arguments to the graph
        for l in file_hv_arg_dict[canvas_line]:
            line = l.split()
            assert line[4] == "@hv_arg"
            is_required = (line[9] == "true")
            default_value = HeavyObject.force_arg_type(line[8], line[7]) \
                if not is_required else None
            g.add_hv_arg(
                arg_index=int(line[5][2:]) -
                1,  # strip off the leading "\$" and make index zero-based
                name=line[6],
                value_type=line[7],
                default_value=default_value,
                required=is_required)

        try:  # this try will capture any critical errors
            for l in file_iterator:
                # remove width parameter
                line = PdParser.__RE_WIDTH.sub("", l).split()

                if line[0] == "#N":
                    if line[1] == "canvas":
                        x = self.graph_from_canvas(
                            file_iterator,
                            file_hv_arg_dict,
                            canvas_line=l,
                            graph_args=
                            graph_args,  # subpatch inherits parent graph arguments, including $0
                            pd_path=pd_path,
                            pos_x=int(line[2]),
                            pos_y=int(line[3]))
                        g.add_object(x)

                elif line[0] == "#X":
                    if line[1] == "restore":
                        if len(line) > 5 and line[5] == "@hv_obj":
                            obj_args = PdParser.__resolve_object_args(
                                obj_type=line[6],
                                obj_args=line[7:],
                                graph=g,
                                raise_on_failure=False,
                                is_root=is_root)
                            if line[6] == "__switchcase":
                                x = HvSwitchcase(obj_type=line[6],
                                                 obj_args=obj_args,
                                                 pos_x=int(line[2]),
                                                 pos_y=int(line[3]))
                            else:
                                x = HeavyObject(obj_type=line[6],
                                                obj_args=obj_args,
                                                pos_x=int(line[2]),
                                                pos_y=int(line[3]))
                            return x  # return a Heavy object instead of a graph
                        else:
                            # are we restoring an array object?
                            # do some final sanity checks
                            if obj_array is not None:
                                declared_size = obj_array.obj_args["size"]
                                values_size = len(obj_array.obj_args["values"])
                                if declared_size != values_size:
                                    new_size = max(declared_size, values_size)
                                    obj_array.add_warning(
                                        "Table \"{0}\" was declared as having {1} values, "
                                        "but {2} were supplied. It will be resized to {3} "
                                        "values (any unsupplied values will be zeroed)."
                                        .format(obj_array.obj_args["name"],
                                                declared_size, values_size,
                                                new_size))
                                    obj_array.obj_args["size"] = new_size
                                    if new_size < declared_size:
                                        obj_array.obj_args[
                                            "values"] = obj_args[
                                                "values"][:new_size]
                                    else:
                                        obj_array.obj_args["values"].extend([
                                            0.0 for _ in range(new_size -
                                                               declared_size)
                                        ])
                                obj_array = None  # done parsing the array

                            # set the subpatch name
                            g.subpatch_name = " ".join(
                                line[5:]) if len(line) > 5 else "subpatch"
                            return g  # pop the graph

                    elif line[1] == "text":
                        # @hv_arg arguments are pre-parsed
                        # TODO(mhroth): is it necessary to split the entire line at once?
                        # always add the comment to the graph, regardless
                        self.obj_counter["text"] += 1
                        g.add_object(
                            HeavyObject(obj_type="comment",
                                        obj_args=[" ".join(line[4:])],
                                        pos_x=int(line[2]),
                                        pos_y=int(line[3])))

                    elif line[1] == "obj":
                        x = None  # a PdObject
                        if len(line) > 4:
                            obj_type = line[4]
                            # sometimes objects have $ arguments in them as well
                            obj_type = PdParser.__resolve_object_args(
                                obj_type=obj_type,
                                obj_args=[obj_type],
                                graph=g,
                                is_root=is_root)[0]
                            obj_args = PdParser.__resolve_object_args(
                                obj_type=obj_type,
                                obj_args=line[5:],
                                graph=g,
                                is_root=is_root)
                        else:
                            g.add_warning(
                                "This graph contains an empty object. "
                                "It should be removed or defined.",
                                NotificationEnum.WARNING_EMPTY_OBJECT)
                            g.add_object(
                                HeavyObject(
                                    obj_type="comment",
                                    obj_args=["null object placeholder"],
                                    pos_x=int(line[2]),
                                    pos_y=int(line[3])))
                            continue

                        # do we have an abstraction for this object?
                        abs_path = self.find_abstraction_path(
                            os.path.dirname(pd_path), obj_type)
                        if abs_path is not None and not g.is_abstraction_on_call_stack(
                                abs_path):
                            # ensure that infinite recursion into abstractions is not possible
                            x = self.graph_from_file(file_path=abs_path,
                                                     obj_args=obj_args,
                                                     pos_x=int(line[2]),
                                                     pos_y=int(line[3]),
                                                     is_root=False)

                        # is this object in lib/pd_converted?
                        elif os.path.isfile(
                                os.path.join(PdParser.__PDLIB_CONVERTED_DIR,
                                             obj_type + ".hv.json")):
                            self.obj_counter[obj_type] += 1
                            hv_path = os.path.join(
                                PdParser.__PDLIB_CONVERTED_DIR,
                                obj_type + ".hv.json")
                            x = HeavyGraph(hv_path=hv_path,
                                           obj_args=obj_args,
                                           pos_x=int(line[2]),
                                           pos_y=int(line[3]))

                        # is this object in lib/heavy_converted?
                        elif os.path.isfile(
                                os.path.join(PdParser.__HVLIB_CONVERTED_DIR,
                                             obj_type + ".hv.json")):
                            self.obj_counter[obj_type] += 1
                            hv_path = os.path.join(
                                PdParser.__HVLIB_CONVERTED_DIR,
                                obj_type + ".hv.json")
                            x = HeavyGraph(hv_path=hv_path,
                                           obj_args=obj_args,
                                           pos_x=int(line[2]),
                                           pos_y=int(line[3]))

                        # is this object in lib/pd?
                        elif os.path.isfile(
                                os.path.join(PdParser.__PDLIB_DIR,
                                             obj_type + ".pd")):
                            self.obj_counter[obj_type] += 1
                            pdlib_path = os.path.join(PdParser.__PDLIB_DIR,
                                                      obj_type + ".pd")

                            # mapping of pd/lib abstraction objects to classes
                            # for checking connection validity
                            clazz = {
                                "abs~": PdLibSignalGraph,
                                "clip~": PdLibSignalGraph,
                                "cos~": PdLibSignalGraph,
                                "dbtopow~": PdLibSignalGraph,
                                "dbtorms~": PdLibSignalGraph,
                                "exp~": PdLibSignalGraph,
                                "ftom~": PdLibSignalGraph,
                                "hip~": PdLibSignalGraph,
                                "lop~": PdLibSignalGraph,
                                "mtof~": PdLibSignalGraph,
                                "powtodb~": PdLibSignalGraph,
                                "q8_rsqrt~": PdLibSignalGraph,
                                "q8_sqrt~": PdLibSignalGraph,
                                "rmstodb~": PdLibSignalGraph,
                                "rsqrt~": PdLibSignalGraph,
                                "sqrt~": PdLibSignalGraph,
                                "wrap~": PdLibSignalGraph
                            }.get(obj_type, PdGraph)

                            x = self.graph_from_file(file_path=pdlib_path,
                                                     obj_args=obj_args,
                                                     pos_x=int(line[2]),
                                                     pos_y=int(line[3]),
                                                     is_root=False,
                                                     pd_graph_class=clazz)

                            # register any object-specific warnings or errors
                            if obj_type in [
                                    "rzero~", "rzero_rev~", "czero~",
                                    "czero_rev~"
                            ]:
                                g.add_warning(
                                    "[{0}] accepts only signal input. "
                                    "Arguments and control connections are ignored."
                                    .format(obj_type))

                        # is this object in lib/heavy?
                        elif os.path.isfile(
                                os.path.join(PdParser.__HVLIB_DIR,
                                             obj_type + ".pd")):
                            self.obj_counter[obj_type] += 1
                            hvlib_path = os.path.join(PdParser.__HVLIB_DIR,
                                                      obj_type + ".pd")
                            x = self.graph_from_file(file_path=hvlib_path,
                                                     obj_args=obj_args,
                                                     pos_x=int(line[2]),
                                                     pos_y=int(line[3]),
                                                     is_root=False)

                        # is this an object that must be programatically parsed?
                        elif obj_type in PdParser.__PD_CLASSES:
                            self.obj_counter[obj_type] += 1
                            obj_class = PdParser.__PD_CLASSES[obj_type]
                            x = obj_class(obj_type,
                                          obj_args,
                                          pos_x=int(line[2]),
                                          pos_y=int(line[3]))

                        elif PdParser.__is_float(obj_type):
                            # parse float literals
                            self.obj_counter["float"] += 1
                            x = HeavyObject(obj_type="__var",
                                            obj_args=[float(obj_type)],
                                            pos_x=int(line[2]),
                                            pos_y=int(line[3]))

                        else:
                            g.add_error(
                                "Don't know how to parse object \"{0}\". Is it an "
                                "object supported by Heavy? Is it an abstraction? "
                                "Have the search paths been correctly configured?"
                                .format(obj_type),
                                NotificationEnum.ERROR_UNKNOWN_OBJECT)
                            x = HeavyObject(
                                obj_type="comment",
                                obj_args=[
                                    "null object placeholder ({0})".format(
                                        obj_type)
                                ])

                        g.add_object(x)

                    elif line[1] in ["floatatom", "symbolatom"]:
                        self.obj_counter[line[1]] += 1
                        x = self.graph_from_file(file_path=os.path.join(
                            PdParser.__PDLIB_DIR, line[1] + ".pd"),
                                                 obj_args=[],
                                                 pos_x=int(line[2]),
                                                 pos_y=int(line[3]),
                                                 is_root=False)
                        g.add_object(x)

                    elif line[1] == "array":
                        assert obj_array is None, "#X array object is already being parsed."
                        # array names can have dollar arguments in them.
                        # ensure that they are resolved
                        table_name = PdParser.__resolve_object_args(
                            obj_type="array", obj_args=[line[2]], graph=g)[0]
                        # Pd encodes arrays with length greater than 999,999 with
                        # scientific notatation (e.g. 1e6) which Python's int() can't parse
                        table_size = int(decimal.Decimal(line[3]))
                        obj_array = HeavyObject(
                            obj_type="table",
                            # ensure that obj_array has its own values instance
                            obj_args=[table_name, table_size, []])
                        # TODO(mhroth): position information
                        g.add_object(obj_array)

                    elif line[1] == "msg":
                        self.obj_counter["msg"] += 1
                        g.add_object(
                            PdMessageObject(obj_type="msg",
                                            obj_args=[" ".join(line[4:])],
                                            pos_x=int(line[2]),
                                            pos_y=int(line[3])))

                    elif line[1] == "connect":
                        g.add_parsed_connection(from_index=int(line[2]),
                                                from_outlet=int(line[3]),
                                                to_index=int(line[4]),
                                                to_inlet=int(line[5]))

                    elif line[1] == "declare":
                        if not is_root:
                            g.add_warning(
                                "[declare] objects are not supported in abstractions. "
                                "They can only be in the root canvas.")
                        elif len(line) >= 4 and line[2] == "-path":
                            did_add = self.add_relative_search_directory(
                                line[3])
                            if not did_add:
                                g.add_warning(
                                    "\"{0}\" is not a valid relative abstraction "
                                    "search path. It will be ignored.".format(
                                        line[3]))

                        else:
                            g.add_warning(
                                "Heavy only supports the -path flag for the "
                                "declare object.",
                                NotificationEnum.WARNING_DECLARE_PATH)

                    elif line[1] == "coords":
                        pass  # don't do anything with this command

                    else:
                        g.add_error("Don't know how to parse line: {0}".format(
                            " ".join(line)))

                elif line[0] == "#A":
                    obj_array.obj_args["values"].extend(
                        [float(f) for f in line[2:]])

                else:
                    g.add_error("Don't know how to parse line: {0}".format(
                        " ".join(line)))

        except Exception as e:
            # bubble the Exception back to the root graph where the graph
            # will be returned
            if not g.is_root:
                raise e
            else:
                # NOTE(mhroth): should the exception be added as an error?
                # Sometimes it's all that we have, so perhaps it's a good idea.
                g.add_error(str(e), NotificationEnum.ERROR_EXCEPTION)

        return g
Ejemplo n.º 22
0
 def get_C_process(clazz, obj_type, process_dict, args):
     return [
         "__hv_line_f(&sLine_{0}, VOf({1}));".format(
             process_dict["id"],
             HeavyObject._c_buffer(process_dict["outputBuffers"][0]))
     ]