2009-06-25 07:16:22 -07:00
|
|
|
|
/*
|
|
|
|
|
* MidiInDevice.cs
|
|
|
|
|
* Copyright (c) 2009 kbinani
|
|
|
|
|
*
|
|
|
|
|
* This file is part of Boare.Lib.Media.
|
|
|
|
|
*
|
|
|
|
|
* Boare.Lib.Media is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the BSD License.
|
|
|
|
|
*
|
|
|
|
|
* Boare.Lib.Media is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
*/
|
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
using bocoree;
|
|
|
|
|
|
|
|
|
|
namespace Boare.Lib.Media {
|
|
|
|
|
|
|
|
|
|
public delegate void MidiReceivedEventHandler( DateTime time, byte[] data );
|
|
|
|
|
|
|
|
|
|
public class MidiInDevice : IDisposable {
|
|
|
|
|
delegate void MidiInProcDelegate( uint hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2 );
|
|
|
|
|
|
|
|
|
|
private volatile MidiInProcDelegate m_delegate;
|
|
|
|
|
private IntPtr m_delegate_pointer;
|
|
|
|
|
private uint m_hmidiin = 0;
|
|
|
|
|
private int m_port_number;
|
|
|
|
|
|
|
|
|
|
public event MidiReceivedEventHandler MidiReceived;
|
|
|
|
|
|
|
|
|
|
public MidiInDevice( int port_number ) {
|
|
|
|
|
m_port_number = port_number;
|
|
|
|
|
m_delegate = new MidiInProcDelegate( MidiInProc );
|
|
|
|
|
m_delegate_pointer = Marshal.GetFunctionPointerForDelegate( m_delegate );
|
2009-07-29 10:03:20 -07:00
|
|
|
|
windows.midiInOpen( ref m_hmidiin, port_number, m_delegate_pointer, 0, windows.CALLBACK_FUNCTION );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Start() {
|
|
|
|
|
if ( m_hmidiin > 0 ) {
|
|
|
|
|
try {
|
|
|
|
|
windows.midiInStart( m_hmidiin );
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
debug.push_log( "MidiInDevice.Start" );
|
|
|
|
|
debug.push_log( " ex=" + ex );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Stop() {
|
|
|
|
|
if ( m_hmidiin > 0 ) {
|
|
|
|
|
try {
|
|
|
|
|
windows.midiInReset( m_hmidiin );
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
debug.push_log( "MidiInDevice.Stop" );
|
|
|
|
|
debug.push_log( " ex=" + ex );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Close() {
|
|
|
|
|
if ( m_hmidiin > 0 ) {
|
|
|
|
|
try {
|
|
|
|
|
windows.midiInClose( m_hmidiin );
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
debug.push_log( "MidiInDevice.Close" );
|
|
|
|
|
debug.push_log( " ex=" + ex );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_hmidiin = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose() {
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int GetNumDevs() {
|
|
|
|
|
try {
|
|
|
|
|
int i = (int)windows.midiInGetNumDevs();
|
|
|
|
|
return i;
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
debug.push_log( "MidiInDevice.GetNumDevs" );
|
|
|
|
|
debug.push_log( " ex=" + ex );
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static MIDIINCAPS[] GetMidiInDevices() {
|
|
|
|
|
List<MIDIINCAPS> ret = new List<MIDIINCAPS>();
|
|
|
|
|
uint num = 0;
|
|
|
|
|
try {
|
|
|
|
|
num = windows.midiInGetNumDevs();
|
|
|
|
|
} catch {
|
|
|
|
|
num = 0;
|
|
|
|
|
}
|
|
|
|
|
for ( uint i = 0; i < num; i++ ) {
|
|
|
|
|
MIDIINCAPS m = new MIDIINCAPS();
|
|
|
|
|
uint r = windows.midiInGetDevCaps( i, ref m, (uint)Marshal.SizeOf( m ) );
|
|
|
|
|
ret.Add( m );
|
|
|
|
|
}
|
|
|
|
|
return ret.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-29 10:03:20 -07:00
|
|
|
|
public void MidiInProc( uint hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2 ) {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
try {
|
|
|
|
|
switch ( wMsg ) {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
case windows.MM_MIM_OPEN:
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
case windows.MM_MIM_CLOSE:
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
case windows.MM_MIM_DATA:
|
2009-06-25 07:16:22 -07:00
|
|
|
|
int receive = dwParam1;
|
|
|
|
|
DateTime now = DateTime.Now;
|
|
|
|
|
switch ( receive & 0xF0 ) {
|
|
|
|
|
case 0x80:
|
|
|
|
|
case 0x90:
|
|
|
|
|
case 0xa0:
|
|
|
|
|
case 0xb0:
|
|
|
|
|
case 0xe0:
|
|
|
|
|
if ( MidiReceived != null ) {
|
|
|
|
|
MidiReceived( now, new byte[] { (byte)(receive & 0xff),
|
|
|
|
|
(byte)((receive & 0xffff) >> 8),
|
|
|
|
|
(byte)((receive & ((2 << 24) - 1)) >> 16) } );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0xc0:
|
|
|
|
|
case 0xd0:
|
|
|
|
|
if ( MidiReceived != null ) {
|
|
|
|
|
MidiReceived( now, new byte[] { (byte)( receive & 0xff ),
|
|
|
|
|
(byte)((receive & 0xffff) >> 8) } );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
case windows.MM_MIM_LONGDATA:
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
case windows.MM_MIM_ERROR:
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
case windows.MM_MIM_LONGERROR:
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
debug.push_log( "MidiInDevice.MidiInProc" );
|
|
|
|
|
debug.push_log( " ex=" + ex );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|