Get MIDI Pad Keypressed

Just starting out? Need help? Post your questions and find answers here.
hub73
User
User
Posts: 10
Joined: Thu Feb 24, 2022 11:59 pm

Get MIDI Pad Keypressed

Post by hub73 »

Hello.
i've an Eagletone Tinypad PAD USB connected to my PC (Windows 10)
I only want to determine which key (pad) is pressed to trigger a sound in my web radio program. (without velocity). Do you have a recent code snippet to do this ? I searched the forum but nothing really worked in my case. Thank you !
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Get MIDI Pad Keypressed

Post by blueb »

A couple of months ago, I purchased a Behringer X-Touch MIDI keyboard to use with flight simulation.

I discovered PB MIDI Keyboard - by Einander and modified it to see what keypresses did to the X-Touch.

Maybe this will work for you...

Code: Select all

; =================================================================
;     File Name:    XTouch_MIDI.pbi
;   Description:    A Midi tool to access XPlane and Behringer's X-Touch Mini keyboard
;        Author:    Blueb
;          Date:    June 23, 2022
;   
; =================================================================
; Original file was from Einander 
; PB MIDI Keyboard  - by Einander
; Updated for PB 5.x
; Improved PC Keyboard input
; New General MIDI Menu
; forum: https://www.purebasic.fr/english/viewtopic.php?p=407609#p407609    
; =================================================================

;
Structure MIDI
  MIDIIn.A
  MIDIOut.A
  Stat.A
  Dat1.A
  Dat2.A
EndStructure

Global _MIDI.MIDI,_hMIDIIn,_HMIDIout

Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1.q, D2.q) ; get NoteOn,NoteOff)
 Protected ans.s
  With _MIDI  ; structure above
    Select WMsg    ; process some MIDI in events; here you can add more events
       Case #MM_MIM_DATA ; 963
          
          \Stat=(D1 >> 8)  & $FF   ;Btn number  
          \Dat1=(D1 >> 16) & $FF   ;127 = ON 0 = OFF
           ;Use Select Case
                        ;           Select \Dat1
                        ;              Case 127
                        ;                 Debug "here is Btn #: " + \Stat + " inside 127"
                        ;                 If \Stat < 8
                        ;                    \Dat1 = 99
                        ;                    Debug \Dat1
                        ;                    Debug \Dat2
                        ;                 EndIf
                        ;               
                        ;           EndSelect      
          If \Dat1 = 127
             Debug \Stat
             Debug \Dat1
             ans.s = "Device (Btn) Number " + Str(\Stat) + " is: ON."
          ElseIf \Dat1 = 0
             Debug \Stat
             Debug \Dat1
             ans.s = "Btn Number " + Str(\Stat) + " is: OFF"
          ElseIf \Dat1 <> 0
             Debug \Stat
             Debug \Dat1
             Debug " not <> zero"
          EndIf
          Debug ans
    EndSelect
  EndWith
EndProcedure

Procedure MIDIinit(*MIDIInProc=-1,Instrument=1) ;MIDIinproc default solo muestra Note on, Note off
  Protected OutDev , InDev
  If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf
  If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
    If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End:  EndIf
  EndIf
  midiOutOpen_(@_HMIDIout, OutDev, 0, 0, 0)
EndProcedure

MIDIinit()



;- ████ TEST AREA ████
;-


EnableExplicit

Define.i MyButton, btnCount, String_0, Event, Exit

OpenWindow(0, 0, 0, 300, 220, "MainWindow", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
MyButton = ButtonGadget(#PB_Any, 150, 20, 50, 50, "Click",#PB_Button_Toggle)
String_0 = StringGadget(#PB_Any, 100, 100, 110, 30, "")

Repeat
  
  event = WaitWindowEvent() ; Level 1
          ; EventWindow()   ; Level 2  (only needed for Multi-Windows)
  Select event
    Case #PB_Event_Gadget
       Select EventGadget() ; level 3 - Gadget/Object
         Case MyButton
           btnCount = btnCount + 1
           SetGadgetText(String_0, Str(btnCount))
       EndSelect
       
     Case #PB_Event_CloseWindow
       Exit = #True
       
  EndSelect
   
Until Exit

; =========================

- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
hub73
User
User
Posts: 10
Joined: Thu Feb 24, 2022 11:59 pm

Re: Get MIDI Pad Keypressed

Post by hub73 »

Many thanks for your code blueb. It works too with mine midi controler !
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Get MIDI Pad Keypressed

Post by blueb »

Tahnks, glad it worked.

I believe most MIDI devices should work with this code.
- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
hub73
User
User
Posts: 10
Joined: Thu Feb 24, 2022 11:59 pm

Re: Get MIDI Pad Keypressed

Post by hub73 »

Have you tried to light a pad button from purebasic ?
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Get MIDI Pad Keypressed

Post by blueb »

Sorry, I haven't tried.
The Behringer X-Touch Mini's buttons are backlit, and are lit when the button is 'ON'
- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
hub73
User
User
Posts: 10
Joined: Thu Feb 24, 2022 11:59 pm

Re: Get MIDI Pad Keypressed

Post by hub73 »

Thanks. Have you some code to detect and choose the MIDI device ?
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Get MIDI Pad Keypressed

Post by blueb »

Hi hub73..

Not specifically, but I have used the code below to determine removable devices...

Code: Select all

; =================================================================
;
;        Author:       TassyJim  
;          Date:       January 29th, 2019, 8:16 pm
;       Explain:       I forget who posted it originally but I use this to detect serial port changes.
;           
; Typical Usage:       see: https://www.purebasic.fr/english/viewtopic.php?t=72177
;
;     File Name:       Detect Removeable USB Devices.pb   
; =================================================================

;GENERAL PROCEDURES

#WM_DEVICECHANGE=$219
#DBT_DEVICEARRIVAL=$8000 ; A device has been inserted
#DBT_DEVICEQUERYREMOVE=$8001 ; Permission is requested to remove a device or piece of media.
#DBT_DEVICEQUERYREMOVEFAILED=$8002 ; A request to remove a device or piece of media has been canceled.
#DBT_DEVICEREMOVEPENDING=$8003 ; A device or piece of media is about to be removed. Cannot be denied.
#DBT_DEVICEREMOVECOMPLETE=$8004; A device has been removed.
#DBT_DEVICETYPESPECIFIC=$8005  ; A device-specific event has occurred.
#DBT_DEVNODES_CHANGED=$0007    ; A device has been added to or removed from the system.
#DBT_QUERYCHANGECONFIG=$0017   ; Permission is requested to change the current configuration (dock or undock).
#DBT_USERDEFINED=$FFFF ; The meaning of this message is user-defined.
#DBT_DEVTYP_DEVICEINTERFACE = 5
#DBT_DEVTYP_HANDLE = 6
#DBT_DEVTYP_OEM = 0
#DBT_DEVTYP_PORT = 3
#DBT_DEVTYP_VOLUME = 2
#DBTF_MEDIA = 1
#DBTF_NET = 2

Procedure GetDeviceEvent(WindowID,Message,wParam,lParam)
   ;Callback procedure to catch a removable device event
   Protected ValidEvent = #False
   result = #PB_ProcessPureBasicEvents
   If Message=#WM_DEVICECHANGE
      result = #True
      Select wParam
         Case #DBT_DEVICEARRIVAL
            AddGadgetItem(5, -1,"WM_DEVICECHANGE "+"DBT_DEVICEARRIVAL")
            ValidEvent = #True
         Case #DBT_DEVICEREMOVECOMPLETE
            AddGadgetItem(5, -1,"WM_DEVICECHANGE "+"DBT_DEVICEREMOVECOMPLETE")
            ValidEvent = #True
            Default
            AddGadgetItem(5, -1,"WM_DEVICECHANGE "+StrU(wParam))
      EndSelect
      If ValidEvent = #True
         *pDBHDR.DEV_BROADCAST_HDR=lParam
         Select *pDBHDR\dbch_devicetype
            Case #DBT_DEVTYP_OEM
               *pDBO.DEV_BROADCAST_OEM=lParam
               oemID = *pDBO\dbco_identifier
               AddGadgetItem(5, -1,"Device Change Info "+"dbco_identifier: " + Str(oemID))
            Case #DBT_DEVTYP_PORT
               *pDBP.DEV_BROADCAST_PORT=lParam
               portName$ = PeekS(*pDBP + OffsetOf(DEV_BROADCAST_PORT\dbcp_name))
               AddGadgetItem(5, -1,"Device Change Info "+"dbcp_name : " + portName$)
            Case #DBT_DEVTYP_VOLUME
               *pDBV.DEV_BROADCAST_VOLUME=lParam
               Select *pDBV\dbcv_flags
                  Case #DBTF_MEDIA
                     AddGadgetItem(5, -1,"Device Change Info "+"DBTF_MEDIA")
                  Case #DBTF_NET
                     AddGadgetItem(5, -1,"Device Change Info "+"DBTF_NET")
               EndSelect
            Case #DBT_DEVTYP_DEVICEINTERFACE
               AddGadgetItem(5, -1,"Device Change Info "+"#DBT_DEVTYP_DEVICEINTERFACE")
            Case #DBT_DEVTYP_HANDLE
               AddGadgetItem(5, -1,"Device Change Info "+"#DBT_DEVTYP_HANDLE")
         EndSelect
       EndIf
        SendMessage_(GadgetID(5), #EM_SETSEL, -1, -1)
   EndIf
   ProcedureReturn result 
EndProcedure


;MAIN WINDOW AND CONTROLS
;Main window flags
Flags=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Flags=Flags|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget


;Open the main window
If OpenWindow(0,0,0,600,400,"Removable device test",Flags)
   EditorGadget(5, 8, 8, 500, 350)
EndIf


;Set the callback to catch a removable device event
SetWindowCallback(@GetDeviceEvent())


;MAIN WINDOW EVENT LOOP
Repeat
   event=WaitWindowEvent()
   Select event
      Case #PB_Event_CloseWindow
         ;Program closed
         Exit=1
   EndSelect
Until Exit
- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Post Reply