예제 #1
0
파일: distance.py 프로젝트: moumar/bliss
def distance(song1, song2):
    """
    Wrapper around `bl_distance_file` function.

    Params:
        - filename1 is the first file to use.
        - filename2 is the second file to use.

    Returns a dict {distance, song1, song2} containing the computed distance
    and the created `bl_song` objects.
    """
    if isinstance(song1, str) and isinstance(song2, str):
        filename1 = ffi.new("char[]", song1.encode("utf-8"))
        filename2 = ffi.new("char[]", song2.encode("utf-8"))
        song1 = ffi.new("struct bl_song *")
        song2 = ffi.new("struct bl_song *")
        return {
            "distance": lib.bl_distance_file(filename1, filename2, song1,
                                             song2),
            "song1": bl_song(c_struct=song1),
            "song2": bl_song(c_struct=song2)
        }
    elif isinstance(song1, bl_song) and isinstance(song2, bl_song):
        return {
            "distance":
            lib.bl_distance(song1["force_vector"], song2["force_vector"]),
            "song1":
            song1,
            "song2":
            song2
        }
    else:
        return {"distance": None, "song1": None, "song2": None}
예제 #2
0
def cosine_similarity(song1, song2):
    """
    Wrapper around `bl_cosine_similarity` function.

    Params:
        - filename1 is the first file to use.
        - filename2 is the second file to use.

    Returns a dict {similarity, song1, song2} containing the computed cosine
    similarity and the created `bl_song` objects.
    """
    if isinstance(song1, str) and isinstance(song2, str):
        filename1 = ffi.new("char[]", song1.encode("utf-8"))
        filename2 = ffi.new("char[]", song2.encode("utf-8"))
        song1 = ffi.new("struct bl_song *")
        song2 = ffi.new("struct bl_song *")
        return {
            "similarity": lib.bl_cosine_similarity_file(filename1, filename2,
                                                        song1, song2),
            "song1": bl_song(c_struct=song1),
            "song2": bl_song(c_struct=song2)
        }
    elif isinstance(song1, bl_song) and isinstance(song2, bl_song):
        return {
            "similarity": lib.bl_cosine_similarity(song1["force_vector"],
                                                   song2["force_vector"]),
            "song1": song1,
            "song2": song2
        }
    else:
        return {
            "similarity": None,
            "song1": None,
            "song2": None
        }
예제 #3
0
    def set(self, key, value):
        """
        Set a data member with a conversion from Python type as much as
        possible.

        Params:
            - key is the id of the data member to set.
            - value is the value to set.
        """
        # Ease manipulation of char* data members, convert python str()
        if self._types[key] == ffi.typeof("char *") and value != ffi.NULL:
            if value != ffi.NULL:
                value = ffi.new("char[]", value.encode("utf-8"))
            # Keep the value in a dict in this object to keep it alive and safe
            # from the garbage collector.
            self._keepalive[key] = value
        # Same for force_vector_s fields
        elif self._types[key] == ffi.typeof("struct force_vector_s"):
            if value == ffi.NULL:
                return
            # Initialization from a valid initializer (tuple, list or dict)
            value = ffi.new("struct force_vector_s[]", [value])
            self._keepalive[key] = value
            value = value[0]
        # Same for array of int fields
        elif self._types[key] == ffi.typeof("int8_t *"):
            if value != ffi.NULL:
                value = ffi.new("int8_t[]", value)
            # Keep the value in a dict in this object to keep it alive and safe
            # from the garbage collector.
            self._keepalive[key] = value
        else:
            # Nothing to do
            pass
        return setattr(self._c_struct, key, value)
예제 #4
0
    def set(self, key, value):
        """
        Set a data member with a conversion from Python type as much as
        possible.

        Params:
            - key is the id of the data member to set.
            - value is the value to set.
        """
        # Ease manipulation of char* data members, convert python str()
        if self._types[key] == ffi.typeof("char *") and value != ffi.NULL:
            if value != ffi.NULL:
                value = ffi.new("char[]", value.encode("utf-8"))
            # Keep the value in a dict in this object to keep it alive and safe
            # from the garbage collector.
            self._keepalive[key] = value
        # Same for force_vector_s fields
        elif self._types[key] == ffi.typeof("struct force_vector_s"):
            if value == ffi.NULL:
                return
            # Initialization from a valid initializer (tuple, list or dict)
            value = ffi.new("struct force_vector_s[]", [value])
            self._keepalive[key] = value
            value = value[0]
        # Same for array of int fields
        elif self._types[key] == ffi.typeof("int8_t *"):
            if value != ffi.NULL:
                value = ffi.new("int8_t[]", value)
            # Keep the value in a dict in this object to keep it alive and safe
            # from the garbage collector.
            self._keepalive[key] = value
        else:
            # Nothing to do
            pass
        return setattr(self._c_struct, key, value)
예제 #5
0
    def __init__(self, filename=None, initializer=None, c_struct=None):
        """
        Initialize a new `bl_song` object.

        Params:
            - filename is a path to a file to load and analyze (optional).
            - initializer is an initializer to feed to `ffi.new` allocation
            call. Valid initializers are a list or tuple or dict of the field
            values.
            - c_struct is a preexisting `struct bl_song *` to use for
            initialization.
        """
        # Initializing private data members
        if c_struct is not None:
            self._c_struct = c_struct
        else:
            self._c_struct = ffi.new("struct bl_song *", initializer)
        self._types = {i[0]: i[1].type
                       for i in ffi.typeof("struct bl_song").fields}
        # _keepalive is useful to prevent garbage
        # collector from collecting dynamically allocated
        # data members
        self._keepalive = {}

        if filename is not None:
            self.analyze(filename)
예제 #6
0
    def __init__(self, filename=None, initializer=None, c_struct=None):
        """
        Initialize a new `bl_song` object.

        Params:
            - filename is a path to a file to load and analyze (optional).
            - initializer is an initializer to feed to `ffi.new` allocation
            call. Valid initializers are a list or tuple or dict of the field
            values.
            - c_struct is a preexisting `struct bl_song *` to use for
            initialization.
        """
        # Initializing private data members
        if c_struct is not None:
            self._c_struct = c_struct
        else:
            self._c_struct = ffi.new("struct bl_song *", initializer)
        self._types = {
            i[0]: i[1].type
            for i in ffi.typeof("struct bl_song").fields
        }
        # _keepalive is useful to prevent garbage
        # collector from collecting dynamically allocated
        # data members
        self._keepalive = {}

        if filename is not None:
            self.analyze(filename)
예제 #7
0
    def analyze(self, filename):
        """
        Load and analyze an audio file, putting it in a `bl_song` object.

        Params:
            - filename is the path to the file to load and analyze.
        """
        filename_char = ffi.new("char[]", filename.encode("utf-8"))
        lib.bl_analyze(filename_char, self._c_struct)
예제 #8
0
    def analyze(self, filename):
        """
        Load and analyze an audio file, putting it in a `bl_song` object.

        Params:
            - filename is the path to the file to load and analyze.
        """
        filename_char = ffi.new("char[]", filename.encode("utf-8"))
        lib.bl_analyze(filename_char, self._c_struct)
예제 #9
0
    def decode(self, filename):
        """
        Decode an audio file and load it into this `bl_song` object. Do not run
        any analysis on it.

        Params:
            - filename is the path to the file to load.
        """
        filename_char = ffi.new("char[]", filename.encode("utf-8"))
        lib.bl_audio_decode(filename_char, self._c_struct)
예제 #10
0
파일: bl_song.py 프로젝트: Phyks/bliss
    def envelope_analysis(self):
        """
        Run an envelope analysis on a previously loaded file.

        Returns a {tempo, attack} dict, which is a direct mapping of
        `struct envelope_result_s`. Also updates the object data members.
        """
        result = ffi.new("struct envelope_result_s *")
        lib.bl_envelope_sort(self._c_struct, result)
        return {"tempo": (result.tempo1, result.tempo2, result.tempo3), "attack": result.attack}
예제 #11
0
    def envelope_analysis(self):
        """
        Run an envelope analysis on a previously loaded file.

        Returns a {tempo, attack} dict, which is a direct mapping of
        `struct envelope_result_s`. Also updates the object data members.
        """
        result = ffi.new("struct envelope_result_s *")
        lib.bl_envelope_sort(self._c_struct, result)
        return {"tempo": (result.tempo), "attack": result.attack}
예제 #12
0
    def decode(self, filename):
        """
        Decode an audio file and load it into this `bl_song` object. Do not run
        any analysis on it.

        Params:
            - filename is the path to the file to load.
        """
        filename_char = ffi.new("char[]", filename.encode("utf-8"))
        lib.bl_audio_decode(filename_char, self._c_struct)
예제 #13
0
def distance(filename1, filename2):
    """
    Wrapper around `bl_distance` function.

    Params:
        - filename1 is the first file to use.
        - filename2 is the second file to use.

    Returns a dict {distance, song1, song2} containing the computed distance
    and the created `bl_song` objects.
    """
    song1 = ffi.new("struct bl_song *")
    song2 = ffi.new("struct bl_song *")
    filename1 = ffi.new("char[]", filename1.encode("utf-8"))
    filename2 = ffi.new("char[]", filename2.encode("utf-8"))
    return {
        "distance": lib.bl_distance_file(filename1, filename2, song1, song2),
        "song1": bl_song(c_struct=song1),
        "song2": bl_song(c_struct=song2)
    }
예제 #14
0
파일: bl_song.py 프로젝트: Phyks/bliss
def cosine_similarity(filename1, filename2):
    """
    Wrapper around `bl_cosine_similarity` function.

    Params:
        - filename1 is the first file to use.
        - filename2 is the second file to use.

    Returns a dict {similarity, song1, song2} containing the computed cosine
    similarity and the created `bl_song` objects.
    """
    song1 = ffi.new("struct bl_song *")
    song2 = ffi.new("struct bl_song *")
    filename1 = ffi.new("char[]", filename1.encode("utf-8"))
    filename2 = ffi.new("char[]", filename2.encode("utf-8"))
    return {
        "similarity": lib.bl_cosine_similarity(filename1, filename2, song1, song2),
        "song1": bl_song(c_struct=song1),
        "song2": bl_song(c_struct=song2),
    }
예제 #15
0
def distance(filename1, filename2):
    """
    Wrapper around `bl_distance` function.

    Params:
        - filename1 is the first file to use.
        - filename2 is the second file to use.

    Returns a dict {distance, song1, song2} containing the computed distance
    and the created `bl_song` objects.
    """
    song1 = ffi.new("struct bl_song *")
    song2 = ffi.new("struct bl_song *")
    filename1 = ffi.new("char[]", filename1.encode("utf-8"))
    filename2 = ffi.new("char[]", filename2.encode("utf-8"))
    return {
        "distance": lib.bl_distance_file(filename1, filename2, song1, song2),
        "song1": bl_song(c_struct=song1),
        "song2": bl_song(c_struct=song2)
    }
예제 #16
0
def cosine_similarity(filename1, filename2):
    """
    Wrapper around `bl_cosine_similarity` function.

    Params:
        - filename1 is the first file to use.
        - filename2 is the second file to use.

    Returns a dict {similarity, song1, song2} containing the computed cosine
    similarity and the created `bl_song` objects.
    """
    song1 = ffi.new("struct bl_song *")
    song2 = ffi.new("struct bl_song *")
    filename1 = ffi.new("char[]", filename1.encode("utf-8"))
    filename2 = ffi.new("char[]", filename2.encode("utf-8"))
    return {
        "similarity": lib.bl_cosine_similarity(filename1, filename2, song1,
                                               song2),
        "song1": bl_song(c_struct=song1),
        "song2": bl_song(c_struct=song2)
    }