Esempio n. 1
0
    def MainLoop(self):
        self.piano_input_obj.ClearInput()
        self.score = None
        while True:
            self.piano_display.Clear()
            self.piano_display.DrawPiano(False)
            self.ShowHighScore()
            self.piano_display.SetKeyText(36, 20, u"\u2212")
            self.piano_display.SetKeyText(40, 20, u"\u2795")
            self.piano_display.SetKeyText(
                38, self.piano_display.KEYBOARD_HEIGHT + 50, "    Slowdown")
            self.piano_display.SetKeyText(
                38, self.piano_display.KEYBOARD_HEIGHT + 25,
                str(self.slowdown))

            self.piano_display.SetKeyText(36 + 12, 20, "<")
            self.piano_display.SetKeyText(40 + 12, 20, ">")
            self.piano_display.SetKeyText(
                38 + 12, self.piano_display.KEYBOARD_HEIGHT + 50,
                "Select Song")
            self.piano_display.SetKeyText(
                38 + 12, self.piano_display.KEYBOARD_HEIGHT + 25,
                self.songs[self.current_song][:-4])

            self.piano_display.SetKeyText(38 + 12, 20, u"\u266a")

            self.piano_display.Refresh()
            if self.piano_input_obj.user_input.empty():
                time.sleep(0.1)  # Avoid hogging the CPU when idle.
            while not self.piano_input_obj.user_input.empty():
                user_cmd = self.piano_input_obj.user_input.get()
                if user_cmd[1] > 0:
                    if user_cmd[0] == 36:
                        self.slowdown = max(0.1, self.slowdown - 0.1)
                    if user_cmd[0] == 40:
                        self.slowdown = self.slowdown + 0.1
                    if user_cmd[0] == 40 + 12:
                        self.score = None
                        self.current_song = (self.current_song + 1) % len(
                            self.songs)
                        self.CreateWaterfall()
                    if user_cmd[0] == 36 + 12:
                        self.score = None
                        self.current_song = (self.current_song + len(
                            self.songs) - 1) % (len(self.songs))
                        midi_file = midi.MidiFile(
                            self.songs[self.current_song])
                        self.waterfall = waterfall.Waterfall(
                            self.piano_input_obj, self.piano_display,
                            midi_file)
                    if user_cmd[0] == 38 + 12:
                        if self.waterfall.EndOfSong():
                            # Reload midi file, because it was destroyed during playback
                            self.CreateWaterfall()
                        self.score = self.waterfall.Continue(self.slowdown)
                        self.ShowHighScore()
                        self.CheckHighScore()
Esempio n. 2
0
def midi_to_midievents(stream):
	import midi
	m = midi.MidiFile()
	m.open(stream)
	m.read()
	m.close()
	
	# WARNING: we only use track0 here and ignore others
	for ev in m.tracks[0].events:
		if ev.type == "DeltaTime": yield ("play", ev.time)
		elif ev.type == "NOTE_ON": yield ("noteon", ev.track.index, ev.pitch, ev.velocity)
		elif ev.type == "NOTE_OFF": yield ("noteoff", ev.track.index, ev.pitch)
		elif ev.type == "SET_TEMPO": pass # TODO (?) ...
		else:
			print "midi warning: event", ev, "ignored"
Esempio n. 3
0
    def __init__(self):
        self.slowdown = 1.0
        self.songs = GetMidiFiles()
        self.current_song = 0
        self.piano_display = piano_output.PianoOutput()
        try:
            self.piano_input_obj = piano_input.PianoInput()
        except IOError:
            print "Using mock input instead of usb one."
            print "To install pyusb run:"
            print "    sudo apt-get install python libusb-1.0-0"
            print "    sudo pip install pyusb --pre"
            self.piano_input_obj = piano_input_mock.PianoInput()

        midi_file = midi.MidiFile(self.songs[self.current_song])
        self.waterfall = waterfall.Waterfall(self.piano_input_obj,
                                             self.piano_display, midi_file)
        self.LoadHighScores()
Esempio n. 4
0
def main(argv):
    global quickFlag, SAMPLERATE, DT, BLIPSIZE, profiling
    quickFlag = 0
    midifile = None
    wavefile = "newguy.wav"
    starttime, finishtime = -1.e5, 1.e5
    optlist, args = getopt.getopt(argv[1:], "s:f:qi:o:p")
    for (option, value) in optlist:
        if option == "-s":
            starttime = eval(value)
        elif option == "-f":
            finishtime = eval(value)
        elif option == "-q":
            quickFlag = 1
        elif option == "-i":
            midifile = value
        elif option == "-o":
            wavefile = value
        elif option == "-p":
            profiling = 1
    if quickFlag:
        SAMPLERATE = 4000
    else:
        SAMPLERATE = 44100
    DT = 1. / SAMPLERATE
    BLIPSIZE = int(0.02 / DT)
    timestamp("reading MIDI file")
    m = midi.MidiFile(midifile)
    m.read()
    m.close()

    def goAhead(play=play,
                notelist=notelist,
                wavefile=wavefile,
                starttime=starttime,
                finishtime=finishtime):
        play(notelist, wavefile, starttime, finishtime)

    if profiling:
        import profile
        globals()['goAhead'] = goAhead
        profile.run("goAhead()")
    else:
        goAhead()
Esempio n. 5
0
        'time=', 'kill=', 'compensation=', 'multiplier=', 'split=', 'minimum=',
        'output='
    ])
except getopt.GetoptError:
    exit()
for o, a in opts:
    if o in ("-c", "--compensation"): comp = float(a)
    if o in ("-k", "--kill"): chord = int(a)
    if o in ("-m", "--multiplier"): mult = float(a)
    if o in ("-s", "--split"): split = int(a)
    if o in ("-n", "--minimum"): mn = int(a)
    if o in ("-o", "--output"):
        sys.stdout = file(a, "w")
        havetoclose = 1
if not args: exit()
m = midi.MidiFile()
m.open(args[0])
m.read()
m.close()
tcks = range(len(m.tracks)) if len(args) == 1 else args[1:]
xt = list()
for i in tcks:
    xt = xt + m.tracks[int(i)].events
    ntk = max(ntk, int(i))
for e in xt:
    if e.type == "NOTE_OFF":
        e.time += 5
concnotes = [0]
for i in range(ntk):
    concnotes.append(0)
Esempio n. 6
0
def analyze(filename, delta_min=0.02):
    notes = midi.MidiFile(filename).getNotes(False)

    note_low = 21  # lowest midi note on a keyboard
    note_high = 108  # highest midi note on a keyboard

    # Analyze note frequency and volume (force)

    stat_note = np.zeros(note_high - note_low)
    pos_note = np.arange(note_high - note_low)

    stat_note_simp = np.zeros(12)
    pos_note_simp = np.arange(12)
    lab_note_simp = [
        'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'
    ]

    stat_vol = np.zeros(128)
    pos_vol = np.arange(128)

    for t, n, v in notes:
        stat_note[n - note_low] += 1
        stat_note_simp[n % 12] += 1
        stat_vol[v] += 1

    # Analyze number of simultaneous notes played (single strokes / chords)

    stat_nb_notes = np.zeros(12)
    pos_nbnotes = np.arange(12)

    time = -1
    nb_notes = 1
    for t, n, v in notes:
        if (t - time) < delta_min:
            nb_notes += 1
        else:
            if time >= 0:
                stat_nb_notes[nb_notes] += 1
            time = t
            nb_notes = 1

    # Analyze time (silence) between notes, i.e. playing speed or tempo (bpm)

    bpm_step = 25
    bpm_max = int(60 / delta_min)
    pos_bpm = np.arange(0, bpm_max + 1, bpm_step)
    stat_bpm = np.zeros(len(pos_bpm))

    time = -1
    for t, n, v in notes:
        delta_t = t - time
        if t == time or delta_t < delta_min:
            continue
        elif time >= 0:
            bpm = min(round(60. / delta_t / bpm_step), bpm_max)
            stat_bpm[bpm] += 1
        time = t

    return [[pos_note, stat_note, 'Key'],
            [pos_note_simp, stat_note_simp, 'Note', lab_note_simp],
            [pos_vol, stat_vol, 'Volume'],
            [
                pos_nbnotes, stat_nb_notes, 'Nb of simultaneous notes',
                pos_nbnotes
            ], [pos_bpm, stat_bpm, 'Tempo (bpm)']]
Esempio n. 7
0
                  label=label)
        if label != None:
            ax[i].legend(loc='upper right')

    f.subplots_adjust(hspace=0.5)

    return f, ax


if __name__ == '__main__':

    set = 'set_3'

    train_stats = analyze_multi(glob(f'data/{set}/train/*.mid'))
    test_stats = analyze_multi(glob(f'data/{set}/test/*.mid'))

    for subset in ('train', 'test'):
        nb_notes = 0
        for f in glob(f'data/{set}/{subset}/*.mid'):
            nb_notes += len(midi.MidiFile(f).getNotes(False))
        print(f'{set} / {subset} : {nb_notes} notes')

    plt.close('all')
    f, ax = plot(train_stats, label='train', nb_series=2, serie=0)
    f, ax = plot(test_stats, label='test', f=f, ax=ax, nb_series=2, serie=1)
    ax[0].set_title('Set 3')
    # adjust x scales
    ax[1].set_xlim(-1, 13)
    ax[-1].set_xlim(0, 2200)
    plt.show()
Esempio n. 8
0
def load_file_mod(name, step=10, timeLimit=-1):
    """
    Charge un fichier, et le converti en tableau de notes échantillonées
    :param step: pas de quantification de la musique (ms)
    :param timeLimit: temps total limite de la musique (ms)
                      ignoré si négatif
    """
    m = midi.MidiFile()
    m.open(name)
    m.read()
    m.close()

    # print(m.tracks[0])
    # conversion en notes jouées toutes les <step> ms
    noteTimeline = {}
    currentNotes = {p: [-1, 0] for p in range(36)}
    currentTempo = 500000
    lastTempoTimeMicro = 0
    lastTempoTimeTick = 0
    for e in m.tracks[0].events:
        pitch = e.pitch%36
        if e.type == 'SET_TEMPO':  # changement de tempo dans la piste
            t = (e.time-lastTempoTimeTick)*currentTempo/m.ticksPerQuarterNote + lastTempoTimeMicro # durée en µs
            currentTempo = e.data
            lastTempoTimeMicro = t
            lastTempoTimeTick = e.time
        elif e.type == 'NOTE_ON':  # début/fin d'une note
            t = (e.time-lastTempoTimeTick)*currentTempo/m.ticksPerQuarterNote + lastTempoTimeMicro # durée en µs
            n = int( t/(step*1000) )
            if e.velocity != 0:
                # début d'une note -> ajout aux notes actuelles
                currentNotes[pitch] = [n, e.velocity]
            else:
                # fin d'une note: rempli le tableau de 1 depuis le début de cette note
                if currentNotes[pitch][0] == -1:
                    continue
                for k in range(currentNotes[pitch][0], n):
                    if k not in noteTimeline:
                        noteTimeline[k] = []  # ajout de la clé de temps <k>
                    vel = currentNotes[pitch][1]
                    noteTimeline[k].append( (pitch, vel) )
                currentNotes[pitch] = [-1, 0]
                
    # conversion en tableau des notes par étapes
    timeline = [[0 for k in range(36 + 3)] for n in range(max(noteTimeline.keys())+2)]
    print('File', name, 'of length:', len(timeline), 'loaded.')
    for n in noteTimeline:
        vel = 0
        for p, v in noteTimeline[n]:
            vel += v
            timeline[n+1][p] = 1
        timeline[n+1][36] = (vel/len(noteTimeline[n]))/36 # moyennage de la vitesse

    # trim les étapes vides au début
    while all(tm == 0 for tm in timeline[0]):
        timeline.pop(0)
    # trim les étapes selon la limite de temps
    if timeLimit < 0:
        # trim les étapes vides à la fin
        while all(tm == 0 for tm in timeline[-1]):
            timeline.pop()
    else:
        # trim les étapes jusqu'à la limite de temps
        timeline = timeline[:int(timeLimit/step)]

    # signaux de début et fin
    timeline = [[1*(i==37) for i in range(39)]] + timeline + [[1*(i==38) for i in range(39)]]
    return np.asarray(timeline)
Esempio n. 9
0
def makeFile(data, filename, step=10):
    """
    écrit un fichier à partir d'une liste échantillonée de notes
    """
    # ajout d'une frame vide pour l'arrêt des notes
    data += [0 for i in range(131)]
    # création du fichier
    m = midi.MidiFile()

    m.ticksPerQuarterNote = 480
    m.format = 0

    tr = midi.MidiTrack(0)
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # sequence_track_name (nom général)
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'SEQUENCE_TRACK_NAME'
    e.data = b'Generated file at '+filename.encode('latin')
    tr.events.append(e)
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # sequence_track_name (nom de la piste)
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'SEQUENCE_TRACK_NAME'
    e.data = b'Generated track'
    tr.events.append(e)
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # text_event (détails)
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'TEXT_EVENT'
    e.data = b'Generated by a LSTM'
    tr.events.append(e)
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # smtpe_offset (obligatoire?)
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'SMTPE_OFFSET'
    e.data = b'`\x00\x03\x00\x00'
    tr.events.append(e)
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # key_signature (obligatoire?)
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'KEY_SIGNATURE'
    e.data = b'\xff\x00'
    tr.events.append(e)
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # set_tempo
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'SET_TEMPO'
    e.data = to3bytes(int(3*step*480*10))  # on choisi 30 ticks/frame, et 480 ticks/noire (limite au 1/8eme de croche)
    tr.events.append(e)
    # ajout des notes
    currentlyPlaying = [0 for i in range(128)]
    lastChange = -1
    print(data[-1])
    for n in range(len(data)):
        # print(len(data[n]))
        if type(data[n]) == type([]):
            frame = data[n][:128]
            changes = [i for i in range(128) if frame[i] != currentlyPlaying[i]]
            if len(changes) > 0:
                # delta_time
                e = midi.DeltaTime(tr)
                e.time = 30*(n-lastChange)
                tr.events.append(e)
                # note 0
                e = midi.MidiEvent(tr)
                e.channel = 1
                e.type = 'NOTE_ON'
                e.pitch = changes[0]
                if frame[changes[0]] == 1:
                    e.velocity = max(min(int(data[n][128]*128),127),0)
                else:
                    e.velocity = 0
                tr.events.append(e)
                for i in range(len(changes)-1):
                    # delta_time
                    e = midi.DeltaTime(tr)
                    e.time = 0
                    tr.events.append(e)
                    # note 0
                    e = midi.MidiEvent(tr)
                    e.channel = 1
                    e.type = 'NOTE_ON'
                    e.pitch = changes[i+1]
                    if frame[changes[i+1]] == 1:
                        e.velocity = max(min(int(data[n][128]*128),127),0)
                    else:
                        e.velocity = 0
                    tr.events.append(e)

                lastChange = n
            currentlyPlaying = frame
    # delta_time 0
    e = midi.DeltaTime(tr)
    e.time = 0
    tr.events.append(e)
    # fin de piste
    e = midi.MidiEvent(tr)
    e.channel = None
    e.type = 'END_OF_TRACK'
    e.data = b''
    tr.events.append(e)
    m.tracks.append(tr)
    # débug
    f = open('midi_write.txt', 'w')
    print(m.tracks[0], file=f)
    f.close()
    # écriture
    m.open(filename, 'wb')
    m.write()
    m.close()
Esempio n. 10
0
 def CreateWaterfall(self):
     midi_file = midi.MidiFile(self.songs[self.current_song])
     self.waterfall = waterfall.Waterfall(self.piano_input_obj,
                                          self.piano_display, midi_file)
Esempio n. 11
0
def main():
  midi_file = midi.MidiFile(sys.argv[1])
  waterfall = Waterfall(piano_input_mock.PianoInput(),
          piano_output.PianoOutput(), midi_file)
  waterfall.Continue(slowdown_factor=1)