def apply(self, transition_cost, penalty, song, beat_names):
        changepoints = np.array(novelty.novelty(song))
        beats = song.analysis["beats"]
        n_beats = len(beats)
        n_target = penalty.shape[1]
        cp_beats_i = [np.argmin(np.abs(beats - cp)) for cp in changepoints]
        cp_beats = [beats[i] for i in cp_beats_i]

        # find emotional changes at each changepoint, if any
        changes = []
        for i in cp_beats_i:
            # check the previous and next 4 beats
            n_prev = min(4, i)
            n_next = min(4, n_beats - i)
            labs = [self.in_labels[j]
                    for j in range(i - n_prev, i + n_next + 1)]
            # check first and last beat in this range... assuming a sort of
            # coarse-grained emotional labeling
            if labs[0] != labs[-1]:
                # there is an emotional change at this point in the music
                changes.append((i, labs[0], labs[-1]))

        for change in changes:
            print "Found emotional change near changepoint: " +\
                change[1] + " -> " + change[2]

        # find those emotional changes in the target output
        for l in xrange(1, n_target):
            target = self.out_labels[l]
            prev_target = self.out_labels[l - 1]
            if target != prev_target:
                for change in changes:
                    if prev_target == change[1] and target == change[2]:
                        print "setting change:\t" +\
                            change[1] + " -> " + change[2]
                        print "\tat beat " + str(l) + " " +\
                            str(l * song.analysis[BEAT_DUR_KEY])

                        # give huge preference to hitting the changepoint here
                        beat_i = change[0]
                        penalty[:n_beats, l] += 1.0
                        n_prev = min(2, beat_i)
                        n_next = min(2, n_beats - beat_i)
                        penalty[beat_i - n_prev:beat_i + n_next, l] -= 1.0

        return transition_cost, penalty, beat_names
示例#2
0
    def apply(self, transition_cost, penalty, song, beat_names):
        changepoints = np.array(novelty.novelty(song))
        beats = song.analysis["beats"]
        n_beats = len(beats)
        n_target = penalty.shape[1]
        cp_beats_i = [np.argmin(np.abs(beats - cp)) for cp in changepoints]
        cp_beats = [beats[i] for i in cp_beats_i]

        # find emotional changes at each changepoint, if any
        changes = []
        for i in cp_beats_i:
            # check the previous and next 4 beats
            n_prev = min(4, i)
            n_next = min(4, n_beats - i)
            labs = [self.in_labels[j]
                    for j in range(i - n_prev, i + n_next + 1)]
            # check first and last beat in this range... assuming a sort of
            # coarse-grained emotional labeling
            if labs[0] != labs[-1]:
                # there is an emotional change at this point in the music
                changes.append((i, labs[0], labs[-1]))

        for change in changes:
            print "Found emotional change near changepoint: " +\
                change[1] + " -> " + change[2]

        # find those emotional changes in the target output
        for l in xrange(1, n_target):
            target = self.out_labels[l]
            prev_target = self.out_labels[l - 1]
            if target != prev_target:
                for change in changes:
                    if prev_target == change[1] and target == change[2]:
                        print "setting change:\t" +\
                            change[1] + " -> " + change[2]
                        print "\tat beat " + str(l) + " " +\
                            str(l * song.analysis[BEAT_DUR_KEY])

                        # give huge preference to hitting the changepoint here
                        beat_i = change[0]
                        penalty[:n_beats, l] += 1.0
                        n_prev = min(2, beat_i)
                        n_next = min(2, n_beats - beat_i)
                        penalty[beat_i - n_prev:beat_i + n_next, l] -= 1.0

        return transition_cost, penalty, beat_names
示例#3
0
def retarget_with_change_points(song, cp_times, duration):
    """Create a composition of a song of a given duration that reaches
    music change points at specified times. This is still under
    construction. It might not work as well with more than
    2 ``cp_times`` at the moment.

    Here's an example of retargeting music to be 40 seconds long and
    hit a change point at the 10 and 30 second marks::

        song = Song("instrumental_music.wav")
        composition, change_points = retarget.retarget_with_change_points(song, [10, 30], 40)
        composition.export(filename="retargeted_instrumental_music.")

    :param song: Song to retarget
    :type song: :py:class:`radiotool.composer.Song`
    :param cp_times: Times to reach change points (in seconds)
    :type cp_times: list of floats
    :param duration: Target length of retargeted music (in seconds)
    :type duration: float
    :returns: Composition of retargeted song and list of locations of
        change points in the retargeted composition
    :rtype: (:py:class:`radiotool.composer.Composition`, list)
    """
    analysis = song.analysis

    beat_length = analysis["avg_beat_duration"]
    beats = N.array(analysis["beats"])

    # find change points
    cps = N.array(novelty(song, nchangepoints=4))
    cp_times = N.array(cp_times)

    # mark change points in original music
    def music_labels(t):
        # find beat closest to t
        closest_beat_idx = N.argmin(N.abs(beats - t))
        closest_beat = beats[closest_beat_idx]
        closest_cp = cps[N.argmin(N.abs(cps - closest_beat))]
        
        if N.argmin(N.abs(beats - closest_cp)) == closest_beat_idx:
            return "cp"
        else:
            return "noncp"

    # mark where we want change points in the output music
    # (a few beats of slack to improve the quality of the end result)
    def out_labels(t):
        if N.min(N.abs(cp_times - t)) < 1.5 * beat_length:
            return "cp"
        return "noncp"

    # lower penalty around the target locations for change points
    # because we don't actually want each of them to be change points-
    # we just want one of the 4 beats covered to be a change point.
    def out_penalty(t):
        if N.min(N.abs(cp_times - t)) < 1.5 * beat_length:
            return .25
        return 1.0

    comp, info = retarget(song, duration, music_labels, out_labels, out_penalty)

    final_cp_locations = [beat_length * i
                          for i, label in enumerate(info['result_labels'])
                          if label == 'cp']

    return comp, final_cp_locations
示例#4
0
文件: Main.py 项目: dbaylies/MIRFinal
seg_times, files = seg_parser.seg_parse(album_num)

precision = 0
recall = 0
f_measure = 0

for i in np.arange(len(files)):

    filepath = audio_root + albums[album_num] + '/' + songs[i]

    chromagram, fs_chromagram = get_chromagram.get_chromagram(filepath, plot)
    N, recurrence, look_back = recurrence_matrix.recurrence_matrix(chromagram,fs_chromagram, plot)
    L = timelag_matrix.timelag_matrix(N, recurrence, plot)
    P = gaussian_matrix.gaussian_matrix(fs_chromagram, L, plot)
    c = novelty.novelty(P, plot)

    # Get relevant array
    seg_times_i = seg_times[files[i]]

    onset_a, onset_t = peak_pick.peak_pick(c, fs_chromagram, look_back, seg_times_i, plot)
    precision_, recall_, f_measure_ = get_metrics.get_metrics(seg_times_i, files, onset_t)

    precision += precision_
    recall += recall_
    f_measure += f_measure_

num_songs = len(files)

precision_avg = precision/num_songs
recall_avg = recall/num_songs
示例#5
0
def retarget_with_change_points(song, cp_times, duration):
    """Create a composition of a song of a given duration that reaches
    music change points at specified times. This is still under
    construction. It might not work as well with more than
    2 ``cp_times`` at the moment.

    Here's an example of retargeting music to be 40 seconds long and
    hit a change point at the 10 and 30 second marks::

        song = Song("instrumental_music.wav")
        composition, change_points =\
            retarget.retarget_with_change_points(song, [10, 30], 40)
        composition.export(filename="retargeted_instrumental_music.")

    :param song: Song to retarget
    :type song: :py:class:`radiotool.composer.Song`
    :param cp_times: Times to reach change points (in seconds)
    :type cp_times: list of floats
    :param duration: Target length of retargeted music (in seconds)
    :type duration: float
    :returns: Composition of retargeted song and list of locations of
        change points in the retargeted composition
    :rtype: (:py:class:`radiotool.composer.Composition`, list)
    """
    analysis = song.analysis

    beat_length = analysis[BEAT_DUR_KEY]
    beats = np.array(analysis["beats"])

    # find change points
    cps = np.array(novelty(song, nchangepoints=4))
    cp_times = np.array(cp_times)

    # mark change points in original music
    def music_labels(t):
        # find beat closest to t
        closest_beat_idx = np.argmin(np.abs(beats - t))
        closest_beat = beats[closest_beat_idx]
        closest_cp = cps[np.argmin(np.abs(cps - closest_beat))]

        if np.argmin(np.abs(beats - closest_cp)) == closest_beat_idx:
            return "cp"
        else:
            return "noncp"

    # mark where we want change points in the output music
    # (a few beats of slack to improve the quality of the end result)
    def out_labels(t):
        if np.min(np.abs(cp_times - t)) < 1.5 * beat_length:
            return "cp"
        return "noncp"

    m_labels = [music_labels(i) for i in
                np.arange(0, song.duration_in_seconds, beat_length)]
    o_labels = [out_labels(i) for i in np.arange(0, duration, beat_length)]

    constraints = [
        rt_constraints.TimbrePitchConstraint(
            context=0, timbre_weight=1.0, chroma_weight=1.0),
        rt_constraints.EnergyConstraint(penalty=.5),
        rt_constraints.MinimumLoopConstraint(8),
        rt_constraints.NoveltyConstraint(m_labels, o_labels, 1.0)
    ]

    comp, info = retarget(
        [song], duration, constraints=[constraints],
        fade_in_len=None, fade_out_len=None)

    final_cp_locations = [beat_length * i
                          for i, label in enumerate(info['result_labels'])
                          if label == 'cp']

    return comp, final_cp_locations
    def apply(self, transition_cost, penalty, song, beat_names):
        changepoints = np.array(novelty.novelty(song))
        beats = song.analysis["beats"]
        n_beats = len(beats)
        n_target = penalty.shape[1]
        cp_beats_i = [np.argmin(np.abs(beats - cp)) for cp in changepoints]
        cp_beats = [beats[i] for i in cp_beats_i]

        far_threshold = .2
        close_threshold = .1

        # find emotional changes at each changepoint
        changes = []
        for i in cp_beats_i:
            # check the previous and next 4 beats
            n_prev = min(4, i)
            n_next = min(4, n_beats - i)
            vas = [self.in_va[j]
                   for j in range(i - n_prev, i + n_next + 1)]
            # check first and last beat in this range... assuming a sort of
            # coarse-grained emotional labeling

            # before_va = np.mean(vas[:3], axis=0)
            # after_va = np.mean(vas[-3:], axis=0)
            before_va = vas[0]
            after_va = vas[-1]

            if np.linalg.norm(before_va - after_va) > far_threshold:
                # there is an emotional change at this point in the music
                changes.append((i, before_va, after_va))

        for change in changes:
            print "Found emotional change near changepoint:",\
                change[1], "->", change[2]

        # find those emotional changes in the target output
        for l in xrange(1, n_target):
            target = self.out_va[l]
            prev_target = self.out_va[l - 1]

            if np.linalg.norm(target - prev_target) > far_threshold:
                for change in changes:
                    # print np.linalg.norm(prev_target - change[1]),\
                    #     np.linalg.norm(target - change[2])
                    if np.linalg.norm(prev_target - change[1]) <\
                            close_threshold and\
                        np.linalg.norm(target - change[2]) <\
                            close_threshold:

                        print "setting change:\t", change[1], "->", change[2]
                        print "\tat beat " + str(l) + " " +\
                            str(l * song.analysis[BEAT_DUR_KEY])

                        # give huge preference to hitting the changepoint here
                        beat_i = change[0]
                        penalty[:n_beats, l] += 1.0
                        n_prev = min(2, beat_i)
                        n_next = min(2, n_beats - beat_i)
                        penalty[beat_i - n_prev:beat_i + n_next, l] -= 1.0

        return transition_cost, penalty, beat_names
示例#7
0
    def apply(self, transition_cost, penalty, song, beat_names):
        changepoints = np.array(novelty.novelty(song))
        beats = song.analysis["beats"]
        n_beats = len(beats)
        n_target = penalty.shape[1]
        cp_beats_i = [np.argmin(np.abs(beats - cp)) for cp in changepoints]
        cp_beats = [beats[i] for i in cp_beats_i]

        far_threshold = .2
        close_threshold = .1

        # find emotional changes at each changepoint
        changes = []
        for i in cp_beats_i:
            # check the previous and next 4 beats
            n_prev = min(4, i)
            n_next = min(4, n_beats - i)
            vas = [self.in_va[j]
                   for j in range(i - n_prev, i + n_next + 1)]
            # check first and last beat in this range... assuming a sort of
            # coarse-grained emotional labeling

            # before_va = np.mean(vas[:3], axis=0)
            # after_va = np.mean(vas[-3:], axis=0)
            before_va = vas[0]
            after_va = vas[-1]

            if np.linalg.norm(before_va - after_va) > far_threshold:
                # there is an emotional change at this point in the music
                changes.append((i, before_va, after_va))

        for change in changes:
            print "Found emotional change near changepoint:",\
                change[1], "->", change[2]

        # find those emotional changes in the target output
        for l in xrange(1, n_target):
            target = self.out_va[l]
            prev_target = self.out_va[l - 1]

            if np.linalg.norm(target - prev_target) > far_threshold:
                for change in changes:
                    # print np.linalg.norm(prev_target - change[1]),\
                    #     np.linalg.norm(target - change[2])
                    if np.linalg.norm(prev_target - change[1]) <\
                            close_threshold and\
                        np.linalg.norm(target - change[2]) <\
                            close_threshold:

                        print "setting change:\t", change[1], "->", change[2]
                        print "\tat beat " + str(l) + " " +\
                            str(l * song.analysis[BEAT_DUR_KEY])

                        # give huge preference to hitting the changepoint here
                        beat_i = change[0]
                        penalty[:n_beats, l] += 1.0
                        n_prev = min(2, beat_i)
                        n_next = min(2, n_beats - beat_i)
                        penalty[beat_i - n_prev:beat_i + n_next, l] -= 1.0

        return transition_cost, penalty, beat_names
示例#8
0
def retarget_with_change_points(song, cp_times, duration):
    """Create a composition of a song of a given duration that reaches
    music change points at specified times. This is still under
    construction. It might not work as well with more than
    2 ``cp_times`` at the moment.

    Here's an example of retargeting music to be 40 seconds long and
    hit a change point at the 10 and 30 second marks::

        song = Song("instrumental_music.wav")
        composition, change_points =\
            retarget.retarget_with_change_points(song, [10, 30], 40)
        composition.export(filename="retargeted_instrumental_music.")

    :param song: Song to retarget
    :type song: :py:class:`radiotool.composer.Song`
    :param cp_times: Times to reach change points (in seconds)
    :type cp_times: list of floats
    :param duration: Target length of retargeted music (in seconds)
    :type duration: float
    :returns: Composition of retargeted song and list of locations of
        change points in the retargeted composition
    :rtype: (:py:class:`radiotool.composer.Composition`, list)
    """
    analysis = song.analysis

    beat_length = analysis[BEAT_DUR_KEY]
    beats = np.array(analysis["beats"])

    # find change points
    cps = np.array(novelty(song, nchangepoints=4))
    cp_times = np.array(cp_times)

    # mark change points in original music
    def music_labels(t):
        # find beat closest to t
        closest_beat_idx = np.argmin(np.abs(beats - t))
        closest_beat = beats[closest_beat_idx]
        closest_cp = cps[np.argmin(np.abs(cps - closest_beat))]

        if np.argmin(np.abs(beats - closest_cp)) == closest_beat_idx:
            return "cp"
        else:
            return "noncp"

    # mark where we want change points in the output music
    # (a few beats of slack to improve the quality of the end result)
    def out_labels(t):
        if np.min(np.abs(cp_times - t)) < 1.5 * beat_length:
            return "cp"
        return "noncp"

    m_labels = [music_labels(i) for i in
                np.arange(0, song.duration_in_seconds, beat_length)]
    o_labels = [out_labels(i) for i in np.arange(0, duration, beat_length)]

    constraints = [
        rt_constraints.TimbrePitchConstraint(
            context=0, timbre_weight=1.0, chroma_weight=1.0),
        rt_constraints.EnergyConstraint(penalty=.5),
        rt_constraints.MinimumLoopConstraint(8),
        rt_constraints.NoveltyConstraint(m_labels, o_labels, 1.0)
    ]

    comp, info = retarget(
        [song], duration, constraints=[constraints],
        fade_in_len=None, fade_out_len=None)

    final_cp_locations = [beat_length * i
                          for i, label in enumerate(info['result_labels'])
                          if label == 'cp']

    return comp, final_cp_locations