Jump to content

COM Midi-OX Scripting


ptrex
 Share

Recommended Posts

What is MIDI-Scripting?

First, a little explanation on what you can do with MIDI-Scripts. 
You can write a script that tells MIDI Device how to act based on the MIDI input message it receives.

Or the other way around you can send MIDI messages from a MIDI Device to a MIDI compatible software,
And script the behavior accordingly.

Writing your own MIDI-Script allows you to execute custom actions, such as play/pause, start/stop recording, ....


MIDI protocol

The protocol is based on messages.
A MIDI message is an instruction that controls some aspect of the receiving Device.

You have short messages (3 bytes) and system Exclusive messages (byte arrays).
the exclusive messages are also called SysEx messages.

Why needing this?

Apart from controlling music device, you can also you this controlling other types of devices and even software.

Most of them are music media related.

 

AutoIt MIDI software :

- MIDI library
- Peace Equalizer

 

MIDI-OX Com library :

MIDI-OX is a versatile utility that is great for troubleshooting MIDI hardware devices
It also acts as a System Exclusive SysEx librarian, which allows you to send (dump) and receive SysEx data

Nevertheless this is quite old software, it is still alive and kicking.

Mentioned many times on the internet as the Swiss Army knife for debugging input and output MIDI messages.

It has a GUI interface but as well is has COM interface.

Download here :

I wrote a quick example to convert the it to AutoIT

#AutoIt3Wrapper_UseX64=N
#include <MsgBoxConstants.au3>

; Initialize SvenP 's  error handler
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

;~  Create object
Local $mox = ObjCreate("MIDIOX.MOXScript.1")

; Custom sink object
Local $oMoxEvents = ObjEvent($mox, "OnTrigger_")

Local $Now = $mox.GetSystemTime

$mox.Sleep(2500)

If $mox.GetSystemTime Then
   ConsoleWrite("At least 2½ second has passed" & @CRLF)
EndIf


Local $n1 = $mox.InstanceCount
Local $n2 = $mox.InstanceNumber

ConsoleWrite("Instances : " & $n2 & " " & $n2 & @CRLF)

$mox.FireMidiInput = 1 ; begins input
$mox.DivertMidiInput = 1 ; when set, routes all data

MsgBox (0,"Midi-OX","Press OK to end MIDI Loop") ; sits in a message loop

; -----------------------------------------------------------
;This is the function that gets called by MIDI-OX
Func OnTrigger_MidiInput( $timestamp, $status, $chan, $dat1, $dat2)
   ; ship it right back
   $mox.OutputMidiMsg ($status + $chan, $dat1, $dat2)
EndFunc

; -----------------------------------------------------------
; The MIDI Input Devices
Local $str = "Sys MIDI Input Devices: " & $mox.SysMidiInCount
Local $strWrk = $mox.GetFirstSysMidiInDev

while $strWrk <> ""
   $str = $str & @CRLF & " " & $strWrk
   $strWrk = $mox.GetNextSysMidiInDev
Wend

ConsoleWrite(@CRLF)
ConsoleWrite($Str  & @CRLF)
ConsoleWrite(@CRLF)

; -----------------------------------------------------------
; The MIDI Input Devices
Local $str = "Sys MIDI Output Devices: " & $mox.SysMidiOutCount
Local $strWrk = $mox.GetFirstSysMidiOutDev

while $strWrk <> ""
   $str = $str & @CRLF & " " & $strWrk
   $strWrk = $mox.GetNextSysMidiOutDev
Wend

ConsoleWrite(@CRLF)
ConsoleWrite($Str  & @CRLF)
ConsoleWrite(@CRLF)

; -----------------------------------------------------------
; The MIDI Next Open Input Device
Local $str =  "Open MIDI Input Devices: " & $mox.OpenMidiInCount
Local $strWrk = $mox.GetFirstOpenMidiInDev
while $strWrk <> ""
   $id = $mox.GetInPortID( $strWrk )
   $name = $mox.GetInPortName( $strWrk )
   $str = $str & @CRLF & " " & $strWrk &  " " & $id & " " & $name
   $strWrk = $mox.GetNextOpenMidiInDev
Wend

ConsoleWrite(@CRLF)
ConsoleWrite($Str  & @CRLF)
ConsoleWrite(@CRLF)

; -----------------------------------------------------------
; The MIDI Next Open Output Device
Local $str =  "Open MIDI Output Devices: " & $mox.OpenMidiOutCount
Local $strWrk = $mox.GetFirstOpenMidiOutDev
while $strWrk <> ""
   $id = $mox.GetOutPortID( $strWrk )
   $name = $mox.GetOutPortName( $strWrk )
   $str = $str & @CRLF & " " & $strWrk &  " " & $id & " " & $name
   $strWrk = $mox.GetNextOpenMidiOutDev
Wend

ConsoleWrite(@CRLF)
ConsoleWrite($Str  & @CRLF)
ConsoleWrite(@CRLF)

MsgBox (0,"Midi-OX","Press OK to end MIDI-OX version : " )


If MsgBox($MB_OKCANCEL, "Shutdown?", "OK to exit MIDI-OX version " & $mox.GetAppVersion ) = 1 Then
   $mox.ShutdownAtEnd = 1

    $mox.FireMidiInput = 0 ; stops MIDI input
    $mox.DivertMidiInput = 0

Else
   $mox.ShutdownAtEnd = 0
EndIf



Func MyErrFunc()
  $HexNumber=hex($oMyError.number,8)
  Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"       & @CRLF  & @CRLF & _
             "err.description is: "    & @TAB & $oMyError.description    & @CRLF & _
             "err.windescription:"     & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "         & @TAB & $HexNumber              & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "     & @TAB & $oMyError.scriptline     & @CRLF & _
             "err.source is: "         & @TAB & $oMyError.source         & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile       & @CRLF & _
             "err.helpcontext is: "    & @TAB & $oMyError.helpcontext _
            )
  SetError(1)  ; to check for after this function returns
Endfunc

 

Testing

Even if you do not have any hardware at your disposal, you can use this LoopBack MIDI driver.

This software can be used to create virtual loopback MIDI-ports to interconnect applications on Windows, that want to open hardware-MIDI-ports for communication.

Download here : https://www.tobias-erichsen.de/software/loopmidi.html 

 

MIDI Protocol Documentation (video)

A must see short video series in order to understand the basics of the MIDI protocol

Especially Part 1 / 2 / 4 / 5 / 7 are most valuable to get a good understanding.

MIDI Part 1 - MIDI Signal Path - YouTube

MIDI Part 2 - MIDI Message Types - YouTube

MIDI Part 3 - DIN MIDI - YouTube

MIDI Part 4 - MIDI Protocol Details - YouTube

MIDI Part 5 - Channel Messages - YouTube

MIDI Part 6 - MIDI Clock - YouTube

MIDI Part 7 - SYSEX, etc. - YouTube

 

Enjoy !

Edited by ptrex
Link to comment
Share on other sites

Second Example :

Converted from the VBScript install with the MIDI-OX software

; MIDIOX Test - Event Sink Example
; Copyright (c) 2001 by Jamie O;Connell
;
; This script is an example of doing VBScript with MIDI-OX
#AutoIt3Wrapper_UseX64=N
#include <MsgBoxConstants.au3>

Local $mox
Local $str, $strWrk
Local $n, $ii, $nInst, $id
Local $bGo

; Initialize SvenP 's  error handler
Local $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

; Create object
 $mox = Objcreate("Midiox.MoxScript.1")

 ; Custom sink object
Local $oMoxEvents = ObjEvent($mox, "Sink_")

Local $str = "MIDI-OX"
Local $n = $mox.InstanceNumber

If $n > 0 Then
  $str = $str & ":" & String( $n )
Else
  MsgBox (0,"Info","No Instances")
EndIf

$str = $str & " " & $mox.GetAppVersion
$str = $str & " of " & $mox.InstanceCount
ConsoleWrite($str & @CRLF)

; *** System devices
$str = "Sys MIDI In Devices: " & $mox.SysMidiInCount & @CRLF
$strWrk = $mox.GetFirstSysMidiInDev

While $strWrk <> ""
   $id  = $mox.GetInPortID( $strWrk )
   $str = $str & @CRLF & String( $id ) & ")  " & $strWrk
   $strWrk = $mox.GetNextSysMidiInDev
WEnd

ConsoleWrite($str & @CRLF)

$str = "Sys MIDI Out Devices: " & $mox.SysMidiOutCount & @CRLF
$strWrk = $mox.GetFirstSysMidiOutDev

While $strWrk <> ""
   $id  = $mox.GetOutPortID( $strWrk )
   $str = $str & @CRLF & String( $id ) & ")  " & $strWrk
   $strWrk = $mox.GetNextSysMidiOutDev
WEnd

ConsoleWrite($str & @CRLF)

; *** MIDI-OX devices
$str = "Open MIDI In Devices: " & $mox.OpenMidiInCount & @CRLF
$strWrk = $mox.GetFirstOpenMidiInDev

While $strWrk <> ""
   $id  = $mox.GetInPortID( $strWrk )
   $str = $str & @CRLF & String( $id ) & ")  " & $strWrk
   $strWrk = $mox.GetNextOpenMidiInDev
WEnd

ConsoleWrite($str & @CRLF)

$str = "Open MIDI Out Devices: " & $mox.OpenMidiOutCount & @CRLF
$strWrk = $mox.GetFirstOpenMidiOutDev

While $strWrk <> ""
   $id  = $mox.GetOutPortID( $strWrk )
   $str = $str & @CRLF & String( $id ) & ")  " & $strWrk
   $strWrk = $mox.GetNextOpenMidiOutDev
WEnd

ConsoleWrite($str & @CRLF)

If MsgBox($MB_OKCANCEL, "Divert MIDI Input?", "Yes / No", "MIDI Notes"  ) = 1 Then
   $mox.DivertMidiInput = 1
Else
   $mox.DivertMidiInput = 0
EndIf

$mox.FireMidiInput = 1
MsgBox(0,"End", "Press OK to end MIDI Loop")

$mox.FireMidiInput = 0
$mox.DivertMidiInput = 0

; All done

If MsgBox($MB_OKCANCEL, "Shutdown?", "OK to exit MIDI-OX version " & $mox.GetAppVersion ) = 1 Then
   $mox.ShutdownAtEnd = 1

    $mox.FireMidiInput = 0 ; stops MIDI input
    $mox.DivertMidiInput = 0

Else
   $mox.ShutdownAtEnd = 0
EndIf

; Exit
;------------------------------------------
Func Sink_MidiInput( $ts, $port, $stat, $dat1, $dat2)

   ; Transpose up a minor 3d
   If $stat = 0x90 Or $stat = 0x80 Then
      $dat1 = $dat1 + 3
   EndIf

   $mox.OutputMiLocalsg (-1, $stat, $dat1, $dat2)

EndFunc

;------------------------------------------
; Connection point sink for SysEx

Func Sink_SysExInput( $strSysEx )
   $mox.SendSysExString ($strSysEx  )
EndFunc

;------------------------------------------

Func Sink_OnTerminateMidiInput()
   MsgBox(0,"TerminateMidiInput" ,"MIDI Input Termination Received From MIDI-OX")
   $mox.FireMidiInput = 0
   $mox.DivertMidiInput = 0
EndFunc


Func MyErrFunc()
  $HexNumber=hex($oMyError.number,8)
  Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"       & @CRLF  & @CRLF & _
             "err.description is: "    & @TAB & $oMyError.description    & @CRLF & _
             "err.windescription:"     & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "         & @TAB & $HexNumber              & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "     & @TAB & $oMyError.scriptline     & @CRLF & _
             "err.source is: "         & @TAB & $oMyError.source         & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile       & @CRLF & _
             "err.helpcontext is: "    & @TAB & $oMyError.helpcontext _
            )
  SetError(1)  ; to check for after this function returns
Endfunc

 

Enjoy !

Link to comment
Share on other sites

Link to comment
Share on other sites

I think that @czardas will be happy for using this stuff :)

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...