From: Huw Davies huw@codeweavers.com
Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- 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;