Example #1
0
def sonorities_segment_by_measure(df):
    """
    If a set (bar) contains more than 10 different pitch
    classes, the bar is divided into beats and the beats are treated as new
    segments. If a set contains less than 2 pitch classes, this set is added to the
    set that is constructed from the next bar, forming a new segment. (HONINGH;
    BOD, 2010, p. 2).
    """

    def make_row(frame, composer, name, opus, measure, notes12, nf, iv, categ):
        row = {'composer': composer, 'name': name, 'opus': opus,
               "measure": measure, 'notes_base12': notes12,
               "normal_form": nf, "interval_vector": iv,
               "sonority_category": categ}
        return frame.append([row], ignore_index=True)

    df2 = pandas.DataFrame(columns=["composer", "name", "opus", "measure",
                                    "notes_base12", "normal_form", "interval_vector",
                                    "sonority_category"])
    previous_measure = None

    # Group sonorities by measure.
    for (composer, name, opus, measure), frame in df.groupby(['composer', 'name', 'opus', 'measure']):
        print "  - ", composer, opus, measure
        son12 = tuple(set(flatten(frame['notes_base12'].tolist())))

        # If we have some sonority from the previous measure, i.e. a sonority
        # with less than 3 elements, we merge to this sonority
        if previous_measure:
            son12 += previous_measure
            previous_measure = None

        # If sonority has less than 3 elements, we save to merge in the next measure
        if len(son12) < 3:
            previous_measure = son12

        # If a sonority has more than 9 elementes, we split by beat and merge beats with
        # less than 3 elements.
        elif len(son12) > 9:
            for item in _split_sonorities_by_beat(frame):
                nf = tuple(music.normal_form0(item))
                iv = tuple(music.interval_vector(item))
                categ = music.sonority_category(item)
                df2 = make_row(df2, composer, name, opus, measure, item, nf, iv, categ)
        else:
            nf = tuple(music.normal_form0(son12))
            iv = tuple(music.interval_vector(son12))
            categ = music.sonority_category(son12)
            df2 = make_row(df2, composer, name, opus, measure, son12, nf, iv, categ)

    return df2
 def test_interval_vector_of_01457_should_be_212221(self):
     iv = interval_vector([0, 1, 4, 5, 7])
     self.assertEqual(iv, [2, 1, 2, 2, 2, 1])