Code: Select all
#SingleInstance Force
#NoEnv
SetBatchLines -1
#MaxHotkeysPerInterval 199
nz = 2A.1E.2C.1F.2D.2E.21.2F.22.30.23.31.32.25.33.26.34.35.28.136.1C ; Scan Acodes for Shift+CapsLock rows
KEYS := ".", MidiDevice := 0
Program1 := 16, Program2 := 1
Velocity1 := 64, Velocity2 := 127
BaseNote1 := 60, BaseNote2 := 36 ; C4 = 261.63Hz, C2 = 65.41Hz
OnExit CleanUp
OpenCloseMidiAPI()
h_midiout := midiOutOpen(MidiDevice)
midiOutShortMsg(h_midiout, 191, 1, Program1, 0) ; Program Change
midiOutShortMsg(h_midiout, 191, 2, Program2, 0) ; Program Change
wid := 45
Gui, +Border
gui, color, 331a00
gui, add, edit, x0 y0 w0 h0 vKEYS,
gui, font, s18 cWhite bold, Verdana
gui, add, text, x400 y5, YAMAHA
gui, font, s10 cWhite, Verdana
Gui, add, text, x+170 y12, Program 1
gui, add, progress, x+10 y14 w12 h12 Background000000 c00ff00 vprog1, 100
Gui, add, text, x+50 y12, Program 2
gui, add, progress, x+10 y14 w12 h12 Background000000 c00ff00 vprog2, 0
Loop, 21
Gui, add, progress, % "y50 x" wid * (A_Index-1) " +Border +BackgroundTrans Backgroundffff80 cffffb3 w45 h200 vWhite" A_Index, 100
gui, add, progress, % "y50 x" wid * 2 / 3 " Background333333 c000000 w30 h130 vBlack1", 100
gui, add, progress, % "y50 x" wid * 5 / 3 " Background333333 c000000 w30 h130 vBlack2", 100
gui, add, progress, % "y50 x" wid * 11 / 3 " Background333333 c000000 w30 h130 vBlack3", 100
gui, add, progress, % "y50 x" wid * 14 / 3 " Background333333 c000000 w30 h130 vBlack4", 100
gui, add, progress, % "y50 x" wid * 17 / 3 " Background333333 c000000 w30 h130 vBlack5", 100
gui, add, progress, % "y50 x" wid * 23 / 3 " Background333333 c000000 w30 h130 vBlack6", 100
gui, add, progress, % "y50 x" wid * 26 / 3 " Background333333 c000000 w30 h130 vBlack7", 100
gui, add, progress, % "y50 x" wid * 32 / 3 " Background333333 c000000 w30 h130 vBlack8", 100
gui, add, progress, % "y50 x" wid * 35 / 3 " Background333333 c000000 w30 h130 vBlack9", 100
gui, add, progress, % "y50 x" wid * 38 / 3 " Background333333 c000000 w30 h130 vBlack10", 100
gui, add, progress, % "y50 x" wid * 44 / 3 " Background333333 c000000 w30 h130 vBlack11", 100
gui, add, progress, % "y50 x" wid * 47 / 3 " Background333333 c000000 w30 h130 vBlack12", 100
gui, add, progress, % "y50 x" wid * 53 / 3 " Background333333 c000000 w30 h130 vBlack13", 100
gui, add, progress, % "y50 x" wid * 56 / 3 " Background333333 c000000 w30 h130 vBlack14", 100
gui, add, progress, % "y50 x" wid * 59 / 3 " Background333333 c000000 w30 h130 vBlack15", 100
Gui, Show, w945 h250, My Piano
#IfWinActive My Piano ahk_class AutoHotkeyGUI
Loop Parse, nz, . ; Shift-Z key row
{
n%A_LoopField% := A_Index - 1
c%A_LoopField% := 2 ; note played in channel 2
HotKey sc%A_LoopField%, KEY
HotKey sc%A_LoopField% UP, KEYup
}
return
Up::
Program2 += Program2 > 126 ? 0 : 1
GuiControl, , prog1, 0
GuiControl, , prog2, 100
midiOutShortMsg(h_midiout, 191, 2, Program2, 0) ; Program Change
Return
Down::
Program2 -= Program2 < 1 ? 0 : 1
GuiControl, , prog1, 100
GuiControl, , prog2, 0
midiOutShortMsg(h_midiout, 191, 2, Program2, 0) ; Program Change
Return
KEY:
k := SubStr(A_ThisHotKey,3)
IfInString KEYS, %k%, Return
IfEqual n%k%,, Return
channel := c%k%, KEYS .= k . "."
Piano_Keyboard()
midiOutShortMsg(h_midiout, 143, channel, BaseNote%channel% + n%k%, Velocity%channel%) ; NoteOn
GuiControl,,KEYS, %KEYS%
Key_Item =
Return
KEYup:
k := SubStr(A_ThisHotKey,3,StrLen(A_ThisHotKey)-5)
channel := c%k%
StringReplace KEYS, KEYS, .%k%., ., All
Piano_Keyboard()
midiOutShortMsg(h_midiout, 127, channel, BaseNote%channel% + n%k%, Velocity%channel%) ; NoteOff
GuiControl,,KEYS, %KEYS%
Key_Item =
Return
Piano_Keyboard(){
global
if (A_ThisHotKey = "sc1E" or A_ThisHotKey = "sc1E UP"){
Key_Item := "Black6"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc1F" or A_ThisHotKey = "sc1F UP"){
Key_Item := "Black7"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc21" or A_ThisHotKey = "sc21 UP"){
Key_Item := "Black8"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc22" or A_ThisHotKey = "sc22 UP"){
Key_Item := "Black9"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc23" or A_ThisHotKey = "sc23 UP"){
Key_Item := "Black10"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc25" or A_ThisHotKey = "sc25 UP"){
Key_Item := "Black11"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc26" or A_ThisHotKey = "sc26 UP"){
Key_Item := "Black12"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc28" or A_ThisHotKey = "sc28 UP"){
Key_Item := "Black13"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc1C" or A_ThisHotKey = "sc1C UP"){
Key_Item := "Black14"
if A_ThisHotKey not contains UP
GuiControl, , %Key_Item%, 0
if A_ThisHotKey contains UP
GuiControl, , %Key_Item%, 100
}
if (A_ThisHotKey = "sc2A" or A_ThisHotKey = "sc2A UP"){
Key_Item := "White8"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black6, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black6, 100
}
}
if (A_ThisHotKey = "sc2C" or A_ThisHotKey = "sc2C UP"){
Key_Item := "White9"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black6, 100
GuiControl, , Black7, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black6, 100
GuiControl, , Black7, 100
}
}
if (A_ThisHotKey = "sc2D" or A_ThisHotKey = "sc2D UP"){
Key_Item := "White10"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black7, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black7, 100
}
}
if (A_ThisHotKey = "sc2E" or A_ThisHotKey = "sc2E UP"){
Key_Item := "White11"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black8, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black8, 100
}
}
if (A_ThisHotKey = "sc2F" or A_ThisHotKey = "sc2F UP"){
Key_Item := "White12"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black8, 100
GuiControl, , Black9, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black8, 100
GuiControl, , Black9, 100
}
}
if (A_ThisHotKey = "sc30" or A_ThisHotKey = "sc30 UP"){
Key_Item := "White13"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black9, 100
GuiControl, , Black10, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black9, 100
GuiControl, , Black10, 100
}
}
if (A_ThisHotKey = "sc31" or A_ThisHotKey = "sc31 UP"){
Key_Item := "White14"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black10, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black10, 100
}
}
if (A_ThisHotKey = "sc32" or A_ThisHotKey = "sc32 UP"){
Key_Item := "White15"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black11, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black11, 100
}
}
if (A_ThisHotKey = "sc33" or A_ThisHotKey = "sc33 UP"){
Key_Item := "White16"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black11, 100
GuiControl, , Black12, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black11, 100
GuiControl, , Black12, 100
}
}
if (A_ThisHotKey = "sc34" or A_ThisHotKey = "sc34 UP"){
Key_Item := "White17"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black12, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black12, 100
}
}
if (A_ThisHotKey = "sc35" or A_ThisHotKey = "sc35 UP"){
Key_Item := "White18"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black13, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black13, 100
}
}
if (A_ThisHotKey = "sc136" or A_ThisHotKey = "sc136 UP"){
Key_Item := "White19"
if A_ThisHotKey not contains UP
{
GuiControl, , %Key_Item%, 0
GuiControl, , Black13, 100
GuiControl, , Black14, 100
}
if A_ThisHotKey contains UP
{
GuiControl, , %Key_Item%, 100
GuiControl, , Black13, 100
GuiControl, , Black14, 100
}
}
}
OpenCloseMidiAPI() { ; at the beginning to load, at the end to unload winmm.dll
Static hModule
If hModule
DllCall("FreeLibrary", UInt,hModule), hModule := ""
If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) {
MsgBox Cannot load libray winmm.dll
ExitApp
}
}
midiOutOpen(uDeviceID = 0) { ; Open midi port for sending individual midi messages --> handle
strh_midiout = 0000
result := DllCall("winmm.dll\midiOutOpen", UInt,&strh_midiout, UInt,uDeviceID, UInt,0, UInt,0, UInt,0, UInt)
If (result or ErrorLevel) {
MsgBox There was an error opening the midi port.`nError code %result%`nErrorLevel = %ErrorLevel%
Return -1
}
Return NumGet(&strh_midiout)
}
midiOutShortMsg(h_midiout, Event, Channel, Param1, Param2) {
; Event: NoteOn 143, NoteOff 127, CC 175, PolyAT 159, ChanAT 207, PChange 191, Wheel 223
result := DllCall("winmm.dll\midiOutShortMsg", UInt,h_midiout, UInt, Event+Channel|(Param1<<8)|(Param2<<16), UInt)
If (result or ErrorLevel) {
MsgBox Error sending the midi event: (%result%`, %ErrorLevel%)
Return -1
}
}
midiOutClose(h_midiout) { ; Close MidiOutput
Loop {
result := DllCall("winmm.dll\midiOutClose", UInt,h_midiout)
If !(result or ErrorLevel)
Return
If (A_Index > 3) {
MsgBox Error [%result%]-[%ErrorLevel%] in closing the midi output port.`nThere may still be midi events being processed.
Return -1 ; result MIDIERR_STILLPLAYING 65, MMSYSERR_INVALHANDLE 5, MMSYSERR_NOMEM 7
}
Sleep 500
}
}
MidiOutsEnumerate() { ; Returns #midi output devices, creates global array MidiOutPortName with their names
Local NumPorts, PortID
VarSetCapacity(MidiOutCaps, 50, 0)
NumPorts := DllCall("winmm.dll\midiOutGetNumDevs") ; #midi output devices on system, first device ID = 0
Loop %NumPorts% {
PortID := A_Index -1
result := DllCall("winmm.dll\midiOutGetDevCapsA", UInt,uDeviceID, UInt,&MidiOutCaps, UInt,50, UInt)
If (result OR ErrorLevel) {
MsgBox Error %result% (EL = %ErrorLevel%) in retrieving the name of midi output %uDeviceID%
Return -1
}
VarSetCapacity(PortName, 32) ; PortNameSize 32
DllCall("RtlMoveMemory", Str,PortName, Uint,&MidiOutCaps+8, Uint,32) ; PortNameOffset 8, PortNameSize 32
MidiOutPortName%PortID% := PortName
}
Return NumPorts
}
CleanUp:
midiOutClose(h_midiout)
OpenCloseMidiAPI()
ExitApp
/* MidiStatus byte: http://www.harmony-central.com/MIDI/Doc/table1.html
MIDIOUTCAPS struct
WORD wMid;
WORD wPid;
MMVERSION vDriverVersion;
CHAR szPname[MAXPNAMELEN];
WORD wTechnology;
WORD wVoices;
WORD wNotes;
WORD wChannelMask;
DWORD dwSupport;
*/