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