Skip to content

Instantly share code, notes, and snippets.

@tatmos
Last active October 27, 2021 06:36
Show Gist options
  • Save tatmos/e39c0003419cd67989822d96d1b99698 to your computer and use it in GitHub Desktop.
Save tatmos/e39c0003419cd67989822d96d1b99698 to your computer and use it in GitHub Desktop.
ALTDEUS:BCのMusicboxMIDIからinoファイルのコードを一部生成
#ALTDEUS:BCのMusicboxのメロディーを演奏する
#ArduinoMega用
#54(note G0) - 29(note G2)
import os
from operator import attrgetter
import mido
from mido import MidiFile
MIDI_FILE = "Musicbox.mid"
mid = MidiFile(MIDI_FILE)
outText = ""
prevTime = 0
duration = 20
flam = 20
bn =0
notes = []
class Note:
atime = 0
noteNo = 0
vel = 127
def __init__(self, val1, val2, val3):
self.atime = val1
self.noteNo = val2
self.vel = val3
for i, track in enumerate(mid.tracks):
print('Track {}: {}'.format(i, track.name))
absolute_time = 0
for msg in track:
if msg.type == 'set_tempo':
tempo = msg.tempo
print("temo is {0}".format(tempo))
if msg.time > 0:
absolute_time = absolute_time + mido.tick2second(msg.time,480,tempo)*1000
#note onのみ
#if i == 0:
if msg.type == 'note_on':
if msg.velocity > 0:
#print(absolute_time)
curNote = 60-(msg.note-12+bn)+36
for repeat in range(0,3):
if curNote < 29:
curNote += 12
print("upper " + str(curNote))
if curNote > 54:
curNote -= 12
print("under " + str(curNote))
noteTime = absolute_time
notes.append(Note(noteTime,curNote,127))
# noteを時間ソートする
notes = sorted(notes, key=attrgetter('atime'))
# 重複ノートをずらす
for note in notes:
noteTime = note.atime
dupNotes = [x for x in notes if x.atime == noteTime] # 同タイムのnoteリスト
tmpFlam = 0
for dupNote in dupNotes:
dupNote.atime -= tmpFlam # 前へずらす
tmpFlam += flam
# noteを時間ソートする
notes = sorted(notes, key=attrgetter('atime'))
# noteoffを追加する
for note in notes:
if note.vel > 0:
noteTime = note.atime
curNote = note.noteNo
notes.append(Note(noteTime+duration,curNote,0))
# noteを時間ソートする
notes = sorted(notes, key=attrgetter('atime'))
#
for note in notes:
absolute_time = note.atime
curNote = note.noteNo
vel = note.vel
delay = int(absolute_time-prevTime)
#print(str(curNote))
#Delay
if delay > 0:
outText += "delay({}*bl);\n".format(delay)
if vel > 0:
#NoteOn
outText += "Serial.println({}+bn);\n".format(curNote)
outText += "digitalWrite({}+bn, HIGH);\n".format(curNote)
if vel == 0:
#NoteOff
outText += "digitalWrite({}+bn, LOW);\n".format(curNote)
#前回の発音時間
prevTime = absolute_time
#ファイルに解析内容を保存
sample_file = open("{}.txt".format(os.path.splitext(os.path.basename(MIDI_FILE))[0]), mode="w")
try:
sample_file.write(outText)
finally:
sample_file.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment