最近突然想到,以前曾經接觸過Squeak Smalltalk,在它內建的class庫中,正好有SimpleMIDIPort這個class可以讓我們接收與發送MIDI event。
只要靠SimpleMIDIPort,我們就可以寫個簡單的程式,送些MIDI event到外接的MIDI設備,看看電腦可以對該MIDI設備做到什麼程度的控制。
於是筆者就在這裡記下一段簡單的Smalltalk程式碼,方便之後做些測試。
| midiPortNum midiPort | midiPortNum := SimpleMIDIPort outputPortNumFromUser. midiPort := SimpleMIDIPort openOnPortNumber: midiPortNum. Transcript show: midiPortNum; cr; show: midiPort; cr. midiPort midiCmd: 16rC0 channel: 0 byte: 90. "change program" midiPort midiCmd: 16r90 channel: 0 byte: 60 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 60 byte: 16r0. midiPort midiCmd: 16r90 channel: 0 byte: 60 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 60 byte: 16r0. midiPort midiCmd: 16r90 channel: 0 byte: 67 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 67 byte: 16r0. midiPort midiCmd: 16r90 channel: 0 byte: 67 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 67 byte: 16r0. midiPort midiCmd: 16r90 channel: 0 byte: 69 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 69 byte: 16r0. midiPort midiCmd: 16r90 channel: 0 byte: 69 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 69 byte: 16r0. midiPort midiCmd: 16r90 channel: 0 byte: 67 byte: 16r7F. (Delay forSeconds: 0.5) wait. midiPort midiCmd: 16r80 channel: 0 byte: 67 byte: 16r0. midiPort midiCmd: 16rC0 channel: 0 byte: 0. "reset program" midiPort midiOutput: (#(16rFF) asByteArray). "system reset"
以上的程式範例會用120bpm的速度控制MIDI設備的Channel 0放送Twinkle Twinkle Little Star的前7個主音。
如果有現成的MIDI檔的話,也可用下面的程式開啟MIDI檔,並輸出到作業系統提供的MIDI裝置。
| file score scorePlayer midiPortNum | file := FileStream fileNamed: 'C:\Windows\Media\flourish.mid'. file binary. score := ((MIDIFileReader new) readMIDIFrom: file) asScore. file close. scorePlayer := ScorePlayer onScore: score. midiPortNum := SimpleMIDIPort outputPortNumFromUser. scorePlayer openMIDIPort: midiPortNum. scorePlayer reset. scorePlayer startMIDIPlaying. (Delay forSeconds: 60.0) wait. scorePlayer stopMIDIPlaying.
之後想要測什麼就可以用這些template程式碼起頭了。