#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; } } }