|  |  | 
|  | This file contains information about the implementation of the | 
|  | multimedia layer of WINE. The libraries consist of MMSYSTEM.DLL | 
|  | (win16), WINMM.DLL (win32) and some (abstracted, not Windows | 
|  | compatible) low level drivers. | 
|  |  | 
|  | The implementation can be found in the dlls/winmm/ sub directory. | 
|  |  | 
|  | 0. Overview | 
|  | =========== | 
|  |  | 
|  | The multimedia stuff is split into 3 layers. The low level (device | 
|  | drivers), mid level (MCI commands) and high level abstraction layers. | 
|  |  | 
|  | The low level may depend on current hardware and OS services (like | 
|  | OSS). Mid level (MCI) and high level must be written independently | 
|  | from the hardware and OS services. | 
|  | There are two specific low level drivers call mappers (for wave and | 
|  | +midi) whose role is to : | 
|  | * help choosing one low level driver between many | 
|  | * add the possibility to convert stream (ie ADPCM => PCM) | 
|  | * add the possibility to filter a stream (adding echo, equalizer...) | 
|  |  | 
|  | All of those components are defined as DLLs (one by one) and are | 
|  | candidate for dllglue migration. | 
|  |  | 
|  | 1. Low level layers | 
|  | =================== | 
|  |  | 
|  | Please note that native low level drivers are not currently supported | 
|  | in WINE, because they either access hardware components or require | 
|  | VxDs to be loaded; WINE does not correctly supports those two so far. | 
|  |  | 
|  | The following low level layers are implemented: | 
|  |  | 
|  | 1.1 (Wave form) Audio | 
|  | --------------------- | 
|  |  | 
|  | MMSYSTEM and WINMM call the real low level audio driver using the | 
|  | wodMessage/widMessage which handles the different requests. | 
|  |  | 
|  | 1.1.1 OSS implementation | 
|  |  | 
|  | The low level audio driver is currently only implemented for the | 
|  | OpenSoundSystem (OSS) as supplied in the Linux and FreeBSD kernels by | 
|  | [1]4Front Technologies. The presence of this driver is checked by | 
|  | configure (depends on the <sys/soundcard.h> file). Source code resides | 
|  | in dlls/winmm/wineoss/audio.c, | 
|  |  | 
|  | The implementation contains all features commonly used, but has | 
|  | several problems (see TODO list). | 
|  |  | 
|  | TODO: | 
|  | * add asynchronous reads [recording] (must use threads) as done for | 
|  | writes [playing] | 
|  | * verify all functions for correctness | 
|  | * looping of WaveHdr will fail | 
|  | * share access to /dev/dsp with dsound interface (either on a | 
|  | descriptor basis, or using a virtual mixer between different wave | 
|  | inputs. EsounD provides this type of capability). | 
|  |  | 
|  | 1.1.2 Other sub systems | 
|  |  | 
|  | None are available. Could think of Sun Audio, remote audio systems | 
|  | (using X extensions, ...), ALSA, EsounD | 
|  |  | 
|  | 1.2 MIDI | 
|  | -------- | 
|  |  | 
|  | MMSYSTEM and WINMM call the low level driver functions using the | 
|  | midMessage and the modMessage functions. | 
|  |  | 
|  | 1.2.1 OSS driver | 
|  |  | 
|  | The low level audio driver is currently only implemented for the | 
|  | OpenSoundSystem (OSS) as supplied in the Linux and FreeBSD kernels by | 
|  | [1]4Front Technologies . The presence of this driver is checked by | 
|  | configure (depends on the <sys/soundcard.h> file, and also some | 
|  | specific defines because MIDI is not supported on all OSes by OSS). | 
|  | Source code resides in dlls/winmm/wineoss/midi.c | 
|  |  | 
|  | Both Midi in and Midi out are provided. The type of MIDI devices | 
|  | supported is external MIDI port (requires an MIDI capable device - | 
|  | keyboard...) and OPL/2 synthesis (the OPL/2 patches for all | 
|  | instruments are in midiPatch.c). | 
|  |  | 
|  | TODO: | 
|  | * use better instrument definition for OPL/2 (midiPatch.c) or use | 
|  | existing instrument definition (from playmidi or kmid) with a | 
|  | .winerc option | 
|  | * have a look at OPL/3 ? | 
|  | * implement asynchronous playback of MidiHdr | 
|  | * implement STREAM'ed MidiHdr (question: how shall we share the code | 
|  | between the midiStream functions in MMSYSTEM/WINMM and the code | 
|  | for the low level driver) | 
|  | * use a more accurate read mechanism than the one of snooping on | 
|  | timers (like select on fd) | 
|  |  | 
|  | 1.2.2 Other sub systems | 
|  |  | 
|  | Could support other midi implementation for other sub systems (any | 
|  | idea here ?) | 
|  |  | 
|  | Could also implement a software synthesizer, either inside Wine or | 
|  | using using MIDI loop back devices in an external program (like | 
|  | timidity). The only trouble is that timidity is GPL'ed... | 
|  |  | 
|  | 1.3 Mixer | 
|  | --------- | 
|  |  | 
|  | MMSYSTEM and WINMM call the low level driver functions using the | 
|  | mixMessage function. | 
|  |  | 
|  | 1.3.1 OSS implementation | 
|  |  | 
|  | The current implementation uses the OpenSoundSystem mixer, and resides | 
|  | in dlls/winmm/wineoss/mixer.c | 
|  |  | 
|  | TODO: | 
|  | * implement notification mechanism when state of mixer's controls | 
|  | change | 
|  |  | 
|  | 1.3.2 Other sub systems | 
|  |  | 
|  | TODO: | 
|  | * implement mixing low level drivers for other mixers (ALSA...) | 
|  |  | 
|  | 1.4 AUX | 
|  | ------- | 
|  |  | 
|  | The AUX low level driver is the predecessor of the mixer driver | 
|  | (introduced in Win 95). | 
|  |  | 
|  | 1.4.1 OSS driver | 
|  |  | 
|  | The implementation uses the OSS mixer API, and is incomplete. | 
|  |  | 
|  | TODO: | 
|  | * verify the implementation | 
|  | * check with what is done in mixer | 
|  | * open question: shall we implement it on top of the low level mixer | 
|  | functions ? | 
|  |  | 
|  | 1.5 Joystick | 
|  | ------------ | 
|  |  | 
|  | The API consists of the joy* functions found in dlls/winmm/joystick.c. | 
|  | The implementation currently uses the Linux joystick device driver | 
|  | API. It is lacking support for enhanced joysticks and has not been | 
|  | extensively tested. | 
|  |  | 
|  | TODO: | 
|  | * better support of enhanced joysticks | 
|  | * support more joystick drivers (like the XInput extension) | 
|  | * should make joystick a separate DLL (impact also on | 
|  | WINMM/MMSYSTEM), or a real low level driver, as it is on Windows | 
|  |  | 
|  |  | 
|  | 1.6 Wave mapper (msacm.drv) | 
|  | --------------------------- | 
|  |  | 
|  | The Wave mapper device allows to load on-demand codecs in order to | 
|  | perform software conversion for the types the actual low level driver | 
|  | (hardware). Those codecs are provided through the standard ACM | 
|  | drivers. | 
|  |  | 
|  |  | 
|  | 1.6.1 Build-in | 
|  |  | 
|  | A first working implementation for wave out as been provided (wave in | 
|  | exists, but doesn't allow conversion). | 
|  | Wave mapper driver implementation can be found in dlls/winmm/wavemap/ | 
|  | directory. This driver heavily relies on MSACM and MSACM32 DLLs which | 
|  | can be found in dlls/msacm and dlls/msacm32. Those DLLs load ACM | 
|  | drivers which provide the conversion to PCM format (which is normally | 
|  | supported by low level drivers). ADPCM, MP3... fit into the category | 
|  | of non PCM formats. | 
|  |  | 
|  | There is currently no builtin ACM driver in Wine, so you must use | 
|  | native ones if you're looking for non PCM playback. | 
|  |  | 
|  | In order to use native ACM drivers to play non PCM files, you must use | 
|  | -dll msacm,msacm32,msacm.drv=b. Note that this code is not complete | 
|  | yet, and may cause problems. sndrec32 and mplayer from Win95 appear to | 
|  | work reasonably well though. | 
|  |  | 
|  | TODO: | 
|  | * do wave in | 
|  | * check for correctness and robustness | 
|  |  | 
|  | 1.6.2 Native | 
|  |  | 
|  | Seems to work quite ok (using of course native MSACM/MSACM32 DLLs) | 
|  | Some other testings report some issues while reading back the registry | 
|  | settings. | 
|  |  | 
|  | 1.7 MIDI mapper | 
|  | --------------- | 
|  |  | 
|  | Midi mapper allows to map each one of 16 MIDI channels to a specific | 
|  | instrument on an installed sound card. This allows for example to | 
|  | support different MIDI instrument definition (XM, GM...). It also | 
|  | permits to output on a per channel basis to different MIDI renderers. | 
|  |  | 
|  |  | 
|  | 1.7.1 Built-in | 
|  |  | 
|  | A builtin MIDI mapper can be found in dlls/winmm/midimap. It only | 
|  | provides the pickup of an existing MIDI low level driver for playback. | 
|  |  | 
|  | TODO: | 
|  | * implement the Midi mapper features (channel / instrument on the | 
|  | fly modification) | 
|  |  | 
|  | 1.7.2 Native | 
|  |  | 
|  | Currently, the native midimapper i'm using is not working (mainly | 
|  | because it reads low level drivers configuration from registry). | 
|  |  | 
|  | TODO: | 
|  | * let native midimapper driver load | 
|  |  | 
|  | 2. Mid level drivers (MCI) | 
|  | ========================== | 
|  |  | 
|  | The mid level drivers are represented by some common API functions, | 
|  | mostly mciSendCommand and mciSendString. See status in chapter 3 for | 
|  | more information. WINE implements several MCI mid level drivers | 
|  | (status is given for both built-in and native implementation): | 
|  |  | 
|  | TODO: (apply to all built-in MCI drivers) | 
|  | * use mmsystem multitasking caps instead of the home grown | 
|  |  | 
|  | 2.1 CDAUDIO | 
|  | ----------- | 
|  |  | 
|  | 2.1.1 Built-in | 
|  |  | 
|  | The currently best implementation is the MCI CDAUDIO driver that can | 
|  | be found in dlls/winmm/mcicda/mcicda.c. The implementation is mostly | 
|  | complete, there have been no reports of errors. It makes use of | 
|  | misc/cdrom.c Wine internal cdrom interface. | 
|  | This interface has been ported on Linux, FreeBSD and NetBSD. (Sun | 
|  | should be similar, but are not implemented.) | 
|  |  | 
|  | A very small example of a cdplayer consists just of the line | 
|  | mciSendString("play cdaudio",NULL,0,0); | 
|  |  | 
|  | TODO: | 
|  | * add support for other cdaudio drivers (Solaris...) | 
|  | * add support for multiple cdaudio devices | 
|  |  | 
|  | 2.1.2 Native | 
|  |  | 
|  | Native MCICDA works also correctly... It uses the mscdex traps (on int | 
|  | 2f). | 
|  |  | 
|  | 2.2 MCIWAVE | 
|  | ----------- | 
|  |  | 
|  | 2.2.1 Built-in | 
|  |  | 
|  | The implementation is rather complete and can be found in | 
|  | dlls/winmm/mciwave/audio.c. It uses the low level audio API (although | 
|  | not abstracted correctly). | 
|  |  | 
|  | FIXME: | 
|  | * The MCI_STATUS command is broken. | 
|  |  | 
|  | TODO: | 
|  | * check for correctness | 
|  | * better use of asynchronous playback from low level | 
|  | * record has to be checked | 
|  | * MCI_CUE command is broken | 
|  | * better implement non waiting command (without the MCI_WAIT flag). | 
|  |  | 
|  | 2.2.2 Native | 
|  |  | 
|  | Native MCIWAVE works also correctly. | 
|  |  | 
|  | 2.3 MCISEQ (MIDI sequencer) | 
|  | --------------------------- | 
|  |  | 
|  | 2.3.1 Built-in | 
|  |  | 
|  | The implementation can be found in dlls/winmm/mciseq/mcimidi.c. Except | 
|  | from the Record command, should be close to completion (except for non | 
|  | blocking commands). | 
|  |  | 
|  | TODO: | 
|  | * implement it correctly | 
|  | * finish asynchronous commands (especially for reading/record) | 
|  | * better implement non waiting command (without the MCI_WAIT flag). | 
|  |  | 
|  | 2.3.2 Native | 
|  |  | 
|  | Native MCIMIDI has been working but is currently blocked by scheduling | 
|  | issues (mmTaskXXX no longer work). | 
|  |  | 
|  | FIXME: | 
|  | * midiStreamPlay get from time to time an incorrect MidiHdr when | 
|  | using the native MCI sequencer | 
|  |  | 
|  | 2.4 MCIANIM | 
|  | ----------- | 
|  |  | 
|  | 2.4.1 Built-in | 
|  |  | 
|  | The implementation consists of stubs and is in dlls/winmm/mcianim.c. | 
|  |  | 
|  | TODO: | 
|  | * implement it, probably using xanim or something similar. | 
|  |  | 
|  | 2.4.2 Native | 
|  |  | 
|  | Native MCIANIM is reported to work (but requires native video DLLs | 
|  | also). | 
|  |  | 
|  | 2.5 MCIAVI | 
|  | ---------- | 
|  |  | 
|  | 2.5.1 Built-in | 
|  |  | 
|  | The implementation consists of stubs and is in | 
|  | dlls/winmm/mciavi/mciavi.c. | 
|  |  | 
|  | TODO: | 
|  | * implement it, probably using xanim or something similar. | 
|  |  | 
|  | 2.5.2 Native | 
|  |  | 
|  | Native MCIAVI is reported to work (but requires native video DLLs | 
|  | also). Some files exhibit some deadlock issues anyway. | 
|  |  | 
|  | 3 High level layers | 
|  | =================== | 
|  |  | 
|  | The rest (basically the MMSYSTEM and WINMM DLLs entry points). It also | 
|  | provides the skeleton for the core functionality for multimedia | 
|  | rendering. Note that native MMSYSTEM and WINMM do not currently work | 
|  | under WINE and there is no plan to support them (it would require to | 
|  | also fully support VxD, which is not done yet). | 
|  | MCI and low level drivers can either be 16 or 32 bit. | 
|  |  | 
|  | TODO: | 
|  | * it seems that some program check what's installed in registry | 
|  | against value returned by drivers. Wine is currently broken | 
|  | regarding this point. | 
|  | * add clean-up mechanisms when process detaches from MM DLLs | 
|  | * prepare for the 16/32 big split | 
|  | * check thread-safeness for MMSYSTEM and WINMM entry points | 
|  | * unicode entry points are badly supported | 
|  |  | 
|  | 3.1 MCI skeleton | 
|  | ---------------- | 
|  |  | 
|  | Implementation of what is needed to load/unload MCI drivers, and to | 
|  | pass correct information to them. This is implemented in | 
|  | dlls/winmm/mci.c. The mciSendString function uses command strings, | 
|  | which are translated into normal MCI commands as used by | 
|  | mciSendCommand with the help of command tables. The API can be found | 
|  | in dlls/winmm/mmsystem.c and dlls/winmm/mci.c. The functions there | 
|  | (mciOpen,mciSysInfo) handle mid level driver allocation and calls. The | 
|  | implementation is not complete. | 
|  | MCI drivers are seen as regular WINE modules, and can be loaded (with | 
|  | a correct load order between built-in, native, elfdll, so), as any | 
|  | other DLL. Please note, that MCI drivers module names must bear the | 
|  | .drv extension to be correctly understood. | 
|  | The list of available MCI drivers is obtained as follows: | 
|  | 1. key 'mci' in [option] section from .winerc (or wineconf) | 
|  | mci=CDAUDIO:SEQUENCER gives the list of MCI drivers (names, in | 
|  | uppercase only) to be used in WINE. | 
|  | 2. This list, when defined, supersedes the mci key in | 
|  | c:\windows\system.ini | 
|  |  | 
|  | Note that native VIDEODISC crashes when the module is loaded, which | 
|  | occurs when the MCI procedures are initialised. Make sure that this is | 
|  | not in the list from above. Try adding: | 
|  | mci=CDAUDIO:SEQUENCER:WAVEAUDIO:AVIVIDEO:MPEGVIDEO | 
|  | to the [options] section of wine.conf. | 
|  |  | 
|  | TODO: | 
|  | * correctly handle the MCI_ALL_DEVICE_ID in functions. | 
|  | * finish mapping 16 <=> 32 of MCI structures and commands | 
|  | * MCI_SOUND is not handled correctly (should not be sent to MCI | 
|  | driver => same behavior as MCI_BREAK) | 
|  | * do not display module warning when failed to 32-bit load a 16 bit | 
|  | module when 16 bit load can succeed (and the other way around) | 
|  | * implement auto-open feature (ie, when a string command is issued | 
|  | for a not yet opened device, MCI automatically opens it) | 
|  |  | 
|  | 3.2 MCI multi-tasking | 
|  | --------------------- | 
|  |  | 
|  | Multi-tasking capabilities used for the MCI drivers are provided in | 
|  | dlls/winmm/mmsystem.c. | 
|  |  | 
|  | TODO: | 
|  |  | 
|  | mmTaskXXX functions are currently broken because the 16 loader does | 
|  | not support binary command lines => provide Wine's own mmtask.tsk not | 
|  | using binary command line. | 
|  |  | 
|  | the Wine native MCI drivers should use the mmThreadXXX API and no | 
|  | longer use the MCI_AsyncCommand hack. | 
|  |  | 
|  | 3.3 Timers | 
|  | ---------- | 
|  |  | 
|  | It currently uses a service thread, run in the context of the calling | 
|  | process, which should correctly mimic Windows behavior. | 
|  |  | 
|  | TODO: | 
|  | * Check if minimal time is satisfactory for most programs. | 
|  | * current implementation may let a timer tick (once) after it has | 
|  | been destroyed | 
|  |  | 
|  | 3.4 MMIO | 
|  | -------- | 
|  |  | 
|  | The API consists of the mmio* functions found in mdlls/winmm/mmio.c. | 
|  | Seems to work ok in most of the cases. There's some linear/segmented | 
|  | issues with 16 bit code. | 
|  |  | 
|  | 3.5 sndPlayXXX functions | 
|  | ------------------------ | 
|  |  | 
|  | Seem to work correctly. | 
|  |  | 
|  | 4 Multimedia configuration | 
|  | ========================== | 
|  |  | 
|  | Currently, multimedia configuration heavily relies on Win 3.x | 
|  | configuration model. | 
|  |  | 
|  | 4.1 Drivers | 
|  | ----------- | 
|  |  | 
|  | Since all multimedia drivers (MCI, low level ones, ACM drivers, | 
|  | mappers) are, at first, drivers they need to appear in the [mci] or | 
|  | [mci32] section of the system.ini file. | 
|  | Since all drivers are, at first, DLLs, you can choose to load their | 
|  | Wine's (builtin) or Windows (native) version. | 
|  |  | 
|  | 4.2 MCI | 
|  | ------- | 
|  |  | 
|  | A default [mci] section (in system.ini) looks like (see the note above | 
|  | on videodisc): | 
|  |  | 
|  | [mci] | 
|  | cdaudio=mcicda.drv | 
|  | sequencer=mciseq.drv | 
|  | waveaudio=mciwave.drv | 
|  | avivideo=mciavi.drv | 
|  | videodisc=mcipionr.drv | 
|  | vcr=mcivisca.drv | 
|  | MPEGVideo=mciqtz.drv | 
|  |  | 
|  | By default, the list of loadable MCI drivers will be made of those | 
|  | drivers (in the [mci] section). | 
|  |  | 
|  | The list of loadable (recognized) MCI drivers can be altered in the | 
|  | [option] section of wine.conf, like: | 
|  | mci=CDAUDIO:SEQUENCER:WAVEAUDIO:AVIVIDEO:MPEGVIDEO | 
|  |  | 
|  | TODO: | 
|  |  | 
|  | use a default registry setting to bypass this (ugly) configuration | 
|  | model | 
|  |  | 
|  | 4.3 Low level drivers | 
|  | --------------------- | 
|  |  | 
|  | They are currently hardcoded in dlls/winmm/lolvldrv.c. | 
|  |  | 
|  | TODO: | 
|  |  | 
|  | use a default registry setting to provide a decent configuration | 
|  | model. this shall also help some programs to work (some of them test | 
|  | the names returned by low level drivers with the ones defined and | 
|  | installed in the registry) | 
|  |  | 
|  | 4.4 ACM | 
|  | ------- | 
|  |  | 
|  | To be done (use the same mechanism as MCI drivers configuration). | 
|  |  | 
|  | 5 Multimedia architecture | 
|  | ========================= | 
|  |  | 
|  | 5.1 Windows 9x multimedia architecture | 
|  | -------------------------------------- | 
|  |  | 
|  | | | 
|  | Kernel space |                    Client applications | 
|  | | | 
|  | |           | |         ^ ^       | |          | | | 
|  | |        16>| |<32   16>| |<32 16>| |<32    16>| |<32 | 
|  | |           | v         | |       | v          | v | 
|  | |      +----|-----------|---------|------------|-------+ | 
|  | |      |    |           |         |            |       |  WinMM.dll | 
|  | |      |    |           |         |            |       |   32 bit | 
|  | |      +----|-----------|---------|------------|-------+ | 
|  | |           | |         | ^       | |          | | 
|  | |  +------+ | |<16      | |       | |<16       | | 
|  | |  |   16>| | |         | |       | |          | | 
|  | |  |      v v v         | |       v v          v | 
|  | |  |   +---------------+---+-------------+-------------+ | 
|  | |  |   | waveInXXX     |   | mciXXX      | *playSound* | | 
|  | |  |   | waveOutXXX    |   |             | mmioXXX     | | 
|  | |  |   | midiInXXX     |   |             | timeXXX     | | 
|  | |  |   | midiOutXXX    |   |             | driverXXX   | | 
|  | |  |   | midiStreamXXX |   |             |             |  MMSystem.dll | 
|  | |  |   | mixerXXX      |   |             |             |     16 bit | 
|  | +--------+  |  |   | auxXXX    +---+   +---+ mmThread|             | | 
|  | |MMDEVLDR|<------->| joyXXX    | Call back | mmTask  |             | | 
|  | +--------+  |  |   +-----------+-----------+---------+-------------+ | 
|  | ^       |  |          |       ^    ^     | ^ | 
|  | |       |  |       16>|       |<16>|  16>| |<16 | 
|  | v       |  |          v       |    |     v | | 
|  | +--------+  |  |   +-------------+    +----------+ | 
|  | |  VxD   |<------->|     .drv    |    | mci*.drv | | 
|  | +--------+  |  |   +--------------+   +-----------+ | 
|  | |  |    | msacmm.drv  |    | mciwave  | | 
|  | |  |    +--------------+   +-----------+ | 
|  | |  |     | midimap.drv |    | mcimidi  | | 
|  | |  |     +-------------+    +-----------+ | 
|  | |  |    Low-level drivers    |    ...   | MCI drivers | 
|  | |  |                         +----------+ | 
|  | |  |                               | | 
|  | |  |                               |<16 | 
|  | |  +-------------------------------+ | 
|  | | | 
|  |  | 
|  | The  important points to notice are: | 
|  | * all drivers (and most of the core code) is 16 bit | 
|  | * all hardware (or most of it) dependant code reside in the kernel | 
|  | space (which is not surprising) | 
|  |  | 
|  | 5.2 Wine multimedia architecture | 
|  | -------------------------------- | 
|  |  | 
|  | | | 
|  | Kernel space |                    Client applications | 
|  | | | 
|  | |           | |         ^ ^       | |          | | | 
|  | |        16>| |<32   16>| |<32 16>| |<32    16>| |<32 | 
|  | |           | |         | |       | |          | | | 
|  | |  +------+ | |         | |       | |          | | | 
|  | |  |32/16>| | |         | |       | |          | | | 
|  | |  |      v v v         | |       v v          v v | 
|  | |  |   +---------------+---+-------------+-------------+ | 
|  | |  |   | waveInXXX     |   | mciXXX      | *playSound* | | 
|  | |  |   | waveOutXXX    |   |             | mmioXXX     | WinMM.dll | 
|  | |  |   | midiInXXX     |   |             | timeXXX     |   32 bit | 
|  | |  |   | midiOutXXX    |   |             | driverXXX   | | 
|  | |  |   | midiStreamXXX |   |             |             | MSystem.dll | 
|  | |  |   | mixerXXX      |   |             |             |   16 bit | 
|  | |  |   | auxXXX    +---+   +---+ mmThread|             | | 
|  | |  |   | joyXXX    | Call back | mmTask  |             | | 
|  | |  |   +-----------+-----------+---------+-------------+ | 
|  | |  |         | |     ^    ^     ||    ^^ | 
|  | |  |      16>| |<32  |<16>|  16>||<32>||<16 | 
|  | |  |         v v     |<32>|     vv    || | 
|  | +---------+  |  |   +-------------+    +----------+ | 
|  | |HW driver|<------->|     .drv    |    | mci*.drv | | 
|  | +---------+  |  |   +--------------+   +-----------+ | 
|  | |  |    | msacmm.drv  |    | mciwave  | | 
|  | |  |    +--------------+   +-----------+ | 
|  | |  |     | midimap.drv |    | mcimidi  | | 
|  | |  |     +-------------+    +-----------+ | 
|  | |  |    Low-level drivers    |    ...   | MCI drivers | 
|  | |  |                         +----------+ | 
|  | |  |                               | | 
|  | |  |                               |<32/16 | 
|  | |  +-------------------------------+ | 
|  | | | 
|  |  | 
|  | From the previous drawings, the most noticeable difference are: | 
|  | * low-level drivers can either be 16 or 32 bit | 
|  | * MCI drivers can either be 16 or 32 bit | 
|  | * MMSystem and WinMM will be hosted in a single elfglue library | 
|  | * no link between the MMSystem/WinMM pair on kernel space shall | 
|  | exist. For example, there will be a low level driver to talk to a | 
|  | UNIX OSS (Open Sound System) driver | 
|  | * all built-in drivers (low-level and MCI) will be written as 32 bit | 
|  | drivers | 
|  | all native drivers will be 16 bits drivers | 
|  |  | 
|  | ______________________________________________________ | 
|  |  | 
|  | Last updated: 6, December 1999 | 
|  | By:          Eric Pouech (eric.pouech@wanadoo.fr) | 
|  |  | 
|  | References | 
|  |  | 
|  | 1. http://www.4front-tech.com/ |