Skip to content

Instantly share code, notes, and snippets.

@tatmos
Last active July 31, 2022 12:33
Show Gist options
  • Save tatmos/8d9f858dcfefbd830262901f28a0c4f6 to your computer and use it in GitHub Desktop.
Save tatmos/8d9f858dcfefbd830262901f28a0c4f6 to your computer and use it in GitHub Desktop.
MIDIファイルからオルゴール用のレーザーカット用svg出力をするprocessingスケッチ
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