Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Apr 29, 2022 at 08:29:54AM +0100, Huw Davies wrote:
The syscall itself is temporary.
Signed-off-by: Huw Davies huw@codeweavers.com
dlls/wineoss.drv/midi.c | 129 +------------------------ dlls/wineoss.drv/oss.c | 2 +- dlls/wineoss.drv/ossmidi.c | 189 +++++++++++++++++++++++++++++++++++-- dlls/wineoss.drv/unixlib.h | 10 +- 4 files changed, 196 insertions(+), 134 deletions(-)
diff --git a/dlls/wineoss.drv/midi.c b/dlls/wineoss.drv/midi.c index b3f980ab3da..0afd9985c03 100644 --- a/dlls/wineoss.drv/midi.c +++ b/dlls/wineoss.drv/midi.c @@ -126,16 +126,6 @@ static LRESULT OSS_MidiExit(void) return 0; }
-static void in_buffer_lock(void) -{
- OSS_CALL(midi_in_lock, ULongToPtr(1));
-}
-static void in_buffer_unlock(void) -{
- OSS_CALL(midi_in_lock, ULongToPtr(0));
-}
static void notify_client(struct notify_context *notify) { TRACE("dev_id = %d msg = %d param1 = %04lX param2 = %04lX\n", @@ -210,123 +200,13 @@ static int midiCloseSeq(int fd) return 0; }
-static void handle_sysex_data(struct midi_src *src, unsigned char value, UINT time) -{
- MIDIHDR *hdr;
- BOOL done = FALSE;
- src->state |= 2;
- src->incLen = 0;
- in_buffer_lock();
- hdr = src->lpQueueHdr;
- if (hdr)
- {
BYTE *data = (BYTE *)hdr->lpData;
data[hdr->dwBytesRecorded++] = value;
if (hdr->dwBytesRecorded == hdr->dwBufferLength)
done = TRUE;
- }
- if (value == 0xf7) /* end */
- {
src->state &= ~2;
done = TRUE;
- }
- if (done && hdr)
- {
src->lpQueueHdr = hdr->lpNext;
hdr->dwFlags &= ~MHDR_INQUEUE;
hdr->dwFlags |= MHDR_DONE;
MIDI_NotifyClient(src - MidiInDev, MIM_LONGDATA, (UINT_PTR)hdr, time);
- }
- in_buffer_unlock();
-}
-static void handle_regular_data(struct midi_src *src, unsigned char value, UINT time) -{
- UINT to_send = 0;
-#define IS_CMD(_x) (((_x) & 0x80) == 0x80) -#define IS_SYS_CMD(_x) (((_x) & 0xF0) == 0xF0)
- if (!IS_CMD(value) && src->incLen == 0) /* try to reuse old cmd */
- {
if (IS_CMD(src->incPrev) && !IS_SYS_CMD(src->incPrev))
{
src->incoming[0] = src->incPrev;
src->incLen = 1;
}
else
{
/* FIXME: should generate MIM_ERROR notification */
return;
}
- }
- src->incoming[(int)src->incLen++] = value;
- if (src->incLen == 1 && !IS_SYS_CMD(src->incoming[0]))
/* store new cmd, just in case */
src->incPrev = src->incoming[0];
-#undef IS_CMD -#undef IS_SYS_CMD
- switch (src->incoming[0] & 0xF0)
- {
- case MIDI_NOTEOFF:
- case MIDI_NOTEON:
- case MIDI_KEY_PRESSURE:
- case MIDI_CTL_CHANGE:
- case MIDI_PITCH_BEND:
if (src->incLen == 3)
to_send = (src->incoming[2] << 16) | (src->incoming[1] << 8) |
src->incoming[0];
break;
- case MIDI_PGM_CHANGE:
- case MIDI_CHN_PRESSURE:
if (src->incLen == 2)
to_send = (src->incoming[1] << 8) | src->incoming[0];
break;
- case MIDI_SYSTEM_PREFIX:
if (src->incLen == 1)
to_send = src->incoming[0];
break;
- }
- if (to_send)
- {
src->incLen = 0;
MIDI_NotifyClient(src - MidiInDev, MIM_DATA, to_send, time);
- }
-}
static void handle_midi_data(unsigned char *buffer, unsigned int len) {
- unsigned int time = GetTickCount(), i;
- struct midi_src *src;
- unsigned char value;
- WORD dev_id;
- struct midi_handle_data_params params;
- for (i = 0; i < len; i += (buffer[i] & 0x80) ? 8 : 4)
- {
if (buffer[i] != SEQ_MIDIPUTC) continue;
dev_id = buffer[i + 2];
value = buffer[i + 1];
if (dev_id >= MIDM_NumDevs) continue;
src = MidiInDev + dev_id;
if (src->state <= 0) continue;
if (value == 0xf0 || src->state & 2) /* system exclusive */
handle_sysex_data(src, value, time - src->startTime);
else
handle_regular_data(src, value, time - src->startTime);
- }
- params.buffer = buffer;
- params.len = len;
- OSS_CALL(midi_handle_data, ¶ms);
}
static DWORD WINAPI midRecThread(void *arg) @@ -565,6 +445,7 @@ static DWORD WINAPI notify_thread(void *p) { OSS_CALL(midi_notify_wait, ¶ms); if (quit) break;
} return 0;if (notify.send_notify) notify_client(¬ify);
} diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c index 8fda9270a4e..c5b422a60c9 100644 --- a/dlls/wineoss.drv/oss.c +++ b/dlls/wineoss.drv/oss.c @@ -1412,5 +1412,5 @@ unixlib_entry_t __wine_unix_call_funcs[] = midi_notify_wait,
midi_seq_open,
- midi_in_lock,
- midi_handle_data,
}; diff --git a/dlls/wineoss.drv/ossmidi.c b/dlls/wineoss.drv/ossmidi.c index 0790eaaec1a..1695f1d2f7b 100644 --- a/dlls/wineoss.drv/ossmidi.c +++ b/dlls/wineoss.drv/ossmidi.c @@ -68,7 +68,11 @@ static struct midi_src srcs[MAX_MIDIINDRV];
static pthread_mutex_t notify_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t notify_read_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t notify_write_cond = PTHREAD_COND_INITIALIZER; static BOOL notify_quit; +#define NOTIFY_BUFFER_SIZE 64 + 1 /* + 1 for the sentinel */ +static struct notify_context notify_buffer[NOTIFY_BUFFER_SIZE]; +static struct notify_context *notify_read = notify_buffer, *notify_write = notify_buffer;
typedef struct sVoice { @@ -151,19 +155,59 @@ static void in_buffer_unlock(void) pthread_mutex_unlock(&in_buffer_mutex); }
-NTSTATUS midi_in_lock(void *args) +/*
- notify buffer: The notification ring buffer is implemented so that
- there is always at least one unused sentinel before the current
- read position in order to allow detection of the full vs empty
- state.
- */
+static struct notify_context *notify_buffer_next(struct notify_context *notify) {
- if (args) in_buffer_lock();
- else in_buffer_unlock();
- if (++notify >= notify_buffer + ARRAY_SIZE(notify_buffer))
notify = notify_buffer;
- return STATUS_SUCCESS;
- return notify;
+}
+static BOOL notify_buffer_empty(void) +{
- return notify_read == notify_write;
+}
+static BOOL notify_buffer_full(void) +{
- return notify_buffer_next(notify_write) == notify_read;
+}
+static BOOL notify_buffer_add(struct notify_context *notify) +{
- if (notify_buffer_full()) return FALSE;
- *notify_write = *notify;
- notify_write = notify_buffer_next(notify_write);
- return TRUE;
+}
+static BOOL notify_buffer_remove(struct notify_context *notify) +{
- if (notify_buffer_empty()) return FALSE;
- *notify = *notify_read;
- notify_read = notify_buffer_next(notify_read);
- return TRUE;
}
static void notify_post(struct notify_context *notify) { pthread_mutex_lock(¬ify_mutex);
- if (notify) FIXME("Not yet handled\n");
- if (notify)
- {
while (notify_buffer_full())
pthread_cond_wait(¬ify_write_cond, ¬ify_mutex);
notify_buffer_add(notify);
- } else notify_quit = TRUE; pthread_cond_signal(¬ify_read_cond);
@@ -1157,6 +1201,133 @@ static UINT midi_out_reset(WORD dev_id) return MMSYSERR_NOERROR; }
+static void handle_sysex_data(struct midi_src *src, unsigned char value, UINT time) +{
- struct notify_context notify;
- MIDIHDR *hdr;
- BOOL done = FALSE;
- src->state |= 2;
- src->incLen = 0;
- in_buffer_lock();
- hdr = src->lpQueueHdr;
- if (hdr)
- {
BYTE *data = (BYTE *)hdr->lpData;
data[hdr->dwBytesRecorded++] = value;
if (hdr->dwBytesRecorded == hdr->dwBufferLength)
done = TRUE;
- }
- if (value == 0xf7) /* end */
- {
src->state &= ~2;
done = TRUE;
- }
- if (done && hdr)
- {
src->lpQueueHdr = hdr->lpNext;
hdr->dwFlags &= ~MHDR_INQUEUE;
hdr->dwFlags |= MHDR_DONE;
set_in_notify(¬ify, src, src - srcs, MIM_LONGDATA, (UINT_PTR)hdr, time);
notify_post(¬ify);
- }
- in_buffer_unlock();
+}
+static void handle_regular_data(struct midi_src *src, unsigned char value, UINT time) +{
- struct notify_context notify;
- UINT to_send = 0;
+#define IS_CMD(_x) (((_x) & 0x80) == 0x80) +#define IS_SYS_CMD(_x) (((_x) & 0xF0) == 0xF0)
- if (!IS_CMD(value) && src->incLen == 0) /* try to reuse old cmd */
- {
if (IS_CMD(src->incPrev) && !IS_SYS_CMD(src->incPrev))
{
src->incoming[0] = src->incPrev;
src->incLen = 1;
}
else
{
/* FIXME: should generate MIM_ERROR notification */
return;
}
- }
- src->incoming[(int)src->incLen++] = value;
- if (src->incLen == 1 && !IS_SYS_CMD(src->incoming[0]))
/* store new cmd, just in case */
src->incPrev = src->incoming[0];
+#undef IS_CMD +#undef IS_SYS_CMD
- switch (src->incoming[0] & 0xF0)
- {
- case MIDI_NOTEOFF:
- case MIDI_NOTEON:
- case MIDI_KEY_PRESSURE:
- case MIDI_CTL_CHANGE:
- case MIDI_PITCH_BEND:
if (src->incLen == 3)
to_send = (src->incoming[2] << 16) | (src->incoming[1] << 8) |
src->incoming[0];
break;
- case MIDI_PGM_CHANGE:
- case MIDI_CHN_PRESSURE:
if (src->incLen == 2)
to_send = (src->incoming[1] << 8) | src->incoming[0];
break;
- case MIDI_SYSTEM_PREFIX:
if (src->incLen == 1)
to_send = src->incoming[0];
break;
- }
- if (to_send)
- {
src->incLen = 0;
set_in_notify(¬ify, src, src - srcs, MIM_DATA, to_send, time);
notify_post(¬ify);
- }
+}
+NTSTATUS midi_handle_data(void *args) +{
- struct midi_handle_data_params *params = args;
- unsigned char *buffer = params->buffer;
- unsigned int len = params->len;
- unsigned int time = NtGetTickCount(), i;
- struct midi_src *src;
- unsigned char value;
- WORD dev_id;
- for (i = 0; i < len; i += (buffer[i] & 0x80) ? 8 : 4)
- {
if (buffer[i] != SEQ_MIDIPUTC) continue;
dev_id = buffer[i + 2];
value = buffer[i + 1];
if (dev_id >= num_srcs) continue;
src = srcs + dev_id;
if (src->state <= 0) continue;
if (value == 0xf0 || src->state & 2) /* system exclusive */
handle_sysex_data(src, value, time - src->startTime);
else
handle_regular_data(src, value, time - src->startTime);
- }
- return STATUS_SUCCESS;
+}
static UINT midi_in_add_buffer(WORD dev_id, MIDIHDR *hdr, UINT hdr_size) { struct midi_src *src; @@ -1397,11 +1568,15 @@ NTSTATUS midi_notify_wait(void *args)
pthread_mutex_lock(¬ify_mutex);
- while (!notify_quit)
while (!notify_quit && notify_buffer_empty()) pthread_cond_wait(¬ify_read_cond, ¬ify_mutex);
*params->quit = notify_quit;
if (!notify_quit)
{
notify_buffer_remove(params->notify);
pthread_cond_signal(¬ify_write_cond);
} pthread_mutex_unlock(¬ify_mutex);
return STATUS_SUCCESS;
diff --git a/dlls/wineoss.drv/unixlib.h b/dlls/wineoss.drv/unixlib.h index ddeba49556c..90d0c47421c 100644 --- a/dlls/wineoss.drv/unixlib.h +++ b/dlls/wineoss.drv/unixlib.h @@ -279,6 +279,12 @@ struct midi_seq_open_params int fd; };
+struct midi_handle_data_params +{
- unsigned char *buffer;
- unsigned int len;
+};
enum oss_funcs { oss_test_connect, @@ -311,7 +317,7 @@ enum oss_funcs oss_midi_notify_wait,
oss_midi_seq_open, /* temporary */
- oss_midi_in_lock,
- oss_midi_handle_data,
};
NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN; @@ -320,7 +326,7 @@ NTSTATUS midi_out_message(void *args) DECLSPEC_HIDDEN; NTSTATUS midi_in_message(void *args) DECLSPEC_HIDDEN; NTSTATUS midi_notify_wait(void *args) DECLSPEC_HIDDEN; NTSTATUS midi_seq_open(void *args) DECLSPEC_HIDDEN; -NTSTATUS midi_in_lock(void *args) DECLSPEC_HIDDEN; +NTSTATUS midi_handle_data(void *args) DECLSPEC_HIDDEN;
extern unixlib_handle_t oss_handle;
-- 2.25.1