From: Anton Baskanov baskanov@gmail.com
--- dlls/wineswmidi/Makefile.in | 1 + dlls/wineswmidi/swmidi.c | 118 ++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+)
diff --git a/dlls/wineswmidi/Makefile.in b/dlls/wineswmidi/Makefile.in index 5e9a8995868..24210437d0a 100644 --- a/dlls/wineswmidi/Makefile.in +++ b/dlls/wineswmidi/Makefile.in @@ -1,4 +1,5 @@ MODULE = wineswmidi.dll +IMPORTS = uuid ole32 DELAYIMPORTS = winmm
SOURCES = \ diff --git a/dlls/wineswmidi/swmidi.c b/dlls/wineswmidi/swmidi.c index f203ad1221a..4e8f50786ff 100644 --- a/dlls/wineswmidi/swmidi.c +++ b/dlls/wineswmidi/swmidi.c @@ -24,10 +24,16 @@ #include "mmddk.h" #include "mmdeviceapi.h"
+#include "initguid.h" +#include "dmusicc.h" + #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(midi);
+#define SWMIDI_AUDIO_CHANNELS 2 +#define SWMIDI_SAMPLE_RATE 22050 + struct swmidi { CRITICAL_SECTION cs; @@ -35,10 +41,93 @@ struct swmidi BOOL open; MIDIOPENDESC open_desc; WORD flags; + + HANDLE close_event; + HANDLE open_event; + HANDLE thread; + DWORD init_result; + + IDirectMusic *dmusic; + IDirectMusicPort *port; };
static struct swmidi swmidi;
+static HRESULT init_dmusic(void) +{ + DMUS_PORTPARAMS port_params; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusic, + (void **)&swmidi.dmusic); + if (FAILED(hr)) + return hr; + + hr = IDirectMusic_SetDirectSound(swmidi.dmusic, NULL, NULL); + if (FAILED(hr)) + { + IDirectMusic_Release(swmidi.dmusic); + return hr; + } + + memset(&port_params, 0, sizeof(port_params)); + port_params.dwSize = sizeof(port_params); + port_params.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS | DMUS_PORTPARAMS_AUDIOCHANNELS + | DMUS_PORTPARAMS_SAMPLERATE | DMUS_PORTPARAMS_EFFECTS; + port_params.dwChannelGroups = 1; + port_params.dwAudioChannels = SWMIDI_AUDIO_CHANNELS; + port_params.dwSampleRate = SWMIDI_SAMPLE_RATE; + port_params.dwEffectFlags = 0; + hr = IDirectMusic_CreatePort(swmidi.dmusic, &GUID_NULL, &port_params, &swmidi.port, NULL); + if (FAILED(hr)) + { + IDirectMusic_Release(swmidi.dmusic); + return hr; + } + + if (FAILED(IDirectMusicPort_Activate(swmidi.port, TRUE))) + { + IDirectMusicPort_Release(swmidi.port); + IDirectMusic_Release(swmidi.dmusic); + return hr; + } + + return S_OK; +} + +static void destroy_dmusic(void) +{ + IDirectMusicPort_Activate(swmidi.port, FALSE); + IDirectMusicPort_Release(swmidi.port); + IDirectMusic_Release(swmidi.dmusic); +} + +static DWORD WINAPI thread_proc(void *param) +{ + SetThreadDescription(GetCurrentThread(), L"swmidi"); + + CoInitialize(NULL); + + if (FAILED(init_dmusic())) + { + CoUninitialize(); + swmidi.init_result = MMSYSERR_ERROR; + SetEvent(swmidi.open_event); + return 0; + } + + swmidi.init_result = MMSYSERR_NOERROR; + SetEvent(swmidi.open_event); + + WaitForSingleObject(swmidi.close_event, INFINITE); + + destroy_dmusic(); + + CoUninitialize(); + + return 0; +} + static DWORD swmidi_init(void) { TRACE("\n"); @@ -88,6 +177,28 @@ static DWORD swmidi_open(MIDIOPENDESC *desc, UINT flags) return MMSYSERR_ALLOCATED; }
+ swmidi.close_event = CreateEventA(NULL, FALSE, FALSE, NULL); + swmidi.open_event = CreateEventA(NULL, FALSE, FALSE, NULL); + + swmidi.thread = CreateThread(NULL, 0, thread_proc, NULL, 0, NULL); + if (!swmidi.thread) + { + LeaveCriticalSection(&swmidi.cs); + return MMSYSERR_ERROR; + } + + WaitForSingleObject(swmidi.open_event, INFINITE); + + if (swmidi.init_result != MMSYSERR_NOERROR) + { + WaitForSingleObject(swmidi.thread, INFINITE); + CloseHandle(swmidi.thread); + CloseHandle(swmidi.open_event); + CloseHandle(swmidi.close_event); + LeaveCriticalSection(&swmidi.cs); + return swmidi.init_result; + } + swmidi.open = TRUE; swmidi.open_desc = *desc; swmidi.flags = HIWORD(flags & CALLBACK_TYPEMASK); @@ -106,6 +217,13 @@ static DWORD swmidi_close(void)
EnterCriticalSection(&swmidi.cs);
+ SetEvent(swmidi.close_event); + WaitForSingleObject(swmidi.thread, INFINITE); + + CloseHandle(swmidi.thread); + CloseHandle(swmidi.open_event); + CloseHandle(swmidi.close_event); + swmidi.open = FALSE;
LeaveCriticalSection(&swmidi.cs);