mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 12:30:58 +00:00
wineoss: Add a temporary midi_out_fm_reset syscall.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bbe19f20a9
commit
5ebc7d78aa
|
@ -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);
|
||||
|
|
|
@ -1409,4 +1409,5 @@ unixlib_entry_t __wine_unix_call_funcs[] =
|
|||
|
||||
midi_seq_open,
|
||||
midi_out_fm_load,
|
||||
midi_out_fm_reset,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue