Piano Player

Post your working scripts, libraries and tools
euras
Posts: 348
Joined: 05 Nov 2015, 12:56

Piano Player

08 Mar 2018, 15:24

I'm not an author (it's Lazsko I think) of that functionality, I just made the GUI for that functionality and give that player for you.

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;
*/
rommmcek
Posts: 391
Joined: 15 Aug 2014, 15:18

Re: Piano Player

08 Mar 2018, 23:19

Great GUI! (I miss mouse click functionality)

P.s.: I knew this Laszlo's work, but I followed his example to load song into buffer. I wasn't able to enlarge the buffer and couldn't load entire lengthy song. Now I have different approach and was tempted to try the same with this function too. (It's a quick adaptation and may contain bugs!)
Attachments
rihanna-man_down.ahk
(831.99 KiB) Downloaded 132 times
Last edited by rommmcek on 13 Mar 2018, 15:24, edited 1 time in total.
User avatar
elModo7
Posts: 36
Joined: 01 Sep 2017, 02:38

Re: Piano Player

09 Mar 2018, 06:42

Plays nice, thanks for sharing! :)
:beer:

Return to “Scripts and Functions”

Who is online

Users browsing this forum: _Ne0n, hoppfrosch, itz4sking, nnnik and 21 guests