AutoHotkey Community

It is currently May 27th, 2012, 11:46 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 98 posts ]  Go to page 1, 2, 3, 4, 5 ... 7  Next
Author Message
PostPosted: June 17th, 2010, 6:19 pm 
Offline

Joined: January 10th, 2009, 1:34 pm
Posts: 135
Location: Virginia
Version 0.6 at download link below.
Added conversion for joystick and mouse to midi.

* These scripts were written for AHK - BASIC and have not been tested on AHK_ L
EDIT - using scite for ahk ver 3 beta, they seem to work compiled AHK_L ansi, not on unicode - up to you to test.

Update - 10/26/2010
*For System Exclusive examples - see page 4, this thread,
Many thanks to dorfl68 and the paddy forum! :lol:
*note - the generic midi program link on this post and this file does NOT have the sys_ex stuff... yet.
It will be incorporated, eventually into version 0.7.

-----------

There are two threads already out here, one on midi output and one on midi input.
After spending time on both of those threads, it seemed to me it was time for another thread that combined them both.

That is this thread and the general_midi_app.

The app includes:
- listbox midi port selection, (gui)
- ini read/write of port selection
- a gui monitor (revised - using listview gui - looks nicer)
- midi input (your selected port)
- midi output (your selected port)
- examples of MidiRules - converting midi notes (transposing), example of converting cc to a different cc
- Could convert midi to keyboard/mouse actions (no examples given)
- 2 different hotkey generated midi message examples.
- Joystick - multiple axes conversion to midi example
- Mouse movement to midi example
- Working on mouse wheel to midi conversion (not finished - just needs to add midi output code.

This is intended to streamline the process, so one can jump in and start playing with midi, quickly.

It does not include the midi_in.dll (orbik's cool dll) (I had problems with that on different systems due to dependencies and with some of the listen(functions).
Don't get me wrong - The midi in portion of this script still uses Orbik's code (nearly verbatim) - his script that calls the winmm.dll directly.

It does require the user to setup rules to filter midi data to manipulate using if else or ifequal ... etc.. methods. Once you get used to it, it is a much more direct way to deal with the midi data, in my opinion.

I know when i first came here, midi is what brought me.
I wanted to do scripting for midi. I think there are others that want to do this as well. This is provided to help lure them into this world.
There may be errors in the script, for that, I apologize.

So many people have worked very hard on this and most of it comes directly from this forum in one form or another. I do not wish to take credit, except for bringing the elements together into one place.
TomB, Laszlo, JimF, Orbik and many, many others, too many for me to even know who did what...contributed. If you contributed and I did not mention you, please forgive me. Tell me here and I will add you.

Please post your creations here -
Please post script revisions to this forum post.
Please post your derivative projects here, so that others can learn from what you do.
Please share, as I am sharing, so that others may learn and grow!

Here ya go -

Lastest version 0.6 - Dec. 17, 2010
*Link, above, fixed to point to site instead of file - Site is sometimes slow.

Ver 0.6 with joystick to midi and mouse to midi.

I will leave version 0.4 below for reference.
Version 0.4 below.

Code:
/*
 ; Last edited 9/5/2010 8:55 AM by genmce
 
 
 I fear that adding so many different examples may make this more difficult to use. ....
I may have to pull different parts, MidiRules into an include file the same goes for the hotkeys midi generation...
Ah well...
 
 ****************************************************************
 Please post your revisions back to this forum post.
 Please post your derivative projects back to this page, so that others can learn from what you do.
 Please share, as I am sharing, so that others may learn and grow!
 ****************************************************************
 
 
 
 Generic Midi Program
  Basic structural framework for a midi program in ahk.
  The description what this is for is contained in the first post on the topic Midi Input/Output Combined at the ahk forum.
  Please read it, if you want to know more.
  I have added a few more examples for different midi data types as well as more, meaningful (I hope), documentation to the script.
  You are strongly encouraged to visit http://www.midi.org/techspecs/midimessages.php (decimal values), to learn more
  about midi data.  It will help you create your own midi rules.
  I have combined much of the work of others here.
  It is a working script, most of the heavy lifing has been done for you.
  You will need to create your own midi rules.
  By creating or modifying if statements in the section of the MidiRules label.
  I don't claim to be an expert on this, just a guy who pulled disparate things together.
  I really need help from someone to add sysex functionality.
 
******  Sections with  !!!!!!!!!!!!!!!!!!!!!! - don't edit between these, unless you know what you are doing (uykwyad) !
 
******  Sections with ++++++++++++++++++++++ Edit between these marks. You won't break it, I don't think???

  v. 0.4
    + added an example of hotkey generating midi (volume controller)
    + added a second example for you create your own hotkey generated midi message.
   
   
  v. 0.3 changes
  + Adding text for how to add new rules.
  + Midi Rules, name used instead of filters, seems more appropriate.
  + Moved all rules outside the detector function, hoping to make it easier to understand and use.
  + abandoned the idea of dynamic code and a gui to create rules, omg, someone else do that, please!
  + Adding more examples for rules.
  + more to come, maybe...
  + removed that notemsg var - did not need it, not sure why i used it... nevermind
 
 
   TODO -
  + add a way to echo all midi input that is not filtered or modified to the output. Like a gui switch (sometimes you want it all sometimes you don't)
  + make the midi monitor easier to use and read, also a toggle for it to be on or off.
      - midi monitor columnar with data columns to show statusbyte, byte1 and byte2 as well as midi chan.
        So need a heading grid for each ....
  + bring back sendnote() funtion instead of a gosub, same for each type of midi data.
  + Figure out how to do SYSEX with it, PLEASE HELP ME ON THIS!
 
 Generic midi program v. - 0.2 changes

  - fixed bad note off detection...
  - select input and output port
  - open and close selected midi ports
  - write ports to ini file
  - send receive midi data
  - modify received midi data, send it to output port
  - uses contributions by so many different people. See midi input and midi output forum posts. Links in midi under the hood section below
  - "under the hood" midi functions and subroutines at the end of this file
  - post your creations back to this midi I/O thread - that way we can all build on it.
 
  Notes - All midi in/out lib stuff is included here, no external dlls, besides winmm.dll required.
  Use of this - you should only need to edit the input part - great way to practice you if else logic and midi manipulation.
  This does not do sysex. I really want to develop that, but not sure how to go about it.
  Perhaps one day.
 
*/
 
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! no edit here
 
#Persistent
#SingleInstance
SendMode Input              ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.

if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME  ; if not xp or 2000 quit
{
    MsgBox This script requires Windows 2000/XP or later.
    ExitApp
}

; ===============
  version = Genmce_Generic_Midi_App_   ; Change this to suit you.
; ===============

readini()                       ; load values from the ini file, via the readini function - see below.
gosub, MidiPortRefresh          ; used to refresh the input and output port lists - see label below
port_test(numports,numports2)   ; test the ports - check for valid ports?
gosub, midiin_go                ; opens the midi input port listening routine
gosub, midiout                  ; opens the midi out port   
gosub, midiMon                  ; see below - a monitor gui - for learning mostly - you will probably comment this out eventually.
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! end edit here

; =============== set variables you may use in MidiRules section

cc_msg = 73,74 ; ++++++++++++++++ you might want to add other vars that load in auto execute section  This example goes with

; varibles below are for keyboarcc
channel = 1     ; default channel =1
ccnum = 7       ; 7 is volume
volVal = 0     ; Default zero for volume
volDelta = 10  ; Amount to change volume
; end of vars for hotkey and keyboardcc

/*
  yourVar = 0
  yourVarDelta = 3
  yourVarCCnum = 1 ; modwheel
*/

settimer, KeyboardCCs, 70 ; timer to run the KeyboardCCs at the 70 interval

return ; !!!! no edit here, need this line to end the auto exec section.

; =============== end of auto execute section =====================

/*
  PARSE - LAST MIDI MESSAGE RECEIVED -
*/
; =============== MIDI input MESSAGE PARSE  ===============

; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! no edit below here ....
; don't edit this part!
MidiMsgDetect(hInput, midiMsg, wMsg) ; Midi input section in "under the hood" calls this function each time a midi message is received. Then the midi message is broken up into parts for manipulation.  See http://www.midi.org/techspecs/midimessages.php (decimal values).
  {
    global statusbyte, chan, note, cc, byte1, byte2
   
    statusbyte    :=  midiMsg & 0xFF         ; EXTRACT THE STATUS BYTE (WHAT KIND OF MIDI MESSAGE IS IT?)
    chan       := (statusbyte & 0x0f) + 1   ; WHAT MIDI CHANNEL IS THE MESSAGE ON?
    byte1       := (midiMsg >> 8) & 0xFF   ; THIS IS DATA1 VALUE = NOTE NUMBER OR CC NUMBER
    byte2       := (midiMsg >> 16) & 0xFF   ; DATA2 VALUE IS NOTE VELEOCITY OR CC VALUE
           
      ; GUI for midi monitor
      GuiControl,12:, MidiMs, MidiMon:%statusbyte% %chan% %byte1% %byte2% ; MidiMs (green text in gui) in midimon gui below - this is for display you will probably comment this out    evenually.
 
    gosub, MidiRules ; run the subroutine below
   
  } ; end of MidiMsgDetect funciton


; =============== filters/rules subroutine tests

/*
      The MidiRules section is for modifying midi input from some other source.
        *See hotkeys below if you wish to generate midi messages from hotkeys.
     
      Write your own MidiRules and put them in this section.
      Keep rules together under proper section, notes, cc, program change etc.
      Keep them after the statusbyte has been determined.
      Examples for each type of rule will be shown.
      The example below is for note type message.
     
      Remember byte1 for a noteon/off is the note number, byte2 is the velocity of that note.
      example
      ifequal, byte1, 20 ; if the note number coming in is note # 20
        {
          byte1 := (do something in here) ; could be do something to the velocity(byte2)
          gosub, SendNote ; send the note out.
        }
  */

MidiRules: ; write your own rules in here, look for : ++++++ for where you might want to add
           ; stay away from !!!!!!!!!!

  ; =============== Is midi input a Note On or Note off message?  ===============
  if statusbyte between 128 and 159 ; see range of values for notemsg var defined in autoexec section. "in" used because ranges of note on and note off
   { ; beginning of note block
     
      if statusbyte between 144 and 159 ; detect if note message is "note on"
        GuiControl,12:, MidiMsOut, noteOn:%statusbyte% %chan% %byte1% %byte2%  ; display noteOn message in gui
      if statusbyte between 128 and 143 ; detect if note message is "note off"
        GuiControl,12:, MidiMsOut, noteOff:%statusbyte% %chan% %byte1% %byte2%  ; display note off in gui
 
  ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! above  end of no edit
     
  ; =============== add your note MidiRules here ==; ===============

  /*
      Write your own note filters and put them in this section.
      Remember byte1 for a noteon/off is the note number, byte2 is the velocity of that note.
      example
      ifequal, byte1, 20 ; if the note number coming in is note # 20
        {
          byte1 := (do something in here) ; could be do something to the velocity(byte2)
          gosub, SendNote ; send the note out.
        }
  */
  ; ++++++++++++++++++++++++++++++++ examples of note rules ++++++++++ feel free to add more.
     
     ifequal, byte1, 20 ; if the note number coming in is note # 20
        {
          byte1 := (byte1 +1) ; transpose that note up 1 note number 
          gosub, SendNote ; send the note out.
        }
     
      ifequal, byte1, 30 ; if the note number coming in is note # 30
        {
          send , {NumLock} ; send a keypress when note number 20 is received.
        }
     
      ; a little more complex filter two notes
      if ((byte1 != 60) and (byte1 != 62)) ; if note message is not(!) 60 and not(!) 62 send the note out - ie - do nothing except statements above (note 20 and 30 have things to do) to it.
        {
            gosub, SendNote ; send it out the selected output midi port
            ;msgbox, ,straight note, note %byte1% message, 1 ; this messagebox for testing only.
        }

      IfEqual, byte1, 60 ; if the note number is middle C (60) (you can change this) 
        {
            byte1 := (byte1 + 5) ;transpost up 5 steps
            gosub, SendNote ;(h_midiout, note) ;send a note transposed up 5 notes.
            ;msgbox, ,transpose up 5, note on %byte1% message, 1 ; for testing only - show msgbox for 1 sec
        }
     
      IfEqual, byte1, 62 ; if note on is note number 62 (just another example of note detection)
        {
            byte1 := (byte1 -5) ;transpose down 5 steps
            gosub, SendNote
            ;msgbox, ,transpose down 5, note on %byte1% message, 1 ; for testing only, uncomment if you need it.
        }   
    ; ++++++++++++++++++++++++++++++++ End of examples of note rules  ++++++++++
    } ; end of note block
 
; =============== all cc detection ----
  ; is input cc?
 
  if statusbyte between 176 and 191 ; check status byte for cc 176-191 is the range for CC messages ; !!!!!!!! no edit this line, uykwyad
    {
    ; ++++++++++++++++++++++++++++++++ examples of CC rules ++++++++++ feel free to add more. 
        if byte1 in %cc_msg%
          {
            cc := (byte1 + 3) ; Will change all cc#'s up 3 for a different controller number
            GuiControl,12:, MidiMsOut, CC %statusbyte% %chan% %cc% %byte2%
            ;midiOutShortMsg(h_midiout, statusbyte, cc, byte2)
            gosub, sendCC
          }
        else if byte1 not in %cc_msg% ; if the byte1 value is one of these...
          {
            cc := byte1 ; pass them as is, no change.
            GuiControl,12:, MidiMsOut, CC %statusbyte% %chan% %cc% %byte2%
            gosub, sendCC
          } 
    ; ++++++++++++++++++++++++++++++++ examples of cc rules ends ++++++++++++
    }
 
  ; Is midi input a Program Change?
  if statusbyte between 192 and 208  ; check if message is in range of program change messages for byte1 values. ; !!!!!!!!!!!! no edit
    {
    ; ++++++++++++++++++++++++++++++++ examples of program change rules ++++++++++ 
      ; Sorry I have not created anything for here nor for pitchbends....
     
      GuiControl,12:, MidiMsOut, ProgC:%statusbyte% %chan% %byte1% %byte2%
          gosub, sendPC
          ; need something for it to do here, could be converting to a cc or a note or changing the value of the pc
          ; however, at this point the only thing that happens is the gui change, not midi is output here.
          ; you may want to make a SendPc: label below
    ; ++++++++++++++++++++++++++++++++ examples of program change rules ++++++++++   
    }
  ;msgbox filter triggered
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  end of edit section

Return

; ++++++++++++++++++++++++ hotkeys here +++++++++++++++++++++++++=
/*
  Generate midi messages from computer keyboard (mouse) events.
  Examples below
 
  Each hotkey is defined to change the value of a varible.
  example f12::Vol=U ;  When f12 is pushed down, this will set the value of that varible to U.
  The keyboardcc loop is running every 70, so it detects the change for vol varible and triggers that process.
  See keyboardcc section (where all the work is done).
  f12 up::vol=  ; when f12 is let go, the vol var is set to blank and keyboardcc does nothing.
  Same for f11 except the vol var is either D or blank.
*/

; here are a few examples of adding controller hotkeys.

F12::Vol = U   ;   
f12 up::Vol =
F11::Vol = D   ; Mod wheel down
f11 up::Vol =

/*
; here are two more examples you can add

  F10::yourVar = U   ; set yourVar to U for changing value up
  F10 UP::yourVar =  ; set yourVar blank to stop message generation
  F9::yourVar = D    ; set yourVar to D for changing value down
  f9::yourVar =      ; set yourVar to blank to stop message generation
*/
; ++++++++++++++++++++++++++++++ end hotkey defs ++++++++++++++++++++

; +++++++++++++++++++++++++++++ begin keyboardccs section +++++++++++

  /*
    Process Definitions for hotkey generated midi controllers.
    Unless you are good at arrays (I am not)
    You will need to add three statements like these for each controller you wish to generate from a pair of hotkeys.
  */

KeyboardCCs:

; =============== this is a section for volume control
If Vol = U
  {
    VolVal := VolVal + VolDelta ;see top where vars defined.
    If VolVal > 127   ; check for max value reached
    VolVal:= 127, Vol:=""
    midiOutShortMsg(h_midiout, (channel+175), CCnum, VolVal)    ;  (channel+175 will make the correct statusbyte for cc message) CCnum var defined in autoexec section at top, as   
  }
If Vol = D
  {
    volVal := volVal- volDelta
    If volVal < 0      ; check min value reached.
    VolVal:=0, Vol=""
    midiOutShortMsg(h_midiout, (channel+175), CCnum, VolVal)
  }
if Vol = ; set the var to blank
  {
    ; do nothing.
  }
; =============== end of volume control

;++++++++++++++++++++++++++++++ edit below as needed
/*
; ********* remember you can't use yourVar unless you define it somewhere,
; ********* same goes for yourVarCCnum and yourVarDelta.... see beginning of script where they are commented out but set to be defined.

; examples to be triggered by f9 and f10 defined above but commented out.
; **********

If yourVar = U
  {
    yourVarVal := yourVarVal + yourVarDelta ;see top where vars defined.
    If yourVarVal > 127   ; check for max value reached
    yourVarVal:= 127, yourVar:=""
    midiOutShortMsg(h_midiout, (channel+175), yourVarCCnum, yourVarVal)    ;  yourVarCCnum is defined in autoexec section and yourVarVal is defined in the lines directly above.
  }
If yourVar = D
  {
    yourVarVal := yourVarVal- yourVarDelta
    If yourVarVal < 0      ; check min value reached.
    yourVarVal:=0, yourVar=""
    midiOutShortMsg(h_midiout, (channel+175), yourVarCCnum, yourVarVal)
  }
if yourVar = ; set the var to blank
  {
    ; do nothing.
  }

*/
Return

 ; ========================= end ============================

; =============== Send midi output data =============================

SendNote: ;(h_midiout,Note) ; send out note messages ; this should probably be a funciton but... eh.
  ;{
  GuiControl,12:, MidiMsOutSend, NoteOut:%statusbyte% %chan% %byte1% %byte2%
    ;global chan, EventType, NoteVel
    ;MidiStatus := 143 + chan
    note = %byte1%                                      ; this var is added to allow transpostion of a note
    midiOutShortMsg(h_midiout, statusbyte, note, byte2) ; call the midi funcitons with these params.
Return
 
SendCC: ; not sure i actually did anything changing cc's here but it is possible.

    GuiControl,12:, MidiMsOutSend, CCOut:%statusbyte% %chan% %cc% %byte2%
    midiOutShortMsg(h_midiout, statusbyte, cc, byte2)
    ;MsgBox, 0, ,sendcc triggered , 1
 Return
 
SendPC:
    GuiControl,12:, MidiMsOutSend, ProgChOut:%statusbyte% %chan% %byte1% %byte2%
    midiOutShortMsg(h_midiout, statusbyte, pc, byte2)
 /*
  COULD BE TRANSLATED TO SOME OTHER MIDI MESSAGE BESIDED PROGRAM CHANGE.
 */
Return






; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! no edit below here, unless you know what you are doing.

; =============== midi monitor gui ==========================

midiMon: ;just a simple gui window for a midi monitor of sorts.

  Gui, 12: +LastFound +AlwaysOnTop +Caption +ToolWindow  ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
  Gui,12: Color, white ; %CustomColor% ;blue ;
  Gui,12: Font, s15 ; Set a large font size (32-point).
  Gui,12: Add, Text, w250 vMidiMs cgreen, XXXXX YYYYY  ; XX & YY serve to auto-size the window.
  gui, 12: add, text, w250 vMidiMsOut cblue, XXXXX YYYYY
  gui, 12: add, text, w250 vMidiMsOutSend cred, XXXXX YYYYY
  Gui,12: Show, xcenter y0 w500 NoActivate, %version% Midi Monitor - thingy  ; NoActivate avoids deactivating the currently active window.

; ===============  end monitor gui
;****************************************************************************************************************
;******************************************** midi "under the hood" *********************************************
/*
    This part is meant to take care of the "under the hood" midi input and output selection and save selection to an ini file.
    Hopefully it simplifies usage for others out here trying to do things with midi and ahk.
   
    * use it as an include.
   
    The code here was taken/modified from the work by TomB/Lazslo on Midi Output
        http://www.autohotkey.com/forum/viewtopic.php?t=18711&highlight=midi+output
   
    Orbik's Midi input thread
        http://www.autohotkey.com/forum/topic30715.html
        This method does NOT use the midi_in.dll, it makes direct calls to the winmm.dll
       
    Many different people took part in the creation of this file.
   
    ; Last edited 6/17/2010 11:30 AM by genmce

*/

MidiPortRefresh: ; get the list of ports

 MIlist := MidiInsList(NumPorts)
   Loop Parse, MIlist, |
      {
      }
   TheChoice := MidiInDevice + 1

MOlist := MidiOutsList(NumPorts2)
   Loop Parse, MOlist, |
      {
      }
   TheChoice2 := MidiOutDevice + 1

return

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

ReadIni() ; also set up the tray Menu
  {
    Menu, tray, add, MidiSet            ; set midi ports tray item
    Menu, tray, add, ResetAll           ; Delete the ini file for testing --------------------------------

    global MidiInDevice, MidiOutDevice, version ; version var is set at the beginning.
    IfExist, %version%io.ini
      {
        IniRead, MidiInDevice, %version%io.ini, Settings, MidiInDevice , %MidiInDevice%     ; read the midi In port from ini file
        IniRead, MidiOutDevice, %version%io.ini, Settings, MidiOutDevice , %MidiOutDevice%  ; read the midi out port from ini file
      }
    Else ; no ini exists and this is either the first run or reset settings.
      {
        MsgBox, 1, No ini file found, Select midi ports?
        IfMsgBox, Cancel
          ExitApp
        IfMsgBox, yes
          gosub, midiset
        ;WriteIni()
      }
  }

;CALLED TO UPDATE INI WHENEVER SAVED PARAMETERS CHANGE
WriteIni()
  {
    global MidiInDevice, MidiOutDevice, version
   
    IfNotExist, %version%io.ini ; if no ini
      FileAppend,, %version%io.ini ; make one with the following entries.
    IniWrite, %MidiInDevice%, %version%io.ini, Settings, MidiInDevice
    IniWrite, %MidiOutDevice%, %version%io.ini, Settings, MidiOutDevice
  }

;------------ port testing to make sure selected midi port is valid --------------------------------

port_test(numports,numports2) ; confirm selected ports exist ; CLEAN THIS UP STILL

  {
    global midiInDevice, midiOutDevice, midiok
   
    ; ----- In port selection test based on numports
    If MidiInDevice not Between 0 and %numports%
      {
        MidiIn := 0 ; this var is just to show if there is an error - set if the ports are valid = 1, invalid = 0
            ;MsgBox, 0, , midi in port Error ; (this is left only for testing)
        If (MidiInDevice = "")              ; if there is no midi in device
            MidiInerr = Midi In Port EMPTY. ; set this var = error message
            ;MsgBox, 0, , midi in port EMPTY
        If (midiInDevice > %numports%)          ; if greater than the number of ports on the system.
            MidiInnerr = Midi In Port Invalid.  ; set this error message
            ;MsgBox, 0, , midi in port out of range
      }
    Else
      {
        MidiIn := 1 ; setting var to non-error state or valid
      }
    ; ----- out port selection test based on numports2
    If  MidiOutDevice not Between 0 and %numports2%
      {
        MidiOut := 0 ; set var to 0 as Error state.
        If (MidiOutDevice = "")                 ; if blank
            MidiOuterr = Midi Out Port EMPTY.   ; set this error message
            ;MsgBox, 0, , midi o port EMPTY
        If (midiOutDevice > %numports2%)             ; if greater than number of availble ports 
            MidiOuterr = Midi Out Port Out Invalid.  ; set this error message   
            ;MsgBox, 0, , midi out port out of range
      }
    Else
      {
        MidiOut := 1 ;set var to 1 as valid state.
      }
      ; ---- test to see if ports valid, if either invalid load the gui to select.
      ;midicheck(MCUin,MCUout)
    If (%MidiIn% = 0) Or (%MidiOut% = 0)
      {
        MsgBox, 49, Midi Port Error!,%MidiInerr%`n%MidiOuterr%`n`nLaunch Midi Port Selection!
        IfMsgBox, Cancel
          ExitApp
        midiok = 0 ; Not sure if this is really needed now....
        Gosub, MidiSet ;Gui, show Midi Port Selection
      }
    Else
      {
        midiok = 1
        Return ; DO NOTHING - PERHAPS DO THE NOT TEST INSTEAD ABOVE.
      }
  }
Return

; ------------------ end of port testing ---------------------------


MidiSet: ; midi port selection gui
 
 ; ------------- MIDI INPUT SELECTION -----------------------
  ;Gui, Destroy
  ;Gosub, Suspendit
  Gui, 6: Destroy
  Gui, 2: Destroy
  Gui, 3: Destroy
  Gui, 4: Destroy
  ;Gui, 5: Destroy
  Gui, 4: +LastFound +AlwaysOnTop   +Caption +ToolWindow ;-SysMenu
  Gui, 4: Font, s12
  Gui, 4: add, text, x10 y10 w300 cmaroon, Select Midi Ports. ; Text title
  Gui, 4: Font, s8
  Gui, 4: Add, Text, x10 y+10 w175 Center , Midi In Port  ;Just text label
  Gui, 4: font, s8
  ; midi ins list box
  Gui, 4: Add, ListBox, x10 w200 h100  Choose%TheChoice% vMidiInPort gDoneInChange AltSubmit, %MiList% ; --- midi in listing of ports
    ;Gui,  Add, DropDownList, x10 w200 h120 Choose%TheChoice% vMidiInPort gDoneInChange altsubmit, %MiList%  ; ( you may prefer this style, may need tweak)

  ; --------------- MidiOutSet ---------------------
  Gui, 4: Add, TEXT,  x220 y40 w175 Center, Midi Out Port ; gDoneOutChange
  ; midi outlist box
  Gui, 4: Add, ListBox, x220 y62 w200 h100 Choose%TheChoice2% vMidiOutPort gDoneOutChange AltSubmit, %MoList% ; --- midi out listing
  ;Gui,  Add, DropDownList, x220 y97 w200 h120 Choose%TheChoice2% vMidiOutPort gDoneOutChange altsubmit , %MoList%
  Gui, 4: add, Button, x10 w205 gSet_Done, Done - Reload script.
  Gui, 4: add, Button, xp+205 w205 gCancel, Cancel
  ;gui, 4: add, checkbox, x10 y+10 vNotShown gDontShow, Do Not Show at startup.
  ;IfEqual, NotShown, 1
  ;guicontrol, 4:, NotShown, 1
  Gui, 4: show , , %version% Midi Port Selection ; main window title and command to show it.

Return

;-----------------gui done change stuff - see label in both gui listbox line

DoneInChange:
  Gui, 4: Submit, NoHide
  Gui, 4: Flash
  If %MidiInPort%
      UDPort:= MidiInPort - 1, MidiInDevice:= UDPort ; probably a much better way do this, I took this from JimF's qwmidi without out editing much.... it does work same with doneoutchange below.
  GuiControl, 4:, UDPort, %MidiIndevice%
  WriteIni()
  ;MsgBox, 32, , midi in device = %MidiInDevice%`nmidiinport = %MidiInPort%`nport = %port%`ndevice= %device% `n UDPort = %UDport% ; only for testing
Return

DoneOutChange:
  Gui, 4: Submit, NoHide
  Gui, 4: Flash
  If %MidiOutPort%
      UDPort2:= MidiOutPort - 1 , MidiOutDevice:= UDPort2
  GuiControl, 4: , UDPort2, %MidiOutdevice%
  WriteIni()
  ;Gui, Destroy
Return

;------------------------ end of the doneout change stuff.

Set_Done: ;  aka reload program, called from midi selection gui
  Gui, 3: Destroy
  Gui, 4: Destroy
   sleep, 100
  Reload
Return

Cancel:
  Gui, Destroy
  Gui, 2: Destroy
  Gui, 3: Destroy
  Gui, 4: Destroy
  Gui, 5: Destroy
Return

; ********************** Midi output detection

MidiOut: ; Function to load new settings from midi out menu item
  OpenCloseMidiAPI()
  h_midiout := midiOutOpen(MidiOutDevice) ; OUTPUT PORT 1 SEE BELOW FOR PORT 2
return

ResetAll: ; for development only, leaving this in for a program reset if needed by user
  MsgBox, 33, %version% - Reset All?, This will delete ALL settings`, and restart this program!
  IfMsgBox, OK
    {
      FileDelete, %version%io.ini   ; delete the ini file to reset ports, probably a better way to do this ...
      Reload                        ; restart the app.
    }
  IfMsgBox, Cancel
Return

GuiClose: ; on x exit app
  Suspend, Permit ; allow Exit to work Paused. I just added this yesterday 3.16.09 Can now quit when Paused.
 
  MsgBox, 4, Exit %version%, Exit %version% %ver%? ;
  IfMsgBox No
      Return
  Else IfMsgBox Yes
      midiOutClose(h_midiout)
   
  Gui, 6: Destroy
  Gui, 2: Destroy
  Gui, 3: Destroy
  Gui, 4: Destroy
  Gui, 5: Destroy
  gui, 7: destroy
 ;gui,
 Sleep 100
  ;winclose, Midi_in_2 ;close the midi in 2 ahk file
 ExitApp


;############################################## MIDI LIB from orbik and lazslo#############
;-------- orbiks midi input code --------------
; Set up midi input and callback_window based on the ini file above.
; This code copied from ahk forum Orbik's post on midi input

; nothing below here to edit.

; =============== midi in =====================

Midiin_go:
DeviceID := MidiInDevice      ; midiindevice from IniRead above assigned to deviceid
CALLBACK_WINDOW := 0x10000    ; from orbiks code for midi input

Gui, +LastFound    ; set up the window for midi data to arrive.
hWnd := WinExist()   ;MsgBox, 32, , line 176 - mcu-input  is := %MidiInDevice% , 3 ; this is just a test to show midi device selection

hMidiIn =
VarSetCapacity(hMidiIn, 4, 0)
  result := DllCall("winmm.dll\midiInOpen", UInt,&hMidiIn, UInt,DeviceID, UInt,hWnd, UInt,0, UInt,CALLBACK_WINDOW, "UInt")
    If result
      {
        MsgBox, Error, midiInOpen Returned %result%`n
        ;GoSub, sub_exit
      }

hMidiIn := NumGet(hMidiIn) ; because midiInOpen writes the value in 32 bit binary Number, AHK stores it as a string
  result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn)
    If result
      {
        MsgBox, Error, midiInStart Returned %result%`nRight Click on the Tray Icon - Left click on MidiSet to select valid midi_in port.
        ;GoSub, sub_exit
      }

OpenCloseMidiAPI()
 
  ; ----- the OnMessage listeners ----

      ; #define MM_MIM_OPEN 0x3C1 /* MIDI input */
      ; #define MM_MIM_CLOSE 0x3C2
      ; #define MM_MIM_DATA 0x3C3
      ; #define MM_MIM_LONGDATA 0x3C4
      ; #define MM_MIM_ERROR 0x3C5
      ; #define MM_MIM_LONGERROR 0x3C6

    OnMessage(0x3C1, "MidiMsgDetect")  ; calling the function MidiMsgDetect in get_midi_in.ahk
    OnMessage(0x3C2, "MidiMsgDetect") 
    OnMessage(0x3C3, "MidiMsgDetect")
    OnMessage(0x3C4, "MidiMsgDetect")
    OnMessage(0x3C5, "MidiMsgDetect")
    OnMessage(0x3C6, "MidiMsgDetect")

Return

;--- MIDI INS LIST FUNCTIONS - port handling -----

MidiInsList(ByRef NumPorts)
  { ; Returns a "|"-separated list of midi output devices
    local List, MidiInCaps, PortName, result
    VarSetCapacity(MidiInCaps, 50, 0)
    VarSetCapacity(PortName, 32)                       ; PortNameSize 32

    NumPorts := DllCall("winmm.dll\midiInGetNumDevs") ; #midi output devices on system, First device ID = 0

    Loop %NumPorts%
      {
        result := DllCall("winmm.dll\midiInGetDevCapsA", UInt,A_Index-1, UInt,&MidiInCaps, UInt,50, UInt)
        If (result OR ErrorLevel) {
            List .= "|-Error-"
            Continue
          }
        DllCall("RtlMoveMemory", Str,PortName, UInt,&MidiInCaps+8, UInt,32) ; PortNameOffset 8, PortNameSize 32
        List .= "|" PortName
      }
    Return SubStr(List,2)
  }

MidiInGetNumDevs() { ; Get number of midi output devices on system, first device has an ID of 0
    Return DllCall("winmm.dll\midiInGetNumDevs")
  }
MidiInNameGet(uDeviceID = 0) { ; Get name of a midiOut device for a given ID

    ;MIDIOUTCAPS struct
    ;    WORD      wMid;
    ;    WORD      wPid;
    ;    MMVERSION vDriverVersion;
    ;    CHAR      szPname[MAXPNAMELEN];
    ;    WORD      wTechnology;
    ;    WORD      wVoices;
    ;    WORD      wNotes;
    ;    WORD      wChannelMask;
    ;    DWORD     dwSupport;

    VarSetCapacity(MidiInCaps, 50, 0)  ; allows for szPname to be 32 bytes
    OffsettoPortName := 8, PortNameSize := 32
    result := DllCall("winmm.dll\midiInGetDevCapsA", UInt,uDeviceID, UInt,&MidiInCaps, UInt,50, UInt)

    If (result OR ErrorLevel) {
        MsgBox Error %result% (ErrorLevel = %ErrorLevel%) in retrieving the name of midi Input %uDeviceID%
        Return -1
      }

    VarSetCapacity(PortName, PortNameSize)
    DllCall("RtlMoveMemory", Str,PortName, Uint,&MidiInCaps+OffsettoPortName, Uint,PortNameSize)
    Return PortName
  }

MidiInsEnumerate() { ; Returns number of midi output devices, creates global array MidiOutPortName with their names
    local NumPorts, PortID
    MidiInPortName =
    NumPorts := MidiInGetNumDevs()

    Loop %NumPorts% {
        PortID := A_Index -1
        MidiInPortName%PortID% := MidiInNameGet(PortID)
      }
    Return NumPorts
  }


; =============== end of midi selection stuff


MidiOutsList(ByRef NumPorts)
  { ; Returns a "|"-separated list of midi output devices
    local List, MidiOutCaps, PortName, result
    VarSetCapacity(MidiOutCaps, 50, 0)
    VarSetCapacity(PortName, 32)                       ; PortNameSize 32

    NumPorts := DllCall("winmm.dll\midiOutGetNumDevs") ; #midi output devices on system, First device ID = 0

    Loop %NumPorts%
      {
        result := DllCall("winmm.dll\midiOutGetDevCapsA", UInt,A_Index-1, UInt,&MidiOutCaps, UInt,50, UInt)
        If (result OR ErrorLevel)
          {
            List .= "|-Error-"
            Continue
          }
        DllCall("RtlMoveMemory", Str,PortName, UInt,&MidiOutCaps+8, UInt,32) ; PortNameOffset 8, PortNameSize 32
        List .= "|" PortName
      }
    Return SubStr(List,2)
  }
;---------------------midiOut from TomB and Lazslo and JimF --------------------------------

;THATS THE END OF MY STUFF (JimF) THE REST ID WHAT LASZLo AND PAXOPHONE WERE USING ALREADY
;AHK FUNCTIONS FOR MIDI OUTPUT - calling winmm.dll
;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_multimedia_functions.asp
;Derived from Midi.ahk dated 29 August 2008 - streaming support removed - (JimF)


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
        Exit
      }
  }

;FUNCTIONS FOR SENDING SHORT MESSAGES

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 UInt@(&strh_midiout)
  }

midiOutShortMsg(h_midiout, MidiStatus,  Param1, Param2) { ;Channel,
    ;h_midiout: handle to midi output device returned by midiOutOpen
    ;EventType, Channel combined -> MidiStatus byte: http://www.harmony-central.com/MIDI/Doc/table1.html
    ;Param3 should be 0 for PChange, ChanAT, or Wheel
    ;Wheel events: entire Wheel value in Param2 - the function splits it into two bytes
/*
    If (EventType = "NoteOn" OR EventType = "N1")
        MidiStatus := 143 + Channel
    Else If (EventType = "NoteOff" OR EventType = "N0")
        MidiStatus := 127 + Channel
    Else If (EventType = "CC")
        MidiStatus := 175 + Channel
    Else If (EventType = "PolyAT"  OR EventType = "PA")
        MidiStatus := 159 + Channel
    Else If (EventType = "ChanAT"  OR EventType = "AT")
        MidiStatus := 207 + Channel
    Else If (EventType = "PChange" OR EventType = "PC")
        MidiStatus := 191 + Channel
    Else If (EventType = "Wheel"   OR EventType = "W") {
        MidiStatus := 223 + Channel
        Param2 := Param1 >> 8      ; MSB of wheel value
        Param1 := Param1 & 0x00FF  ; strip MSB
      }
*/
    result := DllCall("winmm.dll\midiOutShortMsg", UInt,h_midiout, UInt, MidiStatus|(Param1<<8)|(Param2<<16), UInt)
    If (result or ErrorLevel)  {
        MsgBox There was an Error Sending the midi event: (%result%`, %ErrorLevel%)
        Return -1
      }
  }

midiOutClose(h_midiout) {  ; Close MidiOutput
    Loop 9 {
        result := DllCall("winmm.dll\midiOutClose", UInt,h_midiout)
        If !(result or ErrorLevel)
            Return
        Sleep 250
      }
    MsgBox Error in closing the midi output port. There may still be midi events being Processed.
    Return -1
  }

;UTILITY FUNCTIONS
MidiOutGetNumDevs() { ; Get number of midi output devices on system, first device has an ID of 0
    Return DllCall("winmm.dll\midiOutGetNumDevs")
  }

MidiOutNameGet(uDeviceID = 0) { ; Get name of a midiOut device for a given ID

    ;MIDIOUTCAPS struct
    ;    WORD      wMid;
    ;    WORD      wPid;
    ;    MMVERSION vDriverVersion;
    ;    CHAR      szPname[MAXPNAMELEN];
    ;    WORD      wTechnology;
    ;    WORD      wVoices;
    ;    WORD      wNotes;
    ;    WORD      wChannelMask;
    ;    DWORD     dwSupport;

    VarSetCapacity(MidiOutCaps, 50, 0)  ; allows for szPname to be 32 bytes
    OffsettoPortName := 8, PortNameSize := 32
    result := DllCall("winmm.dll\midiOutGetDevCapsA", UInt,uDeviceID, UInt,&MidiOutCaps, UInt,50, UInt)

    If (result OR ErrorLevel) {
        MsgBox Error %result% (ErrorLevel = %ErrorLevel%) in retrieving the name of midi output %uDeviceID%
        Return -1
      }

    VarSetCapacity(PortName, PortNameSize)
    DllCall("RtlMoveMemory", Str,PortName, Uint,&MidiOutCaps+OffsettoPortName, Uint,PortNameSize)
    Return PortName
  }

MidiOutsEnumerate() { ; Returns number of midi output devices, creates global array MidiOutPortName with their names
    local NumPorts, PortID
    MidiOutPortName =
    NumPorts := MidiOutGetNumDevs()

    Loop %NumPorts% {
        PortID := A_Index -1
        MidiOutPortName%PortID% := MidiOutNameGet(PortID)
      }
    Return NumPorts
  }

UInt@(ptr) {
Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
}

PokeInt(p_value, p_address) { ; Windows 2000 and later
    DllCall("ntdll\RtlFillMemoryUlong", UInt,p_address, UInt,4, UInt,p_value)
}








_________________
KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk?


Last edited by genmce on December 18th, 2010, 3:53 pm, edited 21 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2010, 12:16 pm 
Offline

Joined: June 15th, 2010, 6:48 pm
Posts: 13
Great!
:D :D
Many thanks for your effort!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2010, 8:13 pm 
Offline

Joined: January 10th, 2009, 1:34 pm
Posts: 135
Location: Virginia
Glad someone noticed!

_________________
KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 9th, 2010, 9:09 pm 
Offline

Joined: October 13th, 2009, 6:01 pm
Posts: 6
thanks because this script actually works for me. the other ones didn't for whatever silly reason!
urm now i'm going to figure out how to get the various midi buttons to do things in windows...

EDIT:
nup again this is way out of my league to be playing with, sure this midi monitor works and the config wizard is a blast but how can I let it listen for certain buttons to be pressed?

will check back occasionally :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 16th, 2010, 12:28 pm 
Offline

Joined: January 10th, 2009, 1:34 pm
Posts: 135
Location: Virginia
Sorry I have not been around, summer vacation - eh.

You will need to know the information about your button.
Press it with the program running and you should see the data from the button show up on the crappy midi monitor thingy.

Then you will edit .ahk file to add this item...
hmmm... not sure this will make sense.

I probably need to put a gui in here.
I also need to figure out how to do an array so one could keep adding filters ....
I wonder if I can get some help on doing an array like this? TLM was helping me before on arrays... I'll ask him.

I digress.

line 102
I am assuming your button is a CC? Control Change.

This code just detects if any cc is input, if it is then the cc# (data1) is changed up 3, then output to the selected midi port.

Code:
; Is midi input a CC? 
  if statusbyte between 176 and 192 ; check status byte for cc
    {
        cc := (byte1 + 3) ; Set var cc and change the cc number up 3 for a different controller number
        GuiControl,12:, MidiMsOut, %statusbyte% %chan% %cc% %byte2%
        gosub, sendCC
    }


Replace the above code with the below code.
It will detect if you have pressed a controller on midi chan1. (statusbyte = 176)
If that controller is CC#80 (data1) it will press the numlock key, if it is cc#90 it will press the capslock key.
Replace the 80 or 90 with the number of your (button) cc# and try it.

Code:
ifequal, statusbyte, 176 ; is data input a cc message, midi ch 1?
   {
       ifegual, byte1, 80 ; byte1 for cc is the cc# (is this cc, cc#80?)
          {
               send {NumLock} ; if it was cc80 then send a numlock keypress
           }
         
       ifequal, byte1, 90 ; is this cc, cc#90 ?
           {
               send {CapsLock} ; if it was cc90 then send a capslock
           }
             
     }



See how you get on with that. PM me if you like and I will help you more.

Remember a CC# = data1 or what controller number it is.

CC value = data2 or what value that controller is on. example on = 127 and off = 0 (for a button)
The above code does not care what cc value it is, only if it is the correct cc#

_________________
KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 2nd, 2010, 8:50 pm 
genmce,

thank you for putting together this awesome script. i've been working to create a midi control map for my pc for about a month now and I was wondering....would it be possible to use a midi event queue with this script?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 2nd, 2010, 10:54 pm 
mQueue1 wrote:
genmce,

thank you for putting together this awesome script. i've been working to create a midi control map for my pc for about a month now and I was wondering....would it be possible to use a midi event queue with this script?


Good question, I don't know.
Related, I want to figure out how to do sysex with ahk.
At this time, I don't know.

There are scripts on the midi out thread that talk about some queue talk there...


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 2nd, 2010, 10:57 pm 
I'm going to try using the Critical function to see how that works with queueing....

What roadblocks have you found with sysex?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 2nd, 2010, 11:01 pm 
genmce(guest) wrote:
mQueue1 wrote:
genmce,

thank you for putting together this awesome script. i've been working to create a midi control map for my pc for about a month now and I was wondering....would it be possible to use a midi event queue with this script?


Good question, I don't know.
Related, I want to figure out how to do sysex with ahk.
At this time, I don't know.

There are scripts on the midi out thread that talk about some queue talk there...


Let me rephrase that... I thought about the question a few seconds longer.
Depends on what you are after - can you be more specific with your question?

Do you want to use a single midi keyboard event to send multiple pc keyboard presses? Yes, that is possible...
More details please.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 3rd, 2010, 2:16 am 
Offline

Joined: January 10th, 2009, 1:34 pm
Posts: 135
Location: Virginia
New - version 0.3 posted for you pleasure. See top post in thread.

_________________
KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk?


Report this post
Top
 Profile  
Reply with quote  
PostPosted: September 4th, 2010, 2:46 pm 
Offline

Joined: September 4th, 2010, 1:43 pm
Posts: 7
Sorry, have been trying for the last 2 hours to get my head aound this...

All I want to do is send a volume change with a key press....

If I connect up my BCF2000 controller, the message window shows that 176 1 7 0-127 is working, it also pumps this out to my specified midi receiver.... so I tried doing this:

Code:
#!6:: GuiControl,12:, MidiMsOutSend, CCOut:176 1 7 0
midiOutShortMsg(h_midiout, statusbyte, cc, byte2)
Return


The message window shows CCOut:176 1 7 0 but my receiver never gets the message. :(

What have I missed?

Thanks for your help, props to all who made this ahk happen, it's amazing...


Report this post
Top
 Profile  
Reply with quote  
PostPosted: September 4th, 2010, 4:40 pm 
Offline

Joined: January 10th, 2009, 1:34 pm
Posts: 135
Location: Virginia
tdg wrote:
Sorry, have been trying for the last 2 hours to get my head aound this...

All I want to do is send a volume change with a key press....

If I connect up my BCF2000 controller, the message window shows that 176 1 7 0-127 is working, it also pumps this out to my specified midi receiver.... so I tried doing this:

Code:
#!6:: GuiControl,12:, MidiMsOutSend, CCOut:176 1 7 0
midiOutShortMsg(h_midiout, statusbyte, cc, byte2)
Return


The message window shows CCOut:176 1 7 0 but my receiver never gets the message. :(

What have I missed?

Thanks for your help, props to all who made this ahk happen, it's amazing...


Yeah - sorry, I did not even give any examples of midi messages from a hotkey! All my examples are of converting midi input.
I will get back later (possibly today) and post a new version with some examples of that.
I have no time right now.

_________________
KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 5th, 2010, 1:11 am 
mQueue1 wrote:
I'm going to try using the Critical function to see how that works with queueing....

What roadblocks have you found with sysex?



That I don't know how to pack the message.


Report this post
Top
  
Reply with quote  
 Post subject: Version 0.4 added at top
PostPosted: September 5th, 2010, 2:11 pm 
Offline

Joined: January 10th, 2009, 1:34 pm
Posts: 135
Location: Virginia
See new version 0.4 at the top.

Added hotkey generated midi message examples.

Makes it kind of complex to read now tho...
I May need to revisit and break things out into include files, to improve readability ... etc...

_________________
KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 7th, 2010, 11:15 pm 
Offline

Joined: September 4th, 2010, 1:43 pm
Posts: 7
Sorry for the delay in thanking you for doing that.....

You are right, it is a bit confusing.... a lot of stuff in there.

Still, I am happy because I have managed to do what I wanted so thank you very much. :)


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 98 posts ]  Go to page 1, 2, 3, 4, 5 ... 7  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: rrhuffy and 54 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group