1
0
Fork 0

Finish implement all Output functions + Add comment + implement NewInputStream function

This commit is contained in:
Florian RICHER (MrDev023) 2019-02-24 15:23:19 +01:00
parent 6ee47d9f07
commit cc3af59dc7

View file

@ -37,15 +37,31 @@ namespace PortMidi
[DllImport(NativeLibrary, EntryPoint = "Pm_OpenOutput", CallingConvention = CallingConvention.Cdecl)] [DllImport(NativeLibrary, EntryPoint = "Pm_OpenOutput", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_OpenOutput(IntPtr* stream, int outputDeviceID, IntPtr outputDriverInfo, int bufferSize, IntPtr time_proc, IntPtr time_info, int latency); private static extern PmError Pm_OpenOutput(IntPtr* stream, int outputDeviceID, IntPtr outputDriverInfo, int bufferSize, IntPtr time_proc, IntPtr time_info, int latency);
[DllImport(NativeLibrary, EntryPoint = "Pm_OpenInput", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_OpenInput(IntPtr* stream, int inputDeviceID, IntPtr inputDriverInfo, int bufferSize, IntPtr time_proc, IntPtr time_info);
[DllImport(NativeLibrary, EntryPoint = "Pm_Close", CallingConvention = CallingConvention.Cdecl)] [DllImport(NativeLibrary, EntryPoint = "Pm_Close", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_Close(IntPtr stream); private static extern PmError Pm_Close(IntPtr stream);
[DllImport(NativeLibrary, EntryPoint = "Pm_Write", CallingConvention = CallingConvention.Cdecl)] [DllImport(NativeLibrary, EntryPoint = "Pm_Write", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_Write(IntPtr stream, PmEvent* buffer, int length); private static extern PmError Pm_Write(IntPtr stream, PmEvent* buffer, int length);
[DllImport(NativeLibrary, EntryPoint = "Pm_WriteSysEx", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_WriteSysEx(IntPtr stream, int when, byte* msg);
[DllImport(NativeLibrary, EntryPoint = "Pm_SetChannelMask", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_SetChannelMask(IntPtr stream, int mask);
[DllImport(NativeLibrary, EntryPoint = "Pm_Abort", CallingConvention = CallingConvention.Cdecl)]
private static extern PmError Pm_Abort(IntPtr stream);
[DllImport(NativeLibrary, EntryPoint = "Pt_Time", CallingConvention = CallingConvention.Cdecl)] [DllImport(NativeLibrary, EntryPoint = "Pt_Time", CallingConvention = CallingConvention.Cdecl)]
private static extern int Pt_Time(); private static extern int Pt_Time();
// Initialize initializes the portmidi. Needs to be called before
// making any other call from the portmidi package.
// Once portmidi package is no longer required, Terminate should be
// called to free the underlying resources.
public static void Initialize() public static void Initialize()
{ {
PmError error = Pm_Initialize(); PmError error = Pm_Initialize();
@ -56,6 +72,7 @@ namespace PortMidi
Pt_Start(1, 0, 0); Pt_Start(1, 0, 0);
} }
// Terminate terminates and cleans up the midi streams.
public static void Terminate() public static void Terminate()
{ {
Pt_Stop(); Pt_Stop();
@ -66,31 +83,44 @@ namespace PortMidi
} }
} }
// CountDevices returns the number of MIDI devices.
public static int CountDevices() public static int CountDevices()
{ {
return Pm_CountDevices(); return Pm_CountDevices();
} }
// convertToError converts a portmidi error code to a error text.
public static string ConvertToError(PmError error) public static string ConvertToError(PmError error)
{ {
return Pm_GetErrorText(error); return Pm_GetErrorText(error);
} }
// Info returns the device info for the device indentified with deviceID.
// If deviceID is out of range, Info returns null.
public static PmDeviceInfo Info(int deviceID) public static PmDeviceInfo Info(int deviceID)
{ {
return Marshal.PtrToStructure<PmDeviceInfo>(Pm_GetDeviceInfo(deviceID)); return Marshal.PtrToStructure<PmDeviceInfo>(Pm_GetDeviceInfo(deviceID));
} }
// DefaultInputDeviceID returns the default input device's ID.
public static int DefaultInputDeviceID() public static int DefaultInputDeviceID()
{ {
return Pm_GetDefaultInputDeviceID(); return Pm_GetDefaultInputDeviceID();
} }
// DefaultOutputDeviceID returns the default output device's ID.
public static int DefaultOutputDeviceID() public static int DefaultOutputDeviceID()
{ {
return Pm_GetDefaultOutputDeviceID(); return Pm_GetDefaultOutputDeviceID();
} }
// Time returns the portmidi timer's current time.
public static int Time ()
{
return Pt_Time();
}
// NewOutputStream initializes a new output stream.
public static Stream NewOutputStream(int deviceID, int bufferSize, int latency) public static Stream NewOutputStream(int deviceID, int bufferSize, int latency)
{ {
IntPtr pmStream = IntPtr.Zero; IntPtr pmStream = IntPtr.Zero;
@ -107,6 +137,24 @@ namespace PortMidi
return new Stream(deviceID, pmStream, StreamType.OUTPUT, bufferSize); return new Stream(deviceID, pmStream, StreamType.OUTPUT, bufferSize);
} }
// NewInputStream initializes a new input stream.
public static Stream NewInputStream(int deviceID, int bufferSize)
{
IntPtr pmStream = IntPtr.Zero;
PmDeviceInfo deviceInfo = Info(deviceID);
if (deviceInfo.input != 1) throw new Exception("Selected DeviceID is not an input");
PmError error = Pm_OpenInput(&pmStream, deviceID, IntPtr.Zero, bufferSize, IntPtr.Zero, IntPtr.Zero);
if (error != 0)
{
throw new Exception(ConvertToError(error));
}
return new Stream(deviceID, pmStream, StreamType.INPUT, bufferSize);
}
// Write writes a buffer of MIDI events to the output stream.
public static void Write(Stream stream, Event[] events) public static void Write(Stream stream, Event[] events)
{ {
int size = events.Length; int size = events.Length;
@ -139,6 +187,7 @@ namespace PortMidi
} }
} }
// WriteShort writes a MIDI event of three bytes immediately to the output stream.
public static void WriteShort(Stream stream, int status, int data1, int data2) public static void WriteShort(Stream stream, int status, int data1, int data2)
{ {
Event evt = new Event(); Event evt = new Event();
@ -149,6 +198,43 @@ namespace PortMidi
Write(stream, new Event[] { evt }); Write(stream, new Event[] { evt });
} }
// WriteSysExBytes writes a system exclusive MIDI message given as a []byte to the output stream.
public static void WriteSysExBytes(Stream stream,int when, byte[] msg)
{
fixed (byte* p = &msg[0])
{
PmError error = Pm_WriteSysEx(stream.pmStream, when, p);
if (error != 0)
{
throw new Exception(ConvertToError(error));
}
}
}
// WriteSysEx writes a system exclusive MIDI message given as a string of hexadecimal characters to
// the output stream. The string must only consist of hex digits (0-9A-F) and optional spaces. This
// function is case-insenstive.
public static void WriteSysEx(Stream stream, int when, string msg)
{
WriteSysExBytes(stream, when, StringToByteArrayFastest(msg.Replace(" ", "")));
}
// SetChannelMask filters incoming stream based on channel.
// In order to filter from more than a single channel, or multiple channels.
// s.SetChannelMask(Channel(1) | Channel(10)) will both filter input
// from channel 1 and 10.
public static void SetChannelMask(Stream stream, int mask)
{
PmError error = Pm_SetChannelMask(stream.pmStream, mask);
if (error != 0)
{
throw new Exception(ConvertToError(error));
}
}
// Close closes the MIDI stream.
public static void Close(Stream stream) public static void Close(Stream stream)
{ {
if (stream.pmStream == IntPtr.Zero) if (stream.pmStream == IntPtr.Zero)
@ -161,5 +247,40 @@ namespace PortMidi
throw new Exception(ConvertToError(error)); throw new Exception(ConvertToError(error));
} }
} }
// Abort aborts the MIDI stream.
public static void Abort(Stream stream)
{
if (stream.pmStream == IntPtr.Zero)
{
return;
}
PmError error = Pm_Abort(stream.pmStream);
if (error != 0)
{
throw new Exception(ConvertToError(error));
}
}
public static byte[] StringToByteArrayFastest(string hex)
{
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
public static int GetHexVal(char hex)
{
int val = (int)hex;
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
} }
} }