Excelで超音波テルミンを作成する

ExcelのVBAの機能(ExcelでVisual Basicが使用できる機能)を使用して、NeuroCubeをコントロールするプログラムを作成することができます。
ここでは、Excelを使用して、超音波センサーから取得した値で音楽を演奏するプログラムを紹介します。


セキュリティの変更

メニューの[ツール]->[マクロ]->[セキュリティ]を選択します。
セキュリティレベルで「低」を選択して、OKをクリックします。
(プログラムの作成と実行が終わったら、元のレベルに戻してください。)

ツールバーの表示

Excelのメニューで、[表示]->[ツールバー]->[コントロール ツールボックス]を選択します。

デザインモードへの切り替え

ツールバーの中のデザインモードのアイコンをクリックして、デザインモードに切り替えます。

SimToyOcxの読み込み

Excelでプログラムを作成するの手順に従って、NeuroCubeの操作をするためのシミュレータ、SimToyOcxを読み込みます。


開始ボタンの配置


プログラムを開始するためのボタンを配置します。
ツールバーの中のコマンドボタンのアイコンをクリックします。カーソルが+の形になります。
Excelの画面上をドラッグして、ボタンを配置します。
[Caption]の欄に、「開始」と入力します。

終了ボタンの配置

開始ボタンと同じ要領で、終了ボタンを配置します。
[Caption]の欄に、「終了」と入力します。




プログラムの記述


「ニューロキューブの開始」と表示されているボタンをダブルクリックするなどして、Visual Basicの画面を開きます。
下のように記述します。
Private PlayNote As Byte
Private Running As Boolean

Private Sub CommandButton1_Click()
    Running = True
    MidiInitialize
    MidiProgramChange 10, 0
    ToyOcx1.OpenCom (1)
    ToyOcx1.BindControl
End Sub

Private Sub CommandButton2_Click()
    Running = False
    ToyOcx1.CloseCom
    MidiNoteOff 72, 0
    MidiTerminate
End Sub

Private Sub ToyOcx1_BindComplete()
    ToyOcx1.SetRedirect &HFF
    ToyOcx1.UltSetLevel 0, 0
    ToyOcx1.UltSetMode 0, 2
    RequestStart
End Sub

Private Sub ToyOcx1_BindControlComplete()
    ToyOcx1.AddUlt 0
    ToyOcx1.SetCube
    ToyOcx1.BindBlock
End Sub

Private Sub ToyOcx1_UsonicDistance(ByVal idx As Integer, ByVal val As Long)
    If val <> 9999 And (val \ 10) Mod 127 <> PlayNote Then
        MidiNoteOff PlayNote, 0
        PlayNote = (val \ 10) Mod 63 + 64
        MidiNoteOn PlayNote, 127, 0
    End If
    Application.OnTime (Now() + TimeValue("00:00:01")), "Sheet1.RequestStart"
End Sub

Public Sub RequestStart()
    If Running = True Then
        ToyOcx1.UltReqPos 0
    End If
End Sub

音楽演奏モジュールの追加

ウィンドウの左上のほうに表示されている[VBAProject (Book1.xls)]を右クリックします。
メニューから[挿入]->[標準モジュール]を選択します。
[Module1]が追加されるので、それをダブルクリックします。
以下のプログラムを記述します。

Option Explicit

Public Declare Function midiOutGetNumDevs Lib "winmm" () As Integer
Public Declare Function midiOutOpen Lib "winmm.dll" (lphMidiOut As Long, ByVal uDeviceID As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Public Declare Function midiOutShortMsg Lib "winmm.dll" (ByVal hMidiOut As Long, ByVal dwMsg As Long) As Long
Public Declare Function midiOutReset Lib "winmm.dll" (ByVal hMidiOut As Long) As Long
Public Declare Function midiOutClose Lib "winmm.dll" (ByVal hMidiOut As Long) As Long
Public hMidiDev As Long
Public Const MMSYSERR_NOERROR = 0
Public Const MIDI_EVENT_NOTE_ON = &H90
Public Const MIDI_EVENT_NOTE_OFF = &H80

Public Function MidiInitialize()
    Dim num_device As Integer
    Dim result As Long
    MidiInitialize = False
    num_device = midiOutGetNumDevs()
    If num_device = 0 Then
        MsgBox "使用できるMIDIデバイスがありません."
        Exit Function
    End If
    result = midiOutOpen(hMidiDev, -1, 0, 0, 0)
    If result <> MMSYSERR_NOERROR Then
        MsgBox "MIDIデバイスを使用できません."
        Exit Function
    End If
    MidiInitialize = True
End Function

Public Sub MidiTerminate()
    Dim result As Long
    result = midiOutReset(hMidiDev)
    result = midiOutClose(hMidiDev)
End Sub

Public Sub MidiNoteOn(note As Byte, velocity As Byte, chanel As Byte)
    Dim result As Long
    Dim midi_event As Long
    midi_event = velocity * &H10000 + note * &H100 + MIDI_EVENT_NOTE_ON + chanel
    result = midiOutShortMsg(hMidiDev, midi_event)
End Sub

Public Sub MidiNoteOff(note As Byte, chanel As Byte)
    Dim result As Long
    Dim midi_event As Long
    midi_event = note * &H100 + MIDI_EVENT_NOTE_OFF + chanel
    result = midiOutShortMsg(hMidiDev, midi_event)
End Sub

Public Sub MidiProgramChange(prog As Byte, chanel As Byte)
    Dim result As Long
    Dim midi_event As Long
    midi_event = prog * &H100 + &HC0 + chanel
    result = midiOutShortMsg(hMidiDev, midi_event)
End Sub


ウィンドウの左上のほうに表示されている[表示 Microsoft Excel]のアイコンをクリックして、Excelの画面に戻ります。

デザインモードの終了

ツールバーの中のデザインモードの終了アイコンをクリックして、デザインモードを終了します。

プログラムの実行

「開始」と表示されているボタンをクリックします。
(自動でブロックを接続する方法を選択した場合は、接続するブロックを指定するウィンドウが表示されます。
「個別にブロックを指定」を選択し、超音波センサーブロックの0を選択します。)
カーネルブロックと超音波センサーブロックのウィンドウが表示されます。
超音波センサーブロックのスクロールバーを動かすと、音なります。
「終了」と表示されているボタンをクリックします。