Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f086286d
Commit
f086286d
authored
Nov 20, 2002
by
Eric Pouech
Committed by
Alexandre Julliard
Nov 20, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better support for multiple midi devices on the OSS interface.
parent
2b855ded
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
166 additions
and
157 deletions
+166
-157
midi.c
dlls/winmm/wineoss/midi.c
+166
-157
No files found.
dlls/winmm/wineoss/midi.c
View file @
f086286d
...
...
@@ -29,6 +29,7 @@
#include "config.h"
#include <string.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
...
...
@@ -52,7 +53,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(midi);
#define MIDI_SEQ "/dev/sequencer"
typedef
struct
{
int
state
;
int
state
;
/* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
DWORD
bufsize
;
MIDIOPENDESC
midiDesc
;
WORD
wFlags
;
...
...
@@ -62,54 +63,37 @@ typedef struct {
unsigned
char
incPrev
;
char
incLen
;
DWORD
startTime
;
MIDIINCAPSA
caps
;
}
WINE_MIDIIN
;
typedef
struct
{
int
state
;
BOOL
bEnabled
;
DWORD
bufsize
;
MIDIOPENDESC
midiDesc
;
WORD
wFlags
;
LPMIDIHDR
lpQueueHdr
;
DWORD
dwTotalPlayed
;
void
*
lpExtra
;
/* according to port type (MIDI, FM...), extra data when needed */
MIDIOUTCAPSA
caps
;
}
WINE_MIDIOUT
;
static
WINE_MIDIIN
MidiInDev
[
MAX_MIDIINDRV
];
static
WINE_MIDIOUT
MidiOutDev
[
MAX_MIDIOUTDRV
];
/* this is the total number of MIDI out devices found */
static
int
MODM_NUMDEVS
=
0
;
/* this is the number of FM synthetizers (index from 0 to
NUMFMSYNTHDEVS - 1) */
static
int
MODM_NUMFMSYNTHDEVS
=
0
;
/* this is the number of Midi ports (index from NUMFMSYNTHDEVS to
NUMFMSYNTHDEVS + NUMMIDIDEVS - 1) */
static
int
MODM_NUMMIDIDEVS
=
0
;
/* this is the total number of MIDI out devices found (synth and port) */
static
int
MODM_NumDevs
=
0
;
/* this is the number of FM synthetizers (index from 0 to NUMFMSYNTHDEVS - 1) */
static
int
MODM_NumFMSynthDevs
=
0
;
/* the Midi ports have index from NUMFMSYNTHDEVS to NumDevs - 1 */
/* this is the total number of MIDI out devices found */
static
int
MIDM_N
UMDEVS
=
0
;
static
int
MIDM_N
umDevs
=
0
;
static
int
midiSeqFD
=
-
1
;
static
int
numOpenMidiSeq
=
0
;
static
UINT
midiInTimerID
=
0
;
static
int
numStartedMidiIn
=
0
;
/* this structure holds pointers with information for each MIDI
* out device found.
*/
static
LPMIDIOUTCAPSA
midiOutDevices
[
MAX_MIDIOUTDRV
];
/* this structure holds pointers with information for each MIDI
* in device found.
*/
static
LPMIDIINCAPSA
midiInDevices
[
MAX_MIDIINDRV
];
/*
* FIXME : all tests on device ID for midXXX and modYYY are made against
* MAX_MIDIxxDRV (when they are made) but should be done against the actual
* number of midi devices found...
*/
/*======================================================================*
* Low level MIDI implementation *
*======================================================================*/
...
...
@@ -186,51 +170,51 @@ BOOL OSS_MidiInit(void)
}
for
(
i
=
0
;
i
<
numsynthdevs
;
i
++
)
{
LPMIDIOUTCAPSA
tmplpCaps
;
sinfo
.
device
=
i
;
status
=
ioctl
(
midiSeqFD
,
SNDCTL_SYNTH_INFO
,
&
sinfo
);
if
(
status
==
-
1
)
{
ERR
(
"ioctl for synth info failed.
\n
"
);
midiCloseSeq
();
return
TRUE
;
}
tmplpCaps
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
MIDIOUTCAPSA
));
if
(
!
tmplpCaps
)
break
;
/* We also have the information sinfo.synth_subtype, not used here
*/
/* Manufac ID. We do not have access to this with soundcard.h
* Does not seem to be a problem, because in mmsystem.h only
* Microsoft's ID is listed.
*/
tmplpCaps
->
wMid
=
0x00FF
;
tmplpCaps
->
wPid
=
0x0001
;
/* FIXME Product ID */
MidiOutDev
[
i
].
caps
.
wMid
=
0x00FF
;
MidiOutDev
[
i
].
caps
.
wPid
=
0x0001
;
/* FIXME Product ID */
/* Product Version. We simply say "1" */
tmplpCaps
->
vDriverVersion
=
0x001
;
strcpy
(
tmplpCaps
->
szPname
,
sinfo
.
name
);
tmplpCaps
->
wTechnology
=
MIDI_UnixToWindowsDeviceType
(
sinfo
.
synth_type
);
tmplpCaps
->
wVoices
=
sinfo
.
nr_voices
;
/* FIXME Is it possible to know the maximum
* number of simultaneous notes of a soundcard ?
* I believe we don't have this information, but
* it's probably equal or more than wVoices
*/
tmplpCaps
->
wNotes
=
sinfo
.
nr_voices
;
tmplpCaps
->
wChannelMask
=
0xFFFF
;
MidiOutDev
[
i
].
caps
.
vDriverVersion
=
0x001
;
MidiOutDev
[
i
].
caps
.
wChannelMask
=
0xFFFF
;
/* FIXME Do we have this information?
* Assuming the soundcards can handle
* MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
* not MIDICAPS_CACHE.
*/
tmplpCaps
->
dwSupport
=
MIDICAPS_VOLUME
|
MIDICAPS_LRVOLUME
;
MidiOutDev
[
i
].
caps
.
dwSupport
=
MIDICAPS_VOLUME
|
MIDICAPS_LRVOLUME
;
sinfo
.
device
=
i
;
status
=
ioctl
(
midiSeqFD
,
SNDCTL_SYNTH_INFO
,
&
sinfo
);
if
(
status
==
-
1
)
{
ERR
(
"ioctl for synth info failed on %d, disabling it.
\n
"
,
i
);
sprintf
(
MidiOutDev
[
i
].
caps
.
szPname
,
"Wine OSS Midi Out (#%d) - disabled"
,
i
);
MidiOutDev
[
i
].
caps
.
wTechnology
=
MOD_MIDIPORT
;
MidiOutDev
[
i
].
caps
.
wVoices
=
16
;
MidiOutDev
[
i
].
caps
.
wNotes
=
16
;
MidiOutDev
[
i
].
bEnabled
=
FALSE
;
}
else
{
strcpy
(
MidiOutDev
[
i
].
caps
.
szPname
,
sinfo
.
name
);
midiOutDevices
[
i
]
=
tmplpCaps
;
MidiOutDev
[
i
].
caps
.
wTechnology
=
MIDI_UnixToWindowsDeviceType
(
sinfo
.
synth_type
);
MidiOutDev
[
i
].
caps
.
wVoices
=
sinfo
.
nr_voices
;
/* FIXME Is it possible to know the maximum
* number of simultaneous notes of a soundcard ?
* I believe we don't have this information, but
* it's probably equal or more than wVoices
*/
MidiOutDev
[
i
].
caps
.
wNotes
=
sinfo
.
nr_voices
;
MidiOutDev
[
i
].
bEnabled
=
TRUE
;
}
/* We also have the information sinfo.synth_subtype, not used here
*/
if
(
sinfo
.
capabilities
&
SYNTH_CAP_INPUT
)
{
FIXME
(
"Synthesizer support MIDI in. Not supported yet (please report)
\n
"
);
...
...
@@ -238,8 +222,9 @@ BOOL OSS_MidiInit(void)
TRACE
(
"SynthOut[%d]
\t
name='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%ld
\n
"
"
\t
OSS info: synth subtype=%d capa=%lx
\n
"
,
i
,
tmplpCaps
->
szPname
,
tmplpCaps
->
wTechnology
,
tmplpCaps
->
wVoices
,
tmplpCaps
->
wNotes
,
tmplpCaps
->
wChannelMask
,
tmplpCaps
->
dwSupport
,
i
,
MidiOutDev
[
i
].
caps
.
szPname
,
MidiOutDev
[
i
].
caps
.
wTechnology
,
MidiOutDev
[
i
].
caps
.
wVoices
,
MidiOutDev
[
i
].
caps
.
wNotes
,
MidiOutDev
[
i
].
caps
.
wChannelMask
,
MidiOutDev
[
i
].
caps
.
dwSupport
,
sinfo
.
synth_subtype
,
(
long
)
sinfo
.
capabilities
);
}
...
...
@@ -247,8 +232,8 @@ BOOL OSS_MidiInit(void)
status
=
ioctl
(
midiSeqFD
,
SNDCTL_SEQ_NRMIDIS
,
&
nummididevs
);
if
(
status
==
-
1
)
{
ERR
(
"ioctl on nr midi failed.
\n
"
);
midiCloseSeq
()
;
return
TRUE
;
nummididevs
=
0
;
goto
wrapup
;
}
/* FIXME: the two restrictions below could be loosen in some cases */
...
...
@@ -265,20 +250,10 @@ BOOL OSS_MidiInit(void)
}
for
(
i
=
0
;
i
<
nummididevs
;
i
++
)
{
LPMIDIOUTCAPSA
tmplpOutCaps
;
LPMIDIINCAPSA
tmplpInCaps
;
minfo
.
device
=
i
;
status
=
ioctl
(
midiSeqFD
,
SNDCTL_MIDI_INFO
,
&
minfo
);
if
(
status
==
-
1
)
{
ERR
(
"ioctl on midi info for device %d failed.
\n
"
,
i
);
midiCloseSeq
();
return
TRUE
;
}
if
(
status
==
-
1
)
WARN
(
"ioctl on midi info for device %d failed.
\n
"
,
i
);
tmplpOutCaps
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
MIDIOUTCAPSA
));
if
(
!
tmplpOutCaps
)
break
;
/* This whole part is somewhat obscure to me. I'll keep trying to dig
info about it. If you happen to know, please tell us. The very
descritive minfo.dev_type was not used here.
...
...
@@ -286,27 +261,27 @@ BOOL OSS_MidiInit(void)
/* Manufac ID. We do not have access to this with soundcard.h
Does not seem to be a problem, because in mmsystem.h only
Microsoft's ID is listed */
tmplpOutCaps
->
wMid
=
0x00FF
;
tmplpOutCaps
->
wPid
=
0x0001
;
/* FIXME Product ID */
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wMid
=
0x00FF
;
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wPid
=
0x0001
;
/* FIXME Product ID */
/* Product Version. We simply say "1" */
tmplpOutCaps
->
vDriverVersion
=
0x001
;
strcpy
(
tmplpOutCaps
->
szPname
,
minfo
.
name
);
tmplpOutCaps
->
wTechnology
=
MOD_MIDIPORT
;
/* FIXME Is this right? */
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
vDriverVersion
=
0x001
;
if
(
status
==
-
1
)
{
sprintf
(
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
szPname
,
"Wine OSS Midi Out (#%d) - disabled"
,
numsynthdevs
+
i
);
MidiOutDev
[
numsynthdevs
+
i
].
bEnabled
=
FALSE
;
}
else
{
strcpy
(
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
szPname
,
minfo
.
name
);
MidiOutDev
[
numsynthdevs
+
i
].
bEnabled
=
TRUE
;
}
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wTechnology
=
MOD_MIDIPORT
;
/* FIXME Is this right? */
/* Does it make any difference? */
tmplpOutCaps
->
wVoices
=
16
;
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wVoices
=
16
;
/* Does it make any difference? */
tmplpOutCaps
->
wNotes
=
16
;
tmplpOutCaps
->
wChannelMask
=
0xFFFF
;
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wNotes
=
16
;
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wChannelMask
=
0xFFFF
;
/* FIXME Does it make any difference? */
tmplpOutCaps
->
dwSupport
=
MIDICAPS_VOLUME
|
MIDICAPS_LRVOLUME
;
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
dwSupport
=
MIDICAPS_VOLUME
|
MIDICAPS_LRVOLUME
;
midiOutDevices
[
numsynthdevs
+
i
]
=
tmplpOutCaps
;
tmplpInCaps
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
MIDIINCAPSA
));
if
(
!
tmplpInCaps
)
break
;
/* This whole part is somewhat obscure to me. I'll keep trying to dig
info about it. If you happen to know, please tell us. The very
descritive minfo.dev_type was not used here.
...
...
@@ -314,33 +289,36 @@ BOOL OSS_MidiInit(void)
/* Manufac ID. We do not have access to this with soundcard.h
Does not seem to be a problem, because in mmsystem.h only
Microsoft's ID is listed */
tmplpInCaps
->
wMid
=
0x00FF
;
tmplpInCaps
->
wPid
=
0x0001
;
/* FIXME Product ID */
MidiInDev
[
i
].
caps
.
wMid
=
0x00FF
;
MidiInDev
[
i
].
caps
.
wPid
=
0x0001
;
/* FIXME Product ID */
/* Product Version. We simply say "1" */
tmplpInCaps
->
vDriverVersion
=
0x001
;
strcpy
(
tmplpInCaps
->
szPname
,
minfo
.
name
);
MidiInDev
[
i
].
caps
.
vDriverVersion
=
0x001
;
if
(
status
==
-
1
)
{
sprintf
(
MidiInDev
[
i
].
caps
.
szPname
,
"Wine OSS Midi In (#%d) - disabled"
,
numsynthdevs
+
i
);
MidiInDev
[
i
].
state
=
-
1
;
}
else
{
strcpy
(
MidiInDev
[
i
].
caps
.
szPname
,
minfo
.
name
);
MidiInDev
[
i
].
state
=
0
;
}
/* FIXME : could we get better information than that ? */
tmplpInCaps
->
dwSupport
=
MIDICAPS_VOLUME
|
MIDICAPS_LRVOLUME
;
midiInDevices
[
i
]
=
tmplpInCaps
;
MidiInDev
[
i
].
caps
.
dwSupport
=
MIDICAPS_VOLUME
|
MIDICAPS_LRVOLUME
;
TRACE
(
"MidiOut[%d]
\t
name='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%ld
\n
"
"MidiIn [%d]
\t
name='%s' support=%ld
\n
"
"
\t
OSS info: midi dev-type=%d, capa=%lx
\n
"
,
i
,
tmplpOutCaps
->
szPname
,
tmplpOutCaps
->
wTechnology
,
tmplpOutCaps
->
wVoices
,
tmplpOutCaps
->
wNotes
,
tmplpOutCaps
->
wChannelMask
,
tmplpOutCaps
->
dwSupport
,
i
,
tmplpInCaps
->
szPname
,
tmplpInCaps
->
dwSupport
,
i
,
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
szPname
,
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wTechnology
,
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wVoices
,
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wNotes
,
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
wChannelMask
,
MidiOutDev
[
numsynthdevs
+
i
].
caps
.
dwSupport
,
i
,
MidiInDev
[
i
].
caps
.
szPname
,
MidiInDev
[
i
].
caps
.
dwSupport
,
minfo
.
dev_type
,
(
long
)
minfo
.
capabilities
);
}
wrapup:
/* windows does not seem to differentiate Synth from MIDI devices */
MODM_NUMFMSYNTHDEVS
=
numsynthdevs
;
MODM_NUMMIDIDEVS
=
nummididevs
;
MODM_NUMDEVS
=
numsynthdevs
+
nummididevs
;
MODM_NumFMSynthDevs
=
numsynthdevs
;
MODM_NumDevs
=
numsynthdevs
+
nummididevs
;
MIDM_N
UMDEVS
=
nummididevs
;
MIDM_N
umDevs
=
nummididevs
;
/* close file and exit */
midiCloseSeq
();
...
...
@@ -366,8 +344,8 @@ static DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg,
case
MOM_OPEN
:
case
MOM_CLOSE
:
case
MOM_DONE
:
if
(
wDevID
>
M
AX_MIDIOUTDRV
)
return
M
CIERR_INTERNAL
;
if
(
wDevID
>
M
ODM_NumDevs
)
return
M
MSYSERR_BADDEVICEID
;
dwCallBack
=
MidiOutDev
[
wDevID
].
midiDesc
.
dwCallback
;
uFlags
=
MidiOutDev
[
wDevID
].
wFlags
;
...
...
@@ -379,8 +357,8 @@ static DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg,
case
MIM_CLOSE
:
case
MIM_DATA
:
case
MIM_ERROR
:
if
(
wDevID
>
M
AX_MIDIINDRV
)
return
M
CIERR_INTERNAL
;
if
(
wDevID
>
M
IDM_NumDevs
)
return
M
MSYSERR_BADDEVICEID
;
dwCallBack
=
MidiInDev
[
wDevID
].
midiDesc
.
dwCallback
;
uFlags
=
MidiInDev
[
wDevID
].
wFlags
;
...
...
@@ -389,11 +367,11 @@ static DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg,
break
;
default:
WARN
(
"Unsupported MSW-MIDI message %u
\n
"
,
wMsg
);
return
M
CIERR_INTERNAL
;
return
M
MSYSERR_ERROR
;
}
return
DriverCallback
(
dwCallBack
,
uFlags
,
hDev
,
wMsg
,
dwInstance
,
dwParam1
,
dwParam2
)
?
0
:
M
CIERR_INTERNAL
;
0
:
M
MSYSERR_ERROR
;
}
static
int
midi_warn
=
1
;
...
...
@@ -476,12 +454,12 @@ static void midReceiveChar(WORD wDevID, unsigned char value, DWORD dwTime)
TRACE
(
"Adding %02xh to %d[%d]
\n
"
,
value
,
wDevID
,
MidiInDev
[
wDevID
].
incLen
);
if
(
wDevID
>=
M
AX_MIDIINDRV
)
{
if
(
wDevID
>=
M
IDM_NumDevs
)
{
WARN
(
"bad devID
\n
"
);
return
;
}
if
(
MidiInDev
[
wDevID
].
state
=
=
0
)
{
TRACE
(
"input not started, thrown away
\n
"
);
if
(
MidiInDev
[
wDevID
].
state
<
=
0
)
{
TRACE
(
"
disabled or
input not started, thrown away
\n
"
);
return
;
}
...
...
@@ -627,10 +605,10 @@ static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPSA lpCaps, DWORD dwSize)
{
TRACE
(
"(%04X, %p, %08lX);
\n
"
,
wDevID
,
lpCaps
,
dwSize
);
if
(
wDevID
>=
MIDM_N
UMDEVS
)
return
MMSYSERR_BADDEVICEID
;
if
(
wDevID
>=
MIDM_N
umDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
lpCaps
==
NULL
)
return
MMSYSERR_INVALPARAM
;
memcpy
(
lpCaps
,
midiInDevices
[
wDevID
]
,
min
(
dwSize
,
sizeof
(
*
lpCaps
)));
memcpy
(
lpCaps
,
&
MidiInDev
[
wDevID
].
caps
,
min
(
dwSize
,
sizeof
(
*
lpCaps
)));
return
MMSYSERR_NOERROR
;
}
...
...
@@ -650,10 +628,14 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
/* FIXME :
* how to check that content of lpDesc is correct ?
*/
if
(
wDevID
>=
M
AX_MIDIINDRV
)
{
if
(
wDevID
>=
M
IDM_NumDevs
)
{
WARN
(
"wDevID too large (%u) !
\n
"
,
wDevID
);
return
MMSYSERR_BADDEVICEID
;
}
if
(
MidiInDev
[
wDevID
].
state
==
-
1
)
{
WARN
(
"device disabled
\n
"
);
return
MIDIERR_NODEVICE
;
}
if
(
MidiInDev
[
wDevID
].
midiDesc
.
hMidi
!=
0
)
{
WARN
(
"device already open !
\n
"
);
return
MMSYSERR_ALLOCATED
;
...
...
@@ -708,7 +690,7 @@ static DWORD midClose(WORD wDevID)
TRACE
(
"(%04X);
\n
"
,
wDevID
);
if
(
wDevID
>=
M
AX_MIDIINDRV
)
{
if
(
wDevID
>=
M
IDM_NumDevs
)
{
WARN
(
"wDevID too big (%u) !
\n
"
,
wDevID
);
return
MMSYSERR_BADDEVICEID
;
}
...
...
@@ -749,6 +731,9 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
TRACE
(
"(%04X, %p, %08lX);
\n
"
,
wDevID
,
lpMidiHdr
,
dwSize
);
if
(
wDevID
>=
MIDM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
MidiInDev
[
wDevID
].
state
==
-
1
)
return
MIDIERR_NODEVICE
;
if
(
lpMidiHdr
==
NULL
)
return
MMSYSERR_INVALPARAM
;
if
(
sizeof
(
MIDIHDR
)
>
dwSize
)
return
MMSYSERR_INVALPARAM
;
if
(
lpMidiHdr
->
dwBufferLength
==
0
)
return
MMSYSERR_INVALPARAM
;
...
...
@@ -794,6 +779,9 @@ static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
TRACE
(
"(%04X, %p, %08lX);
\n
"
,
wDevID
,
lpMidiHdr
,
dwSize
);
if
(
wDevID
>=
MIDM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
MidiInDev
[
wDevID
].
state
==
-
1
)
return
MIDIERR_NODEVICE
;
if
(
dwSize
<
sizeof
(
MIDIHDR
)
||
lpMidiHdr
==
0
||
lpMidiHdr
->
lpData
==
0
||
lpMidiHdr
->
dwBufferLength
>=
0x10000ul
)
return
MMSYSERR_INVALPARAM
;
...
...
@@ -815,6 +803,9 @@ static DWORD midReset(WORD wDevID)
TRACE
(
"(%04X);
\n
"
,
wDevID
);
if
(
wDevID
>=
MIDM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
MidiInDev
[
wDevID
].
state
==
-
1
)
return
MIDIERR_NODEVICE
;
while
(
MidiInDev
[
wDevID
].
lpQueueHdr
)
{
MidiInDev
[
wDevID
].
lpQueueHdr
->
dwFlags
&=
~
MHDR_INQUEUE
;
MidiInDev
[
wDevID
].
lpQueueHdr
->
dwFlags
|=
MHDR_DONE
;
...
...
@@ -837,7 +828,8 @@ static DWORD midStart(WORD wDevID)
{
TRACE
(
"(%04X);
\n
"
,
wDevID
);
/* FIXME : should test value of wDevID */
if
(
wDevID
>=
MIDM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
MidiInDev
[
wDevID
].
state
==
-
1
)
return
MIDIERR_NODEVICE
;
MidiInDev
[
wDevID
].
state
=
1
;
MidiInDev
[
wDevID
].
startTime
=
GetTickCount
();
...
...
@@ -851,7 +843,9 @@ static DWORD midStop(WORD wDevID)
{
TRACE
(
"(%04X);
\n
"
,
wDevID
);
/* FIXME : should test value of wDevID */
if
(
wDevID
>=
MIDM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
MidiInDev
[
wDevID
].
state
==
-
1
)
return
MIDIERR_NODEVICE
;
MidiInDev
[
wDevID
].
state
=
0
;
return
MMSYSERR_NOERROR
;
}
...
...
@@ -942,7 +936,7 @@ static void modFMReset(WORD wDevID)
sChannel
*
channel
=
extra
->
channel
;
int
i
;
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
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
);
}
...
...
@@ -977,10 +971,10 @@ static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPSA lpCaps, DWORD dwSize)
{
TRACE
(
"(%04X, %p, %08lX);
\n
"
,
wDevID
,
lpCaps
,
dwSize
);
if
(
wDevID
>=
MODM_N
UMDEVS
)
return
MMSYSERR_BADDEVICEID
;
if
(
wDevID
>=
MODM_N
umDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
lpCaps
==
NULL
)
return
MMSYSERR_INVALPARAM
;
memcpy
(
lpCaps
,
midiOutDevices
[
wDevID
]
,
min
(
dwSize
,
sizeof
(
*
lpCaps
)));
memcpy
(
lpCaps
,
&
MidiOutDev
[
wDevID
].
caps
,
min
(
dwSize
,
sizeof
(
*
lpCaps
)));
return
MMSYSERR_NOERROR
;
}
...
...
@@ -995,7 +989,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
WARN
(
"Invalid Parameter !
\n
"
);
return
MMSYSERR_INVALPARAM
;
}
if
(
wDevID
>=
M
AX_MIDIOUTDRV
)
{
if
(
wDevID
>=
M
ODM_NumDevs
)
{
TRACE
(
"MAX_MIDIOUTDRV reached !
\n
"
);
return
MMSYSERR_BADDEVICEID
;
}
...
...
@@ -1003,23 +997,29 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
WARN
(
"device already open !
\n
"
);
return
MMSYSERR_ALLOCATED
;
}
if
(
!
MidiOutDev
[
wDevID
].
bEnabled
)
{
WARN
(
"device disabled !
\n
"
);
return
MIDIERR_NODEVICE
;
}
if
((
dwFlags
&
~
CALLBACK_TYPEMASK
)
!=
0
)
{
WARN
(
"bad dwFlags
\n
"
);
return
MMSYSERR_INVALFLAG
;
}
if
(
midiOutDevices
[
wDevID
]
==
NULL
)
{
TRACE
(
"
un-allocat
ed wDevID
\n
"
);
return
MMSYSERR_
BADDEVICEI
D
;
if
(
!
MidiOutDev
[
wDevID
].
bEnabled
)
{
TRACE
(
"
disabl
ed wDevID
\n
"
);
return
MMSYSERR_
NOTENABLE
D
;
}
MidiOutDev
[
wDevID
].
lpExtra
=
0
;
switch
(
midiOutDevices
[
wDevID
]
->
wTechnology
)
{
switch
(
MidiOutDev
[
wDevID
].
caps
.
wTechnology
)
{
case
MOD_FMSYNTH
:
{
void
*
extra
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
sFMextra
)
+
sizeof
(
struct
sVoice
)
*
(
midiOutDevices
[
wDevID
]
->
wVoices
-
1
));
void
*
extra
;
extra
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
sFMextra
)
+
sizeof
(
struct
sVoice
)
*
(
MidiOutDev
[
wDevID
].
caps
.
wVoices
-
1
));
if
(
extra
==
0
)
{
WARN
(
"can't alloc extra data !
\n
"
);
...
...
@@ -1047,7 +1047,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
break
;
default:
WARN
(
"Technology not supported (yet) %d !
\n
"
,
midiOutDevices
[
wDevID
]
->
wTechnology
);
MidiOutDev
[
wDevID
].
caps
.
wTechnology
);
return
MMSYSERR_NOTENABLED
;
}
...
...
@@ -1088,14 +1088,14 @@ static DWORD modClose(WORD wDevID)
return
MMSYSERR_ERROR
;
}
switch
(
midiOutDevices
[
wDevID
]
->
wTechnology
)
{
switch
(
MidiOutDev
[
wDevID
].
caps
.
wTechnology
)
{
case
MOD_FMSYNTH
:
case
MOD_MIDIPORT
:
midiCloseSeq
();
break
;
default:
WARN
(
"Technology not supported (yet) %d !
\n
"
,
midiOutDevices
[
wDevID
]
->
wTechnology
);
MidiOutDev
[
wDevID
].
caps
.
wTechnology
);
return
MMSYSERR_NOTENABLED
;
}
...
...
@@ -1124,11 +1124,14 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
TRACE
(
"(%04X, %08lX);
\n
"
,
wDevID
,
dwParam
);
if
(
wDevID
>=
MODM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
!
MidiOutDev
[
wDevID
].
bEnabled
)
return
MIDIERR_NODEVICE
;
if
(
midiSeqFD
==
-
1
)
{
WARN
(
"can't play !
\n
"
);
return
MIDIERR_NODEVICE
;
}
switch
(
midiOutDevices
[
wDevID
]
->
wTechnology
)
{
switch
(
MidiOutDev
[
wDevID
].
caps
.
wTechnology
)
{
case
MOD_FMSYNTH
:
/* FIXME:
* - chorus depth controller is not used
...
...
@@ -1142,7 +1145,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
switch
(
evt
&
0xF0
)
{
case
MIDI_NOTEOFF
:
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
;
...
...
@@ -1152,7 +1155,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
break
;
case
MIDI_NOTEON
:
if
(
d2
==
0
)
{
/* note off if velocity == 0 */
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
;
...
...
@@ -1166,7 +1169,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
* - if replaying the same note on the same channel
* - the older voice (LRU)
*/
for
(
i
=
nv
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
;
...
...
@@ -1203,7 +1206,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
voice
[
nv
].
cntMark
=
extra
->
counter
++
;
break
;
case
MIDI_KEY_PRESSURE
:
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
);
}
...
...
@@ -1217,13 +1220,13 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
case
CTL_EXPRESSION
:
channel
[
chn
].
expression
=
d2
;
break
;
case
CTL_SUSTAIN
:
channel
[
chn
].
sustain
=
d2
;
if
(
d2
)
{
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
);
...
...
@@ -1240,7 +1243,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
case
0x0000
:
if
(
channel
[
chn
].
benderRange
!=
d2
)
{
channel
[
chn
].
benderRange
=
d2
;
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
for
(
i
=
0
;
i
<
MidiOutDev
[
wDevID
].
caps
.
wVoices
;
i
++
)
{
if
(
voice
[
i
].
channel
==
chn
)
{
SEQ_BENDER_RANGE
(
wDevID
,
i
,
channel
[
chn
].
benderRange
);
}
...
...
@@ -1250,7 +1253,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
case
0x7F7F
:
channel
[
chn
].
benderRange
=
2
;
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
for
(
i
=
0
;
i
<
MidiOutDev
[
wDevID
].
caps
.
wVoices
;
i
++
)
{
if
(
voice
[
i
].
channel
==
chn
)
{
SEQ_BENDER_RANGE
(
wDevID
,
i
,
channel
[
chn
].
benderRange
);
}
...
...
@@ -1269,7 +1272,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
/* FIXME: I don't know if I have to take care of the channel
* for this control ?
*/
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
);
...
...
@@ -1280,7 +1283,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
/* FIXME: I don't know if I have to take care of the channel
* for this control ?
*/
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
);
...
...
@@ -1297,7 +1300,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
channel
[
chn
].
program
=
d1
;
break
;
case
MIDI_CHN_PRESSURE
:
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
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
);
}
...
...
@@ -1305,7 +1308,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
break
;
case
MIDI_PITCH_BEND
:
channel
[
chn
].
bender
=
(
d2
<<
7
)
+
d1
;
for
(
i
=
0
;
i
<
midiOutDevices
[
wDevID
]
->
wVoices
;
i
++
)
{
for
(
i
=
0
;
i
<
MidiOutDev
[
wDevID
].
caps
.
wVoices
;
i
++
)
{
if
(
voice
[
i
].
channel
==
chn
)
{
SEQ_BENDER
(
wDevID
,
i
,
channel
[
chn
].
bender
);
}
...
...
@@ -1328,7 +1331,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
break
;
case
MOD_MIDIPORT
:
{
int
dev
=
wDevID
-
MODM_N
UMFMSYNTHDEVS
;
int
dev
=
wDevID
-
MODM_N
umFMSynthDevs
;
if
(
dev
<
0
)
{
WARN
(
"Internal error on devID (%u) !
\n
"
,
wDevID
);
return
MIDIERR_NODEVICE
;
...
...
@@ -1392,7 +1395,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
break
;
default:
WARN
(
"Technology not supported (yet) %d !
\n
"
,
midiOutDevices
[
wDevID
]
->
wTechnology
);
MidiOutDev
[
wDevID
].
caps
.
wTechnology
);
return
MMSYSERR_NOTENABLED
;
}
...
...
@@ -1411,6 +1414,9 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
TRACE
(
"(%04X, %p, %08lX);
\n
"
,
wDevID
,
lpMidiHdr
,
dwSize
);
if
(
wDevID
>=
MODM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
!
MidiOutDev
[
wDevID
].
bEnabled
)
return
MIDIERR_NODEVICE
;
if
(
midiSeqFD
==
-
1
)
{
WARN
(
"can't play !
\n
"
);
return
MIDIERR_NODEVICE
;
...
...
@@ -1441,23 +1447,23 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
lpData
[
0
],
lpData
[
1
],
lpData
[
2
],
lpData
[
lpMidiHdr
->
dwBufferLength
-
3
],
lpData
[
lpMidiHdr
->
dwBufferLength
-
2
],
lpData
[
lpMidiHdr
->
dwBufferLength
-
1
]);
switch
(
midiOutDevices
[
wDevID
]
->
wTechnology
)
{
switch
(
MidiOutDev
[
wDevID
].
caps
.
wTechnology
)
{
case
MOD_FMSYNTH
:
/* FIXME: I don't think there is much to do here */
break
;
case
MOD_MIDIPORT
:
if
(
lpData
[
0
]
!=
0xF0
)
{
/* Send end of System Exclusive */
SEQ_MIDIOUT
(
wDevID
-
MODM_N
UMFMSYNTHDEVS
,
0xF0
);
SEQ_MIDIOUT
(
wDevID
-
MODM_N
umFMSynthDevs
,
0xF0
);
WARN
(
"Adding missing 0xF0 marker at the beginning of "
"system exclusive byte stream
\n
"
);
}
for
(
count
=
0
;
count
<
lpMidiHdr
->
dwBytesRecorded
;
count
++
)
{
SEQ_MIDIOUT
(
wDevID
-
MODM_N
UMFMSYNTHDEVS
,
lpData
[
count
]);
SEQ_MIDIOUT
(
wDevID
-
MODM_N
umFMSynthDevs
,
lpData
[
count
]);
}
if
(
lpData
[
count
-
1
]
!=
0xF7
)
{
/* Send end of System Exclusive */
SEQ_MIDIOUT
(
wDevID
-
MODM_N
UMFMSYNTHDEVS
,
0xF7
);
SEQ_MIDIOUT
(
wDevID
-
MODM_N
umFMSynthDevs
,
0xF7
);
WARN
(
"Adding missing 0xF7 marker at the end of "
"system exclusive byte stream
\n
"
);
}
...
...
@@ -1465,7 +1471,7 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
break
;
default:
WARN
(
"Technology not supported (yet) %d !
\n
"
,
midiOutDevices
[
wDevID
]
->
wTechnology
);
MidiOutDev
[
wDevID
].
caps
.
wTechnology
);
return
MMSYSERR_NOTENABLED
;
}
...
...
@@ -1537,6 +1543,9 @@ static DWORD modReset(WORD wDevID)
TRACE
(
"(%04X);
\n
"
,
wDevID
);
if
(
wDevID
>=
MODM_NumDevs
)
return
MMSYSERR_BADDEVICEID
;
if
(
!
MidiOutDev
[
wDevID
].
bEnabled
)
return
MIDIERR_NODEVICE
;
/* stop all notes */
/* FIXME: check if 0x78B0 is channel dependant or not. I coded it so that
* it's channel dependent...
...
...
@@ -1585,7 +1594,7 @@ DWORD WINAPI OSS_midMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
case
MIDM_GETDEVCAPS
:
return
midGetDevCaps
(
wDevID
,
(
LPMIDIINCAPSA
)
dwParam1
,
dwParam2
);
case
MIDM_GETNUMDEVS
:
return
MIDM_N
UMDEVS
;
return
MIDM_N
umDevs
;
case
MIDM_RESET
:
return
midReset
(
wDevID
);
case
MIDM_START
:
...
...
@@ -1631,7 +1640,7 @@ DWORD WINAPI OSS_modMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
case
MODM_GETDEVCAPS
:
return
modGetDevCaps
(
wDevID
,
(
LPMIDIOUTCAPSA
)
dwParam1
,
dwParam2
);
case
MODM_GETNUMDEVS
:
return
MODM_N
UMDEVS
;
return
MODM_N
umDevs
;
case
MODM_GETVOLUME
:
return
0
;
case
MODM_SETVOLUME
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment