単純に鍵盤部分のみの取得。
キーボードやピアノを題材にした音ゲーとか作れそう!斬新!(棒)
単純に鍵盤部分のみの取得。
キーボードやピアノを題材にした音ゲーとか作れそう!斬新!(棒)
; KORGのnanoKEY2でしか動作確認していないのでそこんとこよろしく
; 別にこれ↓やっておく必要ないんだけど渡された数値表示するよりはわかりやすいかと
sdim code,64,128
code(0x0) = "c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#"
code(0x10) = "e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g "
code(0x20) = "g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b "
code(0x30) = "c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#"
code(0x40) = "e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g "
code(0x50) = "g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b "
code(0x60) = "c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#"
code(0x70) = "e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g "
repeat length(code)
code(cnt)=code(cnt)+" ("+(cnt/12-3)+")"
loop
#define CALLBACK_NULL 0x00000000
#define CALLBACK_FUNCTION 0x00030000
#define MMSYSERR_NOERROR 0x0
#define MIM_DATA 0x3C3
#define MIM_ERROR 0x3C5
#define MIM_LONGDATA 0x3C4
title "MIDIコントローラの入力取得"
#include "hscallbk.as" ;ちょくとさんのコールバックプラグイン
#include "winmm.as"
#uselib ""
#func clbkGetMidi "" int,int,int,int,int
md_getmax = 24 ; 同時認識最大キー数
dim md_current,md_getmax
repeat md_getmax
md_current(cnt)=-1
loop
onexit *lEnd
textMidiInfo = "" ; 画面に表示させる情報
md_id = 0 ; とりあえず0番目のデバイスを選択
md_hnd = 0 ; ハンドル
; 有効なデバイス数を取得
midiInGetNumDevs
md_cnt = stat
if md_cnt == 0 {
dialog "接続されていません"
goto *lEnd
}
; デバイスの情報を取得
dim md_caps,11
midiInGetDevCaps md_id, varptr(md_caps), 44
md_caps_mid = md_caps(0) & 0xFF
md_caps_pid = (md_caps(0)>>8) & 0xFF
md_caps_ver = md_caps(1)
sdim md_caps_name,32
memcpy md_caps_name, md_caps, 32, 0, 8
; デバイスの情報を表示
font "meiryo",14
objmode 2,1
objsize 100,30
pos ginfo_winx-110,10
button gosub "リセット",*lMidiReset
pos 10, 10
mes "wMid : "+md_caps_mid
mes "wPid : "+md_caps_pid
mes "vDriverVersion : "+strf("%x",md_caps_ver)
mes "szPname : "+md_caps_name
; コールバック関数登録
setcallbk procGetMidi, clbkGetMidi, *lGetMidi
; 受付開始
gosub *lMidiOpen
stop
; デバイスの入力受け付け開始
*lMidiOpen
; デバイスを開く
midiInOpen varptr(md_hnd), md_id, varptr(procGetMidi), 0, CALLBACK_FUNCTION
textMidiInfo = "\nmidiOpen : "+stat+"\nHndle : "+md_hnd
if stat != MMSYSERR_NOERROR {
dialog "midiInエラー"
goto *lEnd
}
; デバイスの使用開始
midiInStart md_hnd
gosub *lDrawMidiInfo
return
; デバイスの入力受け付け停止、情報リセット、閉じる
*lMidiClose
if md_hnd!=0 {
midiInStop md_hnd
midiInReset md_hnd
midiInClose md_hnd
}
return
; 意図的なリセット
; リセット直後に入力があるような状態は避けてください
*lMidiReset
gosub *lMidiClose
repeat md_getmax
md_current(cnt)=-1
loop
gosub *lMidiOpen
return
; 入力情報の表示
; 単純に textMidiInfo に入っている文字を描画するだけ
*lDrawMidiInfo
redraw 0,0,240,640,480
color 255,255,255 : boxf 0,240,640,480
color 0,0,0
pos 10, 240 : mes "Info : "+textMidiInfo
pos 200, 240 : mes "現在入力中のキー"
repeat md_getmax
if md_current(cnt)!=-1{
mes ""+code(md_current(cnt))
}
if (cnt\8)==7 : pos ginfo_cx+80,260
loop
redraw 1,0,240,640,480
return
; コールバック
; CALLBACK MidiInProc(
; HMIDIIN hMidiIn,
; UINT wMsg,
; DWORD dwInstance,
; DWORD dwParam1,
; DWORD dwParam2
; )
*lGetMidi
clbk_md_hnd = callbkarg(0)
clbk_md_msg = callbkarg(1)
clbk_md_ins = callbkarg(2)
clbk_md_prm1 = callbkarg(3)
clbk_md_prm2 = callbkarg(4)
textMidiInfo = ""
if clbk_md_hnd == md_hnd {
; エラー
if clbk_md_msg == MIM_ERROR {
textMidiInfo = "\nエラー"
textMidiInfo+= "\nParam1 : " + strf("0x%X",clbk_md_prm1)
textMidiInfo+= "\nParam2 : " + strf("0x%X",clbk_md_prm2)
gosub *lMidiReset
; 情報取得
} else:if clbk_md_msg == MIM_DATA {
textMidiInfo+= "\nMIM_DATA"
textMidiInfo+= "\nMsg : " + strf("0x%X",clbk_md_msg)
textMidiInfo+= "\nInstance : " + clbk_md_ins
textMidiInfo+= "\nParam1 : " + strf("0x%X",clbk_md_prm1)
textMidiInfo+= "\nParam2 : " + clbk_md_prm2+" ms"
textMidiInfo+= "\n"
; この辺はもしかするとデバイスによって異なるかも
md_get_code = (clbk_md_prm1>>8) & 0xFF ; 押したキー
md_get_state = (clbk_md_prm1)>>4 & 0xF ; キーの押下状態
md_get_gain = (clbk_md_prm1>>16) & 0xFF ; 押下した強さ
; 表示用に内容解析
textMidiInfo+= "\n音 : "+code(md_get_code)
if md_get_state == 9 {
textMidiInfo+= "\n押した"
_flag = 0
_cur = -1
repeat md_getmax
if md_current(cnt)==md_get_code {
_flag = 1
} else:if _cur==-1 && md_current(cnt)==-1 {
_cur = cnt
}
if _flag==1 && _cur!=-1 : break
loop
if _flag == 0 && _cur!=-1 {
md_current(_cur) = md_get_code
}
} else:if md_get_state == 8 {
textMidiInfo+= "\n離した"
repeat md_getmax
if md_current(cnt)==md_get_code {
md_current(cnt) = -1
}
loop
}
textMidiInfo+= "\n強さ : "+strf("%d%%",md_get_gain*100/127)
}
}
gosub *lDrawMidiInfo
return
; 終了
*lEnd
gosub *lMidiClose
end