Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winealsa.drv/Makefile.in | 1 + dlls/winealsa.drv/alsa.c | 2 + dlls/winealsa.drv/alsamidi.c | 64 +++++++++++++++++++++++ dlls/winealsa.drv/midi.c | 97 +++++++++++++++++------------------ dlls/winealsa.drv/unixlib.h | 4 ++ 5 files changed, 118 insertions(+), 50 deletions(-) create mode 100644 dlls/winealsa.drv/alsamidi.c
diff --git a/dlls/winealsa.drv/Makefile.in b/dlls/winealsa.drv/Makefile.in index 2158e087251..41be57d8b83 100644 --- a/dlls/winealsa.drv/Makefile.in +++ b/dlls/winealsa.drv/Makefile.in @@ -9,5 +9,6 @@ EXTRADLLFLAGS = -mcygwin
C_SRCS = \ alsa.c \ + alsamidi.c \ midi.c \ mmdevdrv.c diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index 085066622c0..cdc3d81d8cc 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -2444,4 +2444,6 @@ unixlib_entry_t __wine_unix_call_funcs[] = set_event_handle, is_started, get_prop_value, + + midi_seq_lock, /* temporary */ }; diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c new file mode 100644 index 00000000000..ab4de4f7f9e --- /dev/null +++ b/dlls/winealsa.drv/alsamidi.c @@ -0,0 +1,64 @@ +/* + * MIDI driver for ALSA (unixlib) + * + * Copyright 1994 Martin Ayotte + * Copyright 1998 Luiz Otavio L. Zorzella + * Copyright 1998, 1999 Eric POUECH + * Copyright 2003 Christian Costa + * Copyright 2022 Huw Davies + * + * 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 + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include <stdarg.h> +#include <stdio.h> +#include <pthread.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "mmdeviceapi.h" + +#include "wine/unixlib.h" + +#include "unixlib.h" + +static pthread_mutex_t seq_mutex = PTHREAD_MUTEX_INITIALIZER; + +static void seq_lock(void) +{ + pthread_mutex_lock(&seq_mutex); +} + +static void seq_unlock(void) +{ + pthread_mutex_unlock(&seq_mutex); +} + +NTSTATUS midi_seq_lock(void *args) +{ + if (args) seq_lock(); + else seq_unlock(); + + return STATUS_SUCCESS; +} diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c index e65cae6cda5..dff77ce88d8 100644 --- a/dlls/winealsa.drv/midi.c +++ b/dlls/winealsa.drv/midi.c @@ -1,17 +1,11 @@ -/* -*- tab-width: 8; c-basic-offset: 4 -*- */ - /* - * Sample MIDI Wine Driver for ALSA (basically Linux) + * MIDI driver for ALSA (PE-side) * - * Copyright 1994 Martin Ayotte - * Copyright 1998 Luiz Otavio L. Zorzella (init procedures) - * Copyright 1998/1999 Eric POUECH : - * 98/7 changes for making this MIDI driver work on OSS - * current support is limited to MIDI ports of OSS systems - * 98/9 rewriting MCI code for MIDI - * 98/11 split in midi.c and mcimidi.c - * Copyright 2003 Christian Costa : - * ALSA port + * Copyright 1994 Martin Ayotte + * Copyright 1998 Luiz Otavio L. Zorzella + * Copyright 1998, 1999 Eric POUECH + * Copyright 2003 Christian Costa + * Copyright 2022 Huw Davies * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,9 +20,6 @@ * 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 - * - * TODO: Finish midi record - * */
#include "config.h" @@ -40,18 +31,22 @@ #include <fcntl.h> #include <errno.h>
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "wingdi.h" -#include "winuser.h" -#include "winnls.h" +#include "winternl.h" #include "mmddk.h" -#include "mmreg.h" -#include "dsound.h" +#include "mmdeviceapi.h" + #include "wine/debug.h" +#include "wine/unixlib.h"
#include <alsa/asoundlib.h>
+#include "unixlib.h" + WINE_DEFAULT_DEBUG_CHANNEL(midi);
typedef struct { @@ -81,14 +76,6 @@ static int MODM_NumDevs = 0; /* this is the total number of MIDI out devices found */ static int MIDM_NumDevs = 0;
-static CRITICAL_SECTION midiSeqLock; -static CRITICAL_SECTION_DEBUG midiSeqLockDebug = -{ - 0, 0, &midiSeqLock, - { &midiSeqLockDebug.ProcessLocksList, &midiSeqLockDebug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": midiSeqLock") } -}; -static CRITICAL_SECTION midiSeqLock = { &midiSeqLockDebug, -1, 0, 0, 0, 0 }; static snd_seq_t* midiSeq = NULL; static int numOpenMidiSeq = 0; static int numStartedMidiIn = 0; @@ -107,6 +94,16 @@ static CRITICAL_SECTION crit_sect = { &critsect_debug, -1, 0, 0, 0, 0 }; static int end_thread; static HANDLE hThread;
+static void seq_lock(void) +{ + ALSA_CALL(midi_seq_lock, (void *)(UINT_PTR)1); +} + +static void seq_unlock(void) +{ + ALSA_CALL(midi_seq_lock, (void *)(UINT_PTR)0); +} + /*======================================================================* * Low level MIDI implementation * *======================================================================*/ @@ -215,7 +212,7 @@ static BOOL midi_warn = TRUE; */ static int midiOpenSeq(BOOL create_client) { - EnterCriticalSection(&midiSeqLock); + seq_lock(); if (numOpenMidiSeq == 0) { if (snd_seq_open(&midiSeq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { @@ -224,7 +221,7 @@ static int midiOpenSeq(BOOL create_client) WARN("Error opening ALSA sequencer.\n"); } midi_warn = FALSE; - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); return -1; }
@@ -242,7 +239,7 @@ static int midiOpenSeq(BOOL create_client) } } numOpenMidiSeq++; - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); return 0; }
@@ -251,13 +248,13 @@ static int midiOpenSeq(BOOL create_client) */ static int midiCloseSeq(void) { - EnterCriticalSection(&midiSeqLock); + seq_lock(); if (--numOpenMidiSeq == 0) { snd_seq_delete_simple_port(midiSeq, port_in); snd_seq_close(midiSeq); midiSeq = NULL; } - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); return 0; }
@@ -381,11 +378,11 @@ static DWORD WINAPI midRecThread(LPVOID arg)
while(!end_thread) { TRACE("Thread loop\n"); - EnterCriticalSection(&midiSeqLock); + seq_lock(); npfd = snd_seq_poll_descriptors_count(midiSeq, POLLIN); pfd = HeapAlloc(GetProcessHeap(), 0, npfd * sizeof(struct pollfd)); snd_seq_poll_descriptors(midiSeq, pfd, npfd, POLLIN); - LeaveCriticalSection(&midiSeqLock); + seq_unlock();
/* Check if an event is present */ if (poll(pfd, npfd, 250) <= 0) { @@ -404,18 +401,18 @@ static DWORD WINAPI midRecThread(LPVOID arg) do { snd_seq_event_t *ev;
- EnterCriticalSection(&midiSeqLock); + seq_lock(); snd_seq_event_input(midiSeq, &ev); - LeaveCriticalSection(&midiSeqLock); + seq_unlock();
if (ev) { handle_midi_event(ev); snd_seq_free_event(ev); }
- EnterCriticalSection(&midiSeqLock); + seq_lock(); ret = snd_seq_event_input_pending(midiSeq, 0); - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); } while(ret > 0); HeapFree(GetProcessHeap(), 0, pfd); @@ -489,10 +486,10 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) MidiInDev[wDevID].startTime = 0;
/* Connect our app port to the device port */ - EnterCriticalSection(&midiSeqLock); + seq_lock(); ret = snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port); - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); if (ret < 0) return MMSYSERR_NOTENABLED;
@@ -550,9 +547,9 @@ static DWORD midClose(WORD wDevID) TRACE("Stopped thread for midi-in\n"); }
- EnterCriticalSection(&midiSeqLock); + seq_lock(); snd_seq_disconnect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port); - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); midiCloseSeq();
MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L); @@ -752,7 +749,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); MidiOutDev[wDevID].midiDesc = *lpDesc;
- EnterCriticalSection(&midiSeqLock); + seq_lock(); /* Create a port dedicated to a specific device */ /* Keep the old name without a number for the first port */ if (wDevID) @@ -780,7 +777,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) wDevID, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port, snd_strerror(ret)); } - LeaveCriticalSection(&midiSeqLock); + seq_unlock();
if (port_out < 0) return MMSYSERR_NOTENABLED; @@ -817,11 +814,11 @@ static DWORD modClose(WORD wDevID) case MOD_FMSYNTH: case MOD_MIDIPORT: case MOD_SYNTH: - EnterCriticalSection(&midiSeqLock); + seq_lock(); TRACE("Deleting port :%d, connected to %d:%d\n", MidiOutDev[wDevID].port_out, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port); snd_seq_delete_simple_port(midiSeq, MidiOutDev[wDevID].port_out); MidiOutDev[wDevID].port_out = -1; - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); midiCloseSeq(); break; default: @@ -942,9 +939,9 @@ static DWORD modData(WORD wDevID, DWORD dwParam) break; } if (handled) { - EnterCriticalSection(&midiSeqLock); + seq_lock(); snd_seq_event_output_direct(midiSeq, &event); - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); } } break; @@ -1033,9 +1030,9 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) snd_seq_ev_set_source(&event, MidiOutDev[wDevID].port_out); snd_seq_ev_set_subs(&event); snd_seq_ev_set_sysex(&event, lpMidiHdr->dwBufferLength + len_add, lpNewData ? lpNewData : lpData); - EnterCriticalSection(&midiSeqLock); + seq_lock(); snd_seq_event_output_direct(midiSeq, &event); - LeaveCriticalSection(&midiSeqLock); + seq_unlock(); HeapFree(GetProcessHeap(), 0, lpNewData); break; default: diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h index c2de48cef65..89afcb71bec 100644 --- a/dlls/winealsa.drv/unixlib.h +++ b/dlls/winealsa.drv/unixlib.h @@ -232,8 +232,12 @@ enum alsa_funcs alsa_set_event_handle, alsa_is_started, alsa_get_prop_value, + + alsa_midi_seq_lock, /* temporary */ };
+NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN; + extern unixlib_handle_t alsa_handle;
#define ALSA_CALL(func, params) __wine_unix_call(alsa_handle, alsa_ ## func, params)