Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

MIDI input library


  • Please log in to reply
90 replies to this topic
automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006

What do you think, which methods would be interesting to create such unique integer numbers?

The best solution I have so far is simply using two binary numbers, one created using only the black keys with 5 bits, and the second one created using only the white keys with 7 bits. In the case of the black keys we could generate numbers 1..31 and in the case of the white keys we could generate numbers 1..127. As a nice side effect we would learn over time the binary representations of numbers in the range up to 7bit.

The pseudocode for the black keys would look something like
FunctionNumber(pc)	;  pc is pitchclass, here only for the black keys
{
	r = 0
	if (pc == 10) 	r+=1	;  key Bb
	if (pc == 8)	r+=2	;  key Ab
	if (pc == 6)	r+=4	;  key Gb
	if (pc == 3)	r+=8	;  key Eb
	if (pc == 1)	r+=16	;  key Db
	return r
}

FunctionNumber would create based on the black key combinations an output function number 1..31 which can be used then to select a certain function for processing, e.g. using the EnterPad method. This would be similar to selecting from menus having at maximum 31 menu options.

ilyaorlov
  • Members
  • 1 posts
  • Last active: Oct 14 2009 10:38 AM
  • Joined: 14 Oct 2009
Thank you, orbik, for you work! It's great!

bio1
  • Guests
  • Last active:
  • Joined: --
How can I capture the "Sustenuto" Key (Left pedal on piano)?

It works with Bome, there the key name is "B0 43 7F" or CC #1: Sustenuto, 127

Any help would be appreciated.

bio1
  • Guests
  • Last active:
  • Joined: --
How can I capture the "Sustenuto" Key (Left pedal on piano)?

It works with Bome, there the key name is "B0 43 7F" or CC #1: Sustenuto, 127

Any help would be appreciated.

genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009
Hey all,

I am wondering if one can have multiple midi in ports active at the same time?
All doing listenCC or listenNote activities.

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


automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006

I am wondering if one can have multiple midi in ports active at the same time?
All doing listenCC or listenNote activities.

No unfortunately not, that is the reason why using Keykit together with AHK might be a much more powerful solution as Keykit supports any combination of available input and output midi ports.

Or changing/extending this midi input library would be the second option.

genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

I am wondering if one can have multiple midi in ports active at the same time?
All doing listenCC or listenNote activities.

No unfortunately not, that is the reason why using Keykit together with AHK might be a much more powerful solution as Keykit supports any combination of available input and output midi ports.

Or changing/extending this midi input library would be the second option.


- then changing extending this lib might be easier, however, I don't know how to do that.

I am hesitant to go toward keykit, but I probably should.

I think a solution that uses 1 program, not multiple ones will be more stable.

However, I suppose I should go to keykit and download it, do you have some relatively simple things for me to look at? Patches, does it use patches or scripts? Can you email a basic patch you have been tweeking, you have my email from our email conversation.

Do you know how to modify the current midi_in lib to accept multiple inputs?

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


automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
Another problem with the midi input library I experience is it sends for each incoming note on event as input two hotkey events as output. I could not find out the reason for this behaviour. I would prefer

1 incoming midi event --> 1 outgoing hotkey event

Right now it seems to be here

1 incoming midi event --> 2 outgoing hotkey events, twice the same event

genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

Another problem with the midi input library I experience is it sends for each incoming note on event as input two hotkey events as output. I could not find out the reason for this behaviour. I would prefer

1 incoming midi event --> 1 outgoing hotkey event

Right now it seems to be here

1 incoming midi event --> 2 outgoing hotkey events, twice the same event


I understand - now, forgive my email, I had not noticed it would send two text events.
I am looking at it, I will post something when I find something.

I am looking at the midi_in.cpp file and wondering how we actually get the note on, off value to be able to work that in to code,
I think what is happening is that the events we generate using
listen note trigger 1 event for note on and one for note off.
Does the midi_in lib need to be redone?
Here is a snip from the source of midi_in.dll
Don't we need some kind of statment for the msgNumber param?

DLLEXPORT int listenNote(int noteNumber, int channel, int msgNumber) {
	if (noteNumber < 0 || noteNumber > 127)
		return -1;
	if (channel < 0 || channel > 16)
		return -2;

	if (channel == 0) for (int i=0; i<16; i++) {
		ruleNoteOn[noteNumber][i] =
		ruleNoteOff[noteNumber][i] = msgNumber;
	}
	else {
		ruleNoteOn[noteNumber][channel-1] =
		ruleNoteOff[noteNumber][channel-1] = msgNumber;
	}

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


genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

Another problem with the midi input library I experience is it sends for each incoming note on event as input two hotkey events as output. I could not find out the reason for this behaviour. I would prefer

1 incoming midi event --> 1 outgoing hotkey event

Right now it seems to be here

1 incoming midi event --> 2 outgoing hotkey events, twice the same event


Yeah ... I see what you mean now.
I have been pounding my head against the wall trying to find a work around for this.

In my pondering, I find that my keyboard, Line 6 KB37, does not output what I would expect for a midi keyboard.
midiox output:
I push key 60 down and I get
|status|data1|data2|chan|note|event
| 144 | 60 | 80 | 1 | C 4| Note On | ok, no surprises
key 60 up
| 128 | 60 | 87 | 1 | C 4| Note Off |

*** huh? why is data2 (vel) 87 for a Note Off msg?
So if we try to code for something based on vel =0 we never get it.

/* 

see the tool tip for changes in the vel value, when you press note 60.

*/

#Persistent
#SingleInstance
SendMode Input 
SetWorkingDir %A_ScriptDir% 

OnExit, sub_exit 
if (midi_in_Open(8)) ; MINE IS SET TO MIDI PORT 8, A REAL MIDI INPUT. ;YOU MIGHT HAVE TO CHANGE YOURS. USE THE TRAY MENU TO COUNT ;WHICH PORT TO SET ACTIVE.
ExitApp 

;vel :=0
ToolTip, note=%note% Vel=%vel% status=%status% 
;--------------------  Midi "hotkey" mappings  ----------------------- 
listenNote(60, "NotePush",1)  ; listen to note #60 if heard run 
return 
;----------------------End of auto execute section-------------------- 

sub_exit: ; this just runs the exit command and stops midi and closes theport
   midi_in_Stop() ;speeds up the closing by stopping first.
   midi_in_Close() 
   ExitApp 

;-------------------------Miscellaneous hotkeys----------------------- 
Esc::           ; hotkey to exit the app.
gosub, sub_exit ; runs the subroutine above
Return

;-------------------------Midi "hotkey" functions--------------------- 

NotePush(note, vel, status) ; here is 1 midi note event with 1 midi output event0
   
   { 
		toolTip, note=%note% Vel=%vel% status=%status% 
   }
 return 
  
;-------------------------  Midi input library  ---------------------- 
#include midi_in_lib.ahk ; this file you must have in your same folder

How do we gain access to the "note on", "note off" message or the status message?
The status message, afaik, did not change on the script above, even though I know it does viewing on midiox.
So it appears the that double trigger occurs because the, somewhere, the noteoff is being treated as a second note on.
How do we filter the second event, the second note on?
I tried last night but to no avail. If I get a chance I will post here or ask for help on the ask for help section...
Any thoughts ?

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


automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
My current suggestion would be: As long as we do not make any direct use of duration which is the difference in time between note off time and note on time, we could simply ommit all note on events and consider only note off events for events detection.

At least until duration is "officially supported" by this midi input library it would behave as wanted.

automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
ruleNoteOn[noteNumber][i] =
		ruleNoteOff[noteNumber][i] = msgNumber;
I also did not understand the meaning of the empty assignment for ruleNoteOn, can't we just comment out just this line? What does this line do?

Or doing the opposite, defining as:

ruleNoteOn[noteNumber][i] = msgNumber;
and commenting out the ruleNoteOff parts everywhere.

genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

My current suggestion would be: As long as we do not make any direct use of duration which is the difference in time between note off time and note on time, we could simply ommit all note on events and consider only note off events for events detection.

At least until duration is "officially supported" by this midi input library it would behave as wanted.


I like that idea very much.
How do we access the noteOn, noteoff status from this lib?
Where/how do we pick up the value to use?

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


genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

ruleNoteOn[noteNumber][i] =
		ruleNoteOff[noteNumber][i] = msgNumber;
I also did not understand the meaning of the empty assignment for ruleNoteOn, can't we just comment out just this line? What does this line do?

Or doing the opposite, defining as:

ruleNoteOn[noteNumber][i] = msgNumber;
and commenting out the ruleNoteOff parts everywhere.


We are out of our depth and swimming against the tide.
My C++ skills are limited and rebuilding the lib ... I don't even have a compiler set up, properly, to accomplish this.
We need someone to help us understand what is going on and how to find our way.
It would be great if we could solve this issue and add the option for multiple input and output ports.

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


genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

Another problem with the midi input library I experience is it sends for each incoming note on event as input two hotkey events as output. I could not find out the reason for this behaviour. I would prefer

1 incoming midi event --> 1 outgoing hotkey event

Right now it seems to be here

1 incoming midi event --> 2 outgoing hotkey events, twice the same event


This is unfortunately true - when using the midi_in.ahk and midi_in.dll a single keypress results in two outputs.
At Orbiks suggestion from a message I got from him a while ago, I went back to look at directly calling the winmm.dll, bypassing his midi_in stuff.

It means writing if statements instead of using his listenNote or listenCC functions he wrote in midi_in.ahk.


/* 
	This code is written by orbik and others,
        I somewhat hacked it.
	
1. Try this just using the tool tip first, when that makes sense, comment the tool tip out
	
2. Then Uncomment the lines at 112 for sending text
		- TAKES A MIDI NOTE AND CONVERTS IT TO A KEYPRESS.
		- IT WILL SEND NOTE ON TEXT WHEN NOTE 60 (MIDILE c) AND
*/

;;"#defines"

; SET THIS DEVICEiD TO YOUR MIDI INPUT PORT, 0 IS THE FIRST MIDI PORT, 
; IF YOU DON'T KNOW THE MIDI PORT USE MIDIOX TO FIND OUT. 
DeviceID := 8 
CALLBACK_WINDOW := 0x10000

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#Persistent

Gui, +LastFound
hWnd := WinExist()

;MsgBox, hWnd = %hWnd%`nPress OK to open winmm.dll library

OpenCloseMidiAPI()
OnExit, Sub_Exit

;MsgBox, winmm.dll loaded.`nPress OK to open midi device`nDevice ID = %DeviceID%`nhWnd = %hWnd%`ndwFlags = CALLBACK_WINDOW

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


;MsgBox, Midi input device opened successfully`nhMidiIn = %hMidiIn%`n`nPress OK to start the midi device

result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn)
If result
	{
		MsgBox, error, midiInStart returned %result%`n
		GoSub, sub_exit
	}


; #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, "midiInHandler") ; calling the function below 
OnMessage(0x3C2, "midiInHandler")
OnMessage(0x3C3, "midiInHandler")
OnMessage(0x3C4, "midiInHandler")
OnMessage(0x3C5, "midiInHandler")
OnMessage(0x3C6, "midiInHandler")

return

;--------End of auto-execute section-----

; =============== this will exit the app when esc is pushed

sub_exit:

	If (hMidiIn)
	DllCall("winmm.dll\midiInClose", UInt,hMidiIn)
	OpenCloseMidiAPI()

	ExitApp



OpenCloseMidiAPI() ; calls the winmm.dll to close midi port
	{
		Static hModule
		If hModule
		DllCall("FreeLibrary", UInt,hModule), hModule := ""
		If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) 
		{
			MsgBox Cannot load library winmm.dll
			ExitApp
		}
	}


midiInHandler(hInput, midiMsg, wMsg) ; THIS IS THE MIDI IN FUNCTION WHERE THE MIDI MESSAGE IS BROKEN UP 
{
	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


;THIS SECTION WILL SEND TEXT - OPEN NOTEPAD AND GIVE IT FOCUS WITH THIS RUNNING
;UNCOMMENT THIS SECTION BELOW TO HAVE THE midi note >TEXT ;SENT.

/*  
	If ((byte1 = 60) & (statusbyte = 144))  ; test note number and status for Note ON (144) and note number middle C
		{
			send, Note %byte1% on, 			; TYPES TEXT WITH THE NOTE NUMBER VAR.  
		}
		Else if ((byte1 = 60) & (statusbyte = 128)) ; test for note off
		{
			send, Note %byte1% off
		}
	
	; Just trying the same idea on a different note a differnt way
	If (byte1 = 62) ; test for note 62 - attempt at splitting the test up
		{
			if (statusbyte = 144) ; is the note above on?
			{
				send, Note %byte1% on 
			}
			Else if (statusbyte = 128) ; is the note off
			{
				send, Note %byte1% off 
			}
		}
*/

;AFTER YOU PLAY WITH THIS FOR A LITTLE WHILE AND SEE IT WORK COMMENT THIS OUT OR USE IT FOR KNOWING WHAT MESSAGES ARE DOING

;/*
ToolTip, ; THIS WILL SHOW A TOOL TIP OF THE MIDI DATA FROM EACH KEYPRESS OR CC PRESS.
(
Received a message: %wMsg%
wParam = %hInput%
lParam = %midiMsg%
statusbyte = %statusbyte%
chan = %chan%
byte1 = %byte1%
byte2 = %byte2%
)
; */ 

}
Return

Esc::GoSub, sub_exit

/*
below is written by orbik

My dll approach is a bit different. The idea was to have the dll call a specified window with messages specified separately for each input type, note/cc number and channel, and then only send messages where it's specified. And since I doubt the code tag would display c++ code properly, i put all relevant files to http://ihme.org/~orbik/midi4ahk/

Some parts of the scripts are borrowed from various fellow ahk users, and I wish I remembered who they were.
*/

automaticman has shown (some other forum) that he is able to eliminate the double keypress problem.

I just thought it might be nice to have this option out here as well.

I am thinking about not using the midi_in.ahk nor midi_in.dll at all and just calling the winmm.dll directly.
I would like an option to open multiple midi in ports and bring messages from different midi ports for conversion to keypresses.
I also want to have the midi out working with multiple ports so midi out messages can send multiple messages that way.
I will post that in that ask for help section after I figure out how to articulate with a code example.

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