mirror of
https://git.femboyfinancial.jp/james/lipsync.git
synced 2024-11-25 12:02:00 -08:00
85 lines
2.8 KiB
C#
85 lines
2.8 KiB
C#
|
/*
|
|||
|
* MidiOutDevice.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.Windows.Forms;
|
|||
|
|
|||
|
using bocoree;
|
|||
|
|
|||
|
namespace Boare.Lib.Media {
|
|||
|
|
|||
|
public unsafe class MidiOutDevice {
|
|||
|
private IntPtr m_handle;
|
|||
|
private uint m_device_id;
|
|||
|
|
|||
|
public MidiOutDevice( uint device_id ) {
|
|||
|
m_device_id = device_id;
|
|||
|
windows.midiOutOpen( ref m_handle, m_device_id, null, 0, windows.CALLBACK_NULL );
|
|||
|
}
|
|||
|
|
|||
|
public void Close() {
|
|||
|
if ( !m_handle.Equals( IntPtr.Zero ) ) {
|
|||
|
windows.midiOutClose( m_handle );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void ProgramChange( byte channel, byte program ) {
|
|||
|
SendShort( new byte[] { (byte)(0xc0 | (channel & 0x0f)) , program, 0x0 } );
|
|||
|
}
|
|||
|
|
|||
|
public void Play( byte channel, byte note, byte velocity ) {
|
|||
|
SendShort( new byte[] { (byte)(0x90 | (channel & 0x0f)), note, velocity } );
|
|||
|
}
|
|||
|
|
|||
|
public void SendData( byte[] data ) {
|
|||
|
if ( 0 < data.Length && data.Length <= 4 ) {
|
|||
|
SendShort( data );
|
|||
|
} else {
|
|||
|
SendLong( data );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SendShort( byte[] data ) {
|
|||
|
uint message = 0;
|
|||
|
for ( int i = 0; i < data.Length; i++ ) {
|
|||
|
message |= ((uint)data[i]) << (i * 8);
|
|||
|
}
|
|||
|
windows.midiOutShortMsg( m_handle, message );
|
|||
|
}
|
|||
|
|
|||
|
private void SendLong( byte[] data ) {
|
|||
|
MIDIHDR hdr = new MIDIHDR();
|
|||
|
GCHandle dataHandle = GCHandle.Alloc( data, GCHandleType.Pinned );
|
|||
|
uint size = (uint)sizeof( MIDIHDR );
|
|||
|
try {
|
|||
|
hdr.lpData = (byte*)dataHandle.AddrOfPinnedObject().ToPointer();
|
|||
|
hdr.dwBufferLength = (uint)data.Length;
|
|||
|
hdr.dwFlags = 0;
|
|||
|
windows.midiOutPrepareHeader( m_handle, ref hdr, size );
|
|||
|
while ( (hdr.dwFlags & windows.WHDR_PREPARED) != windows.WHDR_PREPARED ) {
|
|||
|
Application.DoEvents();
|
|||
|
}
|
|||
|
windows.midiOutLongMsg( m_handle, ref hdr, size );
|
|||
|
while ( (hdr.dwFlags & windows.WHDR_DONE) != windows.WHDR_DONE ) {
|
|||
|
Application.DoEvents();
|
|||
|
}
|
|||
|
windows.midiOutUnprepareHeader( m_handle, ref hdr, size );
|
|||
|
} finally {
|
|||
|
dataHandle.Free();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|