#pragma warning disable IDE1006 // Naming Styles
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Vanara.PInvoke
{
/// Items from the WinMm.dll
public static partial class WinMm
{
///
public const int MIDIPATCHSIZE = 128;
/// Flags giving information about the buffer.
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midihdr_tag")]
[Flags]
public enum MHDR : uint
{
/// Set by the device driver to indicate that it is finished with the buffer and is returning it to the application.
MHDR_DONE = 0x00000001,
///
/// Set by Windows to indicate that the buffer has been prepared by using the midiInPrepareHeader or midiOutPrepareHeader function.
///
MHDR_PREPARED = 0x00000002,
/// Set by Windows to indicate that the buffer is queued for playback.
MHDR_INQUEUE = 0x00000004,
/// Set to indicate that the buffer is a stream buffer.
MHDR_ISSTRM = 0x00000008,
}
/// Options for the cache operation.
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutCacheDrumPatches")]
public enum MIDI_CACHE
{
///
/// Caches all of the specified patches. If they cannot all be cached, it caches none, clears the KEYARRAY array, and returns MMSYSERR_NOMEM.
///
MIDI_CACHE_ALL = 1,
///
/// Caches all of the specified patches. If they cannot all be cached, it caches as many patches as possible, changes the
/// KEYARRAY array to reflect which patches were cached, and returns MMSYSERR_NOMEM.
///
MIDI_CACHE_BESTFIT = 2,
/// Changes the KEYARRAY array to indicate which patches are currently cached.
MIDI_CACHE_QUERY = 3,
/// Uncaches the specified patches and clears the KEYARRAY array.
MIDI_UNCACHE = 4,
}
/// Optional functionality supported by the device.
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.tagMIDIOUTCAPSW")]
[Flags]
public enum MIDI_CAPS : uint
{
/// Supports volume control.
MIDICAPS_VOLUME = 0x0001,
/// Supports separate left and right volume control.
MIDICAPS_LRVOLUME = 0x0002,
/// Supports patch caching.
MIDICAPS_CACHE = 0x0004,
/// Provides direct support for the midiStreamOut function.
MIDICAPS_STREAM = 0x0008,
}
///
/// Flags that specify the action to perform and identify the appropriate property of the MIDI data stream. The
/// midiStreamProperty function requires setting two flags in each use. One flag (either MIDIPROP_GET or MIDIPROP_SET)
/// specifies an action, and the other identifies a specific property to examine or edit.
///
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamProperty")]
[Flags]
public enum MIDIPROP : uint
{
/// Sets the given property.
MIDIPROP_SET = 0x80000000,
/// Retrieves the current setting of the given property.
MIDIPROP_GET = 0x40000000,
///
/// Specifies the time division property. You can get or set this property. The lppropdata parameter points to a MIDIPROPTIMEDIV
/// structure. This property can be set only when the device is stopped.
///
MIDIPROP_TIMEDIV = 0x00000001,
///
/// Retrieves the tempo property. The lppropdata parameter points to a MIDIPROPTEMPO structure. The current tempo value can be
/// retrieved at any time. Output devices set the tempo by inserting MEVT_TEMPO events into the MIDI data.
///
MIDIPROP_TEMPO = 0x00000002,
}
/// Type of the MIDI output device.
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.tagMIDIOUTCAPSW")]
public enum MOD : ushort
{
/// MIDI hardware port.
MOD_MIDIPORT = 1,
/// Synthesizer.
MOD_SYNTH = 2,
/// Square wave synthesizer.
MOD_SQSYNTH = 3,
/// FM synthesizer.
MOD_FMSYNTH = 4,
/// Microsoft MIDI mapper.
MOD_MAPPER = 5,
/// Hardware wavetable synthesizer.
MOD_WAVETABLE = 6,
/// Software synthesizer.
MOD_SWSYNTH = 7,
}
///
/// The midiConnect function connects a MIDI input device to a MIDI thru or output device, or connects a MIDI thru device to
/// a MIDI output device.
///
///
/// Handle to a MIDI input device or a MIDI thru device. (For thru devices, this handle must have been returned by a call to the
/// midiOutOpen function.)
///
/// Handle to the MIDI output or thru device.
/// Reserved; must be NULL.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_NOTREADY
/// Specified input device is already connected to an output device.
///
/// -
/// MMSYSERR_INVALHANDLE
/// Specified device handle is invalid.
///
///
///
///
///
/// After calling this function, the MIDI input device receives event data in an MIM_DATA message whenever a message with the same
/// event data is sent to the output device driver.
///
///
/// A thru driver is a special form of MIDI output driver. The system will allow only one MIDI output device to be connected to a
/// MIDI input device, but multiple MIDI output devices can be connected to a MIDI thru device. Whenever the given MIDI input device
/// receives event data in an MIM_DATA message, a message with the same event data is sent to the given output device driver (or
/// through the thru driver to the output drivers).
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiconnect MMRESULT midiConnect( HMIDI hmi, HMIDIOUT hmo,
// LPVOID pReserved );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiConnect")]
public static extern MMRESULT midiConnect([In] HMIDI hmi, [In] HMIDIOUT hmo, IntPtr pReserved = default);
///
/// The midiDisconnect function disconnects a MIDI input device from a MIDI thru or output device, or disconnects a MIDI thru
/// device from a MIDI output device.
///
/// Handle to a MIDI input device or a MIDI thru device.
/// Handle to the MIDI output device to be disconnected.
/// Reserved; must be NULL.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// Specified device handle is invalid.
///
///
///
///
/// MIDI input, output, and thru devices can be connected by using the midiConnect function. Thereafter, whenever the MIDI
/// input device receives event data in an MIM_DATA message, a message with the same event data is sent to the output device driver
/// (or through the thru driver to the output drivers).
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-mididisconnect MMRESULT midiDisconnect( HMIDI hmi, HMIDIOUT
// hmo, LPVOID pReserved );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiDisconnect")]
public static extern MMRESULT midiDisconnect([In] HMIDI hmi, [In] HMIDIOUT hmo, IntPtr pReserved = default);
///
/// The midiInAddBuffer function sends an input buffer to a specified opened MIDI input device. This function is used for
/// system-exclusive messages.
///
/// Handle to the MIDI input device.
/// Pointer to a MIDIHDR structure that identifies the buffer.
/// Size, in bytes, of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_STILLPLAYING
/// The buffer pointed to by lpMidiInHdr is still in the queue.
///
/// -
/// MIDIERR_UNPREPARED
/// The buffer pointed to by lpMidiInHdr has not been prepared.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
/// When the buffer is filled, it is sent back to the application.
///
/// The buffer must be prepared by using the midiInPrepareHeader function before it is passed to the midiInAddBuffer function.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinaddbuffer MMRESULT midiInAddBuffer( HMIDIIN hmi,
// LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInAddBuffer")]
public static extern MMRESULT midiInAddBuffer([In] HMIDIIN hmi, ref MIDIHDR pmh, uint cbmh);
/// The midiInClose function closes the specified MIDI input device.
///
/// Handle to the MIDI input device. If the function is successful, the handle is no longer valid after the call to this function.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_STILLPLAYING
/// Buffers are still in the queue.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
/// If there are input buffers that have been sent by using the midiInAddBuffer function and have not been returned to the
/// application, the close operation will fail. To return all pending buffers through the callback function, use the midiInReset function.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinclose MMRESULT midiInClose( HMIDIIN hmi );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInClose")]
public static extern MMRESULT midiInClose([In] HMIDIIN hmi);
/// The midiInGetDevCaps function determines the capabilities of a specified MIDI input device.
///
/// Identifier of the MIDI input device. The device identifier varies from zero to one less than the number of devices present. This
/// parameter can also be a properly cast device handle.
///
/// Pointer to a MIDIINCAPS structure that is filled with information about the capabilities of the device.
///
/// Size, in bytes, of the MIDIINCAPS structure. Only cbMidiInCaps bytes (or less) of information is copied to the location pointed
/// to by lpMidiInCaps. If cbMidiInCaps is zero, nothing is copied, and the function returns MMSYSERR_NOERROR.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_BADDEVICEID
/// The specified device identifier is out of range.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NODRIVER
/// The driver is not installed.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
/// To determine the number of MIDI input devices present on the system, use the midiInGetNumDevs function.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiingetdevcaps MMRESULT midiInGetDevCaps( UINT uDeviceID,
// LPMIDIINCAPS pmic, UINT cbmic );
[DllImport(Lib_Winmm, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInGetDevCaps")]
public static extern MMRESULT midiInGetDevCaps(uint uDeviceID, out MIDIINCAPS pmic, uint cbmic);
///
/// The midiInGetErrorText function retrieves a textual description for an error identified by the specified error code.
///
/// Error code.
/// Pointer to the buffer to be filled with the textual error description.
/// Length, in characters, of the buffer pointed to by lpText.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_BADERRNUM
/// The specified error number is out of range.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
/// If the textual error description is longer than the specified buffer, the description is truncated. The returned error string is
/// always null-terminated. If cchText is zero, nothing is copied, and the function returns zero. All error descriptions are less
/// than MAXERRORLENGTH characters long.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiingeterrortext MMRESULT midiInGetErrorText( MMRESULT
// mmrError, LPSTR pszText, UINT cchText );
[DllImport(Lib_Winmm, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInGetErrorText")]
public static extern MMRESULT midiInGetErrorText(MMRESULT mmrError, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszText, uint cchText);
///
/// The midiInGetID function gets the device identifier for the given MIDI input device.
///
/// This function is supported for backward compatibility. New applications can cast a handle of the device rather than retrieving
/// the device identifier.
///
///
/// Handle to the MIDI input device.
/// Pointer to a variable to be filled with the device identifier.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The hwi parameter specifies an invalid handle.
///
/// -
/// MMSYSERR_NODRIVER
/// No device driver is present.
///
/// -
/// MMSYSERR_NOMEM
/// Unable to allocate or lock memory.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiingetid MMRESULT midiInGetID( HMIDIIN hmi, LPUINT
// puDeviceID );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInGetID")]
public static extern MMRESULT midiInGetID([In] HMIDIIN hmi, out uint puDeviceID);
/// The midiInGetNumDevs function retrieves the number of MIDI input devices in the system.
///
/// Returns the number of MIDI input devices present in the system. A return value of zero means that there are no devices (not that
/// there is no error).
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiingetnumdevs UINT midiInGetNumDevs();
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInGetNumDevs")]
public static extern uint midiInGetNumDevs();
/// The midiInMessage function sends a message to the MIDI device driver.
///
/// Identifier of the MIDI device that receives the message. You must cast the device ID to the HMIDIIN handle type. If you
/// supply a handle instead of a device ID, the function fails and returns the MMSYSERR_NOSUPPORT error code.
///
/// Message to send.
/// Message parameter.
/// Message parameter.
/// Returns the value returned by the audio device driver.
///
/// This function is used only for driver-specific messages that are not supported by the MIDI API.
/// The
/// DRV_QUERYDEVICEINTERFACE
/// message queries for the device-interface name of a waveIn, waveOut, midiIn, midiOut, or mixer device.
///
/// For
/// DRV_QUERYDEVICEINTERFACE
/// , dwParam1 is a pointer to a caller-allocated buffer into which the function writes a null-terminated Unicode string containing
/// the device-interface name. If the device has no device interface, the string length is zero.
///
/// For
/// DRV_QUERYDEVICEINTERFACE
/// , dwParam2 specifies the buffer size in bytes. This is an input parameter to the function. The caller should specify a size that
/// is greater than or equal to the buffer size retrieved by the DRV_QUERYDEVICEINTERFACESIZE message.
///
///
/// The DRV_QUERYDEVICEINTERFACE message is supported in Windows Me, and Windows 2000 and later. This message is valid only for the
/// waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, and mixerMessage functions. The system intercepts this
/// message and returns the appropriate value without sending the message to the device driver. For general information about
/// system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
/// The following two message constants are used together for the purpose of obtaining device interface names:
///
/// -
/// DRV_QUERYDEVICEINTERFACESIZE
///
/// -
/// DRV_QUERYDEVICEINTERFACE
///
///
///
/// The first message obtains the size in bytes of the buffer needed to hold the string containing the device interface name. The
/// second message retrieves the name string in a buffer of the required size.
///
/// For more information, see Obtaining a Device Interface Name.
/// The
/// DRV_QUERYDEVICEINTERFACESIZE
/// message queries for the size of the buffer required to hold the device-interface name.
///
/// For
/// DRV_QUERYDEVICEINTERFACESIZE
/// , dwParam1 is a pointer to buffer size. This parameter points to a ULONG variable into which the function writes the required
/// buffer size in bytes. The size includes storage space for the name string's terminating null. The size is zero if the device ID
/// identifies a device that has no device interface.
///
/// For
/// DRV_QUERYDEVICEINTERFACESIZE
/// , dwParam2 is unused. Set this parameter to zero.
///
///
/// This message is valid only for the waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, and mixerMessage
/// functions. The system intercepts this message and returns the appropriate value without sending the message to the device
/// driver. For general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// The buffer size retrieved by this message is expressed as a byte count. It specifies the size of the buffer needed to hold the
/// null-terminated Unicode string that contains the device-interface name. The caller allocates a buffer of the specified size and
/// uses the DRV_QUERYDEVICEINTERFACE message to retrieve the device-interface name string.
///
/// For more information, see Obtaining a Device Interface Name.
/// The
/// DRV_QUERYDEVNODE
/// message queries for the devnode number assigned to the device by the Plug and Play manager.
///
/// For
/// DRV_QUERYDEVNODE
/// , dwParam1 is a pointer to a caller-allocated DWORD variable into which the function writes the devnode number. If no devnode is
/// assigned to the device, the function sets this variable to zero.
///
/// For
/// DRV_QUERYDEVNODE
/// , dwParam2 is unused. Set this parameter to zero.
///
///
/// In Windows 2000 and later, the message always returns MMSYSERR_NOTSUPPORTED. This message is valid only for the waveInMessage,
/// waveOutMessage, midiInMessage, midiOutMessage, and mixerMessage functions. The system intercepts this message and returns
/// the appropriate value without sending the message to the device driver. For general information about system-intercepted
/// xxxMessage functions, see System-Intercepted Device Messages.
///
/// The
/// DRV_QUERYMAPPABLE
/// message queries for whether the specified device can be used by a mapper.
///
/// For
/// DRV_QUERYMAPPABLE
/// , dwParam1 is unused. Set this parameter to zero.
///
/// For
/// DRV_QUERYMAPPABLE
/// , dwParam2 is unused. Set this parameter to zero.
///
///
/// This message is valid only for the waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, mixerMessage and
/// auxOutMessage functions. The system intercepts this message and returns the appropriate value without sending the message to the
/// device driver. For general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// When an application program opens a mapper instead of a specific audio device, the system inserts a mapper between the
/// application and the available devices. The mapper selects an appropriate device by mapping the application's requirements to one
/// of the available devices. For more information about mappers, see the Microsoft Windows SDK documentation.
///
/// The
/// DRVM_MAPPER_CONSOLEVOICECOM_GET
/// message retrieves the device ID of the preferred voice-communications device.
///
/// For
/// DRVM_MAPPER_CONSOLEVOICECOM_GET
/// , dwParam1 is a pointer to device ID. This parameter points to a DWORD variable into which the function writes the device ID of
/// the current preferred voice-communications device. The function writes the value (-1) if no device is available that qualifies
/// as a preferred voice-communications device.
///
/// For
/// DRVM_MAPPER_CONSOLEVOICECOM_GET
/// , dwParam2 is a pointer to status flags. This parameter points to a DWORD variable into which the function writes the
/// device-status flags. Only one flag bit is currently defined: DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY.
///
///
/// This message is valid only for the waveInMessage and waveOutMessage functions. When a caller calls these two functions with the
/// DRVM_MAPPER_CONSOLEVOICECOM_GET message, the caller must specify the device ID as WAVE_MAPPER, and then cast this value to the
/// appropriate handle type. For the waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, or
/// mixerMessage functions, the caller must cast the device ID to a handle of type HWAVEIN, HWAVEOUT, HMIDIIN, HMIDIOUT, or HMIXER,
/// respectively. Note that if the caller supplies a valid handle instead of a device ID for this parameter, the function fails and
/// returns error code MMSYSERR_NOSUPPORT.
///
///
/// The system intercepts this message and returns the appropriate value without sending the message to the device driver. For
/// general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// This message provides a way to determine which device is preferred specifically for voice communications, in contrast to the
/// DRVM_MAPPER_PREFERRED_GET message, which determines which device is preferred for all other audio functions.
///
///
/// For example, the preferred waveOut device for voice communications might be the earpiece in a headset, but the preferred
/// waveOut device for all other audio functions might be a set of stereo speakers.
///
///
/// When the DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY flag bit is set in the DWORD location pointed to by dwParam2, the
/// waveIn and waveOut APIs use only the current preferred voice-communications device and do not search for other
/// available devices if the preferred device is unavailable. The flag that is output by either the waveInMessage or
/// waveOutMessage call applies to the preferred voice-communications device for both the waveIn and waveOut
/// APIs, regardless of whether the call is made to waveInMessage or waveOutMessage. For more information, see
/// Preferred Voice-Communications Device ID.
///
/// The
/// DRVM_MAPPER_PREFERRED_GET
/// message retrieves the device ID of the preferred audio device.
///
/// For
/// DRVM_MAPPER_PREFERRED_GET
/// , dwParam1 is a pointer to device ID. This parameter points to a DWORD variable into which the function writes the device ID of
/// the current preferred device. The function writes the value (-1) if no device is available that qualifies as a preferred device.
///
/// For
/// DRVM_MAPPER_PREFERRED_GET
/// , dwParam2 is a pointer to status flags. This parameter points to a DWORD variable into which the function writes the
/// device-status flags. Only one flag bit is currently defined (for waveInMessage and waveOutMessage calls only): DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY.
///
///
/// This message is valid only for the waveInMessage, waveOutMessage and midiOutMessage functions. When the caller calls these
/// functions with the DRVM_MAPPER_PREFERRED_GET message, the caller must first specify the device ID as WAVE_MAPPER (for
/// waveInMessage or waveOutMessage) or MIDI_MAPPER (for midiOutMessage), and then cast this value to the
/// appropriate handle type. For the waveInMessage, waveOutMessage, or midiOutMessage functions, the caller
/// must cast the device ID to a handle type HWAVEIN, HWAVEOUT or HMIDIOUT, respectively. Note that if the caller supplies a valid
/// handle instead of a device ID for this parameter, the function fails and returns error code MMSYSERR_NOSUPPORT.
///
///
/// The system intercepts this message and returns the appropriate value without sending the message to the device driver. For
/// general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// This message provides a way to determine which device is preferred for audio functions in general, in contrast to the
/// DRVM_MAPPER_CONSOLEVOICECOM_GET message, which determines which device is preferred specifically for voice communications.
///
///
/// When the DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY flag bit is set in the DWORD location pointed to by dwParam2, the
/// waveIn and waveOut APIs use only the current preferred device and do not search for other available devices if the
/// preferred device is unavailable. Note that the midiOutMessage function does not output this flag--the midiOut API
/// always uses only the preferred device. The flag that is output by either the waveInMessage or waveOutMessage call
/// applies to the preferred device for both the waveIn and waveOut APIs, regardless of whether the call is made to
/// waveInMessage or waveOutMessage.
///
///
/// The xxxMessage functions accept this value in place of a valid device handle in order to allow an application to determine the
/// default device ID without first having to open a device. For more information, see Accessing the Preferred Device ID.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinmessage MMRESULT midiInMessage( HMIDIIN hmi, UINT uMsg,
// DWORD_PTR dw1, DWORD_PTR dw2 );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInMessage")]
public static extern MMRESULT midiInMessage([In, Optional] HMIDIIN hmi, uint uMsg, [In, Optional] IntPtr dw1, [In, Optional] IntPtr dw2);
/// The midiInOpen function opens a specified MIDI input device.
///
/// Pointer to an HMIDIIN handle. This location is filled with a handle identifying the opened MIDI input device. The handle
/// is used to identify the device in calls to other MIDI input functions.
///
/// Identifier of the MIDI input device to be opened.
///
/// Pointer to a callback function, a thread identifier, or a handle of a window called with information about incoming MIDI
/// messages. For more information on the callback function, see MidiInProc.
///
///
/// User instance data passed to the callback function. This parameter is not used with window callback functions or threads.
///
///
///
/// Callback flag for opening the device and, optionally, a status flag that helps regulate rapid data transfers. It can be the
/// following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// CALLBACK_FUNCTION
/// The dwCallback parameter is a callback procedure address.
///
/// -
/// CALLBACK_NULL
/// There is no callback mechanism. This value is the default setting.
///
/// -
/// CALLBACK_THREAD
/// The dwCallback parameter is a thread identifier.
///
/// -
/// CALLBACK_WINDOW
/// The dwCallback parameter is a window handle.
///
/// -
/// MIDI_IO_STATUS
///
/// When this parameter also specifies CALLBACK_FUNCTION, MIM_MOREDATA messages are sent to the callback function as well as
/// MIM_DATA messages. Or, if this parameter also specifies CALLBACK_WINDOW, MM_MIM_MOREDATA messages are sent to the window as well
/// as MM_MIM_DATA messages. This flag does not affect event or thread callbacks.
///
///
///
/// Most applications that use a callback mechanism will specify CALLBACK_FUNCTION for this parameter.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following/
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_ALLOCATED
/// The specified resource is already allocated.
///
/// -
/// MMSYSERR_BADDEVICEID
/// The specified device identifier is out of range.
///
/// -
/// MMSYSERR_INVALFLAG
/// The flags specified by dwFlags are invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
///
/// To determine the number of MIDI input devices present in the system, use the midiInGetNumDevs function. The device identifier
/// specified by wDeviceID varies from zero to one less than the number of devices present.
///
///
/// If a window or thread is chosen to receive callback information, the following messages are sent to the window procedure or
/// thread to indicate the progress of MIDI input: MM_MIM_OPEN, MM_MIM_CLOSE, MM_MIM_DATA, MM_MIM_LONGDATA, MM_MIM_ERROR,
/// MM_MIM_LONGERROR, and MM_MIM_MOREDATA.
///
///
/// If a function is chosen to receive callback information, the following messages are sent to the function to indicate the
/// progress of MIDI input: MIM_OPEN, MIM_CLOSE, MIM_DATA, MIM_LONGDATA, MIM_ERROR, MIM_LONGERROR, and MIM_MOREDATA.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinopen MMRESULT midiInOpen( LPHMIDIIN phmi, UINT
// uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInOpen")]
public static extern MMRESULT midiInOpen(out HMIDIIN phmi, uint uDeviceID, [In, Optional] IntPtr dwCallback, [In, Optional] IntPtr dwInstance, CALLBACK_FLAGS fdwOpen);
/// The midiInPrepareHeader function prepares a buffer for MIDI input.
/// Handle to the MIDI input device. To get the device handle, call midiInOpen.
///
/// Pointer to a MIDIHDR structure that identifies the buffer to be prepared.
///
/// Before calling the function, set the lpData, dwBufferLength, and dwFlags members of the MIDIHDR structure.
/// The dwFlags member must be set to zero.
///
///
/// Size, in bytes, of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified address is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
///
/// Before you pass a MIDI data block to a device driver, you must prepare the buffer by passing it to the
/// midiInPrepareHeader function. After the header has been prepared, do not modify the buffer. After the driver is done
/// using the buffer, call the midiInUnprepareHeader function.
///
///
/// The application can re-use the same buffer, or allocate multiple buffers and call midiInPrepareHeader for each buffer. If
/// you re-use the same buffer, it is not necessary to prepare the buffer each time. You can call midiInPrepareHeader once at
/// the beginning and then call midiInUnprepareHeader once at the end.
///
/// Preparing a header that has already been prepared has no effect, and the function returns zero.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinprepareheader MMRESULT midiInPrepareHeader( HMIDIIN
// hmi, LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInPrepareHeader")]
public static extern MMRESULT midiInPrepareHeader([In] HMIDIIN hmi, ref MIDIHDR pmh, uint cbmh);
/// The midiInReset function stops input on a given MIDI input device.
/// Handle to the MIDI input device.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
/// This function returns all pending input buffers to the callback function and sets the MHDR_DONE flag in the dwFlags
/// member of the MIDIHDR structure.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinreset MMRESULT midiInReset( HMIDIIN hmi );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInReset")]
public static extern MMRESULT midiInReset([In] HMIDIIN hmi);
/// The midiInStart function starts MIDI input on the specified MIDI input device.
/// Handle to the MIDI input device.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
///
/// This function resets the time stamp to zero; time stamp values for subsequently received messages are relative to the time that
/// this function was called.
///
///
/// All messages except system-exclusive messages are sent directly to the client when they are received. System-exclusive messages
/// are placed in the buffers supplied by the midiInAddBuffer function. If there are no buffers in the queue, the system-exclusive
/// data is thrown away without notification to the client and input continues. Buffers are returned to the client when they are
/// full, when a complete system-exclusive message has been received, or when the midiInReset function is used. The
/// dwBytesRecorded member of the MIDIHDR structure will contain the actual length of data received.
///
/// Calling this function when input is already started has no effect, and the function returns zero.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinstart MMRESULT midiInStart( HMIDIIN hmi );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInStart")]
public static extern MMRESULT midiInStart([In] HMIDIIN hmi);
/// The midiInStop function stops MIDI input on the specified MIDI input device.
/// Handle to the MIDI input device.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
///
/// If there are any system-exclusive messages or stream buffers in the queue, the current buffer is marked as done (the
/// dwBytesRecorded member of the MIDIHDR structure will contain the actual length of data), but any empty buffers in the
/// queue remain there and are not marked as done.
///
/// Calling this function when input is not started has no effect, and the function returns zero.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinstop MMRESULT midiInStop( HMIDIIN hmi );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInStop")]
public static extern MMRESULT midiInStop([In] HMIDIIN hmi);
/// The midiInUnprepareHeader function cleans up the preparation performed by the midiInPrepareHeader function.
/// Handle to the MIDI input device.
/// Pointer to a MIDIHDR structure identifying the buffer to be cleaned up.
/// Size of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_STILLPLAYING
/// The buffer pointed to by lpMidiInHdr is still in the queue.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
/// This function is complementary to midiInPrepareHeader. You must use this function before freeing the buffer. After passing a
/// buffer to the device driver by using the midiInAddBuffer function, you must wait until the driver is finished with the buffer
/// before using midiInUnprepareHeader. Unpreparing a buffer that has not been prepared has no effect, and the function
/// returns MMSYSERR_NOERROR.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiinunprepareheader MMRESULT midiInUnprepareHeader( HMIDIIN
// hmi, LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiInUnprepareHeader")]
public static extern MMRESULT midiInUnprepareHeader([In] HMIDIIN hmi, ref MIDIHDR pmh, uint cbmh);
///
/// The midiOutCacheDrumPatches function requests that an internal MIDI synthesizer device preload and cache a specified set
/// of key-based percussion patches.
///
///
/// Handle to the opened MIDI output device. This device should be an internal MIDI synthesizer. This parameter can also be the
/// handle of a MIDI stream, cast to HMIDIOUT.
///
///
/// Drum patch number that should be used. This parameter should be set to zero to cache the default drum patch.
///
///
/// Pointer to a KEYARRAY array indicating the key numbers of the specified percussion patches to be cached or uncached.
///
///
/// Options for the cache operation. It can be one of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// MIDI_CACHE_ALL
///
/// Caches all of the specified patches. If they cannot all be cached, it caches none, clears the KEYARRAY array, and returns MMSYSERR_NOMEM.
///
///
/// -
/// MIDI_CACHE_BESTFIT
///
/// Caches all of the specified patches. If they cannot all be cached, it caches as many patches as possible, changes the KEYARRAY
/// array to reflect which patches were cached, and returns MMSYSERR_NOMEM.
///
///
/// -
/// MIDI_CACHE_QUERY
/// Changes the KEYARRAY array to indicate which patches are currently cached.
///
/// -
/// MIDI_UNCACHE
/// Uncaches the specified patches and clears the KEYARRAY array.
///
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALFLAG
/// The flag specified by wFlags is invalid.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The array pointed to by the lpKeyArray array is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The device does not have enough memory to cache all of the requested patches.
///
/// -
/// MMSYSERR_NOTSUPPORTED
/// The specified device does not support patch caching.
///
///
///
///
///
/// Some synthesizers are not capable of keeping all percussion patches loaded simultaneously. Caching patches ensures that the
/// specified patches are available.
///
///
/// Each element of the KEYARRAY array represents one of the 128 key-based percussion patches and has bits set for each of the 16
/// MIDI channels that use the particular patch. The least-significant bit represents physical channel 0, and the most-significant
/// bit represents physical channel 15. For example, if the patch on key number 60 is used by physical channels 9 and 15, element 60
/// would be set to 0x8200.
///
///
/// This function applies only to internal MIDI synthesizer devices. Not all internal synthesizers support patch caching. To see if
/// a device supports patch caching, use the MIDICAPS_CACHE flag to test the dwSupport member of the MIDIOUTCAPS structure
/// filled by the midiOutGetDevCaps function.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutcachedrumpatches MMRESULT midiOutCacheDrumPatches(
// HMIDIOUT hmo, UINT uPatch, LPWORD pwkya, UINT fuCache );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutCacheDrumPatches")]
public static extern MMRESULT midiOutCacheDrumPatches([In] HMIDIOUT hmo, uint uPatch, [In, MarshalAs(UnmanagedType.LPArray, SizeConst = MIDIPATCHSIZE)] ushort[] pwkya, MIDI_CACHE fuCache);
///
/// The midiOutCachePatches function requests that an internal MIDI synthesizer device preload and cache a specified set of patches.
///
///
/// Handle to the opened MIDI output device. This device must be an internal MIDI synthesizer. This parameter can also be the handle
/// of a MIDI stream, cast to HMIDIOUT.
///
/// Bank of patches that should be used. This parameter should be set to zero to cache the default patch bank.
/// Pointer to a PATCHARRAY array indicating the patches to be cached or uncached.
///
/// Options for the cache operation. It can be one of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// MIDI_CACHE_ALL
///
/// Caches all of the specified patches. If they cannot all be cached, it caches none, clears the PATCHARRAY array, and returns MMSYSERR_NOMEM.
///
///
/// -
/// MIDI_CACHE_BESTFIT
///
/// Caches all of the specified patches. If they cannot all be cached, it caches as many patches as possible, changes the PATCHARRAY
/// array to reflect which patches were cached, and returns MMSYSERR_NOMEM.
///
///
/// -
/// MIDI_CACHE_QUERY
/// Changes the PATCHARRAY array to indicate which patches are currently cached.
///
/// -
/// MIDI_UNCACHE
/// Uncaches the specified patches and clears the PATCHARRAY array.
///
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALFLAG
/// The flag specified by wFlags is invalid.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The array pointed to by lpPatchArray is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The device does not have enough memory to cache all of the requested patches.
///
/// -
/// MMSYSERR_NOTSUPPORTED
/// The specified device does not support patch caching.
///
///
///
///
///
/// Some synthesizers are not capable of keeping all patches loaded simultaneously and must load data from disk when they receive
/// MIDI program change messages. Caching patches ensures that the specified patches are immediately available.
///
///
/// Each element of the PATCHARRAY array represents one of the 128 patches and has bits set for each of the 16 MIDI channels that
/// use the particular patch. The least-significant bit represents physical channel 0, and the most-significant bit represents
/// physical channel 15 (0x0F). For example, if patch 0 is used by physical channels 0 and 8, element 0 would be set to 0x0101.
///
///
/// This function applies only to internal MIDI synthesizer devices. Not all internal synthesizers support patch caching. To see if
/// a device supports patch caching, use the MIDICAPS_CACHE flag to test the dwSupport member of the MIDIOUTCAPS structure
/// filled by the midiOutGetDevCaps function.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutcachepatches MMRESULT midiOutCachePatches( HMIDIOUT
// hmo, UINT uBank, LPWORD pwpa, UINT fuCache );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutCachePatches")]
public static extern MMRESULT midiOutCachePatches([In] HMIDIOUT hmo, uint uBank, [In, MarshalAs(UnmanagedType.LPArray, SizeConst = MIDIPATCHSIZE)] ushort[] pwpa, MIDI_CACHE fuCache);
/// The midiOutClose function closes the specified MIDI output device.
///
/// Handle to the MIDI output device. If the function is successful, the handle is no longer valid after the call to this function.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_STILLPLAYING
/// Buffers are still in the queue.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to load mapper string description.
///
///
///
///
/// If there are output buffers that have been sent by using the midiOutLongMsg function and have not been returned to the
/// application, the close operation will fail. To mark all pending buffers as being done, use the midiOutReset function.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutclose MMRESULT midiOutClose( HMIDIOUT hmo );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutClose")]
public static extern MMRESULT midiOutClose([In] HMIDIOUT hmo);
/// The midiOutGetDevCaps function queries a specified MIDI output device to determine its capabilities.
///
///
/// Identifier of the MIDI output device. The device identifier specified by this parameter varies from zero to one less than the
/// number of devices present. The MIDI_MAPPER constant is also a valid device identifier.
///
/// This parameter can also be a properly cast device handle.
///
///
/// Pointer to a MIDIOUTCAPS structure. This structure is filled with information about the capabilities of the device.
///
///
/// Size, in bytes, of the MIDIOUTCAPS structure. Only cbMidiOutCaps bytes (or less) of information is copied to the location
/// pointed to by lpMidiOutCaps. If cbMidiOutCaps is zero, nothing is copied, and the function returns MMSYSERR_NOERROR.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_BADDEVICEID
/// The specified device identifier is out of range.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NODRIVER
/// The driver is not installed.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to load mapper string description.
///
///
///
/// To determine the number of MIDI output devices present in the system, use the midiOutGetNumDevs function.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutgetdevcaps MMRESULT midiOutGetDevCaps( UINT uDeviceID,
// LPMIDIOUTCAPS pmoc, UINT cbmoc );
[DllImport(Lib_Winmm, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutGetDevCaps")]
public static extern MMRESULT midiOutGetDevCaps(uint uDeviceID, out MIDIOUTCAPS pmoc, uint cbmoc);
///
/// The midiOutGetErrorText function retrieves a textual description for an error identified by the specified error code.
///
/// Error code.
/// Pointer to a buffer to be filled with the textual error description.
/// Length, in characters, of the buffer pointed to by lpText.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_BADERRNUM
/// The specified error number is out of range.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
///
///
///
/// If the textual error description is longer than the specified buffer, the description is truncated. The returned error string is
/// always null-terminated. If cchText is zero, nothing is copied, and the function returns MMSYSERR_NOERROR. All error descriptions
/// are less than MAXERRORLENGTH characters long.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutgeterrortext MMRESULT midiOutGetErrorText( MMRESULT
// mmrError, LPSTR pszText, UINT cchText );
[DllImport(Lib_Winmm, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutGetErrorText")]
public static extern MMRESULT midiOutGetErrorText(MMRESULT mmrError, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszText, uint cchText);
///
/// The midiOutGetID function retrieves the device identifier for the given MIDI output device.
///
/// This function is supported for backward compatibility. New applications can cast a handle of the device rather than retrieving
/// the device identifier.
///
///
/// Handle to the MIDI output device.
/// Pointer to a variable to be filled with the device identifier.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The hmo parameter specifies an invalid handle.
///
/// -
/// MMSYSERR_NODRIVER
/// No device driver is present.
///
/// -
/// MMSYSERR_NOMEM
/// Unable to allocate or lock memory.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutgetid MMRESULT midiOutGetID( HMIDIOUT hmo, LPUINT
// puDeviceID );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutGetID")]
public static extern MMRESULT midiOutGetID(HMIDIOUT hmo, out uint puDeviceID);
/// The midiOutGetNumDevs function retrieves the number of MIDI output devices present in the system.
///
/// Returns the number of MIDI output devices. A return value of zero means that there are no devices (not that there is no error).
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutgetnumdevs UINT midiOutGetNumDevs();
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutGetNumDevs")]
public static extern uint midiOutGetNumDevs();
/// The midiOutGetVolume function retrieves the current volume setting of a MIDI output device.
///
/// Handle to an open MIDI output device. This parameter can also contain the handle of a MIDI stream, as long as it is cast to
/// HMIDIOUT. This parameter can also be a device identifier.
///
///
///
/// Pointer to the location to contain the current volume setting. The low-order word of this location contains the left-channel
/// volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a
/// value of 0x0000 is silence.
///
///
/// If a device does not support both left and right volume control, the low-order word of the specified location contains the mono
/// volume level.
///
/// Any value set by using the midiOutSetVolume function is returned, regardless of whether the device supports that value.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
/// -
/// MMSYSERR_NOTSUPPORTED
/// The function is not supported.
///
///
///
///
///
/// If a device identifier is used, then the result of the midiOutGetVolume call and the information returned in lpdwVolume
/// applies to all instances of the device. If a device handle is used, then the result and information returned applies only to the
/// instance of the device referenced by the device handle.
///
///
/// Not all devices support volume control. You can determine whether a device supports volume control by querying the device by
/// using the midiOutGetDevCaps function and specifying the MIDICAPS_VOLUME flag.
///
///
/// You can also determine whether the device supports volume control on both the left and right channels by querying the device by
/// using the midiOutGetDevCaps function and specifying the MIDICAPS_LRVOLUME flag.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutgetvolume MMRESULT midiOutGetVolume( HMIDIOUT hmo,
// LPDWORD pdwVolume );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutGetVolume")]
public static extern MMRESULT midiOutGetVolume([In] HMIDIOUT hmo, out uint pdwVolume);
/// The midiOutLongMsg function sends a system-exclusive MIDI message to the specified MIDI output device.
/// Handle to the MIDI output device. This parameter can also be the handle of a MIDI stream cast to HMIDIOUT.
/// Pointer to a MIDIHDR structure that identifies the MIDI buffer.
/// Size, in bytes, of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_NOTREADY
/// The hardware is busy with other data.
///
/// -
/// MIDIERR_UNPREPARED
/// The buffer pointed to by lpMidiOutHdr has not been prepared.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
///
///
///
/// Before the buffer is passed to midiOutLongMsg, it must be prepared by using the midiOutPrepareHeader function. The MIDI
/// output device driver determines whether the data is sent synchronously or asynchronously.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutlongmsg MMRESULT midiOutLongMsg( HMIDIOUT hmo,
// LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutLongMsg")]
public static extern MMRESULT midiOutLongMsg([In] HMIDIOUT hmo, in MIDIHDR pmh, uint cbmh);
///
/// The midiOutMessage function sends a message to the MIDI device drivers. This function is used only for driver-specific
/// messages that are not supported by the MIDI API.
///
///
/// Identifier of the MIDI device that receives the message. You must cast the device ID to the HMIDIOUT handle type. If you
/// supply a handle instead of a device ID, the function fails and returns the MMSYSERR_NOSUPPORT error code.
///
/// Message to send.
/// Message parameter.
/// Message parameter.
/// Returns the value returned by the audio device driver.
///
/// The
/// DRV_QUERYDEVICEINTERFACE
/// message queries for the device-interface name of a waveIn, waveOut, midiIn, midiOut, or mixer device.
///
/// For
/// DRV_QUERYDEVICEINTERFACE
/// , dwParam1 is a pointer to a caller-allocated buffer into which the function writes a null-terminated Unicode string containing
/// the device-interface name. If the device has no device interface, the string length is zero.
///
/// For
/// DRV_QUERYDEVICEINTERFACE
/// , dwParam2 specifies the buffer size in bytes. This is an input parameter to the function. The caller should specify a size that
/// is greater than or equal to the buffer size retrieved by the DRV_QUERYDEVICEINTERFACESIZE message.
///
///
/// The DRV_QUERYDEVICEINTERFACE message is supported in Windows Me, and Windows 2000 and later. This message is valid only for the
/// waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, and mixerMessage functions. The system intercepts this
/// message and returns the appropriate value without sending the message to the device driver. For general information about
/// system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
/// The following two message constants are used together for the purpose of obtaining device interface names:
///
/// -
/// DRV_QUERYDEVICEINTERFACESIZE
///
/// -
/// DRV_QUERYDEVICEINTERFACE
///
///
///
/// The first message obtains the size in bytes of the buffer needed to hold the string containing the device interface name. The
/// second message retrieves the name string in a buffer of the required size.
///
/// For more information, see Obtaining a Device Interface Name.
/// The
/// DRV_QUERYDEVICEINTERFACESIZE
/// message queries for the size of the buffer required to hold the device-interface name.
///
/// For
/// DRV_QUERYDEVICEINTERFACESIZE
/// , dwParam1 is a pointer to buffer size. This parameter points to a ULONG variable into which the function writes the required
/// buffer size in bytes. The size includes storage space for the name string's terminating null. The size is zero if the device ID
/// identifies a device that has no device interface.
///
/// For
/// DRV_QUERYDEVICEINTERFACESIZE
/// , dwParam2 is unused. Set this parameter to zero.
///
///
/// This message is valid only for the waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, and mixerMessage
/// functions. The system intercepts this message and returns the appropriate value without sending the message to the device
/// driver. For general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// The buffer size retrieved by this message is expressed as a byte count. It specifies the size of the buffer needed to hold the
/// null-terminated Unicode string that contains the device-interface name. The caller allocates a buffer of the specified size and
/// uses the DRV_QUERYDEVICEINTERFACE message to retrieve the device-interface name string.
///
/// For more information, see Obtaining a Device Interface Name.
/// The
/// DRV_QUERYDEVNODE
/// message queries for the devnode number assigned to the device by the Plug and Play manager.
///
/// For
/// DRV_QUERYDEVNODE
/// , dwParam1 is a pointer to a caller-allocated DWORD variable into which the function writes the devnode number. If no devnode is
/// assigned to the device, the function sets this variable to zero.
///
/// For
/// DRV_QUERYDEVNODE
/// , dwParam2 is unused. Set this parameter to zero.
///
///
/// In Windows 2000 and later, the message always returns MMSYSERR_NOTSUPPORTED. This message is valid only for the waveInMessage,
/// waveOutMessage, midiInMessage, midiOutMessage, and mixerMessage functions. The system intercepts this message and returns
/// the appropriate value without sending the message to the device driver. For general information about system-intercepted
/// xxxMessage functions, see System-Intercepted Device Messages.
///
/// The
/// DRV_QUERYMAPPABLE
/// message queries for whether the specified device can be used by a mapper.
///
/// For
/// DRV_QUERYMAPPABLE
/// , dwParam1 is unused. Set this parameter to zero.
///
/// For
/// DRV_QUERYMAPPABLE
/// , dwParam2 is unused. Set this parameter to zero.
///
///
/// This message is valid only for the waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, mixerMessage and
/// auxOutMessage functions. The system intercepts this message and returns the appropriate value without sending the message to the
/// device driver. For general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// When an application program opens a mapper instead of a specific audio device, the system inserts a mapper between the
/// application and the available devices. The mapper selects an appropriate device by mapping the application's requirements to one
/// of the available devices. For more information about mappers, see the Microsoft Windows SDK documentation.
///
/// The
/// DRVM_MAPPER_CONSOLEVOICECOM_GET
/// message retrieves the device ID of the preferred voice-communications device.
///
/// For
/// DRVM_MAPPER_CONSOLEVOICECOM_GET
/// , dwParam1 is a pointer to device ID. This parameter points to a DWORD variable into which the function writes the device ID of
/// the current preferred voice-communications device. The function writes the value (-1) if no device is available that qualifies
/// as a preferred voice-communications device.
///
/// For
/// DRVM_MAPPER_CONSOLEVOICECOM_GET
/// , dwParam2 is a pointer to status flags. This parameter points to a DWORD variable into which the function writes the
/// device-status flags. Only one flag bit is currently defined: DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY.
///
///
/// This message is valid only for the waveInMessage and waveOutMessage functions. When a caller calls these two functions with the
/// DRVM_MAPPER_CONSOLEVOICECOM_GET message, the caller must specify the device ID as WAVE_MAPPER, and then cast this value to the
/// appropriate handle type. For the waveInMessage, waveOutMessage, midiInMessage, midiOutMessage, or
/// mixerMessage functions, the caller must cast the device ID to a handle of type HWAVEIN, HWAVEOUT, HMIDIIN, HMIDIOUT, or HMIXER,
/// respectively. Note that if the caller supplies a valid handle instead of a device ID for this parameter, the function fails and
/// returns error code MMSYSERR_NOSUPPORT.
///
///
/// The system intercepts this message and returns the appropriate value without sending the message to the device driver. For
/// general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// This message provides a way to determine which device is preferred specifically for voice communications, in contrast to the
/// DRVM_MAPPER_PREFERRED_GET message, which determines which device is preferred for all other audio functions.
///
///
/// For example, the preferred waveOut device for voice communications might be the earpiece in a headset, but the preferred
/// waveOut device for all other audio functions might be a set of stereo speakers.
///
///
/// When the DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY flag bit is set in the DWORD location pointed to by dwParam2, the
/// waveIn and waveOut APIs use only the current preferred voice-communications device and do not search for other
/// available devices if the preferred device is unavailable. The flag that is output by either the waveInMessage or
/// waveOutMessage call applies to the preferred voice-communications device for both the waveIn and waveOut
/// APIs, regardless of whether the call is made to waveInMessage or waveOutMessage. For more information, see
/// Preferred Voice-Communications Device ID.
///
/// The
/// DRVM_MAPPER_PREFERRED_GET
/// message retrieves the device ID of the preferred audio device.
///
/// For
/// DRVM_MAPPER_PREFERRED_GET
/// , dwParam1 is a pointer to device ID. This parameter points to a DWORD variable into which the function writes the device ID of
/// the current preferred device. The function writes the value (-1) if no device is available that qualifies as a preferred device.
///
/// For
/// DRVM_MAPPER_PREFERRED_GET
/// , dwParam2 is a pointer to status flags. This parameter points to a DWORD variable into which the function writes the
/// device-status flags. Only one flag bit is currently defined (for waveInMessage and waveOutMessage calls only): DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY.
///
///
/// This message is valid only for the waveInMessage, waveOutMessage and midiOutMessage functions. When the caller calls
/// these functions with the DRVM_MAPPER_PREFERRED_GET message, the caller must first specify the device ID as WAVE_MAPPER (for
/// waveInMessage or waveOutMessage) or MIDI_MAPPER (for midiOutMessage), and then cast this value to the
/// appropriate handle type. For the waveInMessage, waveOutMessage, or midiOutMessage functions, the caller
/// must cast the device ID to a handle type HWAVEIN, HWAVEOUT or HMIDIOUT, respectively. Note that if the caller supplies a valid
/// handle instead of a device ID for this parameter, the function fails and returns error code MMSYSERR_NOSUPPORT.
///
///
/// The system intercepts this message and returns the appropriate value without sending the message to the device driver. For
/// general information about system-intercepted xxxMessage functions, see System-Intercepted Device Messages.
///
///
/// This message provides a way to determine which device is preferred for audio functions in general, in contrast to the
/// DRVM_MAPPER_CONSOLEVOICECOM_GET message, which determines which device is preferred specifically for voice communications.
///
///
/// When the DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY flag bit is set in the DWORD location pointed to by dwParam2, the
/// waveIn and waveOut APIs use only the current preferred device and do not search for other available devices if the
/// preferred device is unavailable. Note that the midiOutMessage function does not output this flag--the midiOut API
/// always uses only the preferred device. The flag that is output by either the waveInMessage or waveOutMessage call
/// applies to the preferred device for both the waveIn and waveOut APIs, regardless of whether the call is made to
/// waveInMessage or waveOutMessage.
///
///
/// The xxxMessage functions accept this value in place of a valid device handle in order to allow an application to determine the
/// default device ID without first having to open a device. For more information, see Accessing the Preferred Device ID.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutmessage MMRESULT midiOutMessage( HMIDIOUT hmo, UINT
// uMsg, DWORD_PTR dw1, DWORD_PTR dw2 );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutMessage")]
public static extern MMRESULT midiOutMessage([In, Optional] HMIDIOUT hmo, uint uMsg, [In, Optional] IntPtr dw1, [In, Optional] IntPtr dw2);
/// The midiOutOpen function opens a MIDI output device for playback.
///
/// Pointer to an HMIDIOUT handle. This location is filled with a handle identifying the opened MIDI output device. The
/// handle is used to identify the device in calls to other MIDI output functions.
///
/// Identifier of the MIDI output device that is to be opened.
///
/// Pointer to a callback function, an event handle, a thread identifier, or a handle of a window or thread called during MIDI
/// playback to process messages related to the progress of the playback. If no callback is desired, specify NULL for this
/// parameter. For more information on the callback function, see MidiOutProc.
///
/// User instance data passed to the callback. This parameter is not used with window callbacks or threads.
///
/// Callback flag for opening the device. It can be the following values.
///
///
/// Value
/// Meaning
///
/// -
/// CALLBACK_EVENT
/// The dwCallback parameter is an event handle. This callback mechanism is for output only.
///
/// -
/// CALLBACK_FUNCTION
/// The dwCallback parameter is a callback function address.
///
/// -
/// CALLBACK_NULL
/// There is no callback mechanism. This value is the default setting.
///
/// -
/// CALLBACK_THREAD
/// The dwCallback parameter is a thread identifier.
///
/// -
/// CALLBACK_WINDOW
/// The dwCallback parameter is a window handle.
///
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_NODEVICE
/// No MIDI port was found. This error occurs only when the mapper is opened.
///
/// -
/// MMSYSERR_ALLOCATED
/// The specified resource is already allocated.
///
/// -
/// MMSYSERR_BADDEVICEID
/// The specified device identifier is out of range.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
///
/// To determine the number of MIDI output devices present in the system, use the midiOutGetNumDevs function. The device identifier
/// specified by wDeviceID varies from zero to one less than the number of devices present. MIDI_MAPPER can also be used as the
/// device identifier.
///
///
/// If a window or thread is chosen to receive callback information, the following messages are sent to the window procedure or
/// thread to indicate the progress of MIDI output: MM_MOM_OPEN, MM_MOM_CLOSE, and MM_MOM_DONE.
///
///
/// If a function is chosen to receive callback information, the following messages are sent to the function to indicate the
/// progress of MIDI output: MOM_OPEN, MOM_CLOSE, and MOM_DONE.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutopen MMRESULT midiOutOpen( LPHMIDIOUT phmo, UINT
// uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutOpen")]
public static extern MMRESULT midiOutOpen(out HMIDIOUT phmo, uint uDeviceID, [In, Optional] IntPtr dwCallback, [In, Optional] IntPtr dwInstance, CALLBACK_FLAGS fdwOpen = CALLBACK_FLAGS.CALLBACK_NULL);
/// The midiOutPrepareHeader function prepares a MIDI system-exclusive or stream buffer for output.
///
/// Handle to the MIDI output device. To get the device handle, call midiOutOpen. This parameter can also be the handle of a MIDI
/// stream cast to a HMIDIOUT type.
///
///
/// Pointer to a MIDIHDR structure that identifies the buffer to be prepared.
///
/// Before calling the function, set the lpData, dwBufferLength, and dwFlags members of the MIDIHDR structure.
/// The dwFlags member must be set to zero.
///
///
/// Size, in bytes, of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified address is invalid or the given stream buffer is greater than 64K.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
///
///
/// Before you pass a MIDI data block to a device driver, you must prepare the buffer by passing it to the
/// midiOutPrepareHeader function. After the header has been prepared, do not modify the buffer. After the driver is done
/// using the buffer, call the midiOutUnprepareHeader function.
///
///
/// The application can re-use the same buffer, or allocate multiple buffers and call midiOutPrepareHeader for each buffer.
/// If you re-use the same buffer, it is not necessary to prepare the buffer each time. You can call midiOutPrepareHeader
/// once at the beginning and then call midiOutUnprepareHeader once at the end.
///
/// A stream buffer cannot be larger than 64K.
/// Preparing a header that has already been prepared has no effect, and the function returns MMSYSERR_NOERROR.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutprepareheader MMRESULT midiOutPrepareHeader( HMIDIOUT
// hmo, LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutPrepareHeader")]
public static extern MMRESULT midiOutPrepareHeader(HMIDIOUT hmo, ref MIDIHDR pmh, uint cbmh);
/// The midiOutReset function turns off all notes on all MIDI channels for the specified MIDI output device.
/// Handle to the MIDI output device. This parameter can also be the handle of a MIDI stream cast to HMIDIOUT.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
///
/// Any pending system-exclusive or stream output buffers are returned to the callback function and the MHDR_DONE flag is set in the
/// dwFlags member of the MIDIHDR structure.
///
///
/// Terminating a system-exclusive message without sending an EOX (end-of-exclusive) byte might cause problems for the receiving
/// device. The midiOutReset function does not send an EOX byte when it terminates a system-exclusive message - applications
/// are responsible for doing this.
///
///
/// To turn off all notes, a note-off message for each note in each channel is sent. In addition, the sustain controller is turned
/// off for each channel.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutreset MMRESULT midiOutReset( HMIDIOUT hmo );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutReset")]
public static extern MMRESULT midiOutReset([In] HMIDIOUT hmo);
/// The midiOutSetVolume function sets the volume of a MIDI output device.
///
/// Handle to an open MIDI output device. This parameter can also contain the handle of a MIDI stream, as long as it is cast to
/// HMIDIOUT. This parameter can also be a device identifier.
///
///
///
/// New volume setting. The low-order word contains the left-channel volume setting, and the high-order word contains the
/// right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.
///
///
/// If a device does not support both left and right volume control, the low-order word of dwVolume specifies the mono volume level,
/// and the high-order word is ignored.
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
/// -
/// MMSYSERR_NOTSUPPORTED
/// The function is not supported.
///
///
///
///
///
/// If a device identifier is used, then the result of the midiOutSetVolume call applies to all instances of the device. If a
/// device handle is used, then the result applies only to the instance of the device referenced by the device handle.
///
///
/// Not all devices support volume changes. You can determine whether a device supports it by querying the device using the
/// midiOutGetDevCaps function and the MIDICAPS_VOLUME flag.
///
///
/// You can also determine whether the device supports volume control on both the left and right channels by querying the device
/// using the midiOutGetDevCaps function and the MIDICAPS_LRVOLUME flag.
///
///
/// Devices that do not support a full 16 bits of volume-level control use the high-order bits of the requested volume setting. For
/// example, a device that supports 4 bits of volume control produces the same volume setting for the following volume-level values:
/// 0x4000, 0x43be, and 0x4fff. The midiOutGetVolume function returns the full 16-bit value, as set by midiOutSetVolume,
/// irrespective of the device's capabilities.
///
///
/// Volume settings are interpreted logarithmically. This means that the perceived increase in volume is the same when increasing
/// the volume level from 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutsetvolume MMRESULT midiOutSetVolume( HMIDIOUT hmo,
// DWORD dwVolume );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutSetVolume")]
public static extern MMRESULT midiOutSetVolume([In] HMIDIOUT hmo, uint dwVolume);
/// The midiOutShortMsg function sends a short MIDI message to the specified MIDI output device.
/// Handle to the MIDI output device. This parameter can also be the handle of a MIDI stream cast to HMIDIOUT.
///
///
/// MIDI message. The message is packed into a DWORD value with the first byte of the message in the low-order byte. The
/// message is packed into this parameter as follows.
///
///
///
/// Word
/// Byte
/// Usage
///
/// -
/// High
/// High-order
/// Not used.
///
/// -
///
/// Low-order
/// The second byte of MIDI data (when needed).
///
/// -
/// Low
/// High-order
/// The first byte of MIDI data (when needed).
///
/// -
///
/// Low-order
/// The MIDI status.
///
///
///
/// The two MIDI data bytes are optional, depending on the MIDI status byte. When a series of messages have the same status byte,
/// the status byte can be omitted from messages after the first one in the series, creating a running status. Pack a message for
/// running status as follows:
///
///
///
/// Word
/// Byte
/// Usage
///
/// -
/// High
/// High-order
/// Not used.
///
/// -
///
/// Low-order
/// Not used.
///
/// -
/// Low
/// High-order
/// The second byte of MIDI data (when needed).
///
/// -
///
/// Low-order
/// The first byte of MIDI data.
///
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_BADOPENMODE
/// The application sent a message without a status byte to a stream handle.
///
/// -
/// MIDIERR_NOTREADY
/// The hardware is busy with other data.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
/// This function is used to send any MIDI message except for system-exclusive or stream messages.
///
/// This function might not return until the message has been sent to the output device. You can send short messages while streams
/// are playing on the same device (although you cannot use a running status in this case).
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutshortmsg MMRESULT midiOutShortMsg( HMIDIOUT hmo, DWORD
// dwMsg );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutShortMsg")]
public static extern MMRESULT midiOutShortMsg([In] HMIDIOUT hmo, uint dwMsg);
/// The midiOutUnprepareHeader function cleans up the preparation performed by the midiOutPrepareHeader function.
/// Handle to the MIDI output device. This parameter can also be the handle of a MIDI stream cast to HMIDIOUT.
/// Pointer to a MIDIHDR structure identifying the buffer to be cleaned up.
/// Size, in bytes, of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MIDIERR_STILLPLAYING
/// The buffer pointed to by lpMidiOutHdr is still in the queue.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The specified pointer or structure is invalid.
///
///
///
///
///
/// This function is complementary to the midiOutPrepareHeader function. You must call midiOutUnprepareHeader before freeing
/// the buffer. After passing a buffer to the device driver with the midiOutLongMsg function, you must wait until the device driver
/// is finished with the buffer before calling midiOutUnprepareHeader.
///
/// Unpreparing a buffer that has not been prepared has no effect, and the function returns MMSYSERR_NOERROR.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutunprepareheader MMRESULT midiOutUnprepareHeader(
// HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiOutUnprepareHeader")]
public static extern MMRESULT midiOutUnprepareHeader([In] HMIDIOUT hmo, ref MIDIHDR pmh, uint cbmh);
/// The midiStreamClose function closes an open MIDI stream.
/// Handle to a MIDI stream, as retrieved by using the midiStreamOpen function.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamclose MMRESULT midiStreamClose( HMIDISTRM hms );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamClose")]
public static extern MMRESULT midiStreamClose([In] HMIDISTRM hms);
///
/// The midiStreamOpen function opens a MIDI stream for output. By default, the device is opened in paused mode. The stream
/// handle retrieved by this function must be used in all subsequent references to the stream.
///
/// Pointer to a variable to contain the stream handle when the function returns.
///
/// Pointer to a device identifier. The device is opened on behalf of the stream and closed again when the stream is closed.
///
/// Reserved; must be 1.
///
/// Pointer to a callback function, an event handle, a thread identifier, or a handle of a window or thread called during MIDI
/// playback to process messages related to the progress of the playback. If no callback mechanism is desired, specify NULL
/// for this parameter.
///
/// Application-specific instance data that is returned to the application with every callback function.
///
/// Callback flag for opening the device. One of the following callback flags must be specified.
///
///
/// Value
/// Meaning
///
/// -
/// CALLBACK_EVENT
/// The dwCallback parameter is an event handle. This callback mechanism is for output only.
///
/// -
/// CALLBACK_FUNCTION
/// The dwCallback parameter is a callback procedure address. For the callback signature, see MidiOutProc.
///
/// -
/// CALLBACK_NULL
/// There is no callback mechanism. This is the default setting.
///
/// -
/// CALLBACK_THREAD
/// The dwCallback parameter is a thread identifier.
///
/// -
/// CALLBACK_WINDOW
/// The dwCallback parameter is a window handle.
///
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_BADDEVICEID
/// The specified device identifier is out of range.
///
/// -
/// MMSYSERR_INVALPARAM
/// The given handle or flags parameter is invalid.
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamopen MMRESULT midiStreamOpen( LPHMIDISTRM phms,
// LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamOpen")]
public static extern MMRESULT midiStreamOpen(out HMIDISTRM phms, ref uint puDeviceID, uint cMidi, [In, Optional] IntPtr dwCallback, [In, Optional] IntPtr dwInstance, CALLBACK_FLAGS fdwOpen);
/// The midiStreamOut function plays or queues a stream (buffer) of MIDI data to a MIDI output device.
///
/// Handle to a MIDI stream. This handle must have been returned by a call to the midiStreamOpen function. This handle identifies
/// the output device.
///
/// Pointer to a MIDIHDR structure that identifies the MIDI buffer.
/// Size, in bytes, of the MIDIHDR structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_NOMEM
/// The system is unable to allocate or lock memory.
///
/// -
/// MIDIERR_STILLPLAYING
/// The output buffer pointed to by lpMidiHdr is still playing or is queued from a previous call to midiStreamOut.
///
/// -
/// MIDIERR_UNPREPARED
/// The header pointed to by lpMidiHdr has not been prepared.
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// The pointer specified by lpMidiHdr is invalid.
///
///
///
///
/// Before the buffer is passed to midiStreamOpen, it must be prepared by using the midiOutPrepareHeader function.
///
/// Because the midiStreamOpen function opens the output device in paused mode, you must call the midiStreamRestart function before
/// you can use midiStreamOut to start the playback.
///
/// For the current implementation of this function, the buffer must be smaller than 64K.
///
/// The buffer pointed to by the MIDIHDR structure contains one or more MIDI events, each of which is defined by a MIDIEVENT structure.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamout MMRESULT midiStreamOut( HMIDISTRM hms,
// LPMIDIHDR pmh, UINT cbmh );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamOut")]
public static extern MMRESULT midiStreamOut([In] HMIDISTRM hms, ref MIDIHDR pmh, uint cbmh);
/// The midiStreamPause function pauses playback of a specified MIDI stream.
///
/// Handle to a MIDI stream. This handle must have been returned by a call to the MIDIEVENT function. This handle identifies the
/// output device.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
///
/// The current playback position is saved when playback is paused. To resume playback from the current position, use the
/// midiStreamRestart function.
///
/// Calling this function when the output is already paused has no effect, and the function returns MMSYSERR_NOERROR.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreampause MMRESULT midiStreamPause( HMIDISTRM hms );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamPause")]
public static extern MMRESULT midiStreamPause([In] HMIDISTRM hms);
/// The midiStreamPosition function retrieves the current position in a MIDI stream.
///
/// Handle to a MIDI stream. This handle must have been returned by a call to the midiStreamOpen function. This handle identifies
/// the output device.
///
/// Pointer to an MMTIME structure.
/// Size, in bytes, of the MMTIME structure.
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// Specified device handle is invalid.
///
/// -
/// MMSYSERR_INVALPARAM
/// Specified pointer or structure is invalid.
///
///
///
///
///
/// Before calling midiStreamPosition, set the wType member of the MMTIME structure to indicate the time format you
/// desire. After calling midiStreamPosition, check the wType member to determine if the desired time format is
/// supported. If the desired format is not supported, wType will specify an alternative format.
///
/// The position is set to zero when the device is opened or reset.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamposition MMRESULT midiStreamPosition( HMIDISTRM
// hms, LPMMTIME lpmmt, UINT cbmmt );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamPosition")]
public static extern MMRESULT midiStreamPosition([In] HMIDISTRM hms, ref MMTIME lpmmt, uint cbmmt);
///
/// The midiStreamProperty function sets or retrieves properties of a MIDI data stream associated with a MIDI output device.
///
/// Handle to the MIDI device that the property is associated with.
/// Pointer to the property data.
///
///
/// Flags that specify the action to perform and identify the appropriate property of the MIDI data stream. The
/// midiStreamProperty function requires setting two flags in each use. One flag (either MIDIPROP_GET or MIDIPROP_SET)
/// specifies an action, and the other identifies a specific property to examine or edit.
///
///
///
/// Value
/// Meaning
///
/// -
/// MIDIPROP_GET
/// Retrieves the current setting of the given property.
///
/// -
/// MIDIPROP_SET
/// Sets the given property.
///
/// -
/// MIDIPROP_TEMPO
///
/// Retrieves the tempo property. The lppropdata parameter points to a MIDIPROPTEMPO structure. The current tempo value can be
/// retrieved at any time. Output devices set the tempo by inserting MEVT_TEMPO events into the MIDI data.
///
///
/// -
/// MIDIPROP_TIMEDIV
///
/// Specifies the time division property. You can get or set this property. The lppropdata parameter points to a MIDIPROPTIMEDIV
/// structure. This property can be set only when the device is stopped.
///
///
///
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified handle is not a stream handle.
///
/// -
/// MMSYSERR_INVALPARAM
/// The given handle or flags parameter is invalid.
///
///
///
///
/// These properties are the default properties defined by the system. Driver writers can implement and document their own properties.
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamproperty MMRESULT midiStreamProperty( HMIDISTRM
// hms, LPBYTE lppropdata, DWORD dwProperty );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamProperty")]
public static extern MMRESULT midiStreamProperty([In] HMIDISTRM hms, IntPtr lppropdata, MIDIPROP dwProperty);
/// The midiStreamRestart function restarts a paused MIDI stream.
///
/// Handle to a MIDI stream. This handle must have been returned by a call to the midiStreamOpen function. This handle identifies
/// the output device.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
/// Calling this function when the output is not paused has no effect, and the function returns MMSYSERR_NOERROR.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamrestart MMRESULT midiStreamRestart( HMIDISTRM hms );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamRestart")]
public static extern MMRESULT midiStreamRestart([In] HMIDISTRM hms);
/// The midiStreamStop function turns off all notes on all MIDI channels for the specified MIDI output device.
///
/// Handle to a MIDI stream. This handle must have been returned by a call to the midiStreamOpen function. This handle identifies
/// the output device.
///
///
/// Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following.
///
///
/// Return code
/// Description
///
/// -
/// MMSYSERR_INVALHANDLE
/// The specified device handle is invalid.
///
///
///
///
///
/// When you call this function, any pending system-exclusive or stream output buffers are returned to the callback mechanism and
/// the MHDR_DONE bit is set in the dwFlags member of the MIDIHDR structure.
///
///
/// While the midiOutReset function turns off all notes, midiStreamStop turns off only those notes that have been turned on
/// by a MIDI note-on message.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamstop MMRESULT midiStreamStop( HMIDISTRM hms );
[DllImport(Lib_Winmm, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mmeapi.h", MSDNShortId = "NF:mmeapi.midiStreamStop")]
public static extern MMRESULT midiStreamStop([In] HMIDISTRM hms);
/// Provides a handle to a MIDI input device or a MIDI thru device.
[StructLayout(LayoutKind.Sequential)]
public struct HMIDI : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HMIDI(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HMIDI NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HMIDI h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HMIDI(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HMIDI h1, HMIDI h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HMIDI h1, HMIDI h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HMIDI h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a handle to a MIDI input device.
[StructLayout(LayoutKind.Sequential)]
public struct HMIDIIN : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HMIDIIN(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HMIDIIN NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HMIDIIN h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HMIDIIN(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HMIDIIN h1, HMIDIIN h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HMIDIIN h1, HMIDIIN h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HMIDIIN h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a handle to a MIDI output or thru device.
[StructLayout(LayoutKind.Sequential)]
public struct HMIDIOUT : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HMIDIOUT(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HMIDIOUT NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HMIDIOUT h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HMIDIOUT(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HMIDIOUT h1, HMIDIOUT h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HMIDIOUT h1, HMIDIOUT h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HMIDIOUT h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a handle to a MIDI stream.
[StructLayout(LayoutKind.Sequential)]
public struct HMIDISTRM : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HMIDISTRM(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HMIDISTRM NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HMIDISTRM h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HMIDISTRM(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HMIDISTRM h1, HMIDISTRM h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HMIDISTRM h1, HMIDISTRM h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HMIDISTRM h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// The MIDIEVENT structure describes a MIDI event in a stream buffer.
///
///
/// The high byte of dwEvent contains flags and an event code. Either the MEVT_F_LONG or MEVT_F_SHORT flag must be specified.
/// The MEVT_F_CALLBACK flag is optional. The following table describes these flags.
///
///
///
/// Flag
/// Meaning
///
/// -
/// MEVT_F_CALLBACK
/// The system generates a callback when the event is about to be executed.
///
/// -
/// MEVT_F_LONG
/// The event is a long event. The low 24 bits of dwEvent contain the length of the event parameters included in dwParms.
///
/// -
/// MEVT_F_SHORT
/// The event is a short event. The event parameters are contained in the low 24 bits of dwEvent.
///
///
/// The remainder of the high byte contains one of the following event codes:
///
///
/// Event Code
/// Meaning
///
/// -
/// MEVT_COMMENT
///
/// Long event. The event data will be ignored. This event is intended to store commentary information about the stream that might
/// be useful to authoring programs or sequencers if the stream data were to be stored in a file in stream format. In a buffer of
/// this data, the zero byte identifies the comment class and subsequent bytes contain the comment data.
///
///
/// -
/// MEVT_LONGMSG
///
/// Long event. The event data is transmitted verbatim. The event data is assumed to be system-exclusive data; that is, running
/// status will be cleared when the event is executed and running status from any previous events will not be applied to any channel
/// events in the event data. Using this event to send a group of channel messages at the same time is not recommended; a set of
/// MEVT_SHORTMSG events with zero delta times should be used instead.
///
///
/// -
/// MEVT_NOP
///
/// Short event. This event is a placeholder; it does nothing. The low 24 bits are ignored. This event will still generate a
/// callback if MEVT_F_CALLBACK is set in dwEvent.
///
///
/// -
/// MEVT_SHORTMSG
///
/// Short event. The data in the low 24 bits of dwEvent is a MIDI short message. (For a description of how a short message is packed
/// into a DWORD value, see the midiOutShortMsg function.)
///
///
/// -
/// MEVT_TEMPO
///
/// Short event. The data in the low 24 bits of dwEvent contain the new tempo for following events. The tempo is specified in the
/// same format as it is for the tempo change meta-event in a MIDI file — that is, in microseconds per quarter note. (This event
/// will have no affect if the time format specified for the stream is SMPTE time.)
///
///
/// -
/// MEVT_VERSION
/// Long event. The event data must contain a MIDISTRMBUFFVER structure.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midievent typedef struct midievent_tag { DWORD dwDeltaTime;
// DWORD dwStreamID; DWORD dwEvent; DWORD dwParms[1]; } MIDIEVENT;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midievent_tag")]
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct MIDIEVENT
{
///
/// Time, in MIDI ticks, between the previous event and the current event. The length of a tick is defined by the time format
/// and possibly the tempo associated with the stream. (The definition is identical to the specification for a tick in a
/// standard MIDI file.)
///
public uint dwDeltaTime;
/// Reserved; must be zero.
public uint dwStreamID;
///
/// Event code and event parameters or length. To parse this information, use the MEVT_EVENTTYPE and MEVT_EVENTPARM macros. See Remarks.
///
public uint dwEvent;
///
///
/// If dwEvent specifies MEVT_F_LONG and the length of the buffer, this member contains parameters for the event. This
/// parameter data must be padded with zeros so that an integral number of DWORD values are stored. For example, if the
/// event data is five bytes long, three pad bytes must follow the data for a total of eight bytes. In this case, the low 24
/// bits of dwEvent would contain the value 5.
///
/// If dwEvent specifies MEVT_F_SHORT, do not use this member in the stream buffer.
///
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public uint[] dwParms;
/// Retrieves the event type from the value specified in the dwEvent member of a MIDIEVENT structure.
public byte EventType => (byte)(((dwEvent) >> 24) & 0xFF);
/// Retrieves the event parameters or length from the value specified in the dwEvent member of a MIDIEVENT structure.
public uint EventParm => (dwEvent) & 0x00FFFFFF;
}
/// The MIDIHDR structure defines the header used to identify a MIDI system-exclusive or stream buffer.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midihdr typedef struct midihdr_tag { LPSTR lpData; DWORD
// dwBufferLength; DWORD dwBytesRecorded; DWORD_PTR dwUser; DWORD dwFlags; struct midihdr_tag *lpNext; DWORD_PTR reserved; DWORD
// dwOffset; DWORD_PTR dwReserved[8]; } MIDIHDR, *PMIDIHDR, *NPMIDIHDR, *LPMIDIHDR;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midihdr_tag")]
[StructLayout(LayoutKind.Sequential)]
public struct MIDIHDR
{
/// Pointer to MIDI data.
public IntPtr lpData;
/// Size of the buffer.
public uint dwBufferLength;
///
/// Actual amount of data in the buffer. This value should be less than or equal to the value given in the dwBufferLength member.
///
public uint dwBytesRecorded;
/// Custom user data.
public IntPtr dwUser;
///
/// Flags giving information about the buffer.
///
///
/// Name
/// Description
///
/// -
/// MHDR_DONE
/// Set by the device driver to indicate that it is finished with the buffer and is returning it to the application.
///
/// -
/// MHDR_INQUEUE
/// Set by Windows to indicate that the buffer is queued for playback.
///
/// -
/// MHDR_ISSTRM
/// Set to indicate that the buffer is a stream buffer.
///
/// -
/// MHDR_PREPARED
///
/// Set by Windows to indicate that the buffer has been prepared by using the midiInPrepareHeader or midiOutPrepareHeader function.
///
///
///
///
public MHDR dwFlags;
/// Reserved; do not use.
public IntPtr lpNext;
/// Reserved; do not use.
public IntPtr reserved;
///
/// Offset into the buffer when a callback is performed. (This callback is generated because the MEVT_F_CALLBACK flag is set in
/// the dwEvent member of the MIDIEVENT structure.) This offset enables an application to determine which event caused
/// the callback.
///
public uint dwOffset;
/// Reserved; do not use.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public IntPtr[] dwReserved;
/// Gets the native size of this structure.
public static uint NativeSize = unchecked((uint)Marshal.SizeOf(typeof(MIDIHDR)));
}
/// The MIDIINCAPS structure describes the capabilities of a MIDI input device.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midiincaps typedef struct midiincaps_tag { WORD wMid; WORD
// wPid; VERSION vDriverVersion; char szPname[MAXPNAMELEN]; DWORD dwSupport; } MIDIINCAPS, *PMIDIINCAPS, *NPMIDIINCAPS, *LPMIDIINCAPS;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midiincaps_tag")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MIDIINCAPS
{
///
/// Manufacturer identifier of the device driver for the MIDI input device. Manufacturer identifiers are defined in Manufacturer
/// and Product Identifiers.
///
public ushort wMid;
/// Product identifier of the MIDI input device. Product identifiers are defined in Manufacturer and Product Identifiers.
public ushort wPid;
///
/// Version number of the device driver for the MIDI input device. The high-order byte is the major version number, and the
/// low-order byte is the minor version number.
///
public uint vDriverVersion;
/// Product name in a null-terminated string.
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)]
public string szPname;
/// Reserved; must be zero.
public uint dwSupport;
/// Gets the native size of this structure.
public static uint NativeSize = unchecked((uint)Marshal.SizeOf(typeof(MIDIINCAPS)));
}
/// The MIDIOUTCAPS structure describes the capabilities of a MIDI output device.
///
/// Note
///
/// The mmeapi.h header defines MIDIOUTCAPS as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midioutcapsw typedef struct tagMIDIOUTCAPSW { WORD wMid; WORD
// wPid; MMVERSION vDriverVersion; WCHAR szPname[MAXPNAMELEN]; WORD wTechnology; WORD wVoices; WORD wNotes; WORD wChannelMask; DWORD
// dwSupport; } MIDIOUTCAPSW, *PMIDIOUTCAPSW, *NPMIDIOUTCAPSW, *LPMIDIOUTCAPSW;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.tagMIDIOUTCAPSW")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MIDIOUTCAPS
{
///
/// Manufacturer identifier of the device driver for the MIDI output device. Manufacturer identifiers are defined in
/// Manufacturer and Product Identifiers.
///
public ushort wMid;
/// Product identifier of the MIDI output device. Product identifiers are defined in Manufacturer and Product Identifiers.
public ushort wPid;
///
/// Version number of the device driver for the MIDI output device. The high-order byte is the major version number, and the
/// low-order byte is the minor version number.
///
public uint vDriverVersion;
/// Product name in a null-terminated string.
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)]
public string szPname;
///
/// Type of the MIDI output device. This value can be one of the following:
///
///
/// Name
/// Description
///
/// -
/// MOD_MIDIPORT
/// MIDI hardware port.
///
/// -
/// MOD_SYNTH
/// Synthesizer.
///
/// -
/// MOD_SQSYNTH
/// Square wave synthesizer.
///
/// -
/// MOD_FMSYNTH
/// FM synthesizer.
///
/// -
/// MOD_MAPPER
/// Microsoft MIDI mapper.
///
/// -
/// MOD_WAVETABLE
/// Hardware wavetable synthesizer.
///
/// -
/// MOD_SWSYNTH
/// Software synthesizer.
///
///
///
public MOD wTechnology;
///
/// Number of voices supported by an internal synthesizer device. If the device is a port, this member is not meaningful and is
/// set to 0.
///
public ushort wVoices;
///
/// Maximum number of simultaneous notes that can be played by an internal synthesizer device. If the device is a port, this
/// member is not meaningful and is set to 0.
///
public ushort wNotes;
///
/// Channels that an internal synthesizer device responds to, where the least significant bit refers to channel 0 and the most
/// significant bit to channel 15. Port devices that transmit on all channels set this member to 0xFFFF.
///
public ushort wChannelMask;
///
/// Optional functionality supported by the device. It can be one or more of the following:
///
///
/// Name
/// Description
///
/// -
/// MIDICAPS_CACHE
/// Supports patch caching.
///
/// -
/// MIDICAPS_LRVOLUME
/// Supports separate left and right volume control.
///
/// -
/// MIDICAPS_STREAM
/// Provides direct support for the midiStreamOut function.
///
/// -
/// MIDICAPS_VOLUME
/// Supports volume control.
///
///
///
/// If a device supports volume changes, the MIDICAPS_VOLUME flag will be set for the dwSupport member. If a device supports
/// separate volume changes on the left and right channels, both the MIDICAPS_VOLUME and the MIDICAPS_LRVOLUME flags will be set
/// for this member.
///
///
public MIDI_CAPS dwSupport;
/// Gets the native size of this structure.
public static uint NativeSize = unchecked((uint)Marshal.SizeOf(typeof(MIDIOUTCAPS)));
}
/// The MIDIPROPTEMPO structure contains the tempo property for a stream.
/// The tempo property is read or written by the midiStreamProperty function.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midiproptempo typedef struct midiproptempo_tag { DWORD
// cbStruct; DWORD dwTempo; } MIDIPROPTEMPO, *LPMIDIPROPTEMPO;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midiproptempo_tag")]
[StructLayout(LayoutKind.Sequential)]
public struct MIDIPROPTEMPO
{
///
/// Length, in bytes, of this structure. This member must be filled in for both the MIDIPROP_SET and MIDIPROP_GET operations of
/// the midiStreamProperty function.
///
public uint cbStruct;
///
/// Tempo of the stream, in microseconds per quarter note. The tempo is honored only if the time division for the stream is
/// specified in quarter note format. This member is set in a MIDIPROP_SET operation and is filled on return from a MIDIPROP_GET operation.
///
public uint dwTempo;
}
/// The MIDIPROPTIMEDIV structure contains the time division property for a stream.
/// The time division property is read or written by the midiStreamProperty function.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midiproptimediv typedef struct midiproptimediv_tag { DWORD
// cbStruct; DWORD dwTimeDiv; } MIDIPROPTIMEDIV, *LPMIDIPROPTIMEDIV;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midiproptimediv_tag")]
[StructLayout(LayoutKind.Sequential)]
public struct MIDIPROPTIMEDIV
{
///
/// Length, in bytes, of this structure. This member must be filled in for both the MIDIPROP_SET and MIDIPROP_GET operations of
/// the midiStreamProperty function.
///
public uint cbStruct;
///
/// Time division for this stream, in the format specified in the Standard MIDI Files 1.0 specification. The low 16 bits of this
/// DWORD value contain the time division. This member is set in a MIDIPROP_SET operation and is filled on return from a
/// MIDIPROP_GET operation.
///
public uint dwTimeDiv;
}
/// The MIDISTRMBUFFVER structure contains version information for a long MIDI event of the MEVT_VERSION type.
// https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-midistrmbuffver typedef struct midistrmbuffver_tag { DWORD
// dwVersion; DWORD dwMid; DWORD dwOEMVersion; } MIDISTRMBUFFVER;
[PInvokeData("mmeapi.h", MSDNShortId = "NS:mmeapi.midistrmbuffver_tag")]
[StructLayout(LayoutKind.Sequential)]
public struct MIDISTRMBUFFVER
{
///
/// Version of the stream. The high 16 bits contain the major version, and the low 16 bits contain the minor version. The
/// version number for the first implementation of MIDI streams should be 1.0.
///
public uint dwVersion;
/// Manufacturer identifier. Manufacturer identifiers are defined in Manufacturer and Product Identifiers.
public uint dwMid;
///
/// OEM version of the stream. Original equipment manufacturers can use this field to version-stamp any custom events they have
/// specified. If a custom event is specified, it must be the first event sent after the stream is opened.
///
public uint dwOEMVersion;
}
}
}