Huw Davies : wineoss: Add a temporary midi_out_fm_reset syscall.
Alexandre Julliard
julliard at winehq.org
Wed Apr 20 16:49:48 CDT 2022
Module: wine
Branch: master
Commit: 5ebc7d78aa9985f7b38aac4ae8331090d818a7ab
URL: https://source.winehq.org/git/wine.git/?a=commit;h=5ebc7d78aa9985f7b38aac4ae8331090d818a7ab
Author: Huw Davies <huw at codeweavers.com>
Date: Wed Apr 20 09:04:03 2022 -0500
wineoss: Add a temporary midi_out_fm_reset syscall.
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wineoss.drv/midi.c | 40 +---------------
dlls/wineoss.drv/oss.c | 1 +
dlls/wineoss.drv/ossmidi.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
dlls/wineoss.drv/unixlib.h | 2 +
4 files changed, 118 insertions(+), 38 deletions(-)
diff --git a/dlls/wineoss.drv/midi.c b/dlls/wineoss.drv/midi.c
index 3d2552007cd..7d21dd32ae8 100644
--- a/dlls/wineoss.drv/midi.c
+++ b/dlls/wineoss.drv/midi.c
@@ -737,42 +737,6 @@ static int modFMLoad(WORD dev, int fd)
return params.ret;
}
-/**************************************************************************
- * modFMReset [internal]
- */
-static void modFMReset(WORD wDevID)
-{
- sFMextra* extra = MidiOutDev[wDevID].lpExtra;
- sVoice* voice = extra->voice;
- sChannel* channel = extra->channel;
- int i;
-
- for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
- if (voice[i].status != sVS_UNUSED) {
- SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);
- }
- SEQ_KEY_PRESSURE(wDevID, i, 127, 0);
- SEQ_CONTROL(wDevID, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
- voice[i].note = 0;
- voice[i].channel = -1;
- voice[i].cntMark = 0;
- voice[i].status = sVS_UNUSED;
- }
- for (i = 0; i < 16; i++) {
- channel[i].program = 0;
- channel[i].bender = 8192;
- channel[i].benderRange = 2;
- channel[i].bank = 0;
- channel[i].volume = 127;
- channel[i].balance = 64;
- channel[i].expression = 0;
- channel[i].sustain = 0;
- }
- extra->counter = 0;
- extra->drumSetMask = 1 << 9; /* channel 10 is normally drums, sometimes 16 also */
- SEQ_DUMPBUF();
-}
-
#define IS_DRUM_CHANNEL(_xtra, _chn) ((_xtra)->drumSetMask & (1 << (_chn)))
/**************************************************************************
@@ -846,7 +810,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
HeapFree(GetProcessHeap(), 0, extra);
return MMSYSERR_ERROR;
}
- modFMReset(wDevID);
+ OSS_CALL(midi_out_fm_reset, (void *)(UINT_PTR)wDevID);
}
break;
case MOD_MIDIPORT:
@@ -1120,7 +1084,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
case MIDI_SYSTEM_PREFIX:
switch (evt & 0x0F) {
case 0x0F: /* Reset */
- modFMReset(wDevID);
+ OSS_CALL(midi_out_fm_reset, (void *)(UINT_PTR)wDevID);
break;
default:
WARN("Unsupported (yet) system event %02x\n", evt & 0x0F);
diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c
index 2fc6c81e560..902685c11b8 100644
--- a/dlls/wineoss.drv/oss.c
+++ b/dlls/wineoss.drv/oss.c
@@ -1409,4 +1409,5 @@ unixlib_entry_t __wine_unix_call_funcs[] =
midi_seq_open,
midi_out_fm_load,
+ midi_out_fm_reset,
};
diff --git a/dlls/wineoss.drv/ossmidi.c b/dlls/wineoss.drv/ossmidi.c
index ba5dbca7e4f..dcafbe609d9 100644
--- a/dlls/wineoss.drv/ossmidi.c
+++ b/dlls/wineoss.drv/ossmidi.c
@@ -52,6 +52,47 @@ static unsigned int num_dests, num_srcs, num_synths, seq_refs;
static struct midi_dest dests[MAX_MIDIOUTDRV];
static struct midi_src srcs[MAX_MIDIINDRV];
+typedef struct sVoice
+{
+ int note; /* 0 means not used */
+ int channel;
+ unsigned cntMark : 30,
+ status : 2;
+#define sVS_UNUSED 0
+#define sVS_PLAYING 1
+#define sVS_SUSTAINED 2
+} sVoice;
+
+typedef struct sChannel
+{
+ int program;
+
+ int bender;
+ int benderRange;
+ /* controllers */
+ int bank; /* CTL_BANK_SELECT */
+ int volume; /* CTL_MAIN_VOLUME */
+ int balance; /* CTL_BALANCE */
+ int expression; /* CTL_EXPRESSION */
+ int sustain; /* CTL_SUSTAIN */
+
+ unsigned char nrgPmtMSB; /* Non register Parameters */
+ unsigned char nrgPmtLSB;
+ unsigned char regPmtMSB; /* Non register Parameters */
+ unsigned char regPmtLSB;
+} sChannel;
+
+typedef struct sFMextra
+{
+ unsigned counter;
+ int drumSetMask;
+ sChannel channel[16]; /* MIDI has only 16 channels */
+ sVoice voice[1]; /* dyn allocated according to sound card */
+ /* do not append fields below voice[1] since the size of this structure
+ * depends on the number of available voices on the FM synth...
+ */
+} sFMextra;
+
WINE_DEFAULT_DEBUG_CHANNEL(midi);
static int oss_to_win_device_type(int type)
@@ -346,6 +387,40 @@ wrapup:
return STATUS_SUCCESS;
}
+/* FIXME: this is a bad idea, it's even not static... */
+SEQ_DEFINEBUF(1024);
+
+/* FIXME: this is not reentrant, not static - because of global variable
+ * _seqbuf and al.
+ */
+/**************************************************************************
+ * seqbuf_dump [internal]
+ *
+ * Used by SEQ_DUMPBUF to flush the buffer.
+ *
+ */
+void seqbuf_dump(void)
+{
+ int fd;
+
+ /* The device is already open, but there's no way to pass the
+ fd to this function. Rather than rely on a global variable
+ we pretend to open the seq again. */
+ fd = seq_open();
+ if (_seqbufptr)
+ {
+ if (write(fd, _seqbuf, _seqbufptr) == -1)
+ {
+ WARN("Can't write data to sequencer %d, errno %d (%s)!\n",
+ fd, errno, strerror(errno));
+ }
+ /* FIXME: In any case buffer is lost so that if many errors occur the buffer
+ * will not overrun */
+ _seqbufptr = 0;
+ }
+ seq_close(fd);
+}
+
extern const unsigned char midiFMInstrumentPatches[16 * 128];
extern const unsigned char midiFMDrumsPatches[16 * 128];
@@ -388,3 +463,41 @@ NTSTATUS midi_out_fm_load(void *args)
params->ret = 0;
return STATUS_SUCCESS;
}
+
+NTSTATUS midi_out_fm_reset(void *args)
+{
+ WORD dev_id = (WORD)(UINT_PTR)args;
+ struct midi_dest *dest = dests + dev_id;
+ sFMextra *extra = dest->lpExtra;
+ sVoice *voice = extra->voice;
+ sChannel *channel = extra->channel;
+ int i;
+
+ for (i = 0; i < dest->caps.wVoices; i++)
+ {
+ if (voice[i].status != sVS_UNUSED)
+ SEQ_STOP_NOTE(dev_id, i, voice[i].note, 64);
+ SEQ_KEY_PRESSURE(dev_id, i, 127, 0);
+ SEQ_CONTROL(dev_id, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
+ voice[i].note = 0;
+ voice[i].channel = -1;
+ voice[i].cntMark = 0;
+ voice[i].status = sVS_UNUSED;
+ }
+ for (i = 0; i < 16; i++)
+ {
+ channel[i].program = 0;
+ channel[i].bender = 8192;
+ channel[i].benderRange = 2;
+ channel[i].bank = 0;
+ channel[i].volume = 127;
+ channel[i].balance = 64;
+ channel[i].expression = 0;
+ channel[i].sustain = 0;
+ }
+ extra->counter = 0;
+ extra->drumSetMask = 1 << 9; /* channel 10 is normally drums, sometimes 16 also */
+ SEQ_DUMPBUF();
+
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/wineoss.drv/unixlib.h b/dlls/wineoss.drv/unixlib.h
index 4dab53f5148..ecca092d540 100644
--- a/dlls/wineoss.drv/unixlib.h
+++ b/dlls/wineoss.drv/unixlib.h
@@ -288,11 +288,13 @@ enum oss_funcs
oss_midi_seq_open, /* temporary */
oss_midi_out_fm_load,
+ oss_midi_out_fm_reset,
};
NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
NTSTATUS midi_seq_open(void *args) DECLSPEC_HIDDEN;
NTSTATUS midi_out_fm_load(void *args) DECLSPEC_HIDDEN;
+NTSTATUS midi_out_fm_reset(void *args) DECLSPEC_HIDDEN;
extern unixlib_handle_t oss_handle;
More information about the wine-cvs
mailing list