MIDI IN

Discussions related to sound, music, video and other multimedia applications
kittertonics
Posts: 3
Joined: Sun 27 May 2018, 10:06

MIDI IN

Post by kittertonics »

Hi,

Couple of related questions (thanks in advance for any answers).

Q1: In previous posts I saw mention of a program called MIDIIN.BBC which is an assembler routine for reading incoming midi events. Does anyone have a copy of this they could share with me/point me in the direction to find it. The code used to be here but link no longer works:

http://groups.yahoo.com/group/bb4w/file ... MIDIIN.BBC

Q2: There is a discussion of MIDI IN here:

https://groups.io/g/bb4w/message/14024? ... ,0,1142294

The thread includes this example posted by Richard and I wondered if there was any advice on the lines below where &#92 returns as bad hex/binary

SYS FN_syscalls("midiInOpen"), ^hMidiIn%, 0, \
\ FN_callback(FNmidiInProc(), 5), 0, _CALLBACK_FUNCTION


The Example....

REM!WC Windows Constants
MIM_CLOSE = &3C2
MIM_DATA = &3C3
MIM_ERROR = &3C5
MIM_LONGDATA = &3C4
MIM_LONGERROR = &3C6
MIM_MOREDATA = &3CC
MIM_OPEN = &3C1
_CALLBACK_FUNCTION = &30000

INSTALL @lib$+"CALLBACK" : REM Must be v3.2 or later

SYS FN_syscalls("midiInOpen"), ^hMidiIn%, 0, \
\ FN_callback(FNmidiInProc(), 5), 0, _CALLBACK_FUNCTION
IF FN_sysresult ERROR 0, "Could not open MIDI input"

SYS FN_syscalls("midiInStart"), hMidiIn%
IF FN_sysresult ERROR 0, "Could not start MIDI input"

Abort% = FALSE
ON CLOSE Abort% = TRUE : RETURN
ON ERROR Abort% = TRUE : SYS "MessageBox", @hwnd%, REPORT$, 0, 0

REPEAT
WAIT 0
UNTIL Abort%

SYS FN_syscalls("midiInStop"), hMidiIn%
IF FN_sysresult ERROR 0, "Could not stop MIDI input"

SYS FN_syscalls("midiInClose"), hMidiIn%
IF FN_sysresult ERROR 0, "Could not close MIDI input"

QUIT

DEF FNmidiInProc(hMidiIn%, wMsg%, dwInstance%, dwParam1%, dwParam2%)
CASE wMsg% OF
WHEN MIM_OPEN:
PRINT "MIDI opening"
WHEN MIM_CLOSE:
PRINT "MIDI closing"
WHEN MIM_DATA:
PRINT "MIDI data received"
OTHERWISE:
PRINT "Another MIDI message received"
ENDCASE
= 0[/font][/font][/font]

Many thanks!

Kit

DDRM
Posts: 396
Joined: Mon 02 Apr 2018, 18:04

Re: MIDI IN

Post by DDRM »

Hi Kit,

I found a copy of Midiin, and Richard has given it a check, and it works fine with the current version of BB4W and Windows10. Hope that's helpful.

I've also stuck a link in the files section of the groups.io site: you'll probably need to be logged in to access it:

https://groups.io/g/bb4w/files/Multimedia/MIDIIN.BBC

Best wishes,

D

Code: Select all

      REM. MIDI input test program, Richard Russell 12-Apr-2005

      ON CLOSE PROCcleanup : QUIT
      ON ERROR SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : QUIT

      DIM MidiQ%(100,1) : REM. Queue for MIDI input data

      hMidiIn% = FNinitMidiIn(MidiQ%())
      IF hMidiIn% = 0 ERROR 100, "Failed to open MIDI input"

      SYS "midiOutOpen", ^hMidiOut%, -1, 0, 0, 0
      IF hMidiOut% = 0 ERROR 100, "Failed to open MIDI output"

      SYS "midiInStart", hMidiIn%

      REPEAT
        IF FNreadMidiIn(MidiQ%(), Message%, Timestamp%) THEN
          SYS "midiOutShortMsg", hMidiOut%, Message%
        ENDIF
        SYS "Sleep", 0
      UNTIL FALSE

      END

      REM. Open MIDI input, returns handle
      DEF FNinitMidiIn(midiq%())
      IF DIM(midiq%())<>2 OR DIM(midiq%(),2)<>1 ERROR 100, "Incorrect queue dimensions"
      midiq%(0,0) = 1
      LOCAL P%, pass%, callback%, hMidiIn%
      DIM callback% 50
      FOR pass% = 0 TO 2 STEP 2
        P% = callback%
        [OPT pass%
        mov eax,[esp+8]  ; wMsg
        cmp eax,963      ; = MIM_DATA?
        jnz callexit
        mov edx,^midiq%(0,0)
        mov ecx,[edx]    ; Queue pointer
        mov eax,[esp+16] ; dwMidiMessage
        mov [edx+8*ecx],eax
        mov eax,[esp+20] ; dwTimestamp
        mov [edx+8*ecx+4],eax
        inc ecx          ; Increment pointer
        cmp ecx,[edx-8]
        jc  update
        mov ecx,1        ; Wrap back to 1
        .update
        mov [edx],ecx    ; Update pointer
        .callexit
        ret 20
        ]
      NEXT pass%
      SYS "midiInOpen", ^hMidiIn%, 0, callback%, 0, &30000 : REM CALLBACK_FUNCTION
      = hMidiIn%

      REM. Read MIDI input data, returns TRUE if new data
      DEF FNreadMidiIn(midiq%(), RETURN message%, RETURN timestamp%)
      PRIVATE rptr%
      IF rptr% = 0 rptr% = 1
      IF rptr% = midiq%(0,0) THEN = FALSE
      message% = midiq%(rptr%,0)
      timestamp% = midiq%(rptr%,1)
      rptr% = (rptr% MOD DIM(midiq%(),1)) + 1
      = TRUE

      REM. Close MIDI devices
      DEF PROCcleanup
      hMidiIn% += 0   : IF hMidiIn%  THEN
        SYS "midiInStop", hMidiIn%
        SYS "midiInClose", hMidiIn%
      ENDIF
      hMidiOut% += 0  : IF hMidiOut% SYS "midiOutClose", hMidiOut%
      ENDPROC


kittertonics
Posts: 3
Joined: Sun 27 May 2018, 10:06

Re: MIDI IN

Post by kittertonics »

Many thanks "DDRM" (sorry don't know your real name!) and a big thanks to Richard for checking the code.

It works perfectly on Windows 10 and has allowed my project to progress.

best wishes

Kit