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)]
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)]
private static extern PmError Pm_Close(IntPtr stream);
[DllImport(NativeLibrary, EntryPoint = "Pm_Write", CallingConvention = CallingConvention.Cdecl)]
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)]
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()
{
PmError error = Pm_Initialize();
@ -56,6 +72,7 @@ namespace PortMidi
Pt_Start(1, 0, 0);
}
// Terminate terminates and cleans up the midi streams.
public static void Terminate()
{
Pt_Stop();
@ -66,31 +83,44 @@ namespace PortMidi
}
}
// CountDevices returns the number of MIDI devices.
public static int CountDevices()
{
return Pm_CountDevices();
}
// convertToError converts a portmidi error code to a error text.
public static string ConvertToError(PmError 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)
{
return Marshal.PtrToStructure<PmDeviceInfo>(Pm_GetDeviceInfo(deviceID));
}
// DefaultInputDeviceID returns the default input device's ID.
public static int DefaultInputDeviceID()
{
return Pm_GetDefaultInputDeviceID();
}
// DefaultOutputDeviceID returns the default output device's ID.
public static int DefaultOutputDeviceID()
{
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)
{
IntPtr pmStream = IntPtr.Zero;
@ -107,6 +137,24 @@ namespace PortMidi
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)
{
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)
{
Event evt = new Event();
@ -149,6 +198,43 @@ namespace PortMidi
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)
{
if (stream.pmStream == IntPtr.Zero)
@ -161,5 +247,40 @@ namespace PortMidi
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));
}
}
}