| 8 | |
| 9 | class LoadMidi(var fn: String) { |
| 10 | |
| 11 | data class Note(var pitch: Int, var velocity: Double, var time: Double, var duration: Double) |
| 12 | { |
| 13 | var previous : Note? = null |
| 14 | var next : Note? = null |
| 15 | } |
| 16 | |
| 17 | val notes = mutableListOf<Note>() |
| 18 | |
| 19 | fun copy() : LoadMidi { |
| 20 | val r = LoadMidi("") |
| 21 | r.notes.addAll(this.notes) |
| 22 | return r |
| 23 | } |
| 24 | |
| 25 | init { |
| 26 | |
| 27 | if (fn!="") |
| 28 | { |
| 29 | val sequence = MidiSystem.getSequence(File(fn)) |
| 30 | |
| 31 | val ttms = ((sequence.microsecondLength / sequence.tickLength) / 1000.0) / 1000.0 |
| 32 | var trackNumber = 0 |
| 33 | for (track in sequence.getTracks()) { |
| 34 | trackNumber++ |
| 35 | println("Track " + trackNumber + ": size = " + track.size()) |
| 36 | println() |
| 37 | |
| 38 | val table = arrayOfNulls<Note>(127); |
| 39 | |
| 40 | for (i in 0 until track.size()) { |
| 41 | val event = track.get(i) |
| 42 | print("@" + event.getTick() * ttms + " ") |
| 43 | val message = event.getMessage() |
| 44 | if (message is ShortMessage) { |
| 45 | val sm = message as ShortMessage |
| 46 | print("Channel: " + sm.channel + " ") |
| 47 | if (sm.command == NOTE_ON) { |
| 48 | val key = sm.data1 |
| 49 | val octave = key / 12 - 1 |
| 50 | val note = key % 12 |
| 51 | val velocity = sm.data2 |
| 52 | if (velocity > 0) { |
| 53 | println("Note on, $note$octave key=$key velocity: $velocity") |
| 54 | if (table[key] == null) { |
| 55 | table[key] = Note(key, velocity / 127.0, event.tick * ttms, 0.0); |
| 56 | } |
| 57 | } else { |
| 58 | if (table[key] != null) { |
| 59 | table[key]!!.duration = event.tick * ttms - table[key]!!.time |
| 60 | notes.add(table[key]!!) |
| 61 | table[key] = null |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | } else if (sm.command == NOTE_OFF) { |
| 66 | val key = sm.data1 |
| 67 | val octave = key / 12 - 1 |