| |
| 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/ |