From: Anton Baskanov baskanov@gmail.com
--- dlls/mmdevapi/Makefile.in | 3 ++- dlls/mmdevapi/main.c | 28 +++++++++++++++++++- dlls/mmdevapi/mmdevapi_private.h | 3 +++ dlls/mmdevapi/swmidi.c | 45 ++++++++++++++++++++++++++++++++ dlls/winmm/tests/midi.c | 5 +++- 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 dlls/mmdevapi/swmidi.c
diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in index 26f0e8ee0aa..ae71f39ea0c 100644 --- a/dlls/mmdevapi/Makefile.in +++ b/dlls/mmdevapi/Makefile.in @@ -10,4 +10,5 @@ SOURCES = \ main.c \ mmdevapi_classes.idl \ session.c \ - spatialaudio.c + spatialaudio.c \ + swmidi.c diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index 1af6508c145..96000b4ecb4 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -428,7 +428,7 @@ DWORD WINAPI midMessage( UINT id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DW return err; }
-DWORD WINAPI modMessage( UINT id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DWORD_PTR param2 ) +DWORD driver_mod_message( UINT id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DWORD_PTR param2 ) { struct midi_out_message_params params; struct notify_context notify; @@ -449,6 +449,32 @@ DWORD WINAPI modMessage( UINT id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DW return err; }
+DWORD WINAPI modMessage( UINT id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DWORD_PTR param2 ) +{ + static DWORD driver_device_count; + + switch (msg) + { + case DRVM_INIT: + swmidi_mod_message(0, DRVM_INIT, 0, 0, 0); + driver_mod_message(0, DRVM_INIT, 0, 0, 0); + driver_device_count = driver_mod_message(0, MODM_GETNUMDEVS, 0, 0, 0); + return MMSYSERR_NOERROR; + + case DRVM_EXIT: + driver_mod_message(0, DRVM_EXIT, 0, 0, 0); + swmidi_mod_message(0, DRVM_EXIT, 0, 0, 0); + return MMSYSERR_NOERROR; + + case MODM_GETNUMDEVS: + return driver_device_count + 1; + } + + if (id < driver_device_count) + return driver_mod_message(id, msg, user, param1, param2); + return swmidi_mod_message(id - driver_device_count, msg, user, param1, param2); +} + DWORD WINAPI auxMessage( UINT id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DWORD_PTR param2 ) { struct aux_message_params params; diff --git a/dlls/mmdevapi/mmdevapi_private.h b/dlls/mmdevapi/mmdevapi_private.h index 8dff5aa0805..94dc870b03d 100644 --- a/dlls/mmdevapi/mmdevapi_private.h +++ b/dlls/mmdevapi/mmdevapi_private.h @@ -134,3 +134,6 @@ extern void main_loop_stop(void); extern const WCHAR drv_keyW[];
extern HRESULT get_audio_sessions(IMMDevice *device, GUID **ret, int *ret_count); + +extern DWORD swmidi_mod_message(UINT dev_id, UINT msg, DWORD_PTR user, DWORD_PTR param1, + DWORD_PTR param2); diff --git a/dlls/mmdevapi/swmidi.c b/dlls/mmdevapi/swmidi.c new file mode 100644 index 00000000000..e19676a98ab --- /dev/null +++ b/dlls/mmdevapi/swmidi.c @@ -0,0 +1,45 @@ +/* + * MIDI driver for software synthesizer + * + * Copyright 2025 Anton Baskanov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "mmddk.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(midi); + +DWORD swmidi_mod_message(UINT dev_id, UINT msg, DWORD_PTR user, DWORD_PTR param1, DWORD_PTR param2) +{ + TRACE("dev_id %u, msg %x, user %#Ix, param1 %#Ix, param2 %#Ix.\n", dev_id, msg, user, param1, + param2); + + switch (msg) + { + case DRVM_INIT: + case DRVM_EXIT: + return MMSYSERR_NOERROR; + case MODM_GETNUMDEVS: + return 1; + } + + return MMSYSERR_NOTSUPPORTED; +} diff --git a/dlls/winmm/tests/midi.c b/dlls/winmm/tests/midi.c index 70a5375f1cb..8be1ace09fc 100644 --- a/dlls/winmm/tests/midi.c +++ b/dlls/winmm/tests/midi.c @@ -279,9 +279,12 @@ static void test_midiOut_device(UINT udev, HWND hwnd) DWORD ovolume; UINT udevid; MIDIHDR mhdr; + BOOL swmidi; + + swmidi = udev == midiOutGetNumDevs() - 1;
rc = midiOutGetDevCapsA(udev, &capsA, sizeof(capsA)); - ok(!rc, "midiOutGetDevCaps(dev=%d) rc=%s\n", udev, mmsys_error(rc)); + todo_wine_if(swmidi) ok(!rc, "midiOutGetDevCaps(dev=%d) rc=%s\n", udev, mmsys_error(rc)); if (!rc) { trace("* %s: manufacturer=%d, product=%d, tech=%d, support=%lX: %d voices, %d notes\n", capsA.szPname, capsA.wMid, capsA.wPid, capsA.wTechnology, capsA.dwSupport, capsA.wVoices, capsA.wNotes);