Page 3 of 3

Posted: Wed Oct 15, 2008 8:17 pm
by noot
hi,

could anyone please help me a bit, I'm trying to get started with this midi in stuff... I found this "Midi_In&Out" example from PureArea, but it hangs with "invalid memory access (read error at address 1)" at the MIDIin procedure. the other example (MidiConnecter.pb) seems to work fine.

i'm connecting midi through a USB adapter, could that be the cause..?

Posted: Wed Oct 15, 2008 9:09 pm
by einander
Here is the simple MIDi In & Out code updated for PB 4.3
I'm using this to get input from my MIDI keyboard, and works OK for me.
Simply run this program and play your MIDI keyboard.

Code: Select all

;MIDI IN & OUT
;By einander - PB 4.30 beta 3 - oct 2008 
;************************************************
;Only works with a MIDI Keyboard attached
;************************************************
Global Chromatic$
Chromatic$="C C#D EbE F F#G AbA BbB C "

Procedure.s MIDI_Note(Note)      ; returns note's name
   ProcedureReturn Mid(Chromatic$,(Note % 12)*2+1,2)
EndProcedure

Procedure MIDIin(hMi, wMsg, dummy,Data1, Data2)
   Select wMsg    ; process MIDI in events
      Case #MM_MIM_DATA
         Status = Data1 & 255
         If Status =144
            Nt=(Data1 >> 8) & 255
            Vel= (Data1 >> 16) & 255
            If Vel
               T$="Note On"
            Else
               T$= "Note Off"
            EndIf
            T$+ " Note : "+MIDI_Note(Nt)+" "+Str(Nt)
            SetWindowTitle(0,T$+ "  Vel : " + Str(Vel))
         EndIf
   EndSelect
EndProcedure
;_______________________________________________________________________________________
OpenWindow(0, x,y,400,0, "PB MIDI Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Instrument=24   ;************* choose here any instrument from 0 to 127 **************
OutDev.L : InDev.L
PokeL(@OutDev, 0)  : PokeL(@InDev, 1)
If MidiInOpen_(@hMi, InDev, @MIDIin(), 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
   If MidiInStart_(hMi) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End:  EndIf
Else
   MessageRequester("Error","Can't open MIDI IN",0) : End
EndIf
MidiOutOpen_(@hMo, OutDev, 0, 0, 0)
midiOutShortMsg_(hMo, 192  | Instrument<<8 )
If hMi And hMo
   If MidiConnect_(hMi, hMo, 0)=0
      SetWindowTitle(0,"MIDI OK! - - - Play MIDI KEYBOARD")
   Else
      MessageRequester("Error","Can't connect MIDI",0) :End:
   EndIf
EndIf

Repeat
   If GetAsyncKeyState_(#VK_ESCAPE) :  Break:EndIf
   EventID.L = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow

MidiDisconnect_(hMi, hMo, 0)
While midiInClose_(hMi) = #MIDIERR_STILLPLAYING : Wend
While midiOutClose_(hMo) = #MIDIERR_STILLPLAYING : Wend
End

Posted: Thu Oct 16, 2008 7:06 pm
by noot
einander wrote:

Code: Select all

Procedure MIDIin(hMi, wMsg, dummy, Data1, Data2)
Ah well, there it was: the code at the PureArea archive says

Code: Select all

Procedure MIDIin(hMi, wMsg, Data1, Data2)
Now it starts up ok, but I don't get anything when I push the keys :(

What I want to do is to trigger and control certain events (not necessarily audio, and in any case not midi) with a midi device... this bit you wrote looks great, but why can't I get it to work :( It's probably something to do with the device..?

Posted: Thu Oct 16, 2008 8:58 pm
by einander
This one reads all the MIDI data, not only Notes.

Code: Select all

;MIDI data reader
; by einander - PB 4.30 - October 2008

Procedure MIDIin(hMi, wMsg, dummy,Data1, Data2)
   Select wMsg    ; process MIDI in events
      Case #MM_MIM_DATA
        SetWindowTitle(0,Str(Data1)+"   "+Str(Data2))
         EndSelect
EndProcedure
;_______________________________________________________________________________________
OpenWindow(0, x,y,400,0, "PB MIDI Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

OutDev.L : InDev.L
PokeL(@OutDev, 0)  : PokeL(@InDev, 1)
If MidiInOpen_(@hMi, InDev, @MIDIin(), 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
   If MidiInStart_(hMi) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End:  EndIf
Else
   MessageRequester("Error","Can't open MIDI IN",0) : End
EndIf
MidiOutOpen_(@hMo, OutDev, 0, 0, 0)
midiOutShortMsg_(hMo, 192  | Instrument<<8 )
If hMi And hMo
   If MidiConnect_(hMi, hMo, 0)=0
      SetWindowTitle(0,"MIDI OK! - - - Enter MIDI data")
   Else
      MessageRequester("Error","Can't connect MIDI",0) :End:
   EndIf
EndIf

Repeat
   If GetAsyncKeyState_(#VK_ESCAPE) :  Break:EndIf
   EventID.L = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow

MidiDisconnect_(hMi, hMo, 0)
While midiInClose_(hMi) = #MIDIERR_STILLPLAYING : Wend
While midiOutClose_(hMo) = #MIDIERR_STILLPLAYING : Wend
End

Posted: Fri Oct 17, 2008 6:42 am
by noot
einander wrote:

Code: Select all

PokeL(@OutDev, 0)  : PokeL(@InDev, 1)
Hey, I changed the InDev value from 1 to 0 and now it works :D

einander, thanks so much for this great stuff - can't wait to start working with this! :)

Posted: Sat Oct 18, 2008 12:09 am
by einander
@noot:
You can replace

Code: Select all

Poke.l(@PutDev)
for

Code: Select all

Outdev=0
the same por InDev. Simpler, thanks to Psychophanta.

With InDev=0 I don't get input from my MIDI Keyboard.
----
I had years ago intentions to explore MIDI to send/receive non musical data, but never had the time to try it.

Please, if you found some light on this, share with us.
Cheers.

Re: Midi Monitor

Posted: Thu Mar 07, 2013 2:08 pm
by lelion
Hi PureBasic Midi people,

Thanks for the awesome midi resource you gave here,
I tried Einander's code on my configuration but it didnt detect any midi connection because I use a direct USB to keyboard as most recent synth's are fitted out with now.

Both Roland Juno G and Kurweil are fitted out with MIDI via USB and the MIDI 5 din plug is only used to chain keyboards and expanders (as a separate midi interface would do).

I'm also using Cakewalk Sonar as main sequencer and it simply came with Roland midi/usb drivers for my windows XP

Before using USB, I was disapointed by windows midi hardware for its terrible latency witch made any serious music creation unpraticable.

Roland (and EMU/Creative) also sells cheap optimised midi usb interface like the UM-2G. A friend of mine just bought it and it comes with optimized drivers that can be downloaded here : http://www.roland.com/support/article/? ... ds&p=UM-2G

My question is :

Does someone have any idea of how midi port can be detected from purebasic while using such a direct usb connection or an interface using such a driver.
Thanks a lot for any research about this. I have the feeling Windows or OSX won't manage real time midi properly and USB synths using MIDI protocol are a standard now

Re: Midi Monitor

Posted: Thu Mar 07, 2013 5:14 pm
by einander
@lelion: this one reads my USB keyboard.

Code: Select all

EnableExplicit
;
Structure MIDIs
  MIDIIn.I
  MIDIOut.I
  Stat.A
  Dat1.A
  Dat2.A
  Ons.I[128] ; to keep Sounding Notes
  Chstep.S  
EndStructure
;
Define Ev
Global _Midi.Midis,_TG,_TGOns,_Quit
Global _CHROMATIC$ = "C C#D EbE F F#G AbA BbB C "            ; mixed # b
;
Macro Mid2(Txt,Pos) :  PeekS(@Txt+Pos-1,2) :EndMacro
;
Macro MIDI2N(Nt) :  Mid2(_Chromatic$,Nt % 12*2+1):EndMacro;  MIDINote name 
;
Procedure$ SBIN(N,Le=32)  :  ProcedureReturn RSet(Bin(N),Le,"0") :EndProcedure 
;
Procedure$ GetOns() ; ret Notes Played From midiKbd
  Protected I,T$
  For I=0 To 127
    If _Midi\Ons[I]
      T$+Midi2N(I)  
    EndIf  
  Next
  ProcedureReturn T$
EndProcedure 
;
Procedure$ Ons2Midiby()
  Protected I,T$
  For I=0 To 127
    If _Midi\Ons[I]
      T$+Chr(I)  
    EndIf  
  Next
  ProcedureReturn T$
EndProcedure 
;
Procedure MIDIInFull(hMidiIn, Msg, Instance, Dat1, Dat2) ; get MIDINotes 
  With _Midi  
    Protected *Mem=@\Ons,A,B
    Select Msg   
      Case #MM_MIM_DATA
        Select Dat1 & $FF
          Case 144   
            \Stat=Dat1 >> 8     ;Note 
            \Dat1=Dat1 >> 16    ;Velocity
            If \Dat1  :  SetGadgetText(_TG,"Note On "+Str(\Stat)+" : "+"Vel "+Str(\Dat1))
              \Ons[\Stat]=1
            Else      :  SetGadgetText(_TG,"Note Off "+Str(\Stat)) 
              \Ons[\Stat]=0
            EndIf
            SetGadgetText(_TGOns,Getons())
          Case 128 
            \Stat=Dat1 >> 8     ;Note 
            \Dat1=Dat1 >> 16    ;Velocity
            \Ons[\Stat]=0
            SetGadgetText(_TG,"Note Off "+Str(\Stat)+" : Vel "+Str(\Dat1))
            SetGadgetText(_TGOns,SBin(PeekL(*Mem+32),12)+Sbin(PeekL(*Mem),12))  
        EndSelect
    EndSelect
  EndWith
EndProcedure
;
Procedure MIDIinitFull(Instrument=0) 
  With _Midi
    If midiInGetNumDevs_()
      If midiInOpen_(@\MidiIN, 0, @MIDIInfull(), 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
        If midiInStart_(\MidiIN) <> #MMSYSERR_NOERROR
          MessageRequester("Error","Can't start MIDI IN",0) 
          End
        EndIf
      Else :  MessageRequester("Error","Can't open MIDI IN",0) 
        End
      EndIf
      midiOutOpen_(@\MidiOUT, 0, 0, 0, 0) 
      midiOutShortMsg_(\MidiOUT, 192 | Instrument<<8 ) ; set instrument
      If \MidiIN And \MidiOUT
        If Not midiConnect_(\MidiIN, \MidiOUT, 0)
          SetGadgetText(_TG, "MIDI setting ready!  Play MIDI Keyboard")
        Else : MessageRequester("Error","Can't connect MIDI",0)
          End
        EndIf
      EndIf
    Else
      MessageRequester("Error","No Midi devices found",0)
      End  
    EndIf
  EndWith
EndProcedure 
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
OpenWindow(0,0,0,400,100,"MIDI Play",#PB_Window_SystemMenu|1)
SetWindowColor(0,$22)
Define Wi=WindowWidth(0), He=WindowHeight(0)
_TG=TextGadget(-1,10,10,Wi-20,24,"")
_TGOns=TextGadget(-1,10,40,Wi-20,24,"")
Define TBVol=TrackBarGadget(-1,10,70,Wi-20,24,0,$Ffff)
SetGadgetState(Tbvol,$FFFF)
MIDIinitFull() 
With _Midi
  midiOutSetVolume_(\MidiOUT,$FFFF)
  Repeat
    If GetAsyncKeyState_(27)&$8000 :_Quit=#True : EndIf
    Ev=WaitWindowEvent()
    If Ev=#PB_Event_Gadget
      Select EventGadget()
        Case TBVol    :  midiOutSetVolume_(\MidiOUT,GetGadgetState(Tbvol))    
      EndSelect
    EndIf
  Until Ev=#PB_Event_CloseWindow Or _Quit
  midiDisconnect_(\MidiIN, \MidiOUT, 0)
  While midiInClose_(\MidiIN) = #MIDIERR_STILLPLAYING : Wend
  While midiOutClose_(\MidiOUT) = #MIDIERR_STILLPLAYING : Wend
  midiOutClose_(\MidiOUT)
EndWith

Re: Midi Monitor

Posted: Thu Mar 07, 2013 8:30 pm
by lelion
einander wrote:@lelion: this one reads my USB keyboard.

Code: Select all

EnableExplicit
;
Thank you so much Einander. You are really amazing in programming ! It works perfectly, even when driver is not activated by sonar (not visible in the icon tray)
I ll take some time to study your code.
Congratulations

Re: Midi Monitor

Posted: Fri Jun 27, 2014 11:52 am
by mpz
Hello to all,

i need for my work a Midi test program for Midi in/Out. I have actualized the code to PB 5.22 and you can choose Midi IN/Out and send midi.

Greetings Michael

Code: Select all

; PowerBasic Example for MIDI In/Out Checker
;
;
; by MPZ June.2014
; for PB 5.22
;

EnableExplicit
;
Structure MIDIs
  MIDIIn.I
  MIDIOut.I
  Stat.A
  Dat1.A
  Dat2.A
  Ons.I[128] ; to keep Sounding Notes
  Chstep.S 
EndStructure
;
Define Ev
Global _Midi.Midis,_TG,_TGOns,_Quit
Global _CHROMATIC$ = "C C#D EbE F F#G AbA BbB C "            ; mixed # b
;
Macro Mid2(Txt,Pos) :  PeekS(@Txt+Pos-1,2) :EndMacro
;
Macro MIDI2N(Nt) :  Mid2(_Chromatic$,Nt % 12*2+1):EndMacro;  MIDINote name
;

Enumeration 100 ; bei vielen Fenstern und Events den Wert 100 erhöhen
  #Window_Selectbox
  #Text_Selectbox1
  #Text_Selectbox2
  #Listview_Selectbox1
  #Listview_Selectbox2
  #Button_Selectbox0
  #Button_Selectbox1
EndEnumeration

#Channel1 = 1
#Channel2 = 2
#Channel3 = 3
#Channel4 = 4
#Channel5 = 5
#Channel6 = 6

Procedure Selectrequester (Selectbox.s,Selecttext1.s,Selecttext2.s,List Mylist1.s(),List Mylist2.s())
  
Protected Return_Selectbox,Return_Selectbox1,Return_Selectbox2, Event, GadgetID,a

Return_Selectbox = -1 ; Fehlerwert = -1

If OpenWindow(#Window_Selectbox,0,0, 430, 178, Selectbox.s,  #PB_Window_SystemMenu | #PB_Window_TitleBar| #PB_Window_ScreenCentered)
  ;If CreateGadgetList(WindowID(#Window_Selectbox))
    TextGadget(#Text_Selectbox1, 10, 10, 150, 14, Selecttext1.s)
    TextGadget(#Text_Selectbox2, 220, 10, 150, 14, Selecttext2.s)
    ListViewGadget(#Listview_Selectbox1, 10, 30, 200, 100)
    ListViewGadget(#Listview_Selectbox2, 220, 30, 200, 100)
    ButtonGadget(#Button_Selectbox0, 270, 140, 70, 23, "Select")
    ButtonGadget(#Button_Selectbox1, 350, 140, 70, 23, "Cancel")
  ;EndIf
EndIf

FirstElement(Mylist1())
For a = 1 To  ListSize(Mylist1())
   AddGadgetItem (#Listview_Selectbox1, -1, Mylist1())   ; definieren des Listview-Inhalts
   NextElement(Mylist1())
Next

FirstElement(Mylist2())
For a = 1 To  ListSize(Mylist2())
   AddGadgetItem (#Listview_Selectbox2, -1, Mylist2())   ; definieren des Listview-Inhalts
   NextElement(Mylist2())
Next

SetGadgetState(#Listview_Selectbox1,0)
SetGadgetState(#Listview_Selectbox2,0)

Repeat ; Start of the event loop
 
  Event = WaitWindowEvent() ; This line waits until an event is received from Windows
  GadgetID = EventGadget() ; Is it a gadget event?
 
  If Event = #PB_Event_Gadget
    If GadgetID = #Button_Selectbox0
       Event = #PB_Event_CloseWindow
       Return_Selectbox1 = GetGadgetState(#Listview_Selectbox1)
       Return_Selectbox2 = GetGadgetState(#Listview_Selectbox2)
    ElseIf GadgetID = #Button_Selectbox1
       Event = #PB_Event_CloseWindow
    EndIf
  EndIf 
Until Event = #PB_Event_CloseWindow ; End of the event loop

CloseWindow(#Window_Selectbox)

Return_Selectbox = Return_Selectbox1 + (Return_Selectbox2 << 8)

ProcedureReturn Return_Selectbox

EndProcedure

Procedure MidiOutMessage(hMidi,iStatus,iChannel,iData1,iData2)
  Protected dwMessage
  dwMessage = iStatus | iChannel | (iData1 << 8 ) | (iData2 << 16)
  ProcedureReturn midiOutShortMsg_(hMidi, dwMessage) ;
EndProcedure

Procedure SetInstrument(channel,instrument)
  MidiOutMessage(_Midi\MidiOUT, $C0,  channel, instrument, 0)
EndProcedure

Procedure PlayNote(channel,Note,velocity)
  MidiOutMessage(_Midi\MidiOUT, $90, channel, Note , velocity)
EndProcedure


Procedure StopNote(channel,Note)
  MidiOutMessage(_Midi\MidiOUT, $90, channel, Note , 0)
EndProcedure

Procedure SendMidi()
  
  Protected a
  
  SetInstrument(#Channel1,25)
  SetInstrument(#Channel2,25)
  SetInstrument(#Channel3,25)
  SetInstrument(#Channel4,25)
 
  For a = 1 To 5
    ; normal sound
    PlayNote(#Channel1,$2D,63)
    PlayNote(#Channel2,$39,63)
    PlayNote(#Channel3,$3C,63)
    PlayNote(#Channel4,$40,63)
   
    Delay (100)
    StopNote(#Channel1,$2D)
    StopNote(#Channel2,$39)
    StopNote(#Channel3,$3C)
    StopNote(#Channel3,$40)
   
    ; this must be a staccato sound
    PlayNote(#Channel1,$39,100)
    PlayNote(#Channel2,$3C,100)
    PlayNote(#Channel3,$40,100)
   
    Delay (30)
    StopNote(#Channel1,$39)
    StopNote(#Channel2,$3C)
    StopNote(#Channel3,$40)
    Delay (20)
   
    ; this must be a muted sound
    PlayNote(#Channel1,$2D,80)
    PlayNote(#Channel2,$30,80)
    PlayNote(#Channel3,$34,80)
   
    Delay (300)
    StopNote(#Channel1,$2D)
    StopNote(#Channel2,$30)
    StopNote(#Channel3,$34 )
    Delay (285)
   
  Next
 
  ; Zurücksetzen der Instrumente
  SetInstrument(#Channel1,0)
  SetInstrument(#Channel2,0)
  SetInstrument(#Channel3,0)
  SetInstrument(#Channel4,0)
  
EndProcedure

Procedure$ SBIN(N,Le=32)
  Protected var$
  var$ = RSet(Bin(N),Le,"0")
  
  If CountString(var$, "0") = Len(var$)
    var$=""
  EndIf  
  
  ProcedureReturn var$
  
EndProcedure
;
Procedure$ GetOns() ; ret Notes Played From midiKbd
  Protected I,T$
  For I=0 To 127
    If _Midi\Ons[I]
      T$+Midi2N(I) 
    EndIf 
  Next
  ProcedureReturn T$
EndProcedure
;
Procedure$ Ons2Midiby()
  Protected I,T$
  For I=0 To 127
    If _Midi\Ons[I]
      T$+Chr(I) 
    EndIf 
  Next
  ProcedureReturn T$
EndProcedure
;
Procedure MIDIInFull(hMidiIn, Msg, Instance, Dat1, Dat2) ; get MIDINotes
  With _Midi 
    Protected *Mem=@\Ons,A,B
    Select Msg   
      Case #MM_MIM_DATA
        Select Dat1 & $FF
          Case 144   
            \Stat=Dat1 >> 8     ;Note
            \Dat1=Dat1 >> 16    ;Velocity
            If \Dat1  :  SetGadgetText(_TG,"Note On "+Str(\Stat)+" : "+"Vel "+Str(\Dat1))
              \Ons[\Stat]=1
            Else      :  SetGadgetText(_TG,"Note Off "+Str(\Stat))
              \Ons[\Stat]=0
            EndIf
            SetGadgetText(_TGOns,Getons())
          Case 128
            \Stat=Dat1 >> 8     ;Note
            \Dat1=Dat1 >> 16    ;Velocity
            \Ons[\Stat]=0
            SetGadgetText(_TG,"Note Off "+Str(\Stat)+" : Vel "+Str(\Dat1))
            SetGadgetText(_TGOns,SBin(PeekI(*Mem+32),12)+Sbin(PeekI(*Mem),12)) 
          Default    
            ;\Stat=Dat1 >> 8     ;Note
            \Dat1=Dat1 >> 16    ;Velocity
            If \Dat1  :  SetGadgetText(_TG,"Controller "+Str(Dat1 & $FF)+": "+Str(\Dat1))
              \Ons[\Stat]=1
            EndIf
            SetGadgetText(_TGOns,Getons())
        EndSelect
    EndSelect
  EndWith
EndProcedure
;
Procedure MIDIinitFull(Instrument=0)
  
  Protected pointer.MidiInCaps,*pointer2.MidiInCaps, count_device, n, MidiIn_device, MidiOut_device,Return_Selectbox
  
  With _Midi
    
      NewList SelectList1.s()
     
      count_device = midiInGetNumDevs_() ; how Many Midi In device?
         
      For n = 1 To count_device 
              midiInGetDevCaps_(n-1,pointer.MidiInCaps,SizeOf(MidiInCaps));
              AddElement(SelectList1())
              SelectList1() = PeekS(@pointer\szPname)
      Next
         
      NewList SelectList2.s()
      
      count_device = midiOutGetNumDevs_(); how Many Midi Out device?
         
      For n = 1 To count_device 
              midiOutGetDevCaps_(n-1,pointer.MidiInCaps,SizeOf(MidiInCaps));
              
              AddElement(SelectList2())
              SelectList2() = PeekS(@pointer\szPname)
      Next
        
      Return_Selectbox = Selectrequester ("Please choose the Midi In/Out Device","Midi In Device","Midi Out Device",SelectList1(),SelectList2())
      
      MidiIn_device = Return_Selectbox & $F ; two informations with one return variable 
      MidiOut_device = (Return_Selectbox & $FF00) >> 8
      
      ;If Midi_device = -1 : 
      ;      MessageRequester("Error","No Midi In devices selected",0)
      ;      End 
      ; EndIf  
       
      If midiInOpen_(@\MidiIN, MidiIn_device, @MIDIInfull(), 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
        If midiInStart_(\MidiIN) <> #MMSYSERR_NOERROR
          MessageRequester("Error","Can't start MIDI IN",0)
          End
        EndIf
      Else :  MessageRequester("Error","Can't open MIDI IN",0)
        End
      EndIf
      
      midiOutOpen_(@\MidiOUT, MidiOut_device, 0, 0, 0)
      midiOutShortMsg_(\MidiOUT, 192 | Instrument<<8 ) ; set instrument
      If \MidiIN And \MidiOUT
        If Not midiConnect_(\MidiIN, \MidiOUT, 0)
          SetGadgetText(_TG, "MIDI setting ready!  Play MIDI Keyboard")
        Else : MessageRequester("Error","Can't connect MIDI",0)
          End
        EndIf
      EndIf
      
      
;    Else
;      MessageRequester("Error","No Midi devices found",0)
;      End 
;    EndIf
  EndWith
EndProcedure

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
OpenWindow(0,0,0,400,140,"MIDI IN/Out Checker (@)MPZ",#PB_Window_SystemMenu|1)
SetWindowColor(0,$22)

Define Wi=WindowWidth(0), He=WindowHeight(0)
_TG=TextGadget(-1,10,10,Wi-20,24,"")
_TGOns=TextGadget(-1,10,40,Wi-20,24,"")

Define TBVol=TrackBarGadget(-1,10,70,Wi-20,24,0,$Ffff)
SetGadgetState(Tbvol,$FFFF)

Define SendMID=ButtonGadget(-1, 10, 104, 200, 20, "Send Midi")

MIDIinitFull()

With _Midi
  midiOutSetVolume_(\MidiOUT,$FFFF)
  Repeat
    If GetAsyncKeyState_(27)&$8000 :_Quit=#True : EndIf
    Ev=WaitWindowEvent()
    If Ev=#PB_Event_Gadget
      Select EventGadget()
        Case TBVol    :  midiOutSetVolume_(\MidiOUT,GetGadgetState(Tbvol)) 
        Case SendMID  : SendMidi()
      EndSelect
    EndIf
  Until Ev=#PB_Event_CloseWindow Or _Quit
  midiDisconnect_(\MidiIN, \MidiOUT, 0)
  While midiInClose_(\MidiIN) = #MIDIERR_STILLPLAYING : Wend
  While midiOutClose_(\MidiOUT) = #MIDIERR_STILLPLAYING : Wend
  midiOutClose_(\MidiOUT)
EndWith


Re: Midi Monitor

Posted: Fri Jan 02, 2015 12:32 am
by ricardo
mpz wrote:Hello to all,

i need for my work a Midi test program for Midi in/Out. I have actualized the code to PB 5.22 and you can choose Midi IN/Out and send midi.

Greetings Michael
This is great, the only problem is that i feel some small delay when using my midi keyboard.

Re: Midi Monitor

Posted: Sat Jan 03, 2015 12:52 pm
by mpz
Hi,

@ricardo

the microsoft synthesizer is in windows build in and used. the synthesizer has a delay from 200 to 400 ms (time of a quarte note). In professional squencing you use a VST instrument an use a ASIO soundcard driver to have only a delay of 10-20ms. In the forum you find a example for a ASIO driver support, the VST Instruments you can find for example here: http://www.plugindex.de/free-vst-plugins/ .

Greetings Michael