Skip to content

Instantly share code, notes, and snippets.

@tatmos
Created August 2, 2022 01:29
Show Gist options
  • Save tatmos/0f8f5a59b0f1e9c7e45302a69c517f7c to your computer and use it in GitHub Desktop.
Save tatmos/0f8f5a59b0f1e9c7e45302a69c517f7c to your computer and use it in GitHub Desktop.
MIDI to musicbox svg. 1ページに複数
import javax.sound.midi.*;
import processing.svg.PGraphicsSVG;
class Note {
long tick;
int noteNo;
}
String titleName = "Musicbox";
String midiFileName = "Musicbox.mid";
ArrayList<Note> notes = new ArrayList<Note>();
void setup() {
size(1300, 780);
String path = dataPath(midiFileName);
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)
{
// 1 bar shift
note.tick += 480*4;
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 = 50;
void DrawNote(float bx, float by, float wakuWidth, float wakuHieght, float tick, int noteNo)
{
fill(0, 200, 250);
float x = bx + leftMargine + tick/speed;
float y = by + noteSize + wakuHieght - (noteNo-41) * noteSize;
if (x > width)
{
return;
}
print("Draw:"+ noteNo + "\n");
ellipse(x-noteSize/2, y-noteSize/2, noteSize, noteSize*1.25);
}
void DrawBeat(float bx, float by, float wakuWidth, float wakuHieght, float tick, int noteNo, float startTick)
{
fill(200, 0, 250);
float x = bx + leftMargine + (tick-startTick)/speed;
float y = by + wakuHieght - (noteNo-41) * noteSize;
if (x > wakuWidth)
{
return;
}
if (noteNo == 42)
{
// bar
text(int(tick/480/4), x-noteSize, y);
} else {
// beat
ellipse(x-noteSize/2, y-noteSize/2, noteSize/2, noteSize/2);
}
}
float widthTicks = 480 * 4 * 6.25;
void DrawWakuAndNote(float wakuWidth, float wakuHieght, int pageNo)
{
float startTick = widthTicks * pageNo;
float bx = 0;
float by = (wakuHieght + 5) * pageNo;
if (pageNo == 0) {
noFill();
stroke(0);
// waku
rect(bx, by, bx + wakuWidth - noteSize, + wakuHieght);
// start
line(bx, by + wakuHieght/2, bx+leftMargine, by + wakuHieght);
fill(0);
text(titleName, bx + leftMargine, by + wakuHieght - noteSize);
noStroke();
} else {
noFill();
stroke(0);
// waku
rect(bx+leftMargine-noteSize, by, wakuWidth -leftMargine, wakuHieght);
noStroke();
}
for (int beat = int(startTick); beat < startTick + widthTicks; beat+=480)
{
DrawBeat(bx, by, wakuWidth, wakuHieght, beat, 43, startTick);
if ((beat/480)%4 ==0) {
DrawBeat(bx, by, wakuWidth, wakuHieght, beat, 42, startTick);
}
}
for (Note note : notes)
{
if (note.tick >= startTick - 480*2) {
DrawNote(bx, by, wakuWidth, wakuHieght, note.tick-startTick, note.noteNo);
}
}
}
void DrawMusic()
{
beginRecord(SVG, "Music.svg");
int pageNo = 0;
//
float wakuHieght = (30+6)*noteSize;
//
float wakuWidth = leftMargine + widthTicks/speed;
for (; pageNo <2; pageNo++) {
DrawWakuAndNote(wakuWidth, wakuHieght, pageNo);
}
endRecord();
println("" + wakuWidth + " " + wakuHieght);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment