1
+ Rebol [
2
+ Title: "Test MIDI port"
3
+ Date: 5-Jun-2023
4
+ Author: "Oldes"
5
+ File: %test-midi.r3
6
+ Version: 1.0.0
7
+ Requires: 3.11.0
8
+ ]
9
+
10
+ midi: query midi://
11
+ unless object? midi [ print as-purple "No MIDI available!" quit]
12
+
13
+ print [as-yellow "Input devices: " length? midi/devices-in ]
14
+ foreach dev midi/devices-in [ print [tab mold dev] ]
15
+ print [as-yellow "Output devices:" length? midi/devices-out ]
16
+ foreach dev midi/devices-out [ print [tab mold dev] ]
17
+
18
+
19
+ *MIDI_message: enum [
20
+ note-off: 2#{ 0000 1000 }
21
+ note-on: 2#{ 0000 1001 }
22
+ poly-aftertouch: 2#{ 0000 1010 }
23
+ control-change: 2#{ 0000 1011 }
24
+ program-change: 2#{ 0000 1100 }
25
+ channel-preasure: 2#{ 0000 1101 }
26
+ pitch_bend-change: 2#{ 0000 1110 }
27
+ ] "MIDI Voice message"
28
+
29
+ *MIDI_message_short: enum [
30
+ Off: 2#{ 0000 1000 }
31
+ On: 2#{ 0000 1001 }
32
+ PoPr: 2#{ 0000 1010 }
33
+ Par: 2#{ 0000 1011 }
34
+ PrCh: 2#{ 0000 1100 }
35
+ ChPr: 2#{ 0000 1101 }
36
+ Pb: 2#{ 0000 1110 }
37
+ ] "MIDI Voice message (short variant)"
38
+
39
+
40
+ process-midi : function [ data [binary! ]] [
41
+ bin: binary data
42
+ while [(length? bin/buffer ) >= 8 ][
43
+ binary/read bin [
44
+ status: UB 4
45
+ channel: UB 4
46
+ byte-1: SI8
47
+ byte-2: SI8
48
+ byte-3: SI8
49
+ time: UI32LE
50
+ ]
51
+ either all [
52
+ byte-3 = 0
53
+ ][
54
+ op: *MIDI_message_short/name status
55
+ prin ajoin [time #" " op " ch=" channel #" " ]
56
+ print ajoin switch /default op [
57
+ Par [["c=" byte-1 " v=" byte-2]]
58
+ Pb ChPr [reduce ["v=" byte-1 + (byte-2 << 7 )]]
59
+ PrCh [["p=" byte-1]]
60
+ ][
61
+ ["n=" byte-1 " v=" byte-2]
62
+ ]
63
+ ][ print "should not happen!" ]
64
+ ]
65
+ ]
66
+
67
+ close-midi : does [
68
+ try [close midi-out]
69
+ try [close midi-inp]
70
+ wait 0
71
+ ]
72
+
73
+ midi-inp: open midi:1
74
+ midi-out: open [scheme: 'midi device-out: 1 ]
75
+
76
+ midi-out/awake:
77
+ midi-inp/awake: function [event [event! ]][
78
+ switch event/type [
79
+ read [ process-midi read event/port ]
80
+ open [ print ["MIDI port opened!" event/port/spec/ref ] ]
81
+ close [ print ["MIDI port closed!" event/port/spec/ref ] ]
82
+ ]
83
+ true
84
+ ]
85
+
86
+ ;; Play some random modern piano music ;-)
87
+ ;; MIDI input should be printed in the console.
88
+ loop 50 [
89
+ write midi-out rejoin [
90
+ #{ 90 } random 127 50 + random 77 0
91
+ #{ 90 } random 127 50 + random 77 0
92
+ #{ 90 } random 127 50 + random 77 0
93
+ ]
94
+ wait 0.5 + random 0.5
95
+ ]
96
+
97
+ close-midi
98
+
99
+ if system/options/script [ask "DONE" ]
0 commit comments