2 This file contains information about the implementation of the
3 multimedia layer of WINE. The libraries consist of MMSYSTEM.DLL
4 (win16), WINMM.DLL (win32) and some (abstracted, not Windows
5 compatible) low level drivers.
7 The implementation can be found in the dlls/winmm/ sub directory.
12 The multimedia stuff is split into 3 layers. The low level (device
13 drivers), mid level (MCI commands) and high level abstraction layers.
15 The low level may depend on current hardware and OS services (like
16 OSS). Mid level (MCI) and high level must be written independently
17 from the hardware and OS services.
18 There are two specific low level drivers call mappers (for wave and
19 +midi) whose role is to :
20 * help choosing one low level driver between many
21 * add the possibility to convert stream (ie ADPCM => PCM)
22 * add the possibility to filter a stream (adding echo, equalizer...)
24 All of those components are defined as DLLs (one by one) and are
25 candidate for dllglue migration.
30 Please note that native low level drivers are not currently supported
31 in WINE, because they either access hardware components or require
32 VxDs to be loaded; WINE does not correctly supports those two so far.
34 The following low level layers are implemented:
39 MMSYSTEM and WINMM call the real low level audio driver using the
40 wodMessage/widMessage which handles the different requests.
42 1.1.1 OSS implementation
44 The low level audio driver is currently only implemented for the
45 OpenSoundSystem (OSS) as supplied in the Linux and FreeBSD kernels by
46 [1]4Front Technologies. The presence of this driver is checked by
47 configure (depends on the <sys/soundcard.h> file). Source code resides
48 in dlls/winmm/wineoss/audio.c,
50 The implementation contains all features commonly used, but has
51 several problems (see TODO list).
54 * add asynchronous reads [recording] (must use threads) as done for
56 * verify all functions for correctness
57 * looping of WaveHdr will fail
58 * share access to /dev/dsp with dsound interface (either on a
59 descriptor basis, or using a virtual mixer between different wave
60 inputs. EsounD provides this type of capability).
62 1.1.2 Other sub systems
64 None are available. Could think of Sun Audio, remote audio systems
65 (using X extensions, ...), ALSA, EsounD
70 MMSYSTEM and WINMM call the low level driver functions using the
71 midMessage and the modMessage functions.
75 The low level audio driver is currently only implemented for the
76 OpenSoundSystem (OSS) as supplied in the Linux and FreeBSD kernels by
77 [1]4Front Technologies . The presence of this driver is checked by
78 configure (depends on the <sys/soundcard.h> file, and also some
79 specific defines because MIDI is not supported on all OSes by OSS).
80 Source code resides in dlls/winmm/wineoss/midi.c
82 Both Midi in and Midi out are provided. The type of MIDI devices
83 supported is external MIDI port (requires an MIDI capable device -
84 keyboard...) and OPL/2 synthesis (the OPL/2 patches for all
85 instruments are in midiPatch.c).
88 * use better instrument definition for OPL/2 (midiPatch.c) or use
89 existing instrument definition (from playmidi or kmid) with a
91 * have a look at OPL/3 ?
92 * implement asynchronous playback of MidiHdr
93 * implement STREAM'ed MidiHdr (question: how shall we share the code
94 between the midiStream functions in MMSYSTEM/WINMM and the code
95 for the low level driver)
96 * use a more accurate read mechanism than the one of snooping on
97 timers (like select on fd)
99 1.2.2 Other sub systems
101 Could support other midi implementation for other sub systems (any
104 Could also implement a software synthesizer, either inside Wine or
105 using using MIDI loop back devices in an external program (like
106 timidity). The only trouble is that timidity is GPL'ed...
111 MMSYSTEM and WINMM call the low level driver functions using the
114 1.3.1 OSS implementation
116 The current implementation uses the OpenSoundSystem mixer, and resides
117 in dlls/winmm/wineoss/mixer.c
120 * implement notification mechanism when state of mixer's controls
123 1.3.2 Other sub systems
126 * implement mixing low level drivers for other mixers (ALSA...)
131 The AUX low level driver is the predecessor of the mixer driver
132 (introduced in Win 95).
136 The implementation uses the OSS mixer API, and is incomplete.
139 * verify the implementation
140 * check with what is done in mixer
141 * open question: shall we implement it on top of the low level mixer
147 The API consists of the joy* functions found in dlls/winmm/joystick.c.
148 The implementation currently uses the Linux joystick device driver
149 API. It is lacking support for enhanced joysticks and has not been
153 * better support of enhanced joysticks
154 * support more joystick drivers (like the XInput extension)
155 * should make joystick a separate DLL (impact also on
156 WINMM/MMSYSTEM), or a real low level driver, as it is on Windows
159 1.6 Wave mapper (msacm.drv)
160 ---------------------------
162 The Wave mapper device allows to load on-demand codecs in order to
163 perform software conversion for the types the actual low level driver
164 (hardware). Those codecs are provided through the standard ACM
170 A first working implementation for wave out as been provided (wave in
171 exists, but doesn't allow conversion).
172 Wave mapper driver implementation can be found in dlls/winmm/wavemap/
173 directory. This driver heavily relies on MSACM and MSACM32 DLLs which
174 can be found in dlls/msacm and dlls/msacm32. Those DLLs load ACM
175 drivers which provide the conversion to PCM format (which is normally
176 supported by low level drivers). ADPCM, MP3... fit into the category
179 There is currently no builtin ACM driver in Wine, so you must use
180 native ones if you're looking for non PCM playback.
182 In order to use native ACM drivers to play non PCM files, you must use
183 -dll msacm,msacm32,msacm.drv=b. Note that this code is not complete
184 yet, and may cause problems. sndrec32 and mplayer from Win95 appear to
185 work reasonably well though.
189 * check for correctness and robustness
193 Seems to work quite ok (using of course native MSACM/MSACM32 DLLs)
194 Some other testings report some issues while reading back the registry
200 Midi mapper allows to map each one of 16 MIDI channels to a specific
201 instrument on an installed sound card. This allows for example to
202 support different MIDI instrument definition (XM, GM...). It also
203 permits to output on a per channel basis to different MIDI renderers.
208 A builtin MIDI mapper can be found in dlls/winmm/midimap. It only
209 provides the pickup of an existing MIDI low level driver for playback.
212 * implement the Midi mapper features (channel / instrument on the
217 Currently, the native midimapper i'm using is not working (mainly
218 because it reads low level drivers configuration from registry).
221 * let native midimapper driver load
223 2. Mid level drivers (MCI)
224 ==========================
226 The mid level drivers are represented by some common API functions,
227 mostly mciSendCommand and mciSendString. See status in chapter 3 for
228 more information. WINE implements several MCI mid level drivers
229 (status is given for both built-in and native implementation):
231 TODO: (apply to all built-in MCI drivers)
232 * use mmsystem multitasking caps instead of the home grown
239 The currently best implementation is the MCI CDAUDIO driver that can
240 be found in dlls/winmm/mcicda/mcicda.c. The implementation is mostly
241 complete, there have been no reports of errors. It makes use of
242 misc/cdrom.c Wine internal cdrom interface.
243 This interface has been ported on Linux, FreeBSD and NetBSD. (Sun
244 should be similar, but are not implemented.)
246 A very small example of a cdplayer consists just of the line
247 mciSendString("play cdaudio",NULL,0,0);
250 * add support for other cdaudio drivers (Solaris...)
251 * add support for multiple cdaudio devices
255 Native MCICDA works also correctly... It uses the mscdex traps (on int
263 The implementation is rather complete and can be found in
264 dlls/winmm/mciwave/audio.c. It uses the low level audio API (although
265 not abstracted correctly).
268 * The MCI_STATUS command is broken.
271 * check for correctness
272 * better use of asynchronous playback from low level
273 * record has to be checked
274 * MCI_CUE command is broken
275 * better implement non waiting command (without the MCI_WAIT flag).
279 Native MCIWAVE works also correctly.
281 2.3 MCISEQ (MIDI sequencer)
282 ---------------------------
286 The implementation can be found in dlls/winmm/mciseq/mcimidi.c. Except
287 from the Record command, should be close to completion (except for non
291 * implement it correctly
292 * finish asynchronous commands (especially for reading/record)
293 * better implement non waiting command (without the MCI_WAIT flag).
297 Native MCIMIDI has been working but is currently blocked by scheduling
298 issues (mmTaskXXX no longer work).
301 * midiStreamPlay get from time to time an incorrect MidiHdr when
302 using the native MCI sequencer
309 The implementation consists of stubs and is in dlls/winmm/mcianim.c.
312 * implement it, probably using xanim or something similar.
316 Native MCIANIM is reported to work (but requires native video DLLs
324 The implementation consists of stubs and is in
325 dlls/winmm/mciavi/mciavi.c.
328 * implement it, probably using xanim or something similar.
332 Native MCIAVI is reported to work (but requires native video DLLs
333 also). Some files exhibit some deadlock issues anyway.
338 The rest (basically the MMSYSTEM and WINMM DLLs entry points). It also
339 provides the skeleton for the core functionality for multimedia
340 rendering. Note that native MMSYSTEM and WINMM do not currently work
341 under WINE and there is no plan to support them (it would require to
342 also fully support VxD, which is not done yet).
343 MCI and low level drivers can either be 16 or 32 bit.
346 * it seems that some program check what's installed in registry
347 against value returned by drivers. Wine is currently broken
348 regarding this point.
349 * add clean-up mechanisms when process detaches from MM DLLs
350 * prepare for the 16/32 big split
351 * check thread-safeness for MMSYSTEM and WINMM entry points
352 * unicode entry points are badly supported
357 Implementation of what is needed to load/unload MCI drivers, and to
358 pass correct information to them. This is implemented in
359 dlls/winmm/mci.c. The mciSendString function uses command strings,
360 which are translated into normal MCI commands as used by
361 mciSendCommand with the help of command tables. The API can be found
362 in dlls/winmm/mmsystem.c and dlls/winmm/mci.c. The functions there
363 (mciOpen,mciSysInfo) handle mid level driver allocation and calls. The
364 implementation is not complete.
365 MCI drivers are seen as regular WINE modules, and can be loaded (with
366 a correct load order between built-in, native, elfdll, so), as any
367 other DLL. Please note, that MCI drivers module names must bear the
368 .drv extension to be correctly understood.
369 The list of available MCI drivers is obtained as follows:
370 1. key 'mci' in [option] section from .winerc (or wineconf)
371 mci=CDAUDIO:SEQUENCER gives the list of MCI drivers (names, in
372 uppercase only) to be used in WINE.
373 2. This list, when defined, supersedes the mci key in
374 c:\windows\system.ini
376 Note that native VIDEODISC crashes when the module is loaded, which
377 occurs when the MCI procedures are initialised. Make sure that this is
378 not in the list from above. Try adding:
379 mci=CDAUDIO:SEQUENCER:WAVEAUDIO:AVIVIDEO:MPEGVIDEO
380 to the [options] section of wine.conf.
383 * correctly handle the MCI_ALL_DEVICE_ID in functions.
384 * finish mapping 16 <=> 32 of MCI structures and commands
385 * MCI_SOUND is not handled correctly (should not be sent to MCI
386 driver => same behavior as MCI_BREAK)
387 * do not display module warning when failed to 32-bit load a 16 bit
388 module when 16 bit load can succeed (and the other way around)
389 * implement auto-open feature (ie, when a string command is issued
390 for a not yet opened device, MCI automatically opens it)
392 3.2 MCI multi-tasking
393 ---------------------
395 Multi-tasking capabilities used for the MCI drivers are provided in
396 dlls/winmm/mmsystem.c.
400 mmTaskXXX functions are currently broken because the 16 loader does
401 not support binary command lines => provide Wine's own mmtask.tsk not
402 using binary command line.
404 the Wine native MCI drivers should use the mmThreadXXX API and no
405 longer use the MCI_AsyncCommand hack.
410 It currently uses a service thread, run in the context of the calling
411 process, which should correctly mimic Windows behavior.
414 * Check if minimal time is satisfactory for most programs.
415 * current implementation may let a timer tick (once) after it has
421 The API consists of the mmio* functions found in mdlls/winmm/mmio.c.
422 Seems to work ok in most of the cases. There's some linear/segmented
423 issues with 16 bit code.
425 3.5 sndPlayXXX functions
426 ------------------------
428 Seem to work correctly.
430 4 Multimedia configuration
431 ==========================
433 Currently, multimedia configuration heavily relies on Win 3.x
439 Since all multimedia drivers (MCI, low level ones, ACM drivers,
440 mappers) are, at first, drivers they need to appear in the [mci] or
441 [mci32] section of the system.ini file.
442 Since all drivers are, at first, DLLs, you can choose to load their
443 Wine's (builtin) or Windows (native) version.
448 A default [mci] section (in system.ini) looks like (see the note above
454 waveaudio=mciwave.drv
456 videodisc=mcipionr.drv
460 By default, the list of loadable MCI drivers will be made of those
461 drivers (in the [mci] section).
463 The list of loadable (recognized) MCI drivers can be altered in the
464 [option] section of wine.conf, like:
465 mci=CDAUDIO:SEQUENCER:WAVEAUDIO:AVIVIDEO:MPEGVIDEO
469 use a default registry setting to bypass this (ugly) configuration
472 4.3 Low level drivers
473 ---------------------
475 They are currently hardcoded in dlls/winmm/lolvldrv.c.
479 use a default registry setting to provide a decent configuration
480 model. this shall also help some programs to work (some of them test
481 the names returned by low level drivers with the ones defined and
482 installed in the registry)
487 To be done (use the same mechanism as MCI drivers configuration).
489 5 Multimedia architecture
490 =========================
492 5.1 Windows 9x multimedia architecture
493 --------------------------------------
496 Kernel space | Client applications
499 | 16>| |<32 16>| |<32 16>| |<32 16>| |<32
501 | +----|-----------|---------|------------|-------+
502 | | | | | | | WinMM.dll
504 | +----|-----------|---------|------------|-------+
506 | +------+ | |<16 | | | |<16 |
507 | | 16>| | | | | | | |
509 | | +---------------+---+-------------+-------------+
510 | | | waveInXXX | | mciXXX | *playSound* |
511 | | | waveOutXXX | | | mmioXXX |
512 | | | midiInXXX | | | timeXXX |
513 | | | midiOutXXX | | | driverXXX |
514 | | | midiStreamXXX | | | | MMSystem.dll
515 | | | mixerXXX | | | | 16 bit
516 +--------+ | | | auxXXX +---+ +---+ mmThread| |
517 |MMDEVLDR|<------->| joyXXX | Call back | mmTask | |
518 +--------+ | | +-----------+-----------+---------+-------------+
520 | | | 16>| |<16>| 16>| |<16
522 +--------+ | | +-------------+ +----------+
523 | VxD |<------->| .drv | | mci*.drv |
524 +--------+ | | +--------------+ +-----------+
525 | | | msacmm.drv | | mciwave |
526 | | +--------------+ +-----------+
527 | | | midimap.drv | | mcimidi |
528 | | +-------------+ +-----------+
529 | | Low-level drivers | ... | MCI drivers
533 | +-------------------------------+
536 The important points to notice are:
537 * all drivers (and most of the core code) is 16 bit
538 * all hardware (or most of it) dependant code reside in the kernel
539 space (which is not surprising)
541 5.2 Wine multimedia architecture
542 --------------------------------
545 Kernel space | Client applications
548 | 16>| |<32 16>| |<32 16>| |<32 16>| |<32
550 | +------+ | | | | | | | |
551 | |32/16>| | | | | | | | |
552 | | v v v | | v v v v
553 | | +---------------+---+-------------+-------------+
554 | | | waveInXXX | | mciXXX | *playSound* |
555 | | | waveOutXXX | | | mmioXXX | WinMM.dll
556 | | | midiInXXX | | | timeXXX | 32 bit
557 | | | midiOutXXX | | | driverXXX |
558 | | | midiStreamXXX | | | | MSystem.dll
559 | | | mixerXXX | | | | 16 bit
560 | | | auxXXX +---+ +---+ mmThread| |
561 | | | joyXXX | Call back | mmTask | |
562 | | +-----------+-----------+---------+-------------+
564 | | 16>| |<32 |<16>| 16>||<32>||<16
566 +---------+ | | +-------------+ +----------+
567 |HW driver|<------->| .drv | | mci*.drv |
568 +---------+ | | +--------------+ +-----------+
569 | | | msacmm.drv | | mciwave |
570 | | +--------------+ +-----------+
571 | | | midimap.drv | | mcimidi |
572 | | +-------------+ +-----------+
573 | | Low-level drivers | ... | MCI drivers
577 | +-------------------------------+
580 From the previous drawings, the most noticeable difference are:
581 * low-level drivers can either be 16 or 32 bit
582 * MCI drivers can either be 16 or 32 bit
583 * MMSystem and WinMM will be hosted in a single elfglue library
584 * no link between the MMSystem/WinMM pair on kernel space shall
585 exist. For example, there will be a low level driver to talk to a
586 UNIX OSS (Open Sound System) driver
587 * all built-in drivers (low-level and MCI) will be written as 32 bit
589 all native drivers will be 16 bits drivers
591 ______________________________________________________
593 Last updated: 6, December 1999
594 By: Eric Pouech (eric.pouech@wanadoo.fr)
598 1. http://www.4front-tech.com/