Last active
July 31, 2022 12:33
-
-
Save tatmos/8d9f858dcfefbd830262901f28a0c4f6 to your computer and use it in GitHub Desktop.
MIDIファイルからオルゴール用のレーザーカット用svg出力をするprocessingスケッチ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.sound.midi.*; | |
import processing.svg.PGraphicsSVG; | |
class Note { | |
long tick; | |
int noteNo; | |
} | |
ArrayList<Note> notes = new ArrayList<Note>(); | |
void setup() { | |
size(1280, 384); | |
String path = dataPath("Musicbox.mid"); | |
File midiFile = new File(path); | |
try { | |
Sequence seq = MidiSystem.getSequence(midiFile); | |
Track[] tracks = seq.getTracks(); | |
// how many tracks are there | |
println("number of tracks: "+ tracks.length); | |
// parse first track | |
println("events of 1st track:"); | |
for (int trackNo = 0; trackNo<tracks.length; trackNo++) { | |
Track myTrack = tracks[trackNo]; | |
for (int j =0; j< myTrack.size(); j++) { | |
// get midi-message for every event | |
if (myTrack.get(j).getMessage() instanceof ShortMessage) { | |
ShortMessage m = (ShortMessage) myTrack.get(j).getMessage(); | |
// log note-on or note-off events | |
int cmd = m.getCommand(); | |
if (cmd == ShortMessage.NOTE_ON) { | |
if (m.getData2()== 0) | |
{ | |
continue; | |
} | |
MidiEvent mev = myTrack.get(j); | |
long evTick = mev.getTick(); | |
print("ticks:" + evTick + "\n"); | |
print( (cmd==ShortMessage.NOTE_ON ? "NOTE_ON" : "NOTE_OFF") + "; "); | |
print("channel: " + m.getChannel() + "; "); | |
print("note: " + m.getData1() + "; "); | |
println("velocity: " + m.getData2()); | |
Note note = new Note(); | |
note.tick = evTick; | |
note.noteNo = m.getData1(); | |
notes.add(note); | |
} else if (cmd == ShortMessage.NOTE_OFF) { | |
} else | |
{ | |
println("Other message: " + cmd); | |
} | |
} | |
} | |
} | |
println(); | |
NoteConvert(); | |
DrawMusic(); | |
} | |
catch(Exception e) { | |
e.printStackTrace(); | |
exit(); | |
} | |
} | |
// 60 C4 | |
// | |
void NoteConvert() | |
{ | |
for (Note note : notes) | |
{ | |
int noteNo = note.noteNo; | |
// upper E3 77 | |
if (noteNo > 77) | |
{ | |
noteNo -=12; | |
print("octave down:"+ (noteNo+12) + " to " + noteNo + "\n"); | |
} | |
// uppper C5 72 | |
if (noteNo > 72) | |
{ | |
if ( | |
noteNo == 74) | |
{ | |
noteNo = 73; | |
print("D5 to 73 :"+ noteNo + "\n"); | |
} else if ( | |
noteNo == 76) { | |
noteNo = 74; | |
print("E5 to 74:"+ noteNo + "\n"); | |
} else { | |
noteNo -= 12; | |
print("octave down1:"+ noteNo + "\n"); | |
} | |
} | |
// lower C2 36 | |
if (noteNo < 36) | |
{ | |
noteNo +=12; | |
print("octave up:"+ (noteNo-12) + " to " + noteNo + "\n"); | |
} | |
// D#3 | |
if (noteNo == 51) | |
{ | |
noteNo +=12; | |
print("D#3 octave up:"+ noteNo + "\n"); | |
} | |
// D3 50 to 51 | |
else if (noteNo == 50) | |
{ | |
noteNo = 51; | |
print("D3 to 51:"+ noteNo + "\n"); | |
} | |
// C#3 49 | |
else if (noteNo == 49) | |
{ | |
noteNo +=12; | |
print("C#3 octave up:"+ noteNo + "\n"); | |
} | |
// C3 48 to 50 | |
else if (noteNo == 48) | |
{ | |
noteNo = 50; | |
print("C3 to 50:"+ noteNo + "\n"); | |
} | |
// B2 47 to 49 | |
else if (noteNo == 47) | |
{ | |
noteNo = 49; | |
print("B2 to 49:"+ noteNo + "\n"); | |
} | |
// A#2 46 | |
else if (noteNo == 46) | |
{ | |
noteNo +=12; | |
print("A#2 octave up:"+ noteNo + "\n"); | |
} | |
// A2 45 to 48 | |
else if (noteNo == 45) | |
{ | |
noteNo = 48; | |
print("A2 to 48:"+ noteNo + "\n"); | |
} | |
// G#2 44 | |
else if (noteNo == 44) | |
{ | |
noteNo +=12; | |
print("G#2 octave up:"+ noteNo + "\n"); | |
} | |
// G2 43 to 47 | |
else if (noteNo == 43) | |
{ | |
noteNo = 47; | |
print("G2 to 47:"+ noteNo + "\n"); | |
} | |
// F#2 42 41 40 39 D# | |
else if (noteNo >= 39 && noteNo <= 42) | |
{ | |
noteNo +=12; | |
print("D#2 - F#2 octave up:"+ noteNo + "\n"); | |
} | |
// D2 38 to 46 | |
else if (noteNo == 38) | |
{ | |
noteNo = 46; | |
print("D2 to 46:"+ noteNo + "\n"); | |
} | |
// C#2 37 | |
else if (noteNo == 37) | |
{ | |
noteNo +=12; | |
print("C#2 octave up:"+ noteNo + "\n"); | |
} | |
// C2 36 to 45 | |
else if (noteNo == 36) | |
{ | |
noteNo = 45; | |
print("C2 to 45:"+ noteNo + "\n"); | |
} | |
note.noteNo = noteNo; | |
} | |
} | |
float noteSize = 10; | |
float speed = 100/10; | |
float leftMargine = 30; | |
void DrawNote(float tick, int noteNo) | |
{ | |
fill(0, 200, 250); | |
float x = leftMargine*4 + tick/speed; | |
float y = height - (noteNo-41) * noteSize; | |
if (x > width) | |
{ | |
return; | |
} | |
print("Draw:"+ noteNo + "\n"); | |
ellipse(x-noteSize/2, y-noteSize/2, noteSize, noteSize); | |
} | |
void DrawBeat(float tick, int noteNo) | |
{ | |
fill(200, 0, 250); | |
float x = leftMargine*4 + tick/speed; | |
float y = height - (noteNo-41) * noteSize; | |
if (x > width) | |
{ | |
return; | |
} | |
ellipse(x-noteSize/2, y-noteSize/2, noteSize/2, noteSize/2); | |
} | |
void DrawMusic() | |
{ | |
float startTick = 480 * 4 * 6*0; | |
beginRecord(SVG, "Music.svg"); | |
float wakuHieght = (30+6)*noteSize; | |
noFill(); | |
rect(0, height/2-wakuHieght/2, width, wakuHieght); | |
line(0, height/2, leftMargine, height/2+wakuHieght/2); | |
noStroke(); | |
//DrawNote(-100, 72); | |
for (int beat = 0; beat < 400; beat++) | |
{ | |
DrawBeat(beat*480, 43); | |
if (beat%4 ==0) { | |
DrawBeat(beat*480, 42); | |
} | |
} | |
for (Note note : notes) | |
{ | |
if (note.tick >= startTick - 480*2) { | |
DrawNote(note.tick-startTick, note.noteNo); | |
} | |
} | |
endRecord(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment