示例#1
0
 def btime_from_ctime(self, clock_time):
     tempo_ctime = self.clock_times[mal_misc.binary_search(
         self.clock_times, clock_time, not_found="force_lower")]
     tempo = self.t_changes_ctimes[tempo_ctime]
     tempo_start = self.clock_time_to_beat_time[tempo_ctime]
     clock_delta = clock_time - tempo_ctime
     return tempo_start + clock_delta * tempo / 60
示例#2
0
 def ctime_from_btime(self, beat_time):
     tempo_btime = self.beat_times[mal_misc.binary_search(
         self.beat_times, beat_time, not_found="force_lower")]
     tempo = self.t_changes_btimes[tempo_btime]
     tempo_start = self.beat_time_to_clock_time[tempo_btime]
     beat_delta = beat_time - tempo_btime
     return tempo_start + beat_delta * 60 / tempo
示例#3
0
    def get_sounding_pitches(self,
                             attack_time,
                             dur=0,
                             min_attack_time=0,
                             min_dur=0):

        sounding_pitches = set()
        end_time = attack_time + dur
        times = list(self.data.keys())
        i = mal_misc.binary_search(times, end_time)
        while i is not None:
            try:
                time = times[i]
            except IndexError:
                i -= 1
                continue
            i -= 1
            notes = self.data[time]
            break_out = False
            for note in reversed(notes):
                if dur > 0 and note.attack_time >= end_time:
                    continue
                elif note.attack_time > end_time:
                    continue
                if note.attack_time < min_attack_time:
                    break_out = True
                    break
                if note.attack_time + note.dur <= attack_time:
                    continue
                if note.dur >= min_dur:
                    sounding_pitches.add(note.pitch)
            if i < 0 or break_out:
                break

        return list(sorted(sounding_pitches))
示例#4
0
    def get_prev_n_notes(
        self,
        n,
        time,
        min_attack_time=0,
        stop_at_rest=False,
        include_start_time=False,
    ):
        """Like get_prev_n_pitches, but returns Note objects.

        If notes are attacked earlier than min_attack_time, None will be
        returned instead. Or, if stop_at_rest is True, then instead of any
        pitches earlier than the first rest, None will be returned instead.
        """

        attack_times = list(self.data.keys())
        i = mal_misc.binary_search(attack_times, time)
        out_notes = []
        if n <= 0:
            return out_notes
        while i is not None:
            i -= 1
            if i < 0:
                break
            attack_time = attack_times[i]
            if attack_time == time and not include_start_time:
                continue

            notes = self.data[attack_time]
            break_out = False
            for note in reversed(notes):
                if note.attack_time < min_attack_time:
                    break_out = True
                    break
                if (stop_at_rest
                        and note.attack_time + note.dur < last_attack_time):
                    break_out = True
                    break
                out_notes.insert(0, note)
                last_attack_time = note.attack_time
                if len(out_notes) == n:
                    break_out = True
                    break
            if break_out:
                break

        for j in range(n - len(out_notes)):
            out_notes.insert(0, None)
        return out_notes
示例#5
0
    def get_prev_n_pitches(
        self,
        n,
        time,
        min_attack_time=0,
        stop_at_rest=False,
        include_start_time=False,
    ):
        """Returns previous n pitches (attacked before time).

        If pitches are attacked earlier than min_attack_time, -1 will be
        returned instead. Or, if stop_at_rest is True, then instead of any
        pitches earlier than the first rest, -1 will be returned in place.
        """

        attack_times = list(self.data.keys())
        i = mal_misc.binary_search(attack_times, time, not_found="force_upper")
        pitches = []
        if n <= 0:
            return pitches
        while i is not None:
            i -= 1
            if i < 0:
                break
            attack_time = last_attack_time = attack_times[i]
            if attack_time == time and not include_start_time:
                continue

            notes = self.data[attack_time]
            break_out = False
            for note in reversed(notes):
                if note.attack_time < min_attack_time:
                    break_out = True
                    break
                if (stop_at_rest
                        and note.attack_time + note.dur < last_attack_time):
                    break_out = True
                    break
                pitches.insert(0, note.pitch)
                last_attack_time = note.attack_time
                if len(pitches) == n:
                    break_out = True
                    break
            if break_out:
                break

        for i in range(n - len(pitches)):
            pitches.insert(0, -1)
        return pitches