Пример #1
0
    def test_midi_export_mode_0(self):
        m = self._export_and_read(mode=0)
        msg = ('Number of parts {} does not equal number of tracks {} while '
               'testing part_voice_assign_mode=0 in save_score_midi'.format(
                   len(self.parts_list), len(m.tracks)))
        self.assertEqual(len(self.parts_list), len(m.tracks), msg)

        for part, track in zip(self.parts_list, m.tracks):
            # voices per note in part
            vc = note_voices(part)
            # channels per note in track
            ch = note_channels(track)
            vcp = partition(lambda x: -1 if x is None else x, vc)
            chp = partition(lambda x: x, ch)
            vc_list = [len(vcp[x]) for x in sorted(vcp.keys())]
            ch_list = [len(chp[x]) for x in sorted(chp.keys())]

            msg = ('Track channels should have {} notes respectively, '
                   'but they have {}'.format(vc_list, ch_list))

            self.assertEqual(vc_list, ch_list, msg)

            ts_part = sum(1 for _ in part.iter_all(score.TimeSignature))
            ts_track = sum(1 for e in track if e.type == 'time_signature')
            msg = ('Track should have {} time signatures respectively, '
                   'but has {}'.format(ts_part, ts_track))
            self.assertEqual(ts_part, ts_track, msg)

            ks_part = sum(1 for _ in part.iter_all(score.KeySignature))
            ks_track = sum(1 for e in track if e.type == 'key_signature')
            msg = ('Track should have {} key signatures respectively, '
                   'but has {}'.format(ks_part, ks_track))
            self.assertEqual(ks_part, ks_track, msg)
Пример #2
0
    def test_midi_import_mode_0(self):
        parts = load_score_midi(self.tmpfile.name, part_voice_assign_mode=0)
        by_track = partition(itemgetter(0), self.notes_per_tr_ch.keys())

        msg = ('Number of parts {} does not equal number of tracks {} while '
               'testing part_voice_assign_mode=0 in load_score_midi').format(
                   len(parts), len(by_track))
        self.assertEqual(len(parts), len(by_track), msg)

        for part, tr in zip(parts, by_track):

            msg = '{} should be a Part instance but it is not'.format(part)
            self.assertTrue(isinstance(part, score.Part), msg)

            n_track_notes = sum(self.notes_per_tr_ch[tr_ch]
                                for tr_ch in by_track[tr])
            part_notes = part.notes
            n_part_notes = len(part_notes)
            msg = 'Part should have {} notes but it has'.format(
                n_track_notes, n_part_notes)
            self.assertEqual(n_track_notes, n_part_notes, msg)

            n_ch_notes = [
                self.notes_per_tr_ch[tr_ch] for tr_ch in by_track[tr]
            ]
            n_voice_notes = [
                len(vn) for v, vn in partition(
                    lambda x: x, [n.voice for n in part_notes]).items()
            ]
            msg = (
                'Part voices should have {} notes respectively, but they have {}'
                .format(n_ch_notes, n_voice_notes))
            self.assertEqual(n_ch_notes, n_voice_notes, msg)
Пример #3
0
 def test_midi_import_mode_2(self):
     part = load_score_midi(self.tmpfile.name, part_voice_assign_mode=2)
     msg = '{} should be a Part instance but it is not'.format(part)
     self.assertTrue(isinstance(part, score.Part), msg)
     by_track = partition(itemgetter(0), self.notes_per_tr_ch.keys())
     by_voice = partition(lambda x: x.voice, part.notes)
     n_track_notes = [
         sum(self.notes_per_tr_ch[tr_ch] for tr_ch in tr_chs)
         for tr_chs in by_track.values()
     ]
     n_voice_notes = ([len(notes) for notes in by_voice.values()])
     msg = ('Number of notes per voice {} does not match number of '
            'notes per track {}'.format(n_voice_notes, n_track_notes))
     self.assertEqual(n_voice_notes, n_track_notes, msg)
Пример #4
0
    def test_midi_import_mode_1(self):
        parts = load_score_midi(self.tmpfile.name, part_voice_assign_mode=1)
        by_track = partition(itemgetter(0), self.notes_per_tr_ch.keys())
        msg = (
            'Number of partgroups {} does not equal number of tracks {} while '
            'testing part_voice_assign_mode=0 in load_score_midi').format(
                len(parts), len(by_track))
        self.assertEqual(len(parts), len(by_track), msg)

        for part_group, tr in zip(parts, by_track):

            msg = '{} should be a PartGroup instance but it is not'
            self.assertTrue(isinstance(part_group, score.PartGroup), msg)
            n_parts = len(part_group.children)
            n_channels = len(by_track[tr])
            msg = (
                'PartGroup should have as many parts as there are '
                'channels in the corresponding track {}, but it has {}'.format(
                    n_channels, n_parts))
            self.assertEqual(n_parts, n_channels, msg)

            for part, tr_ch in zip(part_group.children, by_track[tr]):
                notes_in_track = self.notes_per_tr_ch[tr_ch]
                notes_in_part = len(part.notes)
                msg = 'Part should have {} notes but it has {}'.format(
                    notes_in_track, notes_in_part)
                self.assertEqual(notes_in_part, notes_in_track)
Пример #5
0
def add_voices(part):
    by_staff = partition(attrgetter('staff'), part.notes_tied)
    max_voice = 0
    for staff, notes in by_staff.items():

        voices = estimate_voices(notes_to_notearray(notes))

        assert len(voices) == len(notes)
        for n, voice in zip(notes, voices):
            assert voice > 0
            n.voice = voice + max_voice

            n_next = n
            while n_next.tie_next:
                n_next = n_next.tie_next
                n_next.voice = voice + max_voice

        max_voice = np.max(voices)

    if any([n.voice is None for n in part.notes]):
        # Hack to add voices to notes not included in a staff!
        # not musically meaningful
        ev = 1
        for n in part.notes:
            if n.voice is None:
                n.voice = max_voice + ev
                ev += 1
Пример #6
0
def add_staffs_v1(part):
    # assign staffs by first estimating voices jointly, then assigning voices to staffs

    notes = part.notes_tied
    # estimate voices in strictly monophonic way
    voices = estimate_voices(notes_to_notearray(notes), monophonic_voices=True)
    # for v, note in zip(voices, notes):
    #     print(note.start.t, note.midi_pitch, v)

    # group notes by voice
    by_voice = partition(itemgetter(0), zip(voices, notes))
    clefs = {}

    for v, vnotes in by_voice.items():
        # voice numbers may be recycled throughout the piece, so we split by
        # time gap
        t_diffs = np.diff([n.start.t for _, n in vnotes])
        t_threshold = np.inf  # np.median(t_diffs)+1
        note_groups = np.split([note for _, note in vnotes],
                               np.where(t_diffs > t_threshold)[0] + 1)

        # for each note group estimate the clef
        for note_group in note_groups:
            if len(note_group) > 0:
                pitches = [n.midi_pitch for n in note_group]
                clef = tuple(estimate_clef_properties(pitches).items())
                staff = clefs.setdefault(clef, len(clefs))

                # print((note_group[0].start.t, note_group[-1].end.t),
                #       (np.min(pitches), np.max(pitches), np.mean(pitches)), clef)
                for n in note_group:
                    n.staff = staff
                    n_tied = n.tie_next
                    while n_tied:
                        n_tied.staff = staff
                        n_tied = n_tied.tie_next

    # re-order the staffs to a fixed order (see CLEF_ORDER), rather than by
    # first appearance
    clef_list = list((dict(clef), i) for clef, i in clefs.items())
    clef_list.sort(key=lambda x: x[0].get('octave_change', 0))
    clef_list.sort(key=lambda x: CLEF_ORDER.index(x[0].get('sign', 'G')))
    staff_map = dict((j, i + 1) for i, (_, j) in enumerate(clef_list))
    for n in notes:
        n.staff = staff_map[n.staff]
    for i, (clef_properties, _) in enumerate(clef_list):
        part.add(score.Clef(number=i + 1, **clef_properties), 0)
Пример #7
0
    def test_midi_import_mode_3(self):
        parts = load_score_midi(self.tmpfile.name, part_voice_assign_mode=3)
        by_track = partition(itemgetter(0), self.notes_per_tr_ch.keys())

        msg = ('Number of parts {} does not equal number of tracks {}'.format(
            len(parts), len(by_track)))
        self.assertEqual(len(parts), len(by_track), msg)

        for part, tr in zip(parts, by_track):

            msg = '{} should be a Part instance but it is not'.format(part)
            self.assertTrue(isinstance(part, score.Part), msg)

            n_track_notes = sum(self.notes_per_tr_ch[tr_ch]
                                for tr_ch in by_track[tr])
            part_notes = part.notes
            n_part_notes = len(part_notes)
            msg = 'Part should have {} notes but it has'.format(
                n_track_notes, n_part_notes)
            self.assertEqual(n_track_notes, n_part_notes, msg)
Пример #8
0
    def test_midi_export_mode_2(self):
        m = self._export_and_read(mode=2)
        msg = ('Number of tracks {} does not equal 1 while '
               'testing part_voice_assign_mode=2 in save_score_midi'.format(
                   len(m.tracks)))
        self.assertEqual(1, len(m.tracks), msg)

        n_channels_trg = len(self.parts_list)
        note_ch = note_channels(m.tracks[0])
        by_channel = partition(lambda x: x, note_ch)
        channels = sorted(by_channel.keys())
        n_channels = len(channels)
        msg = ('Number of channels {} does not equal {} while '
               'testing part_voice_assign_mode=2 in save_score_midi'.format(
                   n_channels, n_channels_trg))
        self.assertEqual(n_channels_trg, n_channels, msg)
        for part, ch in zip(self.parts_list, channels):
            n_notes_trg = len(part.notes_tied)
            n_notes = len(by_channel[ch])
            msg = ('Number of notes in channel {} should be '
                   '{} while testing '
                   'part_voice_assign_mode=2 in save_score_midi'.format(
                       n_notes, n_notes_trg))
            self.assertEqual(n_notes_trg, n_notes, msg)
Пример #9
0
def split_datasets_by_piece(datasets, test_size=0.2, valid_size=0.2):

    by_piece = partition(lambda d: '_'.join(d.name.split('_')[:-1]), datasets)
    pieces = list(by_piece.keys())
    RNG.shuffle(pieces)

    n_test = max(1, int(np.round(test_size * len(pieces))))
    n_valid = max(1, int(np.round(valid_size * len(pieces))))
    n_train = len(pieces) - n_test - n_valid

    if n_train < 1:
        raise Exception('Not enough pieces to split datasets according '
                        'to the specified test/validation proportions')

    test_pieces = pieces[:n_test]
    valid_pieces = pieces[n_test:n_test + n_valid]
    train_pieces = pieces[n_test + n_valid:]

    test_set = [d for pd in [by_piece[p] for p in test_pieces] for d in pd]
    valid_set = [d for pd in [by_piece[p] for p in valid_pieces] for d in pd]
    train_set = [d for pd in [by_piece[p] for p in train_pieces] for d in pd]

    return (ConcatDataset(train_set), ConcatDataset(valid_set),
            ConcatDataset(test_set))
Пример #10
0
def save_score_midi(parts,
                    out,
                    part_voice_assign_mode=0,
                    velocity=64,
                    anacrusis_behavior="shift"):
    """Write data from Part objects to a MIDI file

    Parameters
    ----------
    parts : Part, PartGroup or list of these
        The musical score to be saved.
    out : str or file-like object
        Either a filename or a file-like object to write the MIDI data
        to.
    part_voice_assign_mode : {0, 1, 2, 3, 4, 5}, optional
        This keyword controls how part and voice information is
        associated to track and channel information in the MIDI file.
        The semantics of the modes is as follows:

        0
            Write one track for each Part, with channels assigned by
            voices
        1
            Write one track for each PartGroup, with channels assigned by
            Parts (voice info is lost) (There can be multiple levels of
            partgroups, I suggest using the highest level of
            partgroup/part) [note: this will e.g. lead to all strings into
            the same track] Each part not in a PartGroup will be assigned
            its own track
        2
            Write a single track with channels assigned by Part (voice
            info is lost)
        3
            Write one track per Part, and a single channel for all voices
            (voice info is lost)
        4
            Write a single track with a single channel (Part and voice
            info is lost)
        5
            Return one track per <Part, voice> combination, each track
            having a single channel.

        The default mode is 0.
    velocity : int, optional
        Default velocity for all MIDI notes. Defaults to 64.
    anacrusis_behavior : {"shift", "pad_bar"}, optional
        Strategy to deal with anacrusis. If "shift", all
        time points are shifted by the anacrusis (i.e., the first
        note starts at 0). If "pad_bar", the "incomplete" bar  of
        the anacrusis is padded with silence. Defaults to 'shift'.
    """

    ppq = get_ppq(parts)

    events = defaultdict(lambda: defaultdict(list))
    meta_events = defaultdict(lambda: defaultdict(list))

    event_keys = OrderedDict()
    tempos = {}

    quarter_maps = [part.quarter_map for part in score.iter_parts(parts)]

    first_time_point = min(qm(0) for qm in quarter_maps)

    ftp = 0
    # Deal with anacrusis
    if first_time_point < 0:
        if anacrusis_behavior == "shift":
            ftp = first_time_point
        elif anacrusis_behavior == "pad_bar":
            time_signatures = []
            for qm, part in zip(quarter_maps, score.iter_parts(parts)):
                ts_beats, ts_beat_type = part.time_signature_map(0)
                time_signatures.append((ts_beats, ts_beat_type, qm(0)))
            # sort ts according to time
            time_signatures.sort(key=lambda x: x[2])
            ftp = -time_signatures[0][0] / (time_signatures[0][1] / 4)
        else:
            raise Exception(
                'Invalid anacrusis_behavior value, must be one of ("shift", "pad_bar")'
            )

    for qm, part in zip(quarter_maps, score.iter_parts(parts)):

        pg = get_partgroup(part)

        notes = part.notes_tied

        def to_ppq(t):
            # convert div times to new ppq
            return int(ppq * (qm(t) - ftp))

        for tp in part.iter_all(score.Tempo):
            tempos[to_ppq(tp.start.t)] = MetaMessage(
                "set_tempo", tempo=tp.microseconds_per_quarter)

        for ts in part.iter_all(score.TimeSignature):
            meta_events[part][to_ppq(ts.start.t)].append(
                MetaMessage("time_signature",
                            numerator=ts.beats,
                            denominator=ts.beat_type))

        for ks in part.iter_all(score.KeySignature):
            meta_events[part][to_ppq(ks.start.t)].append(
                MetaMessage("key_signature", key=ks.name))

        for note in notes:

            # key is a tuple (part_group, part, voice) that will be
            # converted into a (track, channel) pair.
            key = (pg, part, note.voice)
            events[key][to_ppq(note.start.t)].append(
                Message("note_on", note=note.midi_pitch))
            events[key][to_ppq(note.start.t + note.duration_tied)].append(
                Message("note_off", note=note.midi_pitch))
            event_keys[key] = True

    tr_ch_map = map_to_track_channel(list(event_keys.keys()),
                                     part_voice_assign_mode)

    # replace original event keys (partgroup, part, voice) by (track, ch) keys:
    for key in list(events.keys()):
        evs_by_time = events[key]
        del events[key]
        tr, ch = tr_ch_map[key]
        for t, evs in evs_by_time.items():
            events[tr][t].extend((ev.copy(channel=ch) for ev in evs))

    # figure out in which tracks to replicate the time/key signatures of each part
    part_track_map = partition(lambda x: x[0][1], tr_ch_map.items())
    for part, rest in part_track_map.items():
        part_track_map[part] = set(x[1][0] for x in rest)

    # add the time/key sigs to their corresponding tracks
    for part, m_events in meta_events.items():
        tracks = part_track_map[part]
        for tr in tracks:
            for t, me in m_events.items():
                events[tr][t] = me + events[tr][t]

    n_tracks = max(tr for tr, _ in tr_ch_map.values()) + 1
    tracks = [MidiTrack() for _ in range(n_tracks)]

    # tempo events are handled differently from key/time sigs because the have a
    # global effect. Instead of adding to each relevant track, like the key/time
    # sig events, we add them only to the first track
    for t, tp in tempos.items():
        events[0][t].insert(0, tp)

    for tr, events_by_time in events.items():
        t_prev = 0
        for t in sorted(events_by_time.keys()):
            evs = events_by_time[t]
            delta = t - t_prev
            for ev in evs:
                tracks[tr].append(ev.copy(time=delta))
                delta = 0
            t_prev = t

    midi_type = 0 if n_tracks == 1 else 1

    mf = MidiFile(type=midi_type, ticks_per_beat=ppq)

    for track in tracks:
        mf.tracks.append(track)

    if out:
        if hasattr(out, "write"):
            mf.save(file=out)
        else:
            mf.save(out)
Пример #11
0
def linearize_segment_contents(part, start, end, state):
    """
    Determine the document order of events starting between `start` (inclusive) and `end` (exlusive).
    (notes, directions, divisions, time signatures).
    """

    notes = part.iter_all(score.GenericNote,
                          start=start, end=end,
                          include_subclasses=True)

    notes_by_voice = partition(lambda n: n.voice or 0, notes)
    if len(notes_by_voice) == 0:
        # if there are no notes in this segment, we add a rest
        # NOTE: altering the part instance while exporting is bad!
        # rest = score.Rest()
        # part.add(start.t, rest, end.t)
        # notes_by_voice = {0: [rest]}
        notes_by_voice[None] = []
        
    # make sure there is no polyphony within voices by assigning any violating
    # notes to a new (free) voice.
    remove_voice_polyphony(notes_by_voice)

    # fill_gaps_with_rests(notes_by_voice, start, end, part)
    # # redo
    # notes = part.iter_all(score.GenericNote,
    #                               start=start, end=end,
    #                               include_subclasses=True)
    # notes_by_voice = partition(lambda n: n.voice or 0, notes)

    voices_e = defaultdict(list)

    for voice in sorted(notes_by_voice.keys()):

        voice_notes = notes_by_voice[voice]
        # sort by pitch
        voice_notes.sort(key=lambda n: n.midi_pitch if hasattr(n, 'midi_pitch') else -1, reverse=True)
        # grace notes should precede other notes at the same onset
        voice_notes.sort(key=lambda n: not isinstance(n, score.GraceNote))
        # voice_notes.sort(key=lambda n: -n.duration)
        voice_notes.sort(key=lambda n: n.start.t)
        
        for n in voice_notes:
            if isinstance(n, score.GraceNote):
                # check if it is the first in its sequence
                if not n.grace_prev:
                    # if so we add the whole grace sequence at once to ensure
                    # the correct order
                    for m in n.iter_grace_seq():
                        note_e = do_note(m, end.t, part, voice,
                                         state['note_id_counter'])
                        voices_e[voice].append(note_e)
            else:
                note_e = do_note(n, end.t, part, voice, state['note_id_counter'])
                voices_e[voice].append(note_e)
            
        add_chord_tags(voices_e[voice])

    attributes_e = do_attributes(part, start, end)
    directions_e = do_directions(part, start, end, state['range_counter'])
    prints_e = do_prints(part, start, end)
    barline_e = do_barlines(part, start, end)

    other_e = attributes_e + directions_e + barline_e + prints_e

    contents = merge_measure_contents(voices_e, other_e, start.t)
    
    return contents
Пример #12
0
def save_score_midi(parts, out, part_voice_assign_mode=0, velocity=64):
    """Write data from Part objects to a MIDI file

    Parameters
    ----------
    parts : Part, PartGroup or list of these
        The musical score to be saved.
    out : str or file-like object
        Either a filename or a file-like object to write the MIDI data
        to.
    part_voice_assign_mode : {0, 1, 2, 3, 4, 5}, optional
        This keyword controls how part and voice information is
        associated to track and channel information in the MIDI file.
        The semantics of the modes is as follows:

        0
            Write one track for each Part, with channels assigned by
            voices
        1
            Write one track for each PartGroup, with channels assigned by
            Parts (voice info is lost) (There can be multiple levels of
            partgroups, I suggest using the highest level of
            partgroup/part) [note: this will e.g. lead to all strings into
            the same track] Each part not in a PartGroup will be assigned
            its own track
        2
            Write a single track with channels assigned by Part (voice
            info is lost)
        3
            Write one track per Part, and a single channel for all voices
            (voice info is lost)
        4
            Write a single track with a single channel (Part and voice
            info is lost)
        5
            Return one track per <Part, voice> combination, each track
            having a single channel.

    velocity : int, optional
        Default velocity for all MIDI notes.

    """

    ppq = get_ppq(parts)

    events = defaultdict(lambda: defaultdict(list))
    meta_events = defaultdict(lambda: defaultdict(list))

    event_keys = OrderedDict()
    tempos = {}

    for i, part in enumerate(score.iter_parts(parts)):

        pg = get_partgroup(part)

        notes = part.notes_tied
        qm = part.quarter_map
        q_offset = qm(part.first_point.t)

        def to_ppq(t):
            # convert div times to new ppq
            return int(ppq * qm(t))

        for tp in part.iter_all(score.Tempo):
            tempos[to_ppq(tp.start.t)] = MetaMessage(
                'set_tempo', tempo=tp.microseconds_per_quarter)

        for ts in part.iter_all(score.TimeSignature):
            meta_events[part][to_ppq(ts.start.t)].append(
                MetaMessage('time_signature',
                            numerator=ts.beats,
                            denominator=ts.beat_type))

        for ks in part.iter_all(score.KeySignature):
            meta_events[part][to_ppq(ks.start.t)].append(
                MetaMessage('key_signature', key=ks.name))

        for note in notes:

            # key is a tuple (part_group, part, voice) that will be converted into a (track, channel) pair.
            key = (pg, part, note.voice)
            events[key][to_ppq(note.start.t)].append(
                Message('note_on', note=note.midi_pitch))
            events[key][to_ppq(note.end_tied.t)].append(
                Message('note_off', note=note.midi_pitch))

            event_keys[key] = True

    tr_ch_map = map_to_track_channel(list(event_keys.keys()),
                                     part_voice_assign_mode)

    # replace original event keys (partgroup, part, voice) by (track, ch) keys:
    for key in list(events.keys()):
        evs_by_time = events[key]
        del events[key]
        tr, ch = tr_ch_map[key]
        for t, evs in evs_by_time.items():
            events[tr][t].extend((ev.copy(channel=ch) for ev in evs))

    # figure out in which tracks to replicate the time/key signatures of each part
    part_track_map = partition(lambda x: x[0][1], tr_ch_map.items())
    for part, rest in part_track_map.items():
        part_track_map[part] = set(x[1][0] for x in rest)

    # add the time/key sigs to their corresponding tracks
    for part, m_events in meta_events.items():
        tracks = part_track_map[part]
        for tr in tracks:
            for t, me in m_events.items():
                events[tr][t] = me + events[tr][t]

    n_tracks = max(tr for tr, _ in tr_ch_map.values()) + 1
    tracks = [MidiTrack() for _ in range(n_tracks)]

    # tempo events are handled differently from key/time sigs because the have a
    # global effect. Instead of adding to each relevant track, like the key/time
    # sig events, we add them only to the first track
    track0_events = events[0]
    for t, tp in tempos.items():
        events[0][t].insert(0, tp)

    for tr, events_by_time in events.items():
        t_prev = 0
        for t in sorted(events_by_time.keys()):
            evs = events_by_time[t]
            delta = t - t_prev
            for ev in evs:
                tracks[tr].append(ev.copy(time=delta))
                delta = 0
            t_prev = t

    midi_type = 0 if n_tracks == 1 else 1

    mf = MidiFile(type=midi_type, ticks_per_beat=ppq)

    for track in tracks:
        mf.tracks.append(track)

    if out:
        if hasattr(out, 'write'):
            mf.save(file=out)
        else:
            mf.save(out)
Пример #13
0
def make_plot(fig,
              axs,
              targets,
              onsets=None,
              xticks=None,
              title=None,
              xlabel=None,
              start=None,
              end=None,
              keep_zoom=False):
    names = targets.dtype.names

    xlims = []
    ylims = []
    for ax in axs:
        if keep_zoom:
            xlims.append(list(ax.get_xlim()))
            ylims.append(list(ax.get_ylim()))
        ax.clear()

    n_targets = len(names)

    if onsets is None:
        x = np.arange(len(targets))
    else:
        x = onsets

    w = len(x) / 30
    h = n_targets

    if end is not None:
        idx = x < end
        x = x[idx]
        targets = targets[idx]

    if start is not None:
        idx = x >= start
        x = x[idx]
        targets = targets[idx]

    if n_targets == 1:
        axs = [axs]

    # fig.set_size_inches(w, h)

    if title:
        fig.suptitle(title)

    by_onset = partition(lambda ix: ix[1], enumerate(x))
    for k, v in by_onset.items():
        by_onset[k] = np.array([i for i, _ in v])

    for i, name in enumerate(names):
        target = targets[name]
        targets[np.isnan(target)] = 0

        axs[i].plot(x, target, '.', label=name)

        if xticks is not None:
            axs[i].set_xticks(xticks['t'])
            axs[i].set_xticklabels(xticks['label'])
            axs[i].xaxis.grid()

        tt = []
        vv = []
        for t, v in by_onset.items():
            tt.append(t)
            vv.append(np.mean(target[v]))

        # axs[i].plot(tt, vv, label='{} (mean)'.format(name))
        axs[i].plot(tt, vv)

        axs[i].legend(frameon=False, loc=2)

    if keep_zoom:
        axs[0].set_xlim(xlims[0])
        for xlim, ylim, ax in zip(xlims, ylims, axs):
            ax.set_ylim(ylim)

    return fig, axs
Пример #14
0
def add_clefs(part):
    by_staff = partition(attrgetter('staff'), part.notes_tied)
    for staff, notes in by_staff.items():
        part.add(score.Clef(number=staff, **estimate_clef_properties([n.midi_pitch for n in notes])), 0)