[PATCH 1/4] wineoss: Use separate functions to handle MODM_DATA for FM synths and ports.

Huw Davies huw at codeweavers.com
Thu Apr 21 01:52:15 CDT 2022


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/wineoss.drv/midi.c | 538 ++++++++++++++++++++--------------------
 1 file changed, 268 insertions(+), 270 deletions(-)

diff --git a/dlls/wineoss.drv/midi.c b/dlls/wineoss.drv/midi.c
index d66e926655d..70bc4b7b9bd 100644
--- a/dlls/wineoss.drv/midi.c
+++ b/dlls/wineoss.drv/midi.c
@@ -747,15 +747,274 @@ static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPSW lpCaps, DWORD dwSize)
     return MMSYSERR_NOERROR;
 }
 
+static UINT midi_out_fm_data(WORD dev_id, UINT data)
+{
+    struct midi_dest *dest = MidiOutDev + dev_id;
+    WORD evt = LOBYTE(LOWORD(data));
+    WORD d1  = HIBYTE(LOWORD(data));
+    WORD d2  = LOBYTE(HIWORD(data));
+    sFMextra *extra = dest->lpExtra;
+    sVoice *voice = extra->voice;
+    sChannel *channel = extra->channel;
+    int chn = (evt & 0x0F), i, nv;
+
+    /* FIXME: chorus depth controller is not used */
+
+    switch (evt & 0xF0)
+    {
+    case MIDI_NOTEOFF:
+        for (i = 0; i < dest->caps.wVoices; i++)
+        {
+            /* don't stop sustained notes */
+            if (voice[i].status == sVS_PLAYING && voice[i].channel == chn && voice[i].note == d1)
+            {
+                voice[i].status = sVS_UNUSED;
+                SEQ_STOP_NOTE(dev_id, i, d1, d2);
+            }
+        }
+        break;
+    case MIDI_NOTEON:
+        if (d2 == 0) /* note off if velocity == 0 */
+        {
+            for (i = 0; i < dest->caps.wVoices; i++) /* don't stop sustained notes */
+            {
+                if (voice[i].status == sVS_PLAYING && voice[i].channel == chn && voice[i].note == d1)
+                {
+                    voice[i].status = sVS_UNUSED;
+                    SEQ_STOP_NOTE(dev_id, i, d1, 64);
+                }
+            }
+            break;
+        }
+        /* finding out in this order :
+         * - an empty voice
+         * - if replaying the same note on the same channel
+         * - the older voice (LRU)
+         */
+        for (i = nv = 0; i < dest->caps.wVoices; i++)
+        {
+            if (voice[i].status == sVS_UNUSED || (voice[i].note == d1 && voice[i].channel == chn))
+            {
+                nv = i;
+                break;
+            }
+            if (voice[i].cntMark < voice[0].cntMark)
+                nv = i;
+        }
+        TRACE("playing on voice=%d, pgm=%d, pan=0x%02X, vol=0x%02X, bender=0x%02X, note=0x%02X, vel=0x%02X\n",
+              nv, channel[chn].program, channel[chn].balance, channel[chn].volume, channel[chn].bender, d1, d2);
+
+        SEQ_SET_PATCH(dev_id, nv, IS_DRUM_CHANNEL(extra, chn) ?
+                      (128 + d1) : channel[chn].program);
+        SEQ_BENDER_RANGE(dev_id, nv, channel[chn].benderRange * 100);
+        SEQ_BENDER(dev_id, nv, channel[chn].bender);
+        SEQ_CONTROL(dev_id, nv, CTL_PAN, channel[chn].balance);
+        SEQ_CONTROL(dev_id, nv, CTL_EXPRESSION, channel[chn].expression);
+        SEQ_START_NOTE(dev_id, nv, d1, d2);
+        voice[nv].status = channel[chn].sustain ? sVS_SUSTAINED : sVS_PLAYING;
+        voice[nv].note = d1;
+        voice[nv].channel = chn;
+        voice[nv].cntMark = extra->counter++;
+        break;
+    case MIDI_KEY_PRESSURE:
+        for (i = 0; i < dest->caps.wVoices; i++)
+            if (voice[i].status != sVS_UNUSED && voice[i].channel == chn && voice[i].note == d1)
+                SEQ_KEY_PRESSURE(dev_id, i, d1, d2);
+        break;
+    case MIDI_CTL_CHANGE:
+        switch (d1)
+        {
+        case CTL_BANK_SELECT: channel[chn].bank = d2; break;
+        case CTL_MAIN_VOLUME: channel[chn].volume = d2; break;
+        case CTL_PAN:         channel[chn].balance = d2; break;
+        case CTL_EXPRESSION:  channel[chn].expression = d2; break;
+        case CTL_SUSTAIN:     channel[chn].sustain = d2;
+            if (d2)
+            {
+                for (i = 0; i < dest->caps.wVoices; i++)
+                    if (voice[i].status == sVS_PLAYING && voice[i].channel == chn)
+                        voice[i].status = sVS_SUSTAINED;
+            }
+            else
+            {
+                for (i = 0; i < dest->caps.wVoices; i++)
+                {
+                    if (voice[i].status == sVS_SUSTAINED && voice[i].channel == chn)
+                    {
+                        voice[i].status = sVS_UNUSED;
+                        SEQ_STOP_NOTE(dev_id, i, voice[i].note, 64);
+                    }
+                }
+            }
+            break;
+        case CTL_NONREG_PARM_NUM_LSB: channel[chn].nrgPmtLSB = d2; break;
+        case CTL_NONREG_PARM_NUM_MSB: channel[chn].nrgPmtMSB = d2; break;
+        case CTL_REGIST_PARM_NUM_LSB: channel[chn].regPmtLSB = d2; break;
+        case CTL_REGIST_PARM_NUM_MSB: channel[chn].regPmtMSB = d2; break;
+        case CTL_DATA_ENTRY:
+            switch ((channel[chn].regPmtMSB << 8) | channel[chn].regPmtLSB)
+            {
+            case 0x0000:
+                if (channel[chn].benderRange != d2)
+                {
+                    channel[chn].benderRange = d2;
+                    for (i = 0; i < dest->caps.wVoices; i++)
+                        if (voice[i].channel == chn)
+                            SEQ_BENDER_RANGE(dev_id, i, channel[chn].benderRange);
+                }
+                break;
+
+            case 0x7F7F:
+                channel[chn].benderRange = 2;
+                for (i = 0; i < dest->caps.wVoices; i++)
+                    if (voice[i].channel == chn)
+                        SEQ_BENDER_RANGE(dev_id, i, channel[chn].benderRange);
+                break;
+            default:
+                TRACE("Data entry: regPmt=0x%02x%02x, nrgPmt=0x%02x%02x with %x\n",
+                      channel[chn].regPmtMSB, channel[chn].regPmtLSB,
+                      channel[chn].nrgPmtMSB, channel[chn].nrgPmtLSB, d2);
+                break;
+            }
+            break;
+
+        case 0x78: /* all sounds off */
+            /* FIXME: I don't know if I have to take care of the channel for this control? */
+            for (i = 0; i < dest->caps.wVoices; i++)
+            {
+                if (voice[i].status != sVS_UNUSED && voice[i].channel == chn)
+                {
+                    voice[i].status = sVS_UNUSED;
+                    SEQ_STOP_NOTE(dev_id, i, voice[i].note, 64);
+                }
+            }
+            break;
+        case 0x7B: /* all notes off */
+            /* FIXME: I don't know if I have to take care of the channel for this control? */
+            for (i = 0; i < dest->caps.wVoices; i++)
+            {
+                if (voice[i].status == sVS_PLAYING && voice[i].channel == chn)
+                {
+                    voice[i].status = sVS_UNUSED;
+                    SEQ_STOP_NOTE(dev_id, i, voice[i].note, 64);
+                }
+            }
+            break;
+        default:
+            TRACE("Dropping MIDI control event 0x%02x(%02x) on channel %d\n", d1, d2, chn);
+            break;
+        }
+        break;
+    case MIDI_PGM_CHANGE:
+        channel[chn].program = d1;
+        break;
+    case MIDI_CHN_PRESSURE:
+        for (i = 0; i < dest->caps.wVoices; i++)
+            if (voice[i].status != sVS_UNUSED && voice[i].channel == chn)
+                SEQ_KEY_PRESSURE(dev_id, i, voice[i].note, d1);
+
+        break;
+    case MIDI_PITCH_BEND:
+        channel[chn].bender = (d2 << 7) + d1;
+        for (i = 0; i < dest->caps.wVoices; i++)
+            if (voice[i].channel == chn)
+                SEQ_BENDER(dev_id, i, channel[chn].bender);
+        break;
+    case MIDI_SYSTEM_PREFIX:
+        switch (evt & 0x0F)
+        {
+        case 0x0F: /* Reset */
+            OSS_CALL(midi_out_fm_reset, (void *)(UINT_PTR)dev_id);
+            break;
+        default:
+            WARN("Unsupported (yet) system event %02x\n", evt & 0x0F);
+        }
+        break;
+    default:
+        WARN("Internal error, shouldn't happen (event=%08x)\n", evt & 0xF0);
+        return MMSYSERR_NOTENABLED;
+    }
+
+    SEQ_DUMPBUF();
+    return MMSYSERR_NOERROR;
+}
+
+static UINT midi_out_port_data(WORD dev_id, UINT data)
+{
+    WORD evt = LOBYTE(LOWORD(data));
+    WORD d1  = HIBYTE(LOWORD(data));
+    WORD d2  = LOBYTE(HIWORD(data));
+    int dev = dev_id - MODM_NumFMSynthDevs;
+
+    if (dev < 0)
+    {
+        WARN("Internal error on devID (%u) !\n", dev_id);
+        return MIDIERR_NODEVICE;
+    }
+
+    switch (evt & 0xF0)
+    {
+    case MIDI_NOTEOFF:
+    case MIDI_NOTEON:
+    case MIDI_KEY_PRESSURE:
+    case MIDI_CTL_CHANGE:
+    case MIDI_PITCH_BEND:
+        SEQ_MIDIOUT(dev, evt);
+        SEQ_MIDIOUT(dev, d1);
+        SEQ_MIDIOUT(dev, d2);
+        break;
+    case MIDI_PGM_CHANGE:
+    case MIDI_CHN_PRESSURE:
+        SEQ_MIDIOUT(dev, evt);
+        SEQ_MIDIOUT(dev, d1);
+        break;
+    case MIDI_SYSTEM_PREFIX:
+        switch (evt & 0x0F)
+        {
+        case 0x00: /* System Exclusive, don't do it on MODM_DATA, should require MODM_LONGDATA */
+        case 0x04: /* Undefined. */
+        case 0x05: /* Undefined. */
+        case 0x07: /* End of Exclusive. */
+        case 0x09: /* Undefined. */
+        case 0x0D: /* Undefined. */
+            break;
+        case 0x06: /* Tune Request */
+        case 0x08: /* Timing Clock. */
+        case 0x0A: /* Start. */
+        case 0x0B: /* Continue */
+        case 0x0C: /* Stop */
+        case 0x0E: /* Active Sensing. */
+            SEQ_MIDIOUT(dev, evt);
+            break;
+        case 0x0F: /* Reset */
+            SEQ_MIDIOUT(dev, MIDI_SYSTEM_PREFIX);
+            SEQ_MIDIOUT(dev, 0x7e);
+            SEQ_MIDIOUT(dev, 0x7f);
+            SEQ_MIDIOUT(dev, 0x09);
+            SEQ_MIDIOUT(dev, 0x01);
+            SEQ_MIDIOUT(dev, 0xf7);
+            break;
+        case 0x01: /* MTC Quarter frame */
+        case 0x03: /* Song Select. */
+            SEQ_MIDIOUT(dev, evt);
+            SEQ_MIDIOUT(dev, d1);
+        case 0x02: /* Song Position Pointer. */
+            SEQ_MIDIOUT(dev, evt);
+            SEQ_MIDIOUT(dev, d1);
+            SEQ_MIDIOUT(dev, d2);
+        }
+        break;
+    }
+
+    SEQ_DUMPBUF();
+    return MMSYSERR_NOERROR;
+}
+
 /**************************************************************************
  * 			modData					[internal]
  */
 static DWORD modData(WORD wDevID, DWORD dwParam)
 {
-    WORD	evt = LOBYTE(LOWORD(dwParam));
-    WORD	d1  = HIBYTE(LOWORD(dwParam));
-    WORD	d2  = LOBYTE(HIWORD(dwParam));
-
     TRACE("(%04X, %08X);\n", wDevID, dwParam);
 
     if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;
@@ -767,275 +1026,14 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
     }
     switch (MidiOutDev[wDevID].caps.wTechnology) {
     case MOD_FMSYNTH:
-	/* FIXME:
-	 *	- chorus depth controller is not used
-	 */
-	{
-            sFMextra*   extra   = MidiOutDev[wDevID].lpExtra;
-	    sVoice* 	voice   = extra->voice;
-	    sChannel*	channel = extra->channel;
-	    int		chn = (evt & 0x0F);
-	    int		i, nv;
-
-	    switch (evt & 0xF0) {
-	    case MIDI_NOTEOFF:
-		for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-				/* don't stop sustained notes */
-		    if (voice[i].status == sVS_PLAYING && voice[i].channel == chn && voice[i].note == d1) {
-			voice[i].status = sVS_UNUSED;
-			SEQ_STOP_NOTE(wDevID, i, d1, d2);
-		    }
-		}
-		break;
-	    case MIDI_NOTEON:
-		if (d2 == 0) { /* note off if velocity == 0 */
-		    for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-			/* don't stop sustained notes */
-			if (voice[i].status == sVS_PLAYING && voice[i].channel == chn && voice[i].note == d1) {
-			    voice[i].status = sVS_UNUSED;
-			    SEQ_STOP_NOTE(wDevID, i, d1, 64);
-			}
-		    }
-		    break;
-		}
-		/* finding out in this order :
-		 *	- an empty voice
-		 *	- if replaying the same note on the same channel
-		 *	- the older voice (LRU)
-		 */
-		for (i = nv = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-		    if (voice[i].status == sVS_UNUSED ||
-			(voice[i].note == d1 && voice[i].channel == chn)) {
-			nv = i;
-			break;
-		    }
-		    if (voice[i].cntMark < voice[0].cntMark) {
-			nv = i;
-		    }
-		}
-		TRACE(
-		      "playing on voice=%d, pgm=%d, pan=0x%02X, vol=0x%02X, "
-		      "bender=0x%02X, note=0x%02X, vel=0x%02X\n",
-		      nv, channel[chn].program,
-		      channel[chn].balance,
-		      channel[chn].volume,
-		      channel[chn].bender, d1, d2);
-
-		SEQ_SET_PATCH(wDevID, nv, IS_DRUM_CHANNEL(extra, chn) ?
-			      (128 + d1) : channel[chn].program);
-		SEQ_BENDER_RANGE(wDevID, nv, channel[chn].benderRange * 100);
-		SEQ_BENDER(wDevID, nv, channel[chn].bender);
-		SEQ_CONTROL(wDevID, nv, CTL_PAN, channel[chn].balance);
-		SEQ_CONTROL(wDevID, nv, CTL_EXPRESSION, channel[chn].expression);
-#if 0
-		/* FIXME: does not really seem to work on my SB card and
-		 * screws everything up... so lay it down
-		 */
-		SEQ_CONTROL(wDevID, nv, CTL_MAIN_VOLUME, channel[chn].volume);
-#endif
-		SEQ_START_NOTE(wDevID, nv, d1, d2);
-		voice[nv].status = channel[chn].sustain ? sVS_SUSTAINED : sVS_PLAYING;
-		voice[nv].note = d1;
-		voice[nv].channel = chn;
-		voice[nv].cntMark = extra->counter++;
-		break;
-	    case MIDI_KEY_PRESSURE:
-		for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-		    if (voice[i].status != sVS_UNUSED && voice[i].channel == chn && voice[i].note == d1) {
-			SEQ_KEY_PRESSURE(wDevID, i, d1, d2);
-		    }
-		}
-		break;
-	    case MIDI_CTL_CHANGE:
-		switch (d1) {
-		case CTL_BANK_SELECT:	channel[chn].bank = d2;		break;
-		case CTL_MAIN_VOLUME:	channel[chn].volume = d2;	break;
-		case CTL_PAN:		channel[chn].balance = d2;	break;
-		case CTL_EXPRESSION:	channel[chn].expression = d2;	break;
-		case CTL_SUSTAIN:	channel[chn].sustain = d2;
-		    if (d2) {
-			for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-			    if (voice[i].status == sVS_PLAYING && voice[i].channel == chn) {
-				voice[i].status = sVS_SUSTAINED;
-			    }
-			}
-		    } else {
-			for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-			    if (voice[i].status == sVS_SUSTAINED && voice[i].channel == chn) {
-				voice[i].status = sVS_UNUSED;
-				SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);
-			    }
-			}
-		    }
-		    break;
-		case CTL_NONREG_PARM_NUM_LSB:	channel[chn].nrgPmtLSB = d2;	break;
-		case CTL_NONREG_PARM_NUM_MSB:	channel[chn].nrgPmtMSB = d2;	break;
-		case CTL_REGIST_PARM_NUM_LSB:	channel[chn].regPmtLSB = d2;	break;
-		case CTL_REGIST_PARM_NUM_MSB:	channel[chn].regPmtMSB = d2;	break;
-		case CTL_DATA_ENTRY:
-		    switch ((channel[chn].regPmtMSB << 8) | channel[chn].regPmtLSB) {
-		    case 0x0000:
-			if (channel[chn].benderRange != d2) {
-			    channel[chn].benderRange = d2;
-			    for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-				if (voice[i].channel == chn) {
-				    SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);
-				}
-			    }
-			}
-			break;
-
-		    case 0x7F7F:
-			channel[chn].benderRange = 2;
-			for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-			    if (voice[i].channel == chn) {
-				SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);
-			    }
-			}
-			break;
-		    default:
-			TRACE("Data entry: regPmt=0x%02x%02x, nrgPmt=0x%02x%02x with %x\n",
-			      channel[chn].regPmtMSB, channel[chn].regPmtLSB,
-			      channel[chn].nrgPmtMSB, channel[chn].nrgPmtLSB,
-			      d2);
-			break;
-		    }
-		    break;
-
-		case 0x78: /* all sounds off */
-		    /* FIXME: I don't know if I have to take care of the channel
-		     * for this control ?
-		     */
-		    for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-			if (voice[i].status != sVS_UNUSED && voice[i].channel == chn) {
-			    voice[i].status = sVS_UNUSED;
-			    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);
-			}
-		    }
-		    break;
-		case 0x7B: /* all notes off */
-		    /* FIXME: I don't know if I have to take care of the channel
-		     * for this control ?
-		     */
-		    for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-			if (voice[i].status == sVS_PLAYING && voice[i].channel == chn) {
-			    voice[i].status = sVS_UNUSED;
-			    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);
-			}
-		    }
-		    break;
-		default:
-		    TRACE("Dropping MIDI control event 0x%02x(%02x) on channel %d\n",
-			  d1, d2, chn);
-		    break;
-		}
-		break;
-	    case MIDI_PGM_CHANGE:
-		channel[chn].program = d1;
-		break;
-	    case MIDI_CHN_PRESSURE:
-		for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-		    if (voice[i].status != sVS_UNUSED && voice[i].channel == chn) {
-			SEQ_KEY_PRESSURE(wDevID, i, voice[i].note, d1);
-		    }
-		}
-		break;
-	    case MIDI_PITCH_BEND:
-		channel[chn].bender = (d2 << 7) + d1;
-		for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {
-		    if (voice[i].channel == chn) {
-			SEQ_BENDER(wDevID, i, channel[chn].bender);
-		    }
-		}
-		break;
-	    case MIDI_SYSTEM_PREFIX:
-		switch (evt & 0x0F) {
-		case 0x0F: 	/* Reset */
-		    OSS_CALL(midi_out_fm_reset, (void *)(UINT_PTR)wDevID);
-		    break;
-		default:
-		    WARN("Unsupported (yet) system event %02x\n", evt & 0x0F);
-		}
-		break;
-	    default:
-		WARN("Internal error, shouldn't happen (event=%08x)\n", evt & 0xF0);
-		return MMSYSERR_NOTENABLED;
-	    }
-	}
-	break;
+        return midi_out_fm_data(wDevID, dwParam);
     case MOD_MIDIPORT:
-	{
-	    int	dev = wDevID - MODM_NumFMSynthDevs;
-	    if (dev < 0) {
-		WARN("Internal error on devID (%u) !\n", wDevID);
-		return MIDIERR_NODEVICE;
-	    }
-
-	    switch (evt & 0xF0) {
-	    case MIDI_NOTEOFF:
-	    case MIDI_NOTEON:
-	    case MIDI_KEY_PRESSURE:
-	    case MIDI_CTL_CHANGE:
-	    case MIDI_PITCH_BEND:
-		SEQ_MIDIOUT(dev, evt);
-		SEQ_MIDIOUT(dev, d1);
-		SEQ_MIDIOUT(dev, d2);
-		break;
-	    case MIDI_PGM_CHANGE:
-	    case MIDI_CHN_PRESSURE:
-		SEQ_MIDIOUT(dev, evt);
-		SEQ_MIDIOUT(dev, d1);
-		break;
-	    case MIDI_SYSTEM_PREFIX:
-		switch (evt & 0x0F) {
-		case 0x00:	/* System Exclusive, don't do it on modData,
-				 * should require modLongData*/
-		case 0x04:	/* Undefined. */
-		case 0x05:	/* Undefined. */
-		case 0x07:	/* End of Exclusive. */
-		case 0x09:	/* Undefined. */
-		case 0x0D:	/* Undefined. */
-		    break;
-		case 0x06:	/* Tune Request */
-		case 0x08:	/* Timing Clock. */
-		case 0x0A:	/* Start. */
-		case 0x0B:	/* Continue */
-		case 0x0C:	/* Stop */
-		case 0x0E: 	/* Active Sensing. */
-		    SEQ_MIDIOUT(dev, evt);
-		    break;
-		case 0x0F: 	/* Reset */
-				/* SEQ_MIDIOUT(dev, evt);
-				   this other way may be better */
-		    SEQ_MIDIOUT(dev, MIDI_SYSTEM_PREFIX);
-		    SEQ_MIDIOUT(dev, 0x7e);
-		    SEQ_MIDIOUT(dev, 0x7f);
-		    SEQ_MIDIOUT(dev, 0x09);
-		    SEQ_MIDIOUT(dev, 0x01);
-		    SEQ_MIDIOUT(dev, 0xf7);
-		    break;
-		case 0x01:	/* MTC Quarter frame */
-		case 0x03:	/* Song Select. */
-		    SEQ_MIDIOUT(dev, evt);
-		    SEQ_MIDIOUT(dev, d1);
-		case 0x02:	/* Song Position Pointer. */
-		    SEQ_MIDIOUT(dev, evt);
-		    SEQ_MIDIOUT(dev, d1);
-		    SEQ_MIDIOUT(dev, d2);
-		}
-		break;
-	    }
-	}
-	break;
-    default:
-	WARN("Technology not supported (yet) %d !\n",
-	     MidiOutDev[wDevID].caps.wTechnology);
-	return MMSYSERR_NOTENABLED;
+        return midi_out_port_data(wDevID, dwParam);
     }
 
-    SEQ_DUMPBUF();
-
-    return MMSYSERR_NOERROR;
+    WARN("Technology not supported (yet) %d !\n",
+         MidiOutDev[wDevID].caps.wTechnology);
+    return MMSYSERR_NOTENABLED;
 }
 
 /**************************************************************************
-- 
2.25.1




More information about the wine-devel mailing list