Release 980927
Sun Sep 27 14:25:38 1998 Petter Reinholdtsen <pere@td.org.uit.no>
* [files/drive.c]
Make sure GetDriveType32A() handles param NULL. Added some
doc on function.
Sun Sep 27 14:07:26 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
* [controls/edit.c] [windows/win.c]
Don't call SetWindowLong() in EDIT_WM_NCREATE.
Fix SetWindowLong(GWL_[EX]STYLE) to work for 16bit windows. Remove
UpdateWindow() call.
Sun Sep 27 13:41:22 1998 Alexandre Julliard <julliard@lrc.epfl.ch>
* [scheduler/*.c] [server/event.c] [server/mutex.c]
[server/semaphore.c]
Implemented server-side synchronisation objects.
Sun Sep 27 01:13:35 1998 Alex Priem <alexp@sci.kun.nl>
* [dlls/comctl32/treeview.c] [include/treeview.h] [include/comctl.h]
Treeview implementation.
* [dlls/comctl32/trackbar.c] [include/trackbar.h]
Trackbar implementation.
Sat Sep 26 20:49:13 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de>
* [if1632/thunk.c] [tools/build.c] [win32/kernel32.c]
Bugfix: several problems with flat thunks fixed.
* [memory/selector.c]
Bugfix: IsBad...Ptr16 didn't work for limit_in_pages segments.
* [scheduler/thread.c]
Bugfix: CreateThread: Allow id parameter == NULL.
* [objects/gdiobj.c]
Bugfix: IsGDIObject: Return correct object type for stock objects.
* [msdos/dpmi.c]
Bugfix: fixed typo in INT_DoRealModeInt.
* [msdos/int21.c]
Bugfix: int21 READ *must* use WIN16_hread, not _hread16.
* [if1632/kernel.spec] [if1632/dummy.c] [if1632/thunk.c]
[loader/ne/module.c] [scheduler/event.c] [scheduler/synchro.c]
[scheduler/thread.c] [win32/kernel32.c] [win32/ordinals.c]
Added names/stubs for all undocumented KERNEL routines (Win95).
Added the following undoc. 16-bit equivalents to Win32 routines:
KERNEL.441-443,449-453,456-462,471-476,479-486,488.
Added stubs for some other KERNEL routines.
* [memory/heap.c] [memory/global.c] [include/global.h]
Implemented Local32... 32-bit local heap routines (KERNEL.208-215, 229).
* [miscemu/instr.c] [loader/module.c] [include/module.h]
Implemented __GP fault handling and HasGPHandler (KERNEL.338).
* [misc/error.c]
Implemented LogParamErrorRegs (KERNEL.327).
* [loader/task.c] [include/windows.h]
Implemented GetCodeInfo (KERNEL.104).
* [loader/task.c] [scheduler/thread.c] [include/thread.h]
Implemented [GS]etThreadQueue and [GS]etFastQueue (KERNEL.463/4, 624/5).
* [if1632/gdi.spec] [objects/dc.c] [objects/dib.c]
[objects/bitmap.c] [include/windows.h]
Bugfix: fixed wrong parameter for CreateDIBSection16.
Added [GS]etDIBColorTable16, stub for GetBoundsRect16.
Partially implemented BITMAP_GetObject16 for DIBs.
* [if1632/gdi.spec] [relay32/gdi32.spec] [objects/palette.c]
Added some GDI stubs.
* [if1632/Makefile.in] [if1632/display.spec] [if1632/mouse.spec]
[if1632/keyboard.spec] [if1632/builtin.c] [windows/keyboard.c]
Added some stubs for Win16 drivers: KEYBOARD, MOUSE, DISPLAY.
* [if1632/wprocs.spec] [msdos/vxd.c]
Added some stubs for VxDs: VMM, ConfigMG, TimerAPI.
* [msdos/int2f.c]
Added some stubs for real-mode network drivers.
Sat Sep 26 18:18:18 1998 Marcus Meissner <marcus@jet.franken.de>
* [configure.in]
Merged in some more of the FreeBSD ports/emulators/wine patches.
(Maintainer(s) of this port: You can just submit these
patches to Alexandre directly.)
* [loader/pe_image.c]
Check filesize of image against size derived from header
to spot truncated executeables without crashing.
* [files/directory.c]
Set envvar "COMSPEC". One win32(!!) program crashes without it.
* [multimedia/mmio.c]
Added mmioSetInfo32.
* [include/file.h]
Return STD_ERROR_HANDLE for AUX and PRT dos handles.
* [loader/module.c]
Handle executeables with spaces in their names a bit better in
CreateProcess.
* [relay32/msvfw32.spec][if1632/msvideo.spec][multimedia/msvideo.c][include/vfw.h]
Started on MS Video support (can load Win32 ICMs).
* [tools/testrun]
A bit smarter use of ps.
* [memory/virtual.c]
Report PAGE_GUARDed pages as PAGE_PROTECTED (AutoCAD LT R17 fails
without that check (since Win95 doesn't know about PAGE_GUARD)).
Sat Sep 26 15:04:05 1998 Ove Kaaven <ovek@arcticnet.no>
* [include/miscemu.h] [if1632/builtin.c] [loader/task.c]
[miscemu/instr.c] [msdos/dpmi.c] [msdos/int21.c]
[msdos/interrupts.c] [windows/user.c]
INT_[S|G]etHandler was renamed to INT_[S|G]etPMHandler.
Added handlers to deal with real-mode interrupts; DOS
programs are now able to hook real-mode interrupts.
* [loader/dos/module.c] [msdos/dosmem.c] [msdos/int21.c]
Moved real-mode interrupt table initialization to
msdos/dosmem.c, and made new V86 tasks get a full copy
of the existing "system memory" instead of almost empty
space. Misc fixes.
* [include/dosexe.h] [loader/dos/module.c] [msdos/dpmi.c]
[msdos/int2f.c]
First shot at letting DOS programs start up DPMI (but DPMI
is still disabled for DOS programs, for pkunzip's sake).
* [include/debugger.h] [debugger/break.c] [debugger/dbg.y]
[debugger/registers.c] [debugger/memory.c] [debugger/info.c]
[loader/dos/dosvm.c]
First shot at making Wine's debugger work for DOS programs.
The -debug flag works, as do "nexti" and "stepi".
Sat Sep 26 13:13:13 1998 Juergen Schmied <juergen.schmied@metronet.de>
* [dlls/shell32/dataobject.c]
New classes IEnumFORMATETC implemented, IDataObject stubs.
* [dlls/shell32/*.*][relay32/shell32.spec]
Bugfixes.
New: ICM_InsertItem(), ILCreateFromPath().
Implemented: ILCloneFirst().
Stubs: ILIsEqual(), ILFindChild(), SHLogILFromFSIL(),
PathMatchSpec(), PathIsExe().
Changed: ILGetSize(), _ILIsDesktop(), PathCombine().
* [include/shlobj.h]
New SHLGUID's
New structures: DVTARGETDEVICE32, STGMEDIUM32, FORMATETC32,
CLIPFORMAT32.
New interfaces: IEnumFORMATETC, IDataObject, ICommDlgBrowser
IDockingWindowFrame, IServiceProvider.
* [dlls/shell32/folders.c]
Stubs for IShellLink.
* [loader/resource.c]
Small fixes.
* [misc/crtdll.c][relay32/crtdll.spec]
New __dllonexit().
* [windows/message.c]
SendNotifyMessageA, SendMessageCallBack32A half implemented.
* [controls/edit.c]
EDIT_WM_SetText set EF_UPDATE flag not for ES_MULTILINE.
* [files/file.c]
Handling of fileposition fixed.
Fri Sep 25 18:13:30 1998 Patrik Stridvall <ps@leissner.se>
* [include/windows.h] [include/wintypes.h]
[ole/ole2nls.h] [relay32/kernel32.spec]
Implemented EnumDateFormats and EnumTimeFormats.
Only adds US English support.
* [Makefile.in] [configure.in]
[dlls/Makefile.in] [dlls/psapi/Makefile.in]
[dlls/psapi/psapi_main.c]
New files to implement stubs for PSAPI.DLL (NT only).
* [relay32/Makefile.in] [relay32/builtin32.c]
[relay32/psapi.spec]
New spec file for PSAPI.DLL (NT only).
* [scheduler/handle.c]
HANDLE_GetObjPtr should only interpret the pseudo handles as the
current thread or the current process if a thread or a process is
requested.
* [include/winversion.h] [misc/version.c]
Adds the global function VERSION_GetVersion() so functions can
have different behavior depending on the -winver flag.
* [include/oledlg.h] [ole/oledlg.c]
Minor fixes.
* [windows/winproc.c]
Minor changes.
* [include/imm.h] [misc/imm.c]
Now returns correct values under both Windows 95 and NT 4.0.
Thu Sep 24 22:11:44 1998 Kristian Nielsen <kristian.nielsen@risoe.dk>
* [configure.in] [include/acconfig.h] [include/thread.h]
[scheduler/sysdeps.c]
Autoconfig test for non-reentrant libc.
Wed Sep 23 19:52:12 1998 Matthew Becker <mbecker@glasscity.net>
* [*/*.c]
Miscellaneous documentation updates and debugging output
standardizations.
* [objects/clipping.c]
Added ExtSelectClipRgn.
Wed Sep 23 00:03:28 EDT 1998 Pete Ratzlaff <pratzlaff@cfa.harvard.edu>
* [include/windows.h] [if1632/user.spec] [relay32/user32.spec]
[windows/keyboard.c]
Added, marginally implemented, GetKeyboardLayoutName().
Only returns US English keyboard name.
Tue Sep 22 16:32:41 1998 Marcel Baur <mbaur@iiic.ethz.ch>
* [programs/control/*]
New Winelib application.
Mon Sep 21 00:29:18 1998 Peter Hunnisett <hunnise@nortel.ca>
* [include/dplay.h][multimedia/dplay.c][ole/compobj.c]
Added all DirectPlayLobby interfaces and enhanced DirectPlay
and DirectPlayLobby support. Still not all that much. Useful
enough if you just need to start a program, don't try any
real dplay/lobby stuff.
* [documentation/status/directplay]
Added a very little bit.
* [graphics/ddraw.c]
- Call to SetWindowLong32A wasn't working because there was no
memory set aside when the window class was registered.
- Fixed some xlib reference counting and change the behaviour
of DirectDrawSurface3_SetPalette to mimic observed behaviour
(palette is associated will all backbuffers)
- Also stored all palette colour fields and spit back our saved
colour fields rather than query X for them.
- Added plenty of AddRef and Release traces.
- Added Xlib support for using -desktop option.
- Fixed Xlib message handling. Messages weren't being passed to
the application. Fixes mouse movements in some xlib DDraw games.
- Added a few stubs.
* [windows/win.c][include/winerror.h]
Fixed up some error handling in WIN_SetWindowLong. SetLastError
wasn't being used. Could cause problems with 0 return codes.
Added new error in winerror (1400).
* [AUTHORS] [include/authors.h]
Added myself as a Wine author.
Sun Sep 20 21:22:44 1998 Alexander Larsson <alla@lysator.liu.se>
* [loader/module.c]
Changed GetModuleFileName32A so that is returns the
long version of the filename. Note that just the name
is long, not the directories.
Sat Sep 19 20:05:30 1998 Per Ångström <pang@mind.nu>
* [controls/menu.c]
Made a couple of fixes to make life easier for applications that alter
their menus at runtime.
* [windows/defdlg.c]
Removed the cast of the return value from dialog procedures to a 16-bit
bool. The return value needs to retain all its 32 bits, since it is not
always a bool, such as when responding to the WM_NCHITTEST message.
Fri Sep 18 11:30:38 1998 Sergey Turchanov <turchanov@usa.net>
* [loader/resource.c]
Fixed very funny bug (though gravely affecting further excecution)
with FindResource[Ex]32 functions.
* [include/multimon.h] [windows/multimon.c] [relay32/user32.spec]
[include/windows.h] [windows/sysmetrics.c]
Default implementation for Multimonitor API.
* [include/windows.h] [windows/winpos.c]
Fixed incorrect declaration (and behaviour) of GetWindowRect32.
Wed Sep 16 10:21:15 1998 Gerard Patel <G.Patel@Wanadoo.fr>
* [controls/edit.c]
Fixed EDIT_EM_GetLine to use correctly length of lines.
Tue Sep 15 20:40:16 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
* [misc/tweak.c][include/tweak.h][controls/menu.c]
Replaced the tweak graphic routines by calls to DrawEdge32().
* [misc/tweak.c][include/tweak.h][documentation/win95look]
[wine.ini][*/*]
Changed "look and feel" selection. Allows Win3.1, Win95 and
Win98 (no GUI code implemented) look and feel.
* [dlls/comctl32/header.c][include/header.h][include/commctrl.h]
Started callback item support and did some minor improvements.
* [dlls/comctl32/imagelist.c]
Fixed bug in transparent image display.
ImageList_GetIcon is still buggy :-(
* [dlls/comctl32/toolbar.c]
Fixed button drawing (partial hack).
* [dlls/comctl32/commctrl.c]
Fixed MenuHelp().
* [controls/button.c]
Added 3d effect for groupbox.
* [windows/msgbox.c]
Added font support for message boxes.
* [windows/nonclient.c]
Fixed window moving bug.
* [dlls/comctl32/*.c]
Various improvements.
* [dlls/comctl32/listview.c][dlls/comctl32/rebar.c]
[include/commctrl.h]
More messages.
* [windows/syscolor.c][include/windows.h]
Introduced new Win98 system colors.
Tue Sep 15 18:29:45 1998 Wesley Filardo <eightknots@aol.com>
* [files/profile.c]
Added support in PROFILE_LoadWineIni for -config option
* [misc/main.c] [include/options.h]
Added -config option.
Tue Sep 15 18:22:26 1998 Petter Reinholdtsen <pere@td.org.uit.no>
* [documentation/Makefile.in]
Make sure directory exists before installing into it.
Tue Sep 15 01:47:33 1998 Pablo Saratxaga <pablo.sarachaga@ping.be>
* [ole/nls/*] [ole/ole2nls.c] [include/winnls.h]
Fixed a few errors and completed some NLS files.
Mon Sep 14 01:23:45 1998 Joseph Pranevich <knight@baltimore.wwaves.com>
* [include/miscemu.h] [msdos/interrupts.c]
Removed a compilation warning, added INT 25 to the list of interrupts
callable from DOS applications, added a debug message when unsupported
interrupts are used.
Sun Sep 13 19:55:22 1998 Lawson Whitney <lawson_whitney@juno.com>
* [if1632/relay.c]
CallProcEx32W should not reverse arguments.
Sun Aug 17 21:18:12 1998 Eric Pouech <eric.pouech@lemel.fr>
* [multimedia/midi.c] [multimedia/init.c] [multimedia/mmsys.c]
[include/multimedia.h] [include/mmsystem.h]
[multimedia/Makefile.in] [multimedia/midipatch.c]
[if1632/multimedia.spec]
Made MIDI input and output functional on OSS capable systems.
* [multimedia/timer.c]
Changes to trigger callbacks at the accurate pace even when
fake timers are used.
diff --git a/multimedia/midi.c b/multimedia/midi.c
index c7cae5a..3200e9e 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -1,15 +1,23 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
/*
* Sample MIDI Wine Driver for Linux
*
* Copyright 1994 Martin Ayotte
*/
+/*
+ * Eric POUECH : 98/7 changes for making this MIDI driver work on OSS
+ * current support is limited to MIDI ports of OSS systems
+ */
+
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include "windows.h"
#include "ldt.h"
#include "multimedia.h"
@@ -18,294 +26,327 @@
#include "mmsystem.h"
#include "xmalloc.h"
#include "debug.h"
+#include "callback.h"
+#include "options.h"
-static LINUX_MIDIIN MidiInDev[MAX_MIDIINDRV];
+static LINUX_MIDIIN MidiInDev [MAX_MIDIINDRV ];
static LINUX_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
static LINUX_MCIMIDI MCIMidiDev[MAX_MCIMIDIDRV];
-/* this is the total number of MIDI devices found */
-int MODM_NUMDEVS = 0;
+/* this is the total number of MIDI out devices found */
+int MODM_NUMDEVS = 0;
+/* this is the number of FM synthetizers (index from 0 to
+ NUMFMSYNTHDEVS - 1) */
+int MODM_NUMFMSYNTHDEVS = 0;
+/* this is the number of Midi ports (index from NUMFMSYNTHDEVS to
+ NUMFMSYNTHDEVS + NUMMIDIDEVS - 1) */
+int MODM_NUMMIDIDEVS = 0;
+
+/* this is the total number of MIDI out devices found */
+int MIDM_NUMDEVS = 0;
+
+#ifdef HAVE_OSS
+static int midiSeqFD = -1;
+static int numOpenMidiSeq = 0;
+static UINT32 midiInTimerID = 0;
+static int numStartedMidiIn = 0;
+#endif /* HAVE_OSS */
/* this structure holds pointers with information for each MIDI
- * device found.
+ * out device found.
*/
-LPMIDIOUTCAPS16 midiDevices[MAX_MIDIOUTDRV];
+LPMIDIOUTCAPS16 midiOutDevices[MAX_MIDIOUTDRV];
+
+/* this structure holds pointers with information for each MIDI
+ * in device found.
+ */
+LPMIDIINCAPS16 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...
+ * check also when HAVE_OSS is defined that midiDesc is not NULL
+ */
/**************************************************************************
* MIDI_NotifyClient [internal]
*/
static DWORD MIDI_NotifyClient(UINT16 wDevID, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
- TRACE(midi,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID, wMsg, dwParam1, dwParam2);
-
- switch (wMsg) {
- case MOM_OPEN:
- case MOM_CLOSE:
- case MOM_DONE:
- if (wDevID > MAX_MIDIOUTDRV) return MCIERR_INTERNAL;
-
- if (MidiOutDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
- MidiOutDev[wDevID].midiDesc.dwCallback,
- MidiOutDev[wDevID].wFlags,
- MidiOutDev[wDevID].midiDesc.hMidi,
- wMsg,
- MidiOutDev[wDevID].midiDesc.dwInstance,
- dwParam1,
- dwParam2)) {
- WARN(midi,"can't notify client !\n");
- return MMSYSERR_NOERROR;
- }
- break;
-
- case MIM_OPEN:
- case MIM_CLOSE:
- if (wDevID > MAX_MIDIINDRV) return MCIERR_INTERNAL;
-
- if (MidiInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
- MidiInDev[wDevID].midiDesc.dwCallback, MidiInDev[wDevID].wFlags,
- MidiInDev[wDevID].midiDesc.hMidi, wMsg,
- MidiInDev[wDevID].midiDesc.dwInstance, dwParam1, dwParam2)) {
- WARN(mciwave,"can't notify client !\n");
- return MMSYSERR_NOERROR;
- }
- break;
- }
- return 0;
+ DWORD dwCallBack;
+ UINT16 uFlags;
+ HANDLE16 hDev;
+ DWORD dwInstance;
+
+ TRACE(midi,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",
+ wDevID, wMsg, dwParam1, dwParam2);
+
+ switch (wMsg) {
+ case MOM_OPEN:
+ case MOM_CLOSE:
+ case MOM_DONE:
+ if (wDevID > MAX_MIDIOUTDRV)
+ return MCIERR_INTERNAL;
+
+ dwCallBack = MidiOutDev[wDevID].midiDesc->dwCallback;
+ uFlags = MidiOutDev[wDevID].wFlags;
+ hDev = MidiOutDev[wDevID].midiDesc->hMidi;
+ dwInstance = MidiOutDev[wDevID].midiDesc->dwInstance;
+ break;
+
+ case MIM_OPEN:
+ case MIM_CLOSE:
+ case MIM_DATA:
+ case MIM_ERROR:
+ if (wDevID > MAX_MIDIINDRV)
+ return MCIERR_INTERNAL;
+
+ dwCallBack = MidiInDev[wDevID].midiDesc->dwCallback;
+ uFlags = MidiInDev[wDevID].wFlags;
+ hDev = MidiInDev[wDevID].midiDesc->hMidi;
+ dwInstance = MidiInDev[wDevID].midiDesc->dwInstance;
+ break;
+ default:
+ WARN(midi, "Unsupported MSW-MIDI message %u\n", wMsg);
+ return MCIERR_INTERNAL;
+ }
+
+ return DriverCallback(dwCallBack, uFlags, hDev, wMsg, dwInstance, dwParam1, dwParam2) ?
+ 0 : MCIERR_INTERNAL;
}
-
/**************************************************************************
* MIDI_ReadByte [internal]
*/
static DWORD MIDI_ReadByte(UINT16 wDevID, BYTE *lpbyt)
{
- if (lpbyt != NULL) {
- if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
- (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
- return 0;
- }
+ if (lpbyt != NULL) {
+ if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
+ (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
+ return 0;
}
- WARN(midi, "error reading wDevID=%04X\n", wDevID);
- return MCIERR_INTERNAL;
-
+ }
+ WARN(midi, "error reading wDevID=%04X\n", wDevID);
+ return MCIERR_INTERNAL;
+
}
-
/**************************************************************************
* MIDI_ReadWord [internal]
*/
static DWORD MIDI_ReadWord(UINT16 wDevID, LPWORD lpw)
{
- BYTE hibyte, lobyte;
- if (lpw != NULL) {
- if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
- if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
- *lpw = ((WORD)hibyte << 8) + lobyte;
- return 0;
- }
- }
- }
- WARN(midi, "error reading wDevID=%04X\n", wDevID);
- return MCIERR_INTERNAL;
-}
+ BYTE hibyte, lobyte;
+ if (lpw != NULL) {
+ if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
+ if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
+ *lpw = ((WORD)hibyte << 8) + lobyte;
+ return 0;
+ }
+ }
+ }
+ WARN(midi, "error reading wDevID=%04X\n", wDevID);
+ return MCIERR_INTERNAL;
+}
/**************************************************************************
* MIDI_ReadLong [internal]
*/
static DWORD MIDI_ReadLong(UINT16 wDevID, LPDWORD lpdw)
{
- WORD hiword, loword;
- if (lpdw != NULL) {
- if (MIDI_ReadWord(wDevID, &hiword) == 0) {
- if (MIDI_ReadWord(wDevID, &loword) == 0) {
- *lpdw = MAKELONG(loword, hiword);
- return 0;
- }
- }
- }
- WARN(midi, "error reading wDevID=%04X\n", wDevID);
- return MCIERR_INTERNAL;
-}
+ WORD hiword, loword;
+ if (lpdw != NULL) {
+ if (MIDI_ReadWord(wDevID, &hiword) == 0) {
+ if (MIDI_ReadWord(wDevID, &loword) == 0) {
+ *lpdw = MAKELONG(loword, hiword);
+ return 0;
+ }
+ }
+ }
+ WARN(midi, "error reading wDevID=%04X\n", wDevID);
+ return MCIERR_INTERNAL;
+}
/**************************************************************************
* MIDI_ReadVaryLen [internal]
*/
static DWORD MIDI_ReadVaryLen(UINT16 wDevID, LPDWORD lpdw)
{
- BYTE byte;
- DWORD value;
- if (lpdw == NULL) return MCIERR_INTERNAL;
- if (MIDI_ReadByte(wDevID, &byte) != 0) {
- WARN(midi, "error reading wDevID=%04X\n", wDevID);
- return MCIERR_INTERNAL;
- }
- value = (DWORD)(byte & 0x7F);
- while (byte & 0x80) {
- if (MIDI_ReadByte(wDevID, &byte) != 0) {
- WARN(midi, "error reading wDevID=%04X\n", wDevID);
- return MCIERR_INTERNAL;
- }
- value = (value << 7) + (byte & 0x7F);
- }
- *lpdw = value;
-/*
- TRACE(midi, "val=%08lX \n", value);
-*/
- return 0;
-}
+ BYTE byte;
+ DWORD value;
+ if (lpdw == NULL) return MCIERR_INTERNAL;
+ if (MIDI_ReadByte(wDevID, &byte) != 0) {
+ WARN(midi, "error reading wDevID=%04X\n", wDevID);
+ return MCIERR_INTERNAL;
+ }
+ value = (DWORD)(byte & 0x7F);
+ while (byte & 0x80) {
+ if (MIDI_ReadByte(wDevID, &byte) != 0) {
+ WARN(midi, "error reading wDevID=%04X\n", wDevID);
+ return MCIERR_INTERNAL;
+ }
+ value = (value << 7) + (byte & 0x7F);
+ }
+ *lpdw = value;
+ /*
+ TRACE(midi, "val=%08lX \n", value);
+ */
+ return 0;
+}
/**************************************************************************
* MIDI_ReadMThd [internal]
*/
static DWORD MIDI_ReadMThd(UINT16 wDevID, DWORD dwOffset)
{
- DWORD toberead;
- FOURCC fourcc;
- TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
- if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
- WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
- return MCIERR_INTERNAL;
- }
- if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
- (long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
- return MCIERR_INTERNAL;
- if (MIDI_ReadLong(wDevID, &toberead) != 0)
- return MCIERR_INTERNAL;
- if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0)
- return MCIERR_INTERNAL;
- if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0)
- return MCIERR_INTERNAL;
- if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0)
- return MCIERR_INTERNAL;
- TRACE(midi, "toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
- toberead, MCIMidiDev[wDevID].wFormat,
- MCIMidiDev[wDevID].nTracks,
- MCIMidiDev[wDevID].nTempo);
- toberead -= 3 * sizeof(WORD);
-/*
- ntrks = read16bit ();
- Mf_division = division = read16bit ();
-*/
- return 0;
-}
+ DWORD toberead;
+ FOURCC fourcc;
+ TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
+ if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
+ WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
+ return MCIERR_INTERNAL;
+ }
+ if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
+ (long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
+ return MCIERR_INTERNAL;
+ if (MIDI_ReadLong(wDevID, &toberead) != 0)
+ return MCIERR_INTERNAL;
+ if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0)
+ return MCIERR_INTERNAL;
+ if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0)
+ return MCIERR_INTERNAL;
+ if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0)
+ return MCIERR_INTERNAL;
+ TRACE(midi, "toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
+ toberead, MCIMidiDev[wDevID].wFormat,
+ MCIMidiDev[wDevID].nTracks,
+ MCIMidiDev[wDevID].nTempo);
+ toberead -= 3 * sizeof(WORD);
+ /*
+ ntrks = read16bit ();
+ Mf_division = division = read16bit ();
+ */
+ return 0;
+}
static DWORD MIDI_ReadMTrk(UINT16 wDevID, DWORD dwOffset)
{
- DWORD toberead;
- FOURCC fourcc;
- if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
- WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
- }
- if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
- (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
- return MCIERR_INTERNAL;
- }
- if (MIDI_ReadLong(wDevID, &toberead) != 0) {
- return MCIERR_INTERNAL;
- }
- TRACE(midi, "toberead=%08lX\n", toberead);
- toberead -= 3 * sizeof(WORD);
- MCIMidiDev[wDevID].dwTotalLen = toberead;
- return 0;
-}
+ DWORD toberead;
+ FOURCC fourcc;
+ if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
+ WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
+ }
+ if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
+ (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
+ return MCIERR_INTERNAL;
+ }
+ if (MIDI_ReadLong(wDevID, &toberead) != 0) {
+ return MCIERR_INTERNAL;
+ }
+ TRACE(midi, "toberead=%08lX\n", toberead);
+ toberead -= 3 * sizeof(WORD);
+ MCIMidiDev[wDevID].dwTotalLen = toberead;
+ return 0;
+}
/**************************************************************************
* MIDI_mciOpen [internal]
*/
static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
{
- MIDIOPENDESC MidiDesc;
- DWORD dwRet;
- DWORD dwOffset;
- LPSTR lpstrElementName;
- char str[128];
-
- TRACE(midi, "(%08lX, %p)\n", dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
-
- if (MCIMidiDev[wDevID].nUseCount > 0) {
- /* The driver already open on this channel */
- /* If the driver was opened shareable before and this open specifies */
- /* shareable then increment the use count */
- if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
- ++MCIMidiDev[wDevID].nUseCount;
- else
- return MCIERR_MUST_USE_SHAREABLE;
- } else {
- MCIMidiDev[wDevID].nUseCount = 1;
- MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
- MCIMidiDev[wDevID].hMidiHdr = USER_HEAP_ALLOC(sizeof(MIDIHDR));
+ MIDIOPENDESC MidiDesc;
+ DWORD dwRet;
+ DWORD dwOffset;
+ LPSTR lpstrElementName;
+ char str[128];
+
+ TRACE(midi, "(%08lX, %p)\n", dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+
+ if (MCIMidiDev[wDevID].nUseCount > 0) {
+ /* The driver already open on this channel */
+ /* If the driver was opened shareable before and this open specifies */
+ /* shareable then increment the use count */
+ if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
+ ++MCIMidiDev[wDevID].nUseCount;
+ else
+ return MCIERR_MUST_USE_SHAREABLE;
+ } else {
+ MCIMidiDev[wDevID].nUseCount = 1;
+ MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
+ MCIMidiDev[wDevID].hMidiHdr = USER_HEAP_ALLOC(sizeof(MIDIHDR));
+ }
+
+ TRACE(midi, "wDevID=%04X\n", wDevID);
+ /* lpParms->wDeviceID = wDevID;*/
+ TRACE(midi, "lpParms->wDevID=%04X\n", lpParms->wDeviceID);
+ TRACE(midi, "before OPEN_ELEMENT\n");
+ if (dwFlags & MCI_OPEN_ELEMENT) {
+ lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+ TRACE(midi, "MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
+ if (strlen(lpstrElementName) > 0) {
+ strcpy(str, lpstrElementName);
+ CharUpper32A(str);
+ MCIMidiDev[wDevID].hFile = mmioOpen16(str, NULL,
+ MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
+ if (MCIMidiDev[wDevID].hFile == 0) {
+ WARN(midi, "can't find file='%s' !\n", str);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ } else
+ MCIMidiDev[wDevID].hFile = 0;
+ }
+ TRACE(midi, "hFile=%u\n", MCIMidiDev[wDevID].hFile);
+ memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
+ MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+ MCIMidiDev[wDevID].dwBeginData = 0;
+ MCIMidiDev[wDevID].dwTotalLen = 0;
+ MidiDesc.hMidi = 0;
+ if (MCIMidiDev[wDevID].hFile != 0) {
+ MMCKINFO ckMainRIFF;
+ if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
+ return MCIERR_INTERNAL;
}
-
- TRACE(midi, "wDevID=%04X\n", wDevID);
-/* lpParms->wDeviceID = wDevID;*/
- TRACE(midi, "lpParms->wDevID=%04X\n", lpParms->wDeviceID);
- TRACE(midi, "before OPEN_ELEMENT\n");
- if (dwFlags & MCI_OPEN_ELEMENT) {
- lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
- TRACE(midi, "MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
- if (strlen(lpstrElementName) > 0) {
- strcpy(str, lpstrElementName);
- CharUpper32A(str);
- MCIMidiDev[wDevID].hFile = mmioOpen16(str, NULL,
- MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
- if (MCIMidiDev[wDevID].hFile == 0) {
- WARN(midi, "can't find file='%s' !\n", str);
- return MCIERR_FILE_NOT_FOUND;
- }
- } else
- MCIMidiDev[wDevID].hFile = 0;
+ TRACE(midi,"ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
+ (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
+ ckMainRIFF.cksize);
+ dwOffset = 0;
+ if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
+ TRACE(midi, "is a 'RMID' file \n");
+ dwOffset = ckMainRIFF.dwDataOffset;
}
- TRACE(midi, "hFile=%u\n", MCIMidiDev[wDevID].hFile);
- memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
- MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
- MCIMidiDev[wDevID].dwBeginData = 0;
- MCIMidiDev[wDevID].dwTotalLen = 0;
- MidiDesc.hMidi = 0;
- if (MCIMidiDev[wDevID].hFile != 0) {
- MMCKINFO ckMainRIFF;
- if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
- return MCIERR_INTERNAL;
- }
- TRACE(midi,"ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
- (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
- ckMainRIFF.cksize);
- dwOffset = 0;
- if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
- TRACE(midi, "is a 'RMID' file \n");
- dwOffset = ckMainRIFF.dwDataOffset;
- }
- if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
- WARN(midi, "unknown format !\n");
- return MCIERR_INTERNAL;
- }
- if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
- WARN(midi, "can't read 'MThd' header \n");
- return MCIERR_INTERNAL;
- }
- dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
- if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
- WARN(midi, "can't read 'MTrk' header \n");
- return MCIERR_INTERNAL;
- }
- dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
- MCIMidiDev[wDevID].dwBeginData = dwOffset;
- TRACE(midi, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
- (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
- ckMainRIFF.cksize);
+ if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
+ WARN(midi, "unknown format !\n");
+ return MCIERR_INTERNAL;
}
-
- dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
-/* dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
-
- return 0;
+ if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
+ WARN(midi, "can't read 'MThd' header \n");
+ return MCIERR_INTERNAL;
+ }
+ dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
+ if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
+ WARN(midi, "can't read 'MTrk' header \n");
+ return MCIERR_INTERNAL;
+ }
+ dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
+ MCIMidiDev[wDevID].dwBeginData = dwOffset;
+ TRACE(midi, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
+ (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
+ ckMainRIFF.cksize);
+ }
+
+ dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
+ /* dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
+
+ return 0;
}
/**************************************************************************
@@ -313,458 +354,677 @@
*/
static DWORD MIDI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
- TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
- &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
- return 0;
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+ TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
+ &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
+ return 0;
}
-
/**************************************************************************
- * MIDI_mciClose [internal]
+ * MIDI_mciClose [internal]
*/
static DWORD MIDI_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
{
- DWORD dwRet;
-
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
- if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
- MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
- }
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
- MCIMidiDev[wDevID].nUseCount--;
- if (MCIMidiDev[wDevID].nUseCount == 0) {
- if (MCIMidiDev[wDevID].hFile != 0) {
- mmioClose32(MCIMidiDev[wDevID].hFile, 0);
- MCIMidiDev[wDevID].hFile = 0;
- TRACE(midi, "hFile closed !\n");
- }
- USER_HEAP_FREE(MCIMidiDev[wDevID].hMidiHdr);
- dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
- if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-/*
- dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
- if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-*/
- }
- return 0;
+ DWORD dwRet;
+
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
+ if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
+ MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
+ }
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+ MCIMidiDev[wDevID].nUseCount--;
+ if (MCIMidiDev[wDevID].nUseCount == 0) {
+ if (MCIMidiDev[wDevID].hFile != 0) {
+ mmioClose32(MCIMidiDev[wDevID].hFile, 0);
+ MCIMidiDev[wDevID].hFile = 0;
+ TRACE(midi, "hFile closed !\n");
+ }
+ USER_HEAP_FREE(MCIMidiDev[wDevID].hMidiHdr);
+ dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
+ if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
+ /*
+ dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
+ if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
+ */
+ }
+ return 0;
}
-
/**************************************************************************
- * MIDI_mciPlay [internal]
+ * MIDI_mciPlay [internal]
*/
static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
- int count,start,end;
- LPMIDIHDR lpMidiHdr;
- DWORD dwData,dwRet;
- LPWORD ptr;
-
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (MCIMidiDev[wDevID].hFile == 0) {
- WARN(midi, "can't find file='%08lx' !\n",
- (DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
- return MCIERR_FILE_NOT_FOUND;
- }
- start = 1; end = 99999;
- if (dwFlags & MCI_FROM) {
- start = lpParms->dwFrom;
- TRACE(midi, "MCI_FROM=%d \n", start);
- }
- if (dwFlags & MCI_TO) {
- end = lpParms->dwTo;
- TRACE(midi, "MCI_TO=%d \n", end);
- }
+ int count,start,end;
+ LPMIDIHDR lpMidiHdr;
+ DWORD dwData,dwRet;
+ LPWORD ptr;
+
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (MCIMidiDev[wDevID].hFile == 0) {
+ WARN(midi, "can't find file='%08lx' !\n",
+ (DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ start = 1; end = 99999;
+ if (dwFlags & MCI_FROM) {
+ start = lpParms->dwFrom;
+ TRACE(midi, "MCI_FROM=%d \n", start);
+ }
+ if (dwFlags & MCI_TO) {
+ end = lpParms->dwTo;
+ TRACE(midi, "MCI_TO=%d \n", end);
+ }
#if 0
- if (dwFlags & MCI_NOTIFY) {
- TRACE(midi, "MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
- switch(fork()) {
- case -1:
- WARN(midi, "Can't 'fork' process !\n");
- break;
- case 0:
- TRACE(midi, "process started ! play in background ...\n");
- break;
- default:
- TRACE(midi, "process started ! return to caller...\n");
- return 0;
- }
+ if (dwFlags & MCI_NOTIFY) {
+ TRACE(midi, "MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
+ switch(fork()) {
+ case -1:
+ WARN(midi, "Can't 'fork' process !\n");
+ break;
+ case 0:
+ TRACE(midi, "process started ! play in background ...\n");
+ break;
+ default:
+ TRACE(midi, "process started ! return to caller...\n");
+ return 0;
}
+ }
#endif
-
- lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
-
- lpMidiHdr->lpData = (LPSTR)xmalloc(1200);
- if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
- lpMidiHdr->dwBufferLength = 1024;
- lpMidiHdr->dwUser = 0L;
- lpMidiHdr->dwFlags = 0L;
- dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
-
-/* TRACE(midi, "after MODM_PREPARE \n"); */
-
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
- while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
- TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
- &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
-
- ptr = (LPWORD)lpMidiHdr->lpData;
- for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
- if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
- *ptr = LOWORD(dwData);
- }
-/*
- count = mmioRead32(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
-*/
- TRACE(midi, "after read count = %d\n",count);
-
- if (count < 1) break;
- lpMidiHdr->dwBytesRecorded = count;
- TRACE(midi, "before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
- lpMidiHdr, lpMidiHdr->dwBytesRecorded);
- dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
- if (dwRet != MMSYSERR_NOERROR) {
- switch (dwRet) {
- case MMSYSERR_NOTENABLED:
- return MCIERR_DEVICE_NOT_READY;
-
- case MIDIERR_NODEVICE:
- return MCIERR_INVALID_DEVICE_ID;
-
- case MIDIERR_UNPREPARED:
- return MCIERR_DRIVER_INTERNAL;
-
- case MIDIERR_STILLPLAYING:
- return MCIERR_SEQ_PORT_INUSE;
-
- case MMSYSERR_INVALPARAM:
- return MCIERR_CANNOT_LOAD_DRIVER;
-
- default:
- return MCIERR_DRIVER;
- }
- }
- }
- dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
- if (lpMidiHdr->lpData != NULL) {
- free(lpMidiHdr->lpData);
- lpMidiHdr->lpData = NULL;
+
+ lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
+
+ lpMidiHdr->lpData = (LPSTR)xmalloc(1200);
+ if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
+ lpMidiHdr->dwBufferLength = 1024;
+ lpMidiHdr->dwUser = 0L;
+ lpMidiHdr->dwFlags = 0L;
+ dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+
+ /* TRACE(midi, "after MODM_PREPARE \n"); */
+
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
+ while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
+ TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
+ &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
+
+ ptr = (LPWORD)lpMidiHdr->lpData;
+ for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
+ if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
+ *ptr = LOWORD(dwData);
}
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
- if (dwFlags & MCI_NOTIFY) {
- TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
- mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
+ /*
+ count = mmioRead32(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
+ */
+ TRACE(midi, "after read count = %d\n",count);
+
+ if (count < 1) break;
+ lpMidiHdr->dwBytesRecorded = count;
+ TRACE(midi, "before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
+ lpMidiHdr, lpMidiHdr->dwBytesRecorded);
+ dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+ if (dwRet != MMSYSERR_NOERROR) {
+ switch (dwRet) {
+ case MMSYSERR_NOTENABLED:
+ return MCIERR_DEVICE_NOT_READY;
+
+ case MIDIERR_NODEVICE:
+ return MCIERR_INVALID_DEVICE_ID;
+
+ case MIDIERR_UNPREPARED:
+ return MCIERR_DRIVER_INTERNAL;
+
+ case MIDIERR_STILLPLAYING:
+ return MCIERR_SEQ_PORT_INUSE;
+
+ case MMSYSERR_INVALPARAM:
+ return MCIERR_CANNOT_LOAD_DRIVER;
+
+ default:
+ return MCIERR_DRIVER;
+ }
+ }
+ }
+ dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+ if (lpMidiHdr->lpData != NULL) {
+ free(lpMidiHdr->lpData);
+ lpMidiHdr->lpData = NULL;
+ }
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+ if (dwFlags & MCI_NOTIFY) {
+ TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
- }
- return 0;
- }
-
+ }
+ return 0;
+}
/**************************************************************************
* MIDI_mciRecord [internal]
*/
static DWORD MIDI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
{
- int start, end;
- LPMIDIHDR lpMidiHdr;
- DWORD dwRet;
-
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (MCIMidiDev[wDevID].hFile == 0) {
- WARN(midi, "can't find file='%08lx' !\n",
- (DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
- return MCIERR_FILE_NOT_FOUND;
- }
- start = 1; end = 99999;
- if (dwFlags & MCI_FROM) {
- start = lpParms->dwFrom;
- TRACE(midi, "MCI_FROM=%d \n", start);
- }
- if (dwFlags & MCI_TO) {
- end = lpParms->dwTo;
- TRACE(midi, "MCI_TO=%d \n", end);
- }
- lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
- lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
- lpMidiHdr->dwBufferLength = 1024;
- lpMidiHdr->dwUser = 0L;
- lpMidiHdr->dwFlags = 0L;
- dwRet = midMessage(wDevID, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
- TRACE(midi, "after MIDM_PREPARE \n");
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
- while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
- TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
- &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
- lpMidiHdr->dwBytesRecorded = 0;
- dwRet = midMessage(wDevID, MIDM_START, 0, 0L, 0L);
- TRACE(midi, "after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
- lpMidiHdr, lpMidiHdr->dwBytesRecorded);
- if (lpMidiHdr->dwBytesRecorded == 0) break;
- }
- TRACE(midi, "before MIDM_UNPREPARE \n");
- dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
- TRACE(midi, "after MIDM_UNPREPARE \n");
- if (lpMidiHdr->lpData != NULL) {
- free(lpMidiHdr->lpData);
- lpMidiHdr->lpData = NULL;
- }
- MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
- if (dwFlags & MCI_NOTIFY) {
- TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
- mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
+ int start, end;
+ LPMIDIHDR lpMidiHdr;
+ DWORD dwRet;
+
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (MCIMidiDev[wDevID].hFile == 0) {
+ WARN(midi, "can't find file='%08lx' !\n",
+ (DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ start = 1; end = 99999;
+ if (dwFlags & MCI_FROM) {
+ start = lpParms->dwFrom;
+ TRACE(midi, "MCI_FROM=%d \n", start);
+ }
+ if (dwFlags & MCI_TO) {
+ end = lpParms->dwTo;
+ TRACE(midi, "MCI_TO=%d \n", end);
+ }
+ lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
+ lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
+ lpMidiHdr->dwBufferLength = 1024;
+ lpMidiHdr->dwUser = 0L;
+ lpMidiHdr->dwFlags = 0L;
+ dwRet = midMessage(wDevID, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+ TRACE(midi, "after MIDM_PREPARE \n");
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
+ while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
+ TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
+ &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
+ lpMidiHdr->dwBytesRecorded = 0;
+ dwRet = midMessage(wDevID, MIDM_START, 0, 0L, 0L);
+ TRACE(midi, "after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
+ lpMidiHdr, lpMidiHdr->dwBytesRecorded);
+ if (lpMidiHdr->dwBytesRecorded == 0) break;
+ }
+ TRACE(midi, "before MIDM_UNPREPARE \n");
+ dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
+ TRACE(midi, "after MIDM_UNPREPARE \n");
+ if (lpMidiHdr->lpData != NULL) {
+ free(lpMidiHdr->lpData);
+ lpMidiHdr->lpData = NULL;
+ }
+ MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
+ if (dwFlags & MCI_NOTIFY) {
+ TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
- }
- return 0;
+ }
+ return 0;
}
-
/**************************************************************************
* MIDI_mciPause [internal]
*/
static DWORD MIDI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- return 0;
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ return 0;
}
-
/**************************************************************************
* MIDI_mciResume [internal]
*/
static DWORD MIDI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- return 0;
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ return 0;
}
-
/**************************************************************************
* MIDI_mciSet [internal]
*/
static DWORD MIDI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- TRACE(midi, "dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
- TRACE(midi, "dwAudio=%08lX\n", lpParms->dwAudio);
- if (dwFlags & MCI_SET_TIME_FORMAT) {
- switch (lpParms->dwTimeFormat) {
- case MCI_FORMAT_MILLISECONDS:
- TRACE(midi, "MCI_FORMAT_MILLISECONDS !\n");
- break;
- case MCI_FORMAT_BYTES:
- TRACE(midi, "MCI_FORMAT_BYTES !\n");
- break;
- case MCI_FORMAT_SAMPLES:
- TRACE(midi, "MCI_FORMAT_SAMPLES !\n");
- break;
- default:
- WARN(midi, "bad time format !\n");
- return MCIERR_BAD_TIME_FORMAT;
- }
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ TRACE(midi, "dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
+ TRACE(midi, "dwAudio=%08lX\n", lpParms->dwAudio);
+ if (dwFlags & MCI_SET_TIME_FORMAT) {
+ switch (lpParms->dwTimeFormat) {
+ case MCI_FORMAT_MILLISECONDS:
+ TRACE(midi, "MCI_FORMAT_MILLISECONDS !\n");
+ break;
+ case MCI_FORMAT_BYTES:
+ TRACE(midi, "MCI_FORMAT_BYTES !\n");
+ break;
+ case MCI_FORMAT_SAMPLES:
+ TRACE(midi, "MCI_FORMAT_SAMPLES !\n");
+ break;
+ default:
+ WARN(midi, "bad time format !\n");
+ return MCIERR_BAD_TIME_FORMAT;
}
- if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
- if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
- if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
- if (dwFlags & MCI_SET_AUDIO)
- TRACE(midi, "MCI_SET_AUDIO !\n");
- if (dwFlags && MCI_SET_ON) {
- TRACE(midi, "MCI_SET_ON !\n");
- if (dwFlags && MCI_SET_AUDIO_LEFT)
- TRACE(midi, "MCI_SET_AUDIO_LEFT !\n");
- if (dwFlags && MCI_SET_AUDIO_RIGHT)
- TRACE(midi, "MCI_SET_AUDIO_RIGHT !\n");
- }
- if (dwFlags & MCI_SET_OFF)
- TRACE(midi, "MCI_SET_OFF !\n");
- if (dwFlags & MCI_SEQ_SET_MASTER)
- TRACE(midi, "MCI_SEQ_SET_MASTER !\n");
- if (dwFlags & MCI_SEQ_SET_SLAVE)
- TRACE(midi, "MCI_SEQ_SET_SLAVE !\n");
- if (dwFlags & MCI_SEQ_SET_OFFSET)
- TRACE(midi, "MCI_SEQ_SET_OFFSET !\n");
- if (dwFlags & MCI_SEQ_SET_PORT)
- TRACE(midi, "MCI_SEQ_SET_PORT !\n");
- if (dwFlags & MCI_SEQ_SET_TEMPO)
- TRACE(midi, "MCI_SEQ_SET_TEMPO !\n");
- return 0;
+ }
+ if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_AUDIO)
+ TRACE(midi, "MCI_SET_AUDIO !\n");
+ if (dwFlags && MCI_SET_ON) {
+ TRACE(midi, "MCI_SET_ON !\n");
+ if (dwFlags && MCI_SET_AUDIO_LEFT)
+ TRACE(midi, "MCI_SET_AUDIO_LEFT !\n");
+ if (dwFlags && MCI_SET_AUDIO_RIGHT)
+ TRACE(midi, "MCI_SET_AUDIO_RIGHT !\n");
+ }
+ if (dwFlags & MCI_SET_OFF)
+ TRACE(midi, "MCI_SET_OFF !\n");
+ if (dwFlags & MCI_SEQ_SET_MASTER)
+ TRACE(midi, "MCI_SEQ_SET_MASTER !\n");
+ if (dwFlags & MCI_SEQ_SET_SLAVE)
+ TRACE(midi, "MCI_SEQ_SET_SLAVE !\n");
+ if (dwFlags & MCI_SEQ_SET_OFFSET)
+ TRACE(midi, "MCI_SEQ_SET_OFFSET !\n");
+ if (dwFlags & MCI_SEQ_SET_PORT)
+ TRACE(midi, "MCI_SEQ_SET_PORT !\n");
+ if (dwFlags & MCI_SEQ_SET_TEMPO)
+ TRACE(midi, "MCI_SEQ_SET_TEMPO !\n");
+ return 0;
}
-
/**************************************************************************
- * MIDI_mciStatus [internal]
+ * MIDI_mciStatus [internal]
*/
static DWORD MIDI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- if (dwFlags & MCI_STATUS_ITEM) {
- switch(lpParms->dwItem) {
- case MCI_STATUS_CURRENT_TRACK:
- lpParms->dwReturn = 1;
- break;
- case MCI_STATUS_LENGTH:
- lpParms->dwReturn = 5555;
- if (dwFlags & MCI_TRACK) {
- lpParms->dwTrack = 1;
- lpParms->dwReturn = 2222;
- }
- break;
- case MCI_STATUS_MODE:
- lpParms->dwReturn = MCI_MODE_STOP;
- break;
- case MCI_STATUS_MEDIA_PRESENT:
- TRACE(midi, "MCI_STATUS_MEDIA_PRESENT !\n");
- lpParms->dwReturn = TRUE;
- break;
- case MCI_STATUS_NUMBER_OF_TRACKS:
- lpParms->dwReturn = 1;
- break;
- case MCI_STATUS_POSITION:
- lpParms->dwReturn = 3333;
- if (dwFlags & MCI_STATUS_START)
- lpParms->dwItem = 1;
- if (dwFlags & MCI_TRACK) {
- lpParms->dwTrack = 1;
- lpParms->dwReturn = 777;
- }
- break;
- case MCI_STATUS_READY:
- TRACE(midi, "MCI_STATUS_READY !\n");
- lpParms->dwReturn = TRUE;
- break;
- case MCI_STATUS_TIME_FORMAT:
- TRACE(midi, "MCI_STATUS_TIME_FORMAT !\n");
- lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
- break;
- case MCI_SEQ_STATUS_DIVTYPE:
- TRACE(midi, "MCI_SEQ_STATUS_DIVTYPE !\n");
- lpParms->dwReturn = 0;
- break;
- case MCI_SEQ_STATUS_MASTER:
- TRACE(midi, "MCI_SEQ_STATUS_MASTER !\n");
- lpParms->dwReturn = 0;
- break;
- case MCI_SEQ_STATUS_SLAVE:
- TRACE(midi, "MCI_SEQ_STATUS_SLAVE !\n");
- lpParms->dwReturn = 0;
- break;
- case MCI_SEQ_STATUS_OFFSET:
- TRACE(midi, "MCI_SEQ_STATUS_OFFSET !\n");
- lpParms->dwReturn = 0;
- break;
- case MCI_SEQ_STATUS_PORT:
- TRACE(midi, "MCI_SEQ_STATUS_PORT !\n");
- lpParms->dwReturn = 0;
- break;
- case MCI_SEQ_STATUS_TEMPO:
- TRACE(midi, "MCI_SEQ_STATUS_TEMPO !\n");
- lpParms->dwReturn = 0;
- break;
- default:
- WARN(midi, "unknowm command %08lX !\n", lpParms->dwItem);
- return MCIERR_UNRECOGNIZED_COMMAND;
- }
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (dwFlags & MCI_STATUS_ITEM) {
+ switch(lpParms->dwItem) {
+ case MCI_STATUS_CURRENT_TRACK:
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_STATUS_LENGTH:
+ lpParms->dwReturn = 5555;
+ if (dwFlags & MCI_TRACK) {
+ lpParms->dwTrack = 1;
+ lpParms->dwReturn = 2222;
+ }
+ break;
+ case MCI_STATUS_MODE:
+ lpParms->dwReturn = MCI_MODE_STOP;
+ break;
+ case MCI_STATUS_MEDIA_PRESENT:
+ TRACE(midi, "MCI_STATUS_MEDIA_PRESENT !\n");
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_STATUS_NUMBER_OF_TRACKS:
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_STATUS_POSITION:
+ lpParms->dwReturn = 3333;
+ if (dwFlags & MCI_STATUS_START)
+ lpParms->dwItem = 1;
+ if (dwFlags & MCI_TRACK) {
+ lpParms->dwTrack = 1;
+ lpParms->dwReturn = 777;
+ }
+ break;
+ case MCI_STATUS_READY:
+ TRACE(midi, "MCI_STATUS_READY !\n");
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_STATUS_TIME_FORMAT:
+ TRACE(midi, "MCI_STATUS_TIME_FORMAT !\n");
+ lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+ break;
+ case MCI_SEQ_STATUS_DIVTYPE:
+ TRACE(midi, "MCI_SEQ_STATUS_DIVTYPE !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_SEQ_STATUS_MASTER:
+ TRACE(midi, "MCI_SEQ_STATUS_MASTER !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_SEQ_STATUS_SLAVE:
+ TRACE(midi, "MCI_SEQ_STATUS_SLAVE !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_SEQ_STATUS_OFFSET:
+ TRACE(midi, "MCI_SEQ_STATUS_OFFSET !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_SEQ_STATUS_PORT:
+ TRACE(midi, "MCI_SEQ_STATUS_PORT !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_SEQ_STATUS_TEMPO:
+ TRACE(midi, "MCI_SEQ_STATUS_TEMPO !\n");
+ lpParms->dwReturn = 0;
+ break;
+ default:
+ WARN(midi, "unknowm command %08lX !\n", lpParms->dwItem);
+ return MCIERR_UNRECOGNIZED_COMMAND;
}
- if (dwFlags & MCI_NOTIFY) {
- TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
- mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
+ }
+ if (dwFlags & MCI_NOTIFY) {
+ TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
- }
- return 0;
+ }
+ return 0;
}
/**************************************************************************
* MIDI_mciGetDevCaps [internal]
*/
static DWORD MIDI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,
- LPMCI_GETDEVCAPS_PARMS lpParms)
+ LPMCI_GETDEVCAPS_PARMS lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- if (dwFlags & MCI_GETDEVCAPS_ITEM) {
- switch(lpParms->dwItem) {
- case MCI_GETDEVCAPS_CAN_RECORD:
- lpParms->dwReturn = TRUE;
- break;
- case MCI_GETDEVCAPS_HAS_AUDIO:
- lpParms->dwReturn = TRUE;
- break;
- case MCI_GETDEVCAPS_HAS_VIDEO:
- lpParms->dwReturn = FALSE;
- break;
- case MCI_GETDEVCAPS_DEVICE_TYPE:
- lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
- break;
- case MCI_GETDEVCAPS_USES_FILES:
- lpParms->dwReturn = TRUE;
- break;
- case MCI_GETDEVCAPS_COMPOUND_DEVICE:
- lpParms->dwReturn = TRUE;
- break;
- case MCI_GETDEVCAPS_CAN_EJECT:
- lpParms->dwReturn = FALSE;
- break;
- case MCI_GETDEVCAPS_CAN_PLAY:
- lpParms->dwReturn = TRUE;
- break;
- case MCI_GETDEVCAPS_CAN_SAVE:
- lpParms->dwReturn = FALSE;
- break;
- default:
- return MCIERR_UNRECOGNIZED_COMMAND;
- }
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (dwFlags & MCI_GETDEVCAPS_ITEM) {
+ switch(lpParms->dwItem) {
+ case MCI_GETDEVCAPS_CAN_RECORD:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_HAS_AUDIO:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_HAS_VIDEO:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_DEVICE_TYPE:
+ lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
+ break;
+ case MCI_GETDEVCAPS_USES_FILES:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_CAN_EJECT:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_CAN_PLAY:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_CAN_SAVE:
+ lpParms->dwReturn = FALSE;
+ break;
+ default:
+ return MCIERR_UNRECOGNIZED_COMMAND;
}
- return 0;
+ }
+ return 0;
}
-
/**************************************************************************
* MIDI_mciInfo [internal]
*/
static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
{
- TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_INTERNAL;
- lpParms->lpstrReturn = NULL;
- switch(dwFlags) {
- case MCI_INFO_PRODUCT:
- lpParms->lpstrReturn = "Linux Sound System 0.5";
- break;
- case MCI_INFO_FILE:
- lpParms->lpstrReturn = "FileName";
- break;
- default:
- return MCIERR_UNRECOGNIZED_COMMAND;
- }
- if (lpParms->lpstrReturn != NULL)
- lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
- else
- lpParms->dwRetSize = 0;
- return 0;
+ TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ lpParms->lpstrReturn = NULL;
+ switch(dwFlags) {
+ case MCI_INFO_PRODUCT:
+ lpParms->lpstrReturn = "Linux Sound System 0.5";
+ break;
+ case MCI_INFO_FILE:
+ lpParms->lpstrReturn = "FileName";
+ break;
+ default:
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ if (lpParms->lpstrReturn != NULL)
+ lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
+ else
+ lpParms->dwRetSize = 0;
+ return 0;
}
-
/*-----------------------------------------------------------------------*/
+#ifdef HAVE_OSS
+/**************************************************************************
+ * midiOpenSeq [internal]
+ */
+static int midiOpenSeq(void)
+{
+ if (numOpenMidiSeq == 0) {
+ midiSeqFD = open(MIDI_SEQ, O_RDWR, 0);
+ if (midiSeqFD == -1) {
+ ERR(midi, "can't open '%s' ! (%d)\n", MIDI_SEQ, errno);
+ return -1;
+ }
+ if (fcntl(midiSeqFD, F_SETFL, O_NONBLOCK) < 0) {
+ WARN(midi, "can't set sequencer fd to non blocking (%d)\n", errno);
+ close(midiSeqFD);
+ midiSeqFD = -1;
+ return -1;
+ }
+ ioctl(midiSeqFD, SNDCTL_SEQ_RESET);
+ }
+ numOpenMidiSeq++;
+ return 0;
+}
+
+/**************************************************************************
+ * midiCloseSeq [internal]
+ */
+static int midiCloseSeq(void)
+{
+ if (--numOpenMidiSeq == 0) {
+ close(midiSeqFD);
+ midiSeqFD = -1;
+ }
+ return 0;
+}
+
+/* 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]
+ */
+void seqbuf_dump(void)
+{
+ if (_seqbufptr) {
+ if (write(midiSeqFD, _seqbuf, _seqbufptr) == -1) {
+ WARN(midi, "Can't write data to sequencer (%d/%d)!\n",
+ midiSeqFD, errno);
+ }
+ /* FIXME:
+ * in any case buffer is lost so that if many errors occur the buffer
+ * will not overrun
+ */
+ _seqbufptr = 0;
+ }
+}
+#endif /* HAVE_OSS */
+
+#ifdef HAVE_OSS
+
+static void midReceiveChar(WORD wDevID, unsigned char value, DWORD dwTime)
+{
+ DWORD toSend = 0;
+
+ TRACE(midi, "Adding %02xh to %d[%d]\n",
+ value, wDevID, MidiInDev[wDevID].incLen);
+
+ if (wDevID >= MAX_MIDIINDRV) {
+ WARN(midi, "bad devID\n");
+ return;
+ }
+ if (MidiInDev[wDevID].state == 0) {
+ TRACE(midi, "input not started, thrown away\n");
+ return;
+ }
+
+ if (MidiInDev[wDevID].state & 2) { /* system exclusive */
+ LPMIDIHDR ptr = MidiInDev[wDevID].lpQueueHdr;
+ WORD sbfb = FALSE;
+
+ if (ptr) {
+ ((LPSTR)(ptr->reserved))[ptr->dwBytesRecorded++] = value;
+ if (ptr->dwBytesRecorded == ptr->dwBufferLength) {
+ sbfb = TRUE;
+ }
+ }
+ if (value == 0xF7) { /* then end */
+ MidiInDev[wDevID].state &= ~2;
+ sbfb = TRUE;
+ }
+ if (sbfb && ptr != NULL) {
+ ptr = MidiInDev[wDevID].lpQueueHdr;
+ ptr->dwFlags &= ~MHDR_INQUEUE;
+ ptr->dwFlags |= MHDR_DONE;
+ MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)ptr->lpNext;
+ if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD)ptr, dwTime) != MMSYSERR_NOERROR) {
+ WARN(midi, "Couldn't notify client\n");
+ }
+ }
+ return;
+ }
+
+#define IS_CMD(_x) (((_x) & 0x80) == 0x80)
+#define IS_SYS_CMD(_x) (((_x) & 0xF0) == 0xF0)
+
+ if (!IS_CMD(value) && MidiInDev[wDevID].incLen == 0) { /* try to reuse old cmd */
+ if (IS_CMD(MidiInDev[wDevID].incPrev) && !IS_SYS_CMD(MidiInDev[wDevID].incPrev)) {
+ MidiInDev[wDevID].incoming[0] = MidiInDev[wDevID].incPrev;
+ MidiInDev[wDevID].incLen = 1;
+ TRACE(midi, "Reusing old command %02xh\n", MidiInDev[wDevID].incPrev);
+ } else {
+ FIXME(midi, "error for midi-in, should generate MIM_ERROR notification:"
+ " prev=%02Xh, incLen=%02Xh\n",
+ MidiInDev[wDevID].incPrev, MidiInDev[wDevID].incLen);
+ return;
+ }
+ }
+ MidiInDev[wDevID].incoming[(int)(MidiInDev[wDevID].incLen++)] = value;
+ if (MidiInDev[wDevID].incLen == 1 && !IS_SYS_CMD(MidiInDev[wDevID].incoming[0])) {
+ /* store new cmd, just in case */
+ MidiInDev[wDevID].incPrev = MidiInDev[wDevID].incoming[0];
+ }
+
+#undef IS_CMD(_x)
+#undef IS_SYS_CMD(_x)
+
+ switch (MidiInDev[wDevID].incoming[0] & 0xF0) {
+ case MIDI_NOTEOFF:
+ case MIDI_NOTEON:
+ case MIDI_KEY_PRESSURE:
+ case MIDI_CTL_CHANGE:
+ case MIDI_PITCH_BEND:
+ if (MidiInDev[wDevID].incLen == 3) {
+ toSend = (MidiInDev[wDevID].incoming[2] << 16) |
+ (MidiInDev[wDevID].incoming[1] << 8) |
+ (MidiInDev[wDevID].incoming[0] << 0);
+ }
+ break;
+ case MIDI_PGM_CHANGE:
+ case MIDI_CHN_PRESSURE:
+ if (MidiInDev[wDevID].incLen == 2) {
+ toSend = (MidiInDev[wDevID].incoming[1] << 8) |
+ (MidiInDev[wDevID].incoming[0] << 0);
+ }
+ break;
+ case MIDI_SYSTEM_PREFIX:
+ if (MidiInDev[wDevID].incoming[0] == 0xF0) {
+ MidiInDev[wDevID].state |= 2;
+ MidiInDev[wDevID].incLen = 0;
+ } else {
+ if (MidiInDev[wDevID].incLen == 1) {
+ toSend = (MidiInDev[wDevID].incoming[0] << 0);
+ }
+ }
+ break;
+ default:
+ WARN(midi, "This shouldn't happen (%02X)\n", MidiInDev[wDevID].incoming[0]);
+ }
+ if (toSend != 0) {
+ TRACE(midi, "Sending event %08lx\n", toSend);
+ MidiInDev[wDevID].incLen = 0;
+ dwTime -= MidiInDev[wDevID].startTime;
+ if (MIDI_NotifyClient(wDevID, MIM_DATA, toSend, dwTime) != MMSYSERR_NOERROR) {
+ WARN(midi, "Couldn't notify client\n");
+ }
+ }
+}
+
+static VOID midTimeCallback(HWND32 hwnd, UINT32 msg, UINT32 id, DWORD dwTime)
+{
+ unsigned char buffer[256];
+ int len, idx;
+
+ TRACE(midi, "(%04X, %d, %d, %lu)\n", hwnd, msg, id, dwTime);
+
+ len = read(midiSeqFD, buffer, sizeof(buffer));
+
+ if ((len % 4) != 0) {
+ WARN(midi, "bad length %d (%d)\n", len, errno);
+ return;
+ }
+
+ for (idx = 0; idx < len; ) {
+ if (buffer[idx] & 0x80) {
+ TRACE(midi,
+ "reading<8> %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ buffer[idx + 0], buffer[idx + 1],
+ buffer[idx + 2], buffer[idx + 3],
+ buffer[idx + 4], buffer[idx + 5],
+ buffer[idx + 6], buffer[idx + 7]);
+ idx += 8;
+ } else {
+ switch (buffer[idx + 0]) {
+ case SEQ_WAIT:
+ case SEQ_ECHO:
+ break;
+ case SEQ_MIDIPUTC:
+ midReceiveChar(buffer[idx + 2], buffer[idx + 1], dwTime);
+ break;
+ default:
+ TRACE(midi, "Unsupported event %d\n", buffer[idx + 0]);
+ break;
+ }
+ idx += 4;
+ }
+ }
+}
+#endif /* HAVE_OSS */
/**************************************************************************
* midGetDevCaps [internal]
*/
static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS16 lpCaps, DWORD dwSize)
{
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
- lpCaps->wMid = 0x00FF; /* Manufac ID */
- lpCaps->wPid = 0x0001; /* Product ID */
- lpCaps->vDriverVersion = 0x001; /* Product Version */
- strcpy(lpCaps->szPname, "Linux MIDIIN Driver");
-
- return MMSYSERR_NOERROR;
+ LPMIDIINCAPS16 tmplpCaps;
+
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
+
+ if (wDevID >= MIDM_NUMDEVS) {
+ return MMSYSERR_BADDEVICEID;
+ }
+ if (lpCaps == NULL) {
+ return MMSYSERR_INVALPARAM;
+ }
+
+ tmplpCaps = midiInDevices[wDevID];
+ lpCaps->wMid = tmplpCaps->wMid;
+ lpCaps->wPid = tmplpCaps->wPid;
+ lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;
+ strcpy(lpCaps->szPname, tmplpCaps->szPname);
+ if (dwSize == sizeof(MIDIINCAPS16)) {
+ /* we should run win 95, so make use of dwSupport */
+ lpCaps->dwSupport = tmplpCaps->dwSupport;
+ } else if (dwSize != sizeof(MIDIINCAPS16) - sizeof(DWORD)) {
+ TRACE(midi, "bad size for lpCaps\n");
+ return MMSYSERR_INVALPARAM;
+ }
+
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -772,46 +1032,85 @@
*/
static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
{
- int midi;
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
- if (lpDesc == NULL) {
- WARN(midi, "Invalid Parameter !\n");
- return MMSYSERR_INVALPARAM;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
+
+ if (lpDesc == NULL) {
+ WARN(midi, "Invalid Parameter !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ /* FIXME :
+ * how to check that content of lpDesc is correct ?
+ */
+ if (wDevID >= MAX_MIDIINDRV) {
+ WARN(midi,"wDevID too large (%u) !\n", wDevID);
+ return MMSYSERR_BADDEVICEID;
+ }
+ if (MidiInDev[wDevID].midiDesc != 0) {
+ WARN(midi, "device already open !\n");
+ return MMSYSERR_ALLOCATED;
+ }
+ if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) {
+ FIXME(midi, "No support for MIDI_IO_STATUS in dwFlags\n");
+ return MMSYSERR_INVALFLAG;
+ }
+
+#ifdef HAVE_OSS
+ if (midiOpenSeq() < 0) {
+ return MMSYSERR_ERROR;
+ }
+
+ if (numStartedMidiIn++ == 0) {
+ midiInTimerID = SetTimer32(0, 0, 250, midTimeCallback);
+ if (!midiInTimerID) {
+ numStartedMidiIn = 0;
+ WARN(midi, "Couldn't start timer for midi-in\n");
+ midiCloseSeq();
+ return MMSYSERR_ERROR;
}
- if (wDevID >= MAX_MIDIINDRV) {
- TRACE(midi,"MAX_MIDIINDRV reached !\n");
- return MMSYSERR_ALLOCATED;
- }
+ TRACE(midi, "Starting timer (%u) for midi-in\n", midiInTimerID);
+ }
+#else /* HAVE_OSS */
+ {
+ int midi = open(MIDI_DEV, O_WRONLY, 0);
+
MidiInDev[wDevID].unixdev = 0;
- midi = open (MIDI_DEV, O_RDONLY, 0);
if (midi == -1) {
- WARN(midi,"can't open !\n");
- return MMSYSERR_NOTENABLED;
+ WARN(midi,"can't open '%s' (%d)!\n", MIDI_DEV, errno);
+ return MMSYSERR_ALLOCATED;
}
- MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
- switch(MidiInDev[wDevID].wFlags) {
- case DCB_NULL:
- TRACE(midi,"CALLBACK_NULL !\n");
- break;
- case DCB_WINDOW:
- TRACE(midi, "CALLBACK_WINDOW !\n");
- break;
- case DCB_TASK:
- TRACE(midi, "CALLBACK_TASK !\n");
- break;
- case DCB_FUNCTION:
- TRACE(midi, "CALLBACK_FUNCTION !\n");
- break;
- }
- MidiInDev[wDevID].lpQueueHdr = NULL;
MidiInDev[wDevID].unixdev = midi;
- MidiInDev[wDevID].dwTotalPlayed = 0;
- MidiInDev[wDevID].bufsize = 0x3FFF;
- if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
- WARN(midi,"can't notify client !\n");
- return MMSYSERR_INVALPARAM;
- }
- return MMSYSERR_NOERROR;
+ }
+#endif /* HAVE_OSS */
+
+ MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+ switch(MidiInDev[wDevID].wFlags) {
+ case DCB_NULL:
+ TRACE(midi,"CALLBACK_NULL !\n");
+ break;
+ case DCB_WINDOW:
+ TRACE(midi, "CALLBACK_WINDOW !\n");
+ break;
+ case DCB_TASK:
+ TRACE(midi, "CALLBACK_TASK !\n");
+ break;
+ case DCB_FUNCTION:
+ TRACE(midi, "CALLBACK_FUNCTION (%08lX)!\n", lpDesc->dwCallback);
+ break;
+ }
+ MidiInDev[wDevID].lpQueueHdr = NULL;
+ MidiInDev[wDevID].dwTotalPlayed = 0;
+ MidiInDev[wDevID].bufsize = 0x3FFF;
+ MidiInDev[wDevID].midiDesc = lpDesc;
+ MidiInDev[wDevID].state = 0;
+#ifdef HAVE_OSS
+ MidiInDev[wDevID].incLen = 0;
+ MidiInDev[wDevID].startTime = 0;
+#endif /* HAVE_OSS */
+ if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
+ WARN(midi,"can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -819,28 +1118,76 @@
*/
static DWORD midClose(WORD wDevID)
{
- TRACE(midi, "(%04X);\n", wDevID);
- if (MidiInDev[wDevID].unixdev == 0) {
- WARN(midi,"can't close !\n");
- return MMSYSERR_NOTENABLED;
- }
- close(MidiInDev[wDevID].unixdev);
- MidiInDev[wDevID].unixdev = 0;
- MidiInDev[wDevID].bufsize = 0;
- if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
- WARN(midi,"can't notify client !\n");
- return MMSYSERR_INVALPARAM;
- }
- return MMSYSERR_NOERROR;
+ int ret = MMSYSERR_NOERROR;
+
+ TRACE(midi, "(%04X);\n", wDevID);
+
+ if (wDevID >= MAX_MIDIINDRV) {
+ WARN(midi,"wDevID too bif (%u) !\n", wDevID);
+ return MMSYSERR_BADDEVICEID;
+ }
+ if (MidiInDev[wDevID].midiDesc == 0) {
+ WARN(midi, "device not opened !\n");
+ return MMSYSERR_ERROR;
+ }
+ if (MidiInDev[wDevID].lpQueueHdr != 0) {
+ return MIDIERR_STILLPLAYING;
+ }
+
+#ifdef HAVE_OSS
+ if (midiSeqFD == -1) {
+ WARN(midi,"ooops !\n");
+ return MMSYSERR_ERROR;
+ }
+ if (--numStartedMidiIn == 0) {
+ TRACE(midi, "Stopping timer for midi-in\n");
+ if (!KillTimer32(0, midiInTimerID)) {
+ WARN(midi, "Couldn't stop timer for midi-in\n");
+ }
+ midiInTimerID = 0;
+ }
+ midiCloseSeq();
+#else /* HAVE_OSS */
+ if (MidiInDev[wDevID].unixdev == 0) {
+ WARN(midi,"ooops !\n");
+ return MMSYSERR_ERROR;
+ }
+ close(MidiInDev[wDevID].unixdev);
+ MidiInDev[wDevID].unixdev = 0;
+#endif /* HAVE_OSS */
+ MidiInDev[wDevID].bufsize = 0;
+ if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
+ WARN(midi,"can't notify client !\n");
+ ret = MMSYSERR_INVALPARAM;
+ }
+ MidiInDev[wDevID].midiDesc = 0;
+ return ret;
}
/**************************************************************************
- * midAddBuffer [internal]
+ * midAddBuffer [internal]
*/
static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
- return MMSYSERR_NOTENABLED;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+
+ if (lpMidiHdr == NULL) return MMSYSERR_INVALPARAM;
+ if (sizeof(MIDIHDR) != dwSize) return MMSYSERR_INVALPARAM;
+ if (lpMidiHdr->dwBufferLength == 0) return MMSYSERR_INVALPARAM;
+ if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
+ if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
+
+ if (MidiInDev[wDevID].lpQueueHdr == 0) {
+ MidiInDev[wDevID].lpQueueHdr = lpMidiHdr;
+ } else {
+ LPMIDIHDR ptr;
+
+ for (ptr = MidiInDev[wDevID].lpQueueHdr;
+ ptr->lpNext != 0;
+ ptr = (LPMIDIHDR)ptr->lpNext);
+ ptr->lpNext = (struct midihdr_tag*)lpMidiHdr;
+ }
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -848,8 +1195,18 @@
*/
static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
- return MMSYSERR_NOTENABLED;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+
+ if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0 ||
+ lpMidiHdr->lpData == 0 || lpMidiHdr->dwFlags != 0 ||
+ lpMidiHdr->dwBufferLength >= 0x10000ul)
+ return MMSYSERR_INVALPARAM;
+
+ lpMidiHdr->lpNext = 0;
+ lpMidiHdr->dwFlags |= MHDR_PREPARED;
+ lpMidiHdr->dwBytesRecorded = 0;
+
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -857,8 +1214,18 @@
*/
static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
- return MMSYSERR_NOTENABLED;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+
+ if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0 ||
+ lpMidiHdr->lpData == 0 || lpMidiHdr->dwBufferLength >= 0x10000ul)
+ return MMSYSERR_INVALPARAM;
+
+ if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
+ if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
+
+ lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
+
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -866,8 +1233,21 @@
*/
static DWORD midReset(WORD wDevID)
{
- TRACE(midi, "(%04X);\n", wDevID);
- return MMSYSERR_NOTENABLED;
+ DWORD dwTime = GetTickCount();
+
+ TRACE(midi, "(%04X);\n", wDevID);
+
+ while (MidiInDev[wDevID].lpQueueHdr) {
+ MidiInDev[wDevID].lpQueueHdr->dwFlags &= ~MHDR_INQUEUE;
+ MidiInDev[wDevID].lpQueueHdr->dwFlags |= MHDR_DONE;
+ if (MIDI_NotifyClient(wDevID, MIM_LONGDATA,
+ (DWORD)MidiInDev[wDevID].lpQueueHdr, dwTime) != MMSYSERR_NOERROR) {
+ WARN(midi, "Couldn't notify client\n");
+ }
+ MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)MidiInDev[wDevID].lpQueueHdr->lpNext;
+ }
+
+ return MMSYSERR_NOERROR;
}
@@ -876,88 +1256,229 @@
*/
static DWORD midStart(WORD wDevID)
{
- TRACE(midi, "(%04X);\n", wDevID);
- return MMSYSERR_NOTENABLED;
+ TRACE(midi, "(%04X);\n", wDevID);
+
+ /* FIXME : should test value of wDevID */
+
+#ifdef HAVE_OSS
+ MidiInDev[wDevID].state = 1;
+ MidiInDev[wDevID].startTime = GetTickCount();
+ return MMSYSERR_NOERROR;
+#else
+ return MMSYSERR_NOTENABLED;
+#endif /* HAVE_OSS */
}
-
/**************************************************************************
* midStop [internal]
*/
static DWORD midStop(WORD wDevID)
{
- TRACE(midi, "(%04X);\n", wDevID);
- return MMSYSERR_NOTENABLED;
+ TRACE(midi, "(%04X);\n", wDevID);
+
+ /* FIXME : should test value of wDevID */
+
+#ifdef HAVE_OSS
+ MidiInDev[wDevID].state = 0;
+ return MMSYSERR_NOERROR;
+#else /* HAVE_OSS */
+ return MMSYSERR_NOTENABLED;
+#endif /* HAVE_OSS */
}
-
/**************************************************************************
* midMessage [sample driver]
*/
DWORD WINAPI midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
- TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
- wDevID, wMsg, dwUser, dwParam1, dwParam2);
- switch(wMsg) {
- case MIDM_OPEN:
- return midOpen(wDevID,(LPMIDIOPENDESC)dwParam1, dwParam2);
- case MIDM_CLOSE:
- return midClose(wDevID);
- case MIDM_ADDBUFFER:
- return midAddBuffer(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
- case MIDM_PREPARE:
- return midPrepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
- case MIDM_UNPREPARE:
- return midUnprepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
- case MIDM_GETDEVCAPS:
- return midGetDevCaps(wDevID,(LPMIDIINCAPS16)dwParam1,dwParam2);
- case MIDM_GETNUMDEVS:
- return 0;
- case MIDM_RESET:
- return midReset(wDevID);
- case MIDM_START:
- return midStart(wDevID);
- case MIDM_STOP:
- return midStop(wDevID);
- }
- return MMSYSERR_NOTSUPPORTED;
+ TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
+ wDevID, wMsg, dwUser, dwParam1, dwParam2);
+ switch(wMsg) {
+ case MIDM_OPEN:
+ return midOpen(wDevID,(LPMIDIOPENDESC)dwParam1, dwParam2);
+ case MIDM_CLOSE:
+ return midClose(wDevID);
+ case MIDM_ADDBUFFER:
+ return midAddBuffer(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+ case MIDM_PREPARE:
+ return midPrepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+ case MIDM_UNPREPARE:
+ return midUnprepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
+ case MIDM_GETDEVCAPS:
+ return midGetDevCaps(wDevID,(LPMIDIINCAPS16)dwParam1,dwParam2);
+ case MIDM_GETNUMDEVS:
+ return MIDM_NUMDEVS;
+ case MIDM_RESET:
+ return midReset(wDevID);
+ case MIDM_START:
+ return midStart(wDevID);
+ case MIDM_STOP:
+ return midStop(wDevID);
+ default:
+ TRACE(midi, "Unsupported message\n");
+ }
+ return MMSYSERR_NOTSUPPORTED;
}
/*-----------------------------------------------------------------------*/
+#ifdef HAVE_OSS
+
+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;
+ /* controlers */
+ 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;
+
+extern unsigned char midiFMInstrumentPatches[16 * 128];
+extern unsigned char midiFMDrumsPatches [16 * 128];
+
+/**************************************************************************
+ * modFMLoad [internal]
+ */
+static int modFMLoad(int dev)
+{
+ int i;
+ struct sbi_instrument sbi;
+
+ sbi.device = dev;
+ sbi.key = FM_PATCH;
+
+ memset(sbi.operators + 16, 0, 16);
+ for (i = 0; i < 128; i++) {
+ sbi.channel = i;
+ memcpy(sbi.operators, midiFMInstrumentPatches + i * 16, 16);
+
+ if (write(midiSeqFD, (char*)&sbi, sizeof(sbi)) == -1) {
+ WARN(midi, "Couldn't write patch for instrument %d (%d)!\n", sbi.channel, errno);
+ return -1;
+ }
+ }
+ for (i = 0; i < 128; i++) {
+ sbi.channel = 128 + i;
+ memcpy(sbi.operators, midiFMDrumsPatches + i * 16, 16);
+
+ if (write(midiSeqFD, (char*)&sbi, sizeof(sbi)) == -1) {
+ WARN(midi, "Couldn't write patch for drum %d (%d)!\n", sbi.channel, errno);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**************************************************************************
+ * modFMReset [internal]
+ */
+static void modFMReset(WORD wDevID)
+{
+ sFMextra* extra = (sFMextra*)MidiOutDev[wDevID].lpExtra;
+ sVoice* voice = extra->voice;
+ sChannel* channel = extra->channel;
+ int i;
+
+ for (i = 0; i < midiOutDevices[wDevID]->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)))
+
+#endif /* HAVE_OSS */
+
/**************************************************************************
* modGetDevCaps [internal]
*/
-static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS16 lpCaps, DWORD dwSize)
+static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS16 lpCaps,
+ DWORD dwSize)
{
- LPMIDIOUTCAPS16 tmplpCaps;
-
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
- if (wDevID == (WORD) MIDI_MAPPER) {
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
+ if (wDevID == (WORD) MIDI_MAPPER) {
lpCaps->wMid = 0x00FF; /* Manufac ID */
lpCaps->wPid = 0x0001; /* Product ID */
lpCaps->vDriverVersion = 0x001; /* Product Version */
- strcpy(lpCaps->szPname, "MIDI Maper (not functional yet)");
- lpCaps->wTechnology = MOD_FMSYNTH; /* FIXME Does it make any difference ? */
- lpCaps->wVoices = 14; /* FIXME */
- lpCaps->wNotes = 14; /* FIXME */
- lpCaps->dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; /* FIXME Does it make any difference ? */
- } else {
- /* FIXME There is a way to do it so easily, but I'm too
- * sleepy to think and I want to test
-*/
- tmplpCaps = midiDevices [wDevID];
- lpCaps->wMid = tmplpCaps->wMid;
- lpCaps->wPid = tmplpCaps->wPid;
- lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;
- strcpy(lpCaps->szPname, tmplpCaps->szPname);
- lpCaps->wTechnology = tmplpCaps->wTechnology;
- lpCaps->wVoices = tmplpCaps->wVoices;
- lpCaps->wNotes = tmplpCaps->wNotes;
- lpCaps->dwSupport = tmplpCaps->dwSupport;
- }
- return MMSYSERR_NOERROR;
+ strcpy(lpCaps->szPname, "MIDI Mapper (not functional yet)");
+ /* FIXME Does it make any difference ? */
+ lpCaps->wTechnology = MOD_FMSYNTH;
+ lpCaps->wVoices = 14; /* FIXME */
+ lpCaps->wNotes = 14; /* FIXME */
+ /* FIXME Does it make any difference ? */
+ lpCaps->dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
+ } else {
+ LPMIDIOUTCAPS16 tmplpCaps;
+
+ if (wDevID >= MODM_NUMDEVS) {
+ TRACE(midi, "MAX_MIDIOUTDRV reached !\n");
+ return MMSYSERR_BADDEVICEID;
+ }
+ /* FIXME There is a way to do it so easily, but I'm too
+ * sleepy to think and I want to test
+ */
+
+ tmplpCaps = midiOutDevices[wDevID];
+ lpCaps->wMid = tmplpCaps->wMid;
+ lpCaps->wPid = tmplpCaps->wPid;
+ lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;
+ strcpy(lpCaps->szPname, tmplpCaps->szPname);
+ lpCaps->wTechnology = tmplpCaps->wTechnology;
+ lpCaps->wVoices = tmplpCaps->wVoices;
+ lpCaps->wNotes = tmplpCaps->wNotes;
+ lpCaps->dwSupport = tmplpCaps->dwSupport;
+ }
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -965,48 +1486,101 @@
*/
static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
{
- int midi;
-
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
- if (lpDesc == NULL) {
- WARN(midi, "Invalid Parameter !\n");
- return MMSYSERR_INVALPARAM;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
+ if (lpDesc == NULL) {
+ WARN(midi, "Invalid Parameter !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ if (wDevID >= MAX_MIDIOUTDRV) {
+ TRACE(midi,"MAX_MIDIOUTDRV reached !\n");
+ return MMSYSERR_BADDEVICEID;
+ }
+ if (MidiOutDev[wDevID].midiDesc != 0) {
+ WARN(midi, "device already open !\n");
+ return MMSYSERR_ALLOCATED;
+ }
+ if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) {
+ WARN(midi, "bad dwFlags\n");
+ return MMSYSERR_INVALFLAG;
+ }
+
+#ifdef HAVE_OSS
+ MidiOutDev[wDevID].lpExtra = 0;
+
+ switch (midiOutDevices[wDevID]->wTechnology) {
+ case MOD_FMSYNTH:
+ {
+ void* extra = xmalloc(sizeof(struct sFMextra) +
+ sizeof(struct sVoice) *
+ (midiOutDevices[wDevID]->wVoices - 1));
+
+ if (extra == 0) {
+ WARN(midi, "can't alloc extra data !\n");
+ return MMSYSERR_NOMEM;
+ }
+ MidiOutDev[wDevID].lpExtra = extra;
+ if (midiOpenSeq() < 0) {
+ MidiOutDev[wDevID].lpExtra = 0;
+ free(extra);
+ return MMSYSERR_ERROR;
+ }
+ if (modFMLoad(wDevID) < 0) {
+ midiCloseSeq();
+ MidiOutDev[wDevID].lpExtra = 0;
+ free(extra);
+ return MMSYSERR_ERROR;
+ }
+ modFMReset(wDevID);
}
- if (wDevID>= MAX_MIDIOUTDRV) {
- TRACE(midi,"MAX_MIDIOUTDRV reached !\n");
- return MMSYSERR_ALLOCATED; /* FIXME isn't MMSYSERR_BADDEVICEID the right answer ? */
+ break;
+ case MOD_MIDIPORT:
+ if (midiOpenSeq() < 0) {
+ return MMSYSERR_ALLOCATED;
}
+ break;
+ default:
+ WARN(midi,"Technology not supported (yet) %d !\n",
+ midiOutDevices[wDevID]->wTechnology);
+ return MMSYSERR_NOTENABLED;
+ }
+#else /* HAVE_OSS */
+ {
+ int midi = open (MIDI_DEV, O_WRONLY, 0);
MidiOutDev[wDevID].unixdev = 0;
- midi = open (MIDI_DEV, O_WRONLY, 0);
if (midi == -1) {
- WARN(midi, "can't open !\n");
- return MMSYSERR_NOTENABLED;
+ WARN(midi, "can't open !\n");
+ return MMSYSERR_ALLOCATED;
}
- MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
- switch(MidiOutDev[wDevID].wFlags) {
- case DCB_NULL:
- TRACE(midi,"CALLBACK_NULL !\n");
- break;
- case DCB_WINDOW:
- TRACE(midi, "CALLBACK_WINDOW !\n");
- break;
- case DCB_TASK:
- TRACE(midi, "CALLBACK_TASK !\n");
- break;
- case DCB_FUNCTION:
- TRACE(midi, "CALLBACK_FUNCTION !\n");
- break;
- }
- MidiOutDev[wDevID].lpQueueHdr = NULL;
MidiOutDev[wDevID].unixdev = midi;
- MidiOutDev[wDevID].dwTotalPlayed = 0;
- MidiOutDev[wDevID].bufsize = 0x3FFF;
- if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
- WARN(midi,"can't notify client !\n");
- return MMSYSERR_INVALPARAM;
- }
- TRACE(midi, "Succesful unixdev=%d !\n", midi);
- return MMSYSERR_NOERROR;
+ }
+#endif /* HAVE_OSS */
+
+ MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+ switch(MidiOutDev[wDevID].wFlags) {
+ case DCB_NULL:
+ TRACE(midi,"CALLBACK_NULL !\n");
+ break;
+ case DCB_WINDOW:
+ TRACE(midi, "CALLBACK_WINDOW !\n");
+ break;
+ case DCB_TASK:
+ TRACE(midi, "CALLBACK_TASK !\n");
+ break;
+ case DCB_FUNCTION:
+ TRACE(midi, "CALLBACK_FUNCTION !\n");
+ break;
+ }
+ MidiOutDev[wDevID].lpQueueHdr = NULL;
+ MidiOutDev[wDevID].dwTotalPlayed = 0;
+ MidiOutDev[wDevID].bufsize = 0x3FFF;
+ MidiOutDev[wDevID].midiDesc = lpDesc;
+
+ if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
+ WARN(midi,"can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ TRACE(midi, "Succesful !\n");
+ return MMSYSERR_NOERROR;
}
@@ -1015,19 +1589,54 @@
*/
static DWORD modClose(WORD wDevID)
{
- TRACE(midi, "(%04X);\n", wDevID);
- if (MidiOutDev[wDevID].unixdev == 0) {
- WARN(midi,"can't close !\n");
- return MMSYSERR_NOTENABLED;
- }
- close(MidiOutDev[wDevID].unixdev);
- MidiOutDev[wDevID].unixdev = 0;
- MidiOutDev[wDevID].bufsize = 0;
- if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
- WARN(midi,"can't notify client !\n");
- return MMSYSERR_INVALPARAM;
- }
- return MMSYSERR_NOERROR;
+ int ret = MMSYSERR_NOERROR;
+
+ TRACE(midi, "(%04X);\n", wDevID);
+
+ if (MidiOutDev[wDevID].midiDesc == 0) {
+ WARN(midi, "device not opened !\n");
+ return MMSYSERR_ERROR;
+ }
+ /* FIXME: should test that no pending buffer is still in the queue for
+ * playing */
+
+#ifdef HAVE_OSS
+ if (midiSeqFD == -1) {
+ WARN(midi,"can't close !\n");
+ return MMSYSERR_ERROR;
+ }
+
+ switch (midiOutDevices[wDevID]->wTechnology) {
+ case MOD_FMSYNTH:
+ case MOD_MIDIPORT:
+ midiCloseSeq();
+ break;
+ default:
+ WARN(midi,"Technology not supported (yet) %d !\n",
+ midiOutDevices[wDevID]->wTechnology);
+ return MMSYSERR_NOTENABLED;
+ }
+
+ if (MidiOutDev[wDevID].lpExtra != 0) {
+ free(MidiOutDev[wDevID].lpExtra);
+ MidiOutDev[wDevID].lpExtra = 0;
+ }
+#else
+ if (MidiOutDev[wDevID].unixdev == 0) {
+ WARN(midi,"can't close !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(MidiOutDev[wDevID].unixdev);
+ MidiOutDev[wDevID].unixdev = 0;
+#endif /* HAVE_OSS */
+
+ MidiOutDev[wDevID].bufsize = 0;
+ if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
+ WARN(midi,"can't notify client !\n");
+ ret = MMSYSERR_INVALPARAM;
+ }
+ MidiOutDev[wDevID].midiDesc = 0;
+ return ret;
}
/**************************************************************************
@@ -1035,19 +1644,298 @@
*/
static DWORD modData(WORD wDevID, DWORD dwParam)
{
- WORD event;
-
- TRACE(midi, "(%04X, %08lX);\n", wDevID, dwParam);
- if (MidiOutDev[wDevID].unixdev == 0) {
- WARN(midi,"can't play !\n");
+ WORD evt = LOBYTE(LOWORD(dwParam));
+ WORD d1 = HIBYTE(LOWORD(dwParam));
+ WORD d2 = LOBYTE(HIWORD(dwParam));
+
+ TRACE(midi, "(%04X, %08lX);\n", wDevID, dwParam);
+
+#ifdef HAVE_OSS
+ if (midiSeqFD == -1) {
+ WARN(midi,"can't play !\n");
+ return MIDIERR_NODEVICE;
+ }
+ switch (midiOutDevices[wDevID]->wTechnology) {
+ case MOD_FMSYNTH:
+ /* FIXME:
+ * - chorus depth controller is not used
+ */
+ {
+ sFMextra* extra = (sFMextra*)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 < midiOutDevices[wDevID]->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 < midiOutDevices[wDevID]->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 < midiOutDevices[wDevID]->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(midi,
+ "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 < midiOutDevices[wDevID]->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 < midiOutDevices[wDevID]->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++) {
+ 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 < midiOutDevices[wDevID]->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 < midiOutDevices[wDevID]->wVoices; i++) {
+ if (voice[i].channel == chn) {
+ SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);
+ }
+ }
+ break;
+ default:
+ TRACE(midi, "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 */
+ for (i = 0; i < midiOutDevices[wDevID]->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, 0);
+ }
+ }
+ break;
+ case 0x7B: /* all notes off */
+ for (i = 0; i < midiOutDevices[wDevID]->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, 0);
+ }
+ }
+ break;
+ default:
+ TRACE(midi, "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 < midiOutDevices[wDevID]->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 < midiOutDevices[wDevID]->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 */
+ modFMReset(wDevID);
+ break;
+ default:
+ WARN(midi,
+ "Unsupported (yet) system event %02x\n",
+ evt & 0x0F);
+ }
+ break;
+ default:
+ WARN(midi, "Internal error, shouldn't happen\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ }
+ break;
+ case MOD_MIDIPORT:
+ {
+ int dev = wDevID - MODM_NUMFMSYNTHDEVS;
+ if (dev < 0) {
+ WARN(midi, "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 0x01: /* Undefined */
+ 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 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;
+ }
}
- event = LOWORD(dwParam);
- if (write (MidiOutDev[wDevID].unixdev,
- &event, sizeof(WORD)) != sizeof(WORD)) {
- WARN(midi, "error writting unixdev !\n");
- }
+ break;
+ default:
+ WARN(midi, "Technology not supported (yet) %d !\n",
+ midiOutDevices[wDevID]->wTechnology);
return MMSYSERR_NOTENABLED;
+ }
+
+ SEQ_DUMPBUF();
+ TRACE(midi, "done\n");
+#else
+ if (MidiOutDev[wDevID].unixdev == 0) {
+ WARN(midi,"can't play !\n");
+ return MIDIERR_NODEVICE;
+ }
+ {
+ WORD event = LOWORD(dwParam);
+ if (write (MidiOutDev[wDevID].unixdev,
+ &event, sizeof(event)) != sizeof(WORD)) {
+ WARN(midi, "error writting unixdev !\n");
+ }
+ }
+#endif /* HAVE_OSS */
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -1055,51 +1943,96 @@
*/
static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
- int count;
- LPWORD ptr;
- int en;
-
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
- if (MidiOutDev[wDevID].unixdev == 0) {
- WARN(midi,"can't play !\n");
- return MIDIERR_NODEVICE;
- }
- if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
- if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
- if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
- lpMidiHdr->dwFlags &= ~MHDR_DONE;
- lpMidiHdr->dwFlags |= MHDR_INQUEUE;
- TRACE(midi, "dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
- TRACE(midi, " %02X %02X %02X %02X\n",
- lpMidiHdr->lpData[0], lpMidiHdr->lpData[1],
- lpMidiHdr->lpData[2], lpMidiHdr->lpData[3]);
-/*
- count = write (MidiOutDev[wDevID].unixdev,
- lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
-*/
- ptr = (LPWORD)lpMidiHdr->lpData;
- for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
- if (write (MidiOutDev[wDevID].unixdev, ptr,
- sizeof(WORD)) != sizeof(WORD)) break;
- ptr++;
+ int count;
+
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+
+#ifdef HAVE_OSS
+ if (midiSeqFD == -1) {
+ WARN(midi,"can't play !\n");
+ return MIDIERR_NODEVICE;
+ }
+#else /* HAVE_OSS */
+ if (MidiOutDev[wDevID].unixdev == 0) {
+ WARN(midi,"can't play !\n");
+ return MIDIERR_NODEVICE;
+ }
+#endif /* HAVE_OSS */
+
+ if (lpMidiHdr->lpData == NULL)
+ return MIDIERR_UNPREPARED;
+ if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
+ return MIDIERR_UNPREPARED;
+ if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
+ return MIDIERR_STILLPLAYING;
+ lpMidiHdr->dwFlags &= ~MHDR_DONE;
+ lpMidiHdr->dwFlags |= MHDR_INQUEUE;
+ TRACE(midi, "dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
+ TRACE(midi, " %02X %02X %02X %02X\n",
+ ((LPBYTE)(lpMidiHdr->reserved))[0],
+ ((LPBYTE)(lpMidiHdr->reserved))[1],
+ ((LPBYTE)(lpMidiHdr->reserved))[2],
+ ((LPBYTE)(lpMidiHdr->reserved))[3]);
+#ifdef HAVE_OSS
+ switch (midiOutDevices[wDevID]->wTechnology) {
+ case MOD_FMSYNTH:
+ /* FIXME: I don't think there is much to do here */
+ break;
+ case MOD_MIDIPORT:
+ if (((LPBYTE)lpMidiHdr->reserved)[0] != 0xF0) {
+ /* Send end of System Exclusive */
+ SEQ_MIDIOUT(wDevID - MODM_NUMFMSYNTHDEVS, 0xF0);
+ TRACE(midi, "Adding missing 0xF0 marker at the begining of "
+ "system exclusive byte stream\n");
}
-
+ for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
+ SEQ_MIDIOUT(wDevID - MODM_NUMFMSYNTHDEVS,
+ ((LPBYTE)lpMidiHdr->reserved)[count]);
+ }
+ if (((LPBYTE)lpMidiHdr->reserved)[count - 1] != 0xF7) {
+ /* Send end of System Exclusive */
+ SEQ_MIDIOUT(wDevID - MODM_NUMFMSYNTHDEVS, 0xF7);
+ TRACE(midi, "Adding missing 0xF7 marker at the end of "
+ "system exclusive byte stream\n");
+ }
+ SEQ_DUMPBUF();
+ break;
+ default:
+ WARN(midi, "Technology not supported (yet) %d !\n",
+ midiOutDevices[wDevID]->wTechnology);
+ return MMSYSERR_NOTENABLED;
+ }
+#else /* HAVE_OSS */
+ {
+ LPWORD ptr = (LPWORD)lpMidiHdr->reserved;
+ int en;
+
+ for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
+ if (write(MidiOutDev[wDevID].unixdev,
+ ptr, sizeof(WORD)) != sizeof(WORD))
+ break;
+ ptr++;
+ }
+
en = errno;
TRACE(midi, "after write count = %d\n",count);
if (count != lpMidiHdr->dwBytesRecorded) {
- WARN(midi, "error writting unixdev #%d ! (%d != %ld)\n",
- MidiOutDev[wDevID].unixdev, count,
- lpMidiHdr->dwBytesRecorded);
- TRACE(midi, "\terrno = %d error = %s\n",en,strerror(en));
- return MMSYSERR_NOTENABLED;
+ WARN(midi, "error writting unixdev #%d ! (%d != %ld)\n",
+ MidiOutDev[wDevID].unixdev, count,
+ lpMidiHdr->dwBytesRecorded);
+ TRACE(midi, "\terrno = %d error = %s\n",en,strerror(en));
+ return MMSYSERR_NOTENABLED;
}
- lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
- lpMidiHdr->dwFlags |= MHDR_DONE;
- if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
- WARN(midi,"can't notify client !\n");
- return MMSYSERR_INVALPARAM;
- }
- return MMSYSERR_NOERROR;
+ }
+#endif /* HAVE_OSS */
+
+ lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
+ lpMidiHdr->dwFlags |= MHDR_DONE;
+ if (MIDI_NotifyClient(wDevID, MOM_DONE, (DWORD)lpMidiHdr, 0L) != MMSYSERR_NOERROR) {
+ WARN(midi,"can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -1107,21 +2040,28 @@
*/
static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
- if (MidiOutDev[wDevID].unixdev == 0) {
- WARN(midi,"can't prepare !\n");
- return MMSYSERR_NOTENABLED;
- }
- if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
- TRACE(midi,"already prepare !\n");
- return MMSYSERR_NOTENABLED;
- }
- MidiOutDev[wDevID].dwTotalPlayed = 0;
- MidiOutDev[wDevID].lpQueueHdr = PTR_SEG_TO_LIN(lpMidiHdr);
- if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
- lpMidiHdr->dwFlags |= MHDR_PREPARED;
- lpMidiHdr->dwFlags &= ~MHDR_DONE;
- return MMSYSERR_NOERROR;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+
+#ifdef HAVE_OSS
+ if (midiSeqFD == -1) {
+ WARN(midi,"can't prepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+#else /* HAVE_OSS */
+ if (MidiOutDev[wDevID].unixdev == 0) {
+ WARN(midi,"can't prepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+#endif /* HAVE_OSS */
+ if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0 ||
+ lpMidiHdr->lpData == 0 || lpMidiHdr->dwFlags != 0 ||
+ lpMidiHdr->dwBufferLength >= 0x10000ul)
+ return MMSYSERR_INVALPARAM;
+
+ lpMidiHdr->lpNext = 0;
+ lpMidiHdr->dwFlags |= MHDR_PREPARED;
+ lpMidiHdr->dwFlags &= ~MHDR_DONE;
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -1129,12 +2069,24 @@
*/
static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
- TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
- if (MidiOutDev[wDevID].unixdev == 0) {
- WARN(midi,"can't unprepare !\n");
- return MMSYSERR_NOTENABLED;
- }
- return MMSYSERR_NOERROR;
+ TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
+#ifdef HAVE_OSS
+ if (midiSeqFD == -1) {
+ WARN(midi,"can't unprepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+#else /* HAVE_OSS */
+ if (MidiOutDev[wDevID].unixdev == 0) {
+ WARN(midi,"can't unprepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+#endif /* HAVE_OSS */
+ if (dwSize != sizeof(MIDIHDR) || lpMidiHdr == 0)
+ return MMSYSERR_INVALPARAM;
+ if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
+ return MIDIERR_STILLPLAYING;
+ lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -1142,102 +2094,106 @@
*/
static DWORD modReset(WORD wDevID)
{
- TRACE(midi, "(%04X);\n", wDevID);
- return MMSYSERR_NOTENABLED;
+ TRACE(midi, "(%04X);\n", wDevID);
+ /* FIXME: this function should :
+ * turn off every note, remove sustain on all channels
+ * remove any pending buffers
+ */
+ return MMSYSERR_NOTENABLED;
}
-
/**************************************************************************
* modMessage [sample driver]
*/
DWORD WINAPI modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
- TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
- wDevID, wMsg, dwUser, dwParam1, dwParam2);
- switch(wMsg) {
- case MODM_OPEN:
- return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
- case MODM_CLOSE:
- return modClose(wDevID);
- case MODM_DATA:
- return modData(wDevID, dwParam1);
- case MODM_LONGDATA:
- return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
- case MODM_PREPARE:
- return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
- case MODM_UNPREPARE:
- return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
- case MODM_GETDEVCAPS:
- return modGetDevCaps(wDevID,(LPMIDIOUTCAPS16)dwParam1,dwParam2);
- case MODM_GETNUMDEVS:
- return MODM_NUMDEVS;
- case MODM_GETVOLUME:
- return 0;
- case MODM_SETVOLUME:
- return 0;
- case MODM_RESET:
- return modReset(wDevID);
- }
- return MMSYSERR_NOTSUPPORTED;
+ TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
+ wDevID, wMsg, dwUser, dwParam1, dwParam2);
+ switch(wMsg) {
+ case MODM_OPEN:
+ return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
+ case MODM_CLOSE:
+ return modClose(wDevID);
+ case MODM_DATA:
+ return modData(wDevID, dwParam1);
+ case MODM_LONGDATA:
+ return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+ case MODM_PREPARE:
+ return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+ case MODM_UNPREPARE:
+ return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+ case MODM_GETDEVCAPS:
+ return modGetDevCaps(wDevID,(LPMIDIOUTCAPS16)dwParam1,dwParam2);
+ case MODM_GETNUMDEVS:
+ return MODM_NUMDEVS;
+ case MODM_GETVOLUME:
+ return 0;
+ case MODM_SETVOLUME:
+ return 0;
+ case MODM_RESET:
+ return modReset(wDevID);
+ default:
+ TRACE(midi, "Unsupported message\n");
+ }
+ return MMSYSERR_NOTSUPPORTED;
}
-
/**************************************************************************
* MIDI_DriverProc [sample driver]
*/
LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
- switch(wMsg) {
- case DRV_LOAD:
- return 1;
- case DRV_FREE:
- return 1;
- case DRV_OPEN:
- return 1;
- case DRV_CLOSE:
- return 1;
- case DRV_ENABLE:
- return 1;
- case DRV_DISABLE:
- return 1;
- case DRV_QUERYCONFIGURE:
- return 1;
- case DRV_CONFIGURE:
- MessageBox16(0, "Sample Midi Linux Driver !",
- "MMLinux Driver", MB_OK);
- return 1;
- case DRV_INSTALL:
- return DRVCNF_RESTART;
- case DRV_REMOVE:
- return DRVCNF_RESTART;
- case MCI_OPEN_DRIVER:
- case MCI_OPEN:
- return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
- case MCI_CLOSE_DRIVER:
- case MCI_CLOSE:
- return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_PLAY:
- return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_RECORD:
- return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_STOP:
- return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_SET:
- return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_PAUSE:
- return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_RESUME:
- return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_STATUS:
- return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_GETDEVCAPS:
- return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
- case MCI_INFO:
- return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
- default:
- return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
- }
+ switch(wMsg) {
+ case DRV_LOAD:
+ return 1;
+ case DRV_FREE:
+ return 1;
+ case DRV_OPEN:
+ return 1;
+ case DRV_CLOSE:
+ return 1;
+ case DRV_ENABLE:
+ return 1;
+ case DRV_DISABLE:
+ return 1;
+ case DRV_QUERYCONFIGURE:
+ return 1;
+ case DRV_CONFIGURE:
+ MessageBox16(0, "Sample Midi Linux Driver !",
+ "MMLinux Driver", MB_OK);
+ return 1;
+ case DRV_INSTALL:
+ return DRVCNF_RESTART;
+ case DRV_REMOVE:
+ return DRVCNF_RESTART;
+ case MCI_OPEN_DRIVER:
+ case MCI_OPEN:
+ return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_CLOSE_DRIVER:
+ case MCI_CLOSE:
+ return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_PLAY:
+ return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_RECORD:
+ return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_STOP:
+ return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_SET:
+ return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_PAUSE:
+ return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_RESUME:
+ return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_STATUS:
+ return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_GETDEVCAPS:
+ return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
+ case MCI_INFO:
+ return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
+ default:
+ return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+ }
}
/*-----------------------------------------------------------------------*/