IOCTL90 - OS/2 Ioctl90 Multimedia Mixer - Official API Definition
By Joseph Nord
The category 0x90 mixer IOCTLs define an interface between application level mixer programs and audio device drivers (PDDs) on OS/2 platforms.
- Last API update 14-May-2002.
- Last document update 09-Aug-2003
The IOCTLs were invented to expand on the operating system base APIs (The 0x80 APIs) to make it possible for a user to control the listening level of a CD-ROM or other source which is not controllable via the standard MMPM/2 API. The original driving application was a tuner application for a FM radio card connected to the sound cards line-in jack. With the base operating system defined interfaces, there was no means to control the relative sound level of the line input to the sound card.
Note: In this document, "the operating system APIs" refer to the original OS/2 mixer definition. There does exist an exhanced mixer interface which can do many of the things that Ioctl90 provides, but the operating system defined enhanced mixer interface has some issues in implementation which prevented wide spread acceptance.
CD-DA Listening level
The other driving force in the development of Ioctl90 was a means to adjust the relative volume of CD-DA playback.
Users will note that the OS/2 shipped CD-Player application includes a volume slider. This slider adjust the CD-ROM playback volume at the CD-ROM unit. The analog signal from the CD-ROM player is provided to the system audio device via an analog cable. Under MMPM/2, there is no means to adjust the volume of this signal at the audio device.
Master volume can be adjusted and wave volume can be adjusted, but the relative volume of the CD input cannot be adjusted with just the MMPM/2 API.
The category 90 mixer IOCTLs fill this gap and the text below is the API specification. Example code is provided for both physical device driver implementation as well as mixer application implementation.
The IOCTLs also support volume control for various other inputs to the audio device mixer and the ability to override record gain and stream volume for execution of WinOS2 and other applications that do not implement their own sliders for these controls.
For feedback, send email - "joe" at this domain.
Contents
- 1 Example code
- 2 Hardware mixer model
- 2.1 40 - MonoInSet
- 2.2 41 - PhoneSet
- 2.3 42 - MicSet
- 2.4 43 - LineSet
- 2.5 44 - CDSet
- 2.6 45 - VideoSet
- 2.7 46 - AuxSet
- 2.8 48 - SPDIFSet
- 2.9 4B - BassTrebleSet
- 2.10 4C - ThreeDSet
- 2.11 4D - StreamVolSet
- 2.12 4E - RecordSrcSet
- 2.13 4F - RecordGainSet
- 2.14 60 - MonoInQuery
- 2.15 61 - PhoneQuery
- 2.16 62 - MicQuery
- 2.17 63 - LineQuery
- 2.18 64 - CDQuery
- 2.19 65 - VideoQuery
- 2.20 66 - AuxQuery
- 2.21 68 - SPDIFQuery
- 2.22 6C - ThreeDQuery
- 2.23 6B - BassTrebleQuery
- 2.24 6D - StreamVolQuery
- 2.25 6E - RecordSrcQuery
- 2.26 6F - RecordGainQuery
- 2.27 80 - ApiLevelQuery
- 2.28 81 - GetApiMap
- 2.29 82 - CallbackReg
- 2.30 83 - MsgBuf
- 2.31 Useful prototypes (header file)
- 2.32 Example Query PDD Name:
- 2.33 Example DosOpen:
- 2.34 Example DosDevIOCTL:
- 2.35 Device Specific Information:
Example code
- IOCTL90 Sample Mixer Application source code and OS/2 executable (zip file)
- IOCTL90 Physical Device Driver sample source code
STATUS (Drivers known to implement this API)
- Crystal Semiconductor ISA Mode 3 device driver, version 2.08
- CS4236B, CS4237B, CS4238B, CS4235, CS4239
- Crystal Semiconductor PCI device driver set, version 3.02
- CS4614, CS4624, CS4280
- Sound Blaster Live (SBLive) - Sander van Leeuwen
- C-Media 8738 - Ruediger Ihle
If your device driver supports the Ioctl90 API and you would like to be listed above, send me a note.
Limitations and differences from Windows mixer definitions
A programmer will note that this API does not address some of the common features of a mixer application. The most notable missing function is Master Volume.
The IOCTL90 definition attempts to not redefine things that are already defined in MMPM/2 API. Exceptions are made for record gain, record source and stream volume, but these exceptions are kept to a minimum to avoid complicating the programming of an audio device driver.
A developed mixer application is expected to use a combination of the standard MMPM/2 APIs (via MCI commands) along with the Category 0x90 IOCTLs defined in this file.
Master Volume
MMPM/2 defines master volume and the operating system ships a master volume application. The standard application works. Since master volume is already handled by the MMPM/2 API, it is not re-invented in the category 90 IOCTLs. Mixer application developers COULD issue appropriate MCI commands to adjust master volume outside IOCTL90. They are encouraged to not implement master volume in the mixer application.
The OS/2 shipped "Volume Control" application is not very robust. It provides no means for message callbacks. That is, there can be at-most ONE controller of master volume in the system as any change of master volume by a secondary application cannot be reflected on the GUI of the OS/2 standard volume control application.
Per-Stream Volume and Per-Stream Gain
On OS/2, wave audio volume, record gain and record source are defined as per-stream concepts. This is very different than Windows where application volume and gain are defined as system global.
On OS/2, any external set of wave playback or capture volume are system defined to be un-done when a stream is started. Volume and gain are supposed to be different for each application and each application is expected to implement sliders to support adjustment of its stream volume and gain (and most do).
Unfortunately, a sufficiently large number of applications do not. Usually, this is due to the application being ported from Windows environment where the support of a global external mixer was assumed.
IOCTL90 allows the mixer application to override MMPM/2 per-stream volume and record gain. These are not required elements for implementation of a supporting device driver, but they may be implemented to support these applications.
This ability to override stream playback and capture volumes is most useful for execution of Windows multimedia applications inside WinOS2. By allowing the OS/2 native mixer to control these settings globally, the OS/2 mixer can effect record gain, record source and playback volumes for WinOS2 applications.
This eliminates the need for a WinOS2 mixer application.
Hardware mixer model
The Category 0x90 mixer IOCTLs are modeled on the Intel AC97 Audio CODEC definition.
The same hardware architecture is used by numerous audio system venders, thus promoting the portability of the IOCTL90 mixer API. The AC97 is also a "fairly simple" mixer device and can therefore be emulated on many other more full-function devices, again promoting portability of the API.
For details on the AC97 mixer architecture, consult this data sheet, Crystal Clear™ SoundFusion™ Audio Codec '97 (CS4297A)
All Set/Get functions accept a single parameter (data block pointer) which has this definition:
typedef struct { ULONG Mute; // UnMute==0, Mute==1 ULONG VolumeL; // 0..100 percent ULONG VolumeR; // 0..100 percent } MIXSTRUCT, *PMIXSTRUCT;
The IOCTLs in the 0x40 and 0x60 range are nearly self explanatory. (Get/Set volume).
The 0x80 and 0x81 APIs were added after external review to improve evolution of the API.
The query APIs return the value most recently written, not a calculated value based on the setting read from the hardware. This avoids granularity issues of the physical device hardware (often only 32 possible settings) versus 101 possible volume settings in the API (0..100 percent).
40 - MonoInSet
Set volume of system Mono input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Volume range 0..100 |
Right | Not used. Set = Left. |
Connection:
In most add-in card systems, this input is not used.
In many motherboard installations, this input is used for PC Speaker (beeps and clicks).
It is also used on motherboard systems for the audible signal from internal modems.
The device driver takes the MONO volume from the "left" field of the passed structure.
Application should fill in "right" field of structure with same value set for left.
41 - PhoneSet
Set volume of system Phone input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
In most add-in card systems, this input is not used.
In many PCI audio motherboard installations, this input is used connection from internal modem.
42 - MicSet
Set volume of system microphone.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
This IOCTL sets the listening level of the system microphone. System microphone is normally muted.
It can be un-muted to enable karoke mode.
Note: This IOCTL does not effect the record level for microphone.
43 - LineSet
Set volume of system Line-In connection
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
Line-In is normally an input on the system sound card - accessible on the back of the computer system.
44 - CDSet
Sets the listening level of the CD-ROM analog signal input to the audio device.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
CD-ROM input to sound card volume is controlled with this API.
This input is normally connected to the sound card via connector inside the PC system unit. The signal controlled with this API is that which arrives on the analog cable from the CD-ROM drive.
Note: If CD-DA digital streaming is being used, the sound card views the CD data as normal wave-audio. That is, this API will not effect CD-ROM lisenting level if CD-DA digital streaming is being used (CD player application choice).
45 - VideoSet
Sets the listening level of the sound card "video" input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
On equiped systems, effects the lisenting level of movie playback.
Most systems do not used this mixer input.
46 - AuxSet
Sets the listening level of the sound card "aux" input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
On equiped systems, effects the lisenting level of aux input.
AC97 systems include an Aux connection that may or may not actually be populated on system.
Most ISA devices do not include an Aux connector.
48 - SPDIFSet
Sets the listening level of the sound card "S/PDIF" input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
On equiped systems, effects the lisenting level of S/PDIF input.
4B - BassTrebleSet
Change Bass and Treble settings
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute (flags) | not used, set to 0 |
Left (Bass) | 0..100 |
Right (Treble) | 0..100 |
Connection:
Bass and Treble are not part of the AC97 mixer definition.
They are implemented on some audio devices as a post processing algorithm applied to the output of audio device. Bass and Treble effect the sound level of low frequency and high frequency sounds independent of volume.
A device driver can indicate support for Bass only, Treble only or both via the BassTrebleQuery API.
Device drivers default both bass and treble to 50%.
A setting of 50% means no effect to the audio signal.
4C - ThreeDSet
Enables or disables 3D sound effect. Popular algorithms include SRS and QSOUND.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute (enable) | 0x01=No 3D (Muted) 0x00=Enabled |
Left (Space) | 0..100 |
Right (Center) | 0..100 |
Connection:
3D is a post processing algorithm applied to the output of audio device to artificially make the speakers sound like they are further apart.
A device driver can indicate support for Space and Center via the ThreeDQuery API.
Enable flags:
Application should set only bit D0. Other bits should be zero.
Device driver should reference only bit D0. Other bits are don't care.
4D - StreamVolSet
Sets the stream playback volume globally - disabling MMPM/2 per-stream volume.
Notice that this API is redundent to and overrides the MMPM/2 defined concept of per-stream volume.
This API is implemented as counterpart to function 4F RecordGainSet.
Introduced: API Level 2
All device drivers implementing this IOCTL are expected to return API level 2 or beyond on API level query IOCTL.
Parameters (PMIXSTRUCT).
Mute (Flags) | 0x0001=>Mute 0x0002=>Release |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
Overrides MMPM/2 per-stream volume.
Note, this API does not effect system master volume.
4E - RecordSrcSet
Overrides MMPM/2 defined per-stream record source.
Provided record source will be used as global record source.
Call with "release" bit set in flags to return control to MMPM/2.
Introduced: API Level 2
Parameters (PMIXSTRUCT).
Mute (Flags) | 0x0002=>Release |
Left | Record Source |
Right | Not used, set to 0 |
Record Source Definition
0x00000000..0x0000000F | Reserved |
0x00000010 | Mic |
0x00000020 | CD-ROM |
0x00000040 | Video |
0x00000080 | Aux |
0x00000100 | Line |
0x00000200 | Loopback |
0x00000400 | SPDIF |
0x00000800 | Phone |
On query, device driver indicates whether or not it supports input mixer.
If input mux, mixer application can set only one source as input.
If input mixer, mixer application can OR on appropriate bits.
Application should use results of function 81 (function support map) to know
which inputs the device supports.
For many AC97 based implementations, the bit value from this API can be shifted and placed in the hardware MUX register with no modification. There are execptions:
The AC97 hardware definition includes two "Loopback" entries (one for stereo, one for mono).
The audio driver already knows how many channels are involved based on the stream initialization and accordingly only needs to define a single "Looback" record source. These are position 5 and 6. One is redundent.
By definition, the "5" position (Stereo loop) is defined in Ioctl90 as "Loopback" and covers both stereo and mono loopback.
The S/PDIF capture record source is defined to occupy the position of the mono record source.
Device Specific Notes:
On the Crystal Semiconductor ISA Mode 3 device driver, (CS4236B/7B/8B, CS4235, CS4239):
MONO-IN is a playback source and its volume can be adjusted via function 0x40.
MONO-IN however is not a possible record source. The device driver treats a request to record from MONO-IN as a request to record from NULL device (no sound).
4F - RecordGainSet
Sets the record gain globally - disabling MMPM/2 per-stream record gain.
Notice that this API is redundent to and overrides the MMPM/2 defined concept of per-stream record gain.
It can be argued that this API should only effect record gain for WinOS2.
MMPM/2 already defines record gain as a concept for OS/2 applications.
The API exists for two primary reasons
- Help poorly written OS/2 native applications perform record function - adjust their record gain.
- WinOS2 support - mixer control for record gain as a global concept as defined in Windows.
This API changes definition of record gain from a MMPM/2 per-stream concept to a mixer application global concept. Once this IOCTL is sent, record gain is global.
The gain sent from the mixer application overrules the per-stream gain sent from MMPM/2.
API Level 2 includes the ability for the mixer application to return control of gain to traditional MMPM/2 per-stream definition.
Introduced: API Level 1, Current implementation requires API level 2 (for release)
Parameters (PMIXSTRUCT).
Mute (Flags) | 0x0001=>Mute 0x0002=>Release |
Left | Left volume range 0..100 |
Right | Not used, set to 0 |
Connection:
Sets the record gain setting just before the Analog/Digital converter inside the AC97 mixer.
This API effects what you "record", not what you "hear".
Notes:
Crystal Semiconductor drivers 2.08 (ISA) and 3.03 (PCI) implement this API, but implement
it only with global effect (API level 1).
Crystal Semiconductor driver 2.09 (ISA) implements this API at API level 2.
That is, the "release" bit is defined and recognized by the device driver.
In API level 2, the mixer definition was enhanced to allow the mixer to return record gain to be a per-stream concept.
That is, to cancel the override and again place record gain into the control of MMPM/2.
60 - MonoInQuery
Query volume of system Mono input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Volume range 0..100 |
Right | Not used, PDD will set to 0 |
Connection:
In most add-in card systems, this input is not used.
In many motherboard installations, this input is used for PC Speaker (beeps and clicks).
It is also used on motherboard systems for the audible signal from internal modems.
The device driver sets the left field to value for mono volume.
61 - PhoneQuery
Query volume of system Phone input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
In most add-in card systems, this input is not used.
In many motherboard installations, this input is used connection from internal modem.
62 - MicQuery
Query volume of system microphone.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
This IOCTL sets the listening level of the system microphone. System microphone is normally muted.
It can be un-muted to enable karoke mode.
Note: This IOCTL does not effect the record level for microphone.
63 - LineQuery
Query volume of system Line-In connection
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
Line-In is normally an input on the system sound card - on the back of the PC system unit.
64 - CDQuery
Query the listening level of the CD-ROM analog signal input to the audio device.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
CD-ROM input to sound card volume is controlled with this API.
If CD-DA digital streaming is being used, the sound card views the CD data as wave-out. That is, this API will not effect CD-ROM lisenting level if CD-DA digital streaming is being used (CD player application choice).
65 - VideoQuery
Query the listening level of the sound card "video" input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
On equiped systems, effects the lisenting level of movie playback.
Most systems do not used this mixer input.
66 - AuxQuery
Queries the listening level of the sound card "aux" input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
On equiped systems, effects the lisenting level of aux input.
AC97 systems include an Aux connection that may or may not actually be populated on system.
Most ISA devices do not include an Aux connector.
68 - SPDIFQuery
Queries the listening level of the sound card "S/PDIF" input.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute | 0=>Audible, 1=>Mute |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
Connection:
On equiped systems, effects the lisenting level of S/PDIF input.
6C - ThreeDQuery
Queries 3D sound effect. Popular algorithms include SRS and QSOUND.
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute (flags) | D0 = 1 3D Is off (muted) D0 = 0 3D Enabled D1 = Space is supported D2 = Center is supported |
Left (Space) | 0..100 |
Right (Center) | 0..100 |
A device driver implementing support for 3D sound effect may or may not support Space and Center. Both are independently programmable items.
The device driver will turn on the 0x02 and 0x04 bits to indicate which of the slider options can be implemented in mixer application.
The 0x01 bit indicates the current state of 3D effect. If bit is on, 3D is enabled.
6B - BassTrebleQuery
Query Bass and Treble settings
Introduced: API Level 1
Parameters (PMIXSTRUCT).
Mute (flags) | 0x0001 - Bass is supported 0x0002 - Treble supported |
Left (Bass) | 0..100 |
Right (Treble) | 0..100 |
Connection:
See the BassTrebleSet API for description for details on Bass and Treble.
Device driver returns current setting for Bass and Treble and bit flags indicating which Bass/Treble adjustements are supported by the device.
If either Bass or Treble is not supported, the matching bit in the flags will be off and the Left/Right field of the returned parm will be 0.
A device driver implementing this Ioctl must support at least one of the adjustable settings (Bass/Treble).
6D - StreamVolQuery
Query the global stream volume.
See function 4D (StreamVolSet) for a detailed description of this APIs behavior.
Introduced: API Level 2
Parameters (PMIXSTRUCT).
Mute (flags) | 0x0001=>Mute 0x0002=>Release |
Left | Left volume range 0..100 |
Right | Right volume range 0..100 |
API Level 2:
The Mute field is a bit mask (flags).
Bit 0x00000001 - If true, then stream volume is muted.
Bit 0x00000002 - If true, then stream volume is "released" to MMPM/2 control.
Notes:
The values returned are dependent on who controls the record gain.
If under MMPM/2 control (mixer has released), then the mute and volume levels returned reflect the most recent value programmed from MMPM/2.
If mixer application is controlling the setting, then the values returned for mute and volume are the most recent values sent via function 4F.
Note, the values returned may reflect the values sent from a different mixer application (multiple mixer clients).
6E - RecordSrcQuery
Query global record source.
Introduced: API Level 2
Parameters (PMIXSTRUCT).
Mute (Flags) | 0x0001=>Reserved 0x0002=>Release 0x0004=>Input mixer |
Left | Record Source |
Right | Not used, set to 0 |
See function 4E for definition of record sources.
The record source value returned is dependent on who controls the record source.
Bit D1 will be set in the flags field to let the mixer application know if record source definition is global (0) or MMPM/2 per-stream (1).
Bit D2 will be set in the flags field to indicate that the device supports an input mixer rather than the AC97 standard input mux.
If under MMPM/2 control (mixer has released), then
1) The record source is a per-stream concept.
2) The record source returned represents the record source most recently set by MMPM/2. This allows the mixer application to initialize its record source to the record source most recently programmed by MMPM/2.
If mixer application controls record source, then
1) Record source is a global concept
2) Record source may actually be multiple sources (if input mixer)
3) Record source returned represents the record source most recently
sent via function 4F.
Note, the value returned may reflect the value sent from a different mixer application (multiple mixer clients).
6F - RecordGainQuery
Query the global record gain level.
See function 4F (RecordGainSet) for a detailed description of this APIs behavior.
Introduced: API Level 1. Enhanced in API Level 2.
In API Level 1
If the device driver has never received API call 4F, this IOCTL will return
the gain level most recently sent by MMPM/2 for per-stream volume.
This technique can be useful to initialize the value of the record gain slider to
the volume that is presently in effect per definition from MMPM/2.
Once function 4F has been sent, this API returns the record gain level most recently set via function 4F.
In API Level 2
The values returned are dependent on who controls the record gain.
If under MMPM/2 control (mixer has released), then the mute and volume
levels returned reflect the most recent value programmed from MMPM/2.
If mixer application is controlling the setting, then the values returned
for mute and volume are the most recent values sent via function 4F.
Note, the values returned may reflect the values sent from a different
mixer application (multiple mixer clients).
Parameters (PMIXSTRUCT).
Mute (flags) | 0x0001=>Mute 0x0002=>Release |
Left | Left volume range 0..100 |
Right | Not used, PDD will set to 0 |
Connection:
Reads the record gain setting just before the Analog/Digital converter inside the AC97 mixer.
This API effects what you "record", not what you "hear".
In API Level 1:
The Mute field is a boolean. If true, then record gain is muted.
In API Level 2:
The Mute field is a bit mask (flags).
Bit 0x00000001 - If true, then record gain is muted.
Bit 0x00000002 - If true, then record gain is "released" to MMPM/2 control.
80 - ApiLevelQuery
In first release, this function returns a ULONG, 0x00000001.
As significant changes are made to the Category 90 mixer API, the return value
of this function will be incremented.
In current specification, audio device drivers should return 2.
Introduced: API Level 1
Parameters (PULONG).
ulAPILevel | Driver returns level supported |
API Level Functions Map - Where label omitted, API level is 1. The API level indicates the minimum version of the specification that will support execution of the Ioctl. Notice that many elements are added after "level 2", but are level 1 in definition as their implementation is compatiable with a mixer application that understands only level 1 communication.
40 - MonoInSet | 60 - MonoInQuery |
41 - PhoneSet | 61 - PhoneQuery |
42 - MicSet | 62 - MicQuery |
43 - LineSet | 63 - LineQuery |
44 - CDSet | 64 - CDQuery |
45 - VideoSet | 65 - VideoQuery |
46 - AuxSet | 66 - AuxQuery |
48 - SPDIFSet |
68 - SPDIFQuery |
4B - BassTrebleSet | 6B - BassTrebleQuery |
4C - ThreeDSet | 6C - ThreeDQuery |
4D - StreamVolSet (2) | 6D - StreamVolQuery (2) |
4E - RecordSrcSet (2) | 6E - RecordSrcQuery (2) |
4F - RecordGainSet (1,2) | 4F - RecordGainQuery (1,2) |
80 - ApiLevelQuery | |
81 - GetApiMap | |
82 - CallbackReg | |
83 - MsgBuf | |
Differences from original API definition result in increment of the API level.
The table above uses this convention.
With no notation, API level 1 is assumed. API level 1 means that if the API is listed in the API support map, it is implemented by the device driver.
New API level 1 IOCTLs can be added even after later API levels are defined.
The API level is used to describe differences in definition of an IOCTL.
These differences are noted in the table and are documented below and in the documentation for each IOCTL.
(1,2)
The RecordGainSet API differs in behavior on API levels 1 and 2.
In API level 1, once the mixer application forces an override of record
gain, control of record gain is forever in the domain of the mixer application.
This is enhanced in API level 2 where the mixer application can return
record gain to be a per-stream concept as defined by MMPM/2.
(2)
A device driver implementing StreamVolSet API is expected to return
API level 2 or greater. This API follows programming convention of
the level 2 implementation of RecordGainSet.
81 - GetApiMap
Device driver fills in an application memory buffer (256 bytes) with BYTE size booleans representing which of the possible 256 IOCTL functions that the device driver implements.
Introduced: API Level 1
This API can be used to identify mixer components that do not apply for the particular hardware.
For example, the Crystal Semiconductor PCI driver set implements the full AC97 defined mixer interface.
The Crystal Semiconductor ISA driver however does not implement "Video" or "Phone" volume as these are concepts which are alien to the ISA hardware.
Notice that the buffer returned is 256 bytes while it is only possible for an application to send 192 IOCTL functions (IOCTL API requires that function be >= 0x40). Wasting these 64 bytes of memory allows the application to index the array using the IOCTL number rather than IOCTL function number less 0x40.
82 - CallbackReg
Application provides handle to shared event semaphore.
Introduced: API Level 1
Parameters (HEV).
Application provides event semaphore handle to audio device driver.
This API is designed to let multiple mixer applications execute concurrently with sliders that "track".
The application is responsible for creating the event semahore.
When a mixer component state changes, the device driver posts the event semaphore which
wakes up an application thread that is blocked on the semaphore. The application should
then issue query APIs to read the current state of the mixer.
This API is implemented in Crystal Semiconductor PCI driver set 3.04 and ISA 2.09.
Example code
HEV hevCallback; ulRC = DosCreateEventSem (NULL, &hevCallback, DC_SEM_SHARED, FALSE); if (ulRC != 0) { printf ("mixerapiInit - CreateSem failed\n"); hevCallback = NULL; } else { fCallbackThreadAlive = TRUE; if (_beginthread (CallbackThreadFunc, NULL, 32*1024, NULL) == -1) { printf ("mixerapiInit - callback thread create failed\n"); CallbackFunc = NULL; fCallbackThreadAlive = FALSE; ulRC = 1; } } ulRC = mixerapiIOCTL90 (CALLBACKREG, &hevCallback, sizeof(hevCallback));
When the mixer application terminates or otherwise closes the semaphore, it should contact the audio PDD to de-register. De-register is done by registering a NULL semaphore.
Example code
ulZero = 0; ulRC = mixerapiIOCTL90 (CALLBACKREG, &ulZero, sizeof(ulZero)); ulRC = DosCloseEventSem (hsemCallback); hsemCallback = NULL;
83 - MsgBuf
Device driver fills in an application memory buffer with characters displayed during boot and any strings displayed by device driver for debug or problem diagnosis in the field.
Introduced: API Level 1
Parameters (PMSGBUF).
typedef struct { ULONG pBuffer; // Application linear address to message buffer (in) ULONG ulSize; // Size of buffer (in). Count of chars (out). ULONG fClear; // PDD should clear buffer after copy (in) ULONG fError; // Message buffer includes error message (out) ULONG fNewInfo; // Message buffer has new text since last read (out) ULONG ulCharsLost; // Messages lost - circular queue wrap around (out) } MIXMSGBUF, *PMIXMSGBUF;
Application should pass NULL buffer on first call.
Device driver will set ulSize field to the maximum possible size of returned buffer and will set the boolean return values to indicate what information is in the buffer.
Application should then malloc that much memory and call device driver to retrieve message text.
If pBuffer points to invalid memory, the application will fail with access violation.
fError and ulCharsLost are clearned when buffer is cleared.
fNewInfo is cleared on each buffer read where pBuffer is not NULL.
When new message text is added to the buffer, the device driver posts the callback semaphore.
Useful prototypes (header file)
// This structure is passed to the device driver using DosDevIOCTL. typedef struct { ULONG Mute; // UnMute==0, Mute==1 ULONG VolumeL; // 0..100 percent ULONG VolumeR; // 0..100 percent } MIXSTRUCT, *PMIXSTRUCT; #define MONOINSET 0x40 // SET functions in the 0x40 range #define PHONESET 0x41 #define MICSET 0x42 #define LINESET 0x43 #define CDSET 0x44 #define VIDEOSET 0x45 #define AUXSET 0x46 #define SPDIFSET 0x48 #define BASSTREBLESET 0x4B #define THREEDSET 0x4C #define STREAMVOLSET 0x4D #define RECORDSRCSET 0x4E #define RECORDGAINSET 0x4F #define MONOINQUERY 0x60 // QUERY functions in the 0x60 range #define PHONEQUERY 0x61 #define MICQUERY 0x62 #define LINEQUERY 0x63 #define CDQUERY 0x64 #define VIDEOQUERY 0x65 #define AUXQUERY 0x66 #define SPDIFQUERY 0x68 #define BASSTREBLEQUERY 0x6B #define THREEDQUERY 0x6C #define STREAMVOLQUERY 0x4D #define RECORDSRCQUERY 0x4E #define RECORDGAINQUERY 0x4F #define APILEVELQUERY 0x80 #define GETAPIMAP 0x81 // Get 256 byte BOOL list of supported IOCTLs #define CALLBACKREG 0x82 // Provide HSEM for mixer change callbacks #define MSGBUF 0x83 // Get PDD error log message buffer
Example Query PDD Name:
The application will query the 8 character device driver name by calling MMPM/2 MCI APIs to get the PDD name for the "WaveAudio" MCI device. Application should then issue DosOpen on the device name and finally DosDevIOCTL to perform mixer operations.
NOTE: The device driver names used by audio device drivers DO change and are not guaranteed to remain the same for any given release. USE the available MMPM/2 APIs!
// // OS/2 32-bit program to query the Physical Device Driver name // for the default MMPM/2 WaveAudio device. Joe Nord 10-Mar-1999 // #include <stdlib.h> #include <stdio.h> #include <string.h> #include <os2.h> #define INCL_OS2MM #include <os2me.h> ULONG GetAudioPDDName (char *pszPDDName) { ULONG ulRC; char szAmpMix[9] = "AMPMIX01"; MCI_SYSINFO_PARMS SysInfo; MCI_SYSINFO_LOGDEVICE SysInfoParm; MCI_SYSINFO_QUERY_NAME QueryNameParm; memset (&SysInfo, '\0', sizeof(SysInfo)); memset (&SysInfoParm, '\0', sizeof(SysInfoParm)); memset (&QueryNameParm, '\0', sizeof(QueryNameParm)); SysInfo.ulItem = MCI_SYSINFO_QUERY_NAMES; SysInfo.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; SysInfo.pSysInfoParm = &QueryNameParm; strcpy (QueryNameParm.szLogicalName, szAmpMix); ulRC = mciSendCommand (0, MCI_SYSINFO, MCI_SYSINFO_ITEM | MCI_WAIT, (PVOID) &SysInfo, 0); if (ulRC != 0) { printf ("mciSendCommand ulRC=%u\n", ulRC); return (ulRC); } // Get PDD associated with our AmpMixer // Device name is in pSysInfoParm->szPDDName SysInfo.ulItem = MCI_SYSINFO_QUERY_DRIVER; SysInfo.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; SysInfo.pSysInfoParm = &SysInfoParm; strcpy (SysInfoParm.szInstallName, QueryNameParm.szInstallName); ulRC = mciSendCommand (0, MCI_SYSINFO, MCI_SYSINFO_ITEM | MCI_WAIT, (PVOID) &SysInfo, 0); if (ulRC != 0) { printf ("mciSendCommand ulRC=%u\n", ulRC); return (ulRC); } strcpy (pszPDDName, SysInfoParm.szPDDName); return (ulRC); } int main (void) { ULONG ulRC; char szPddName [256]; ulRC = GetAudioPDDName (&szPddName); printf ("GetAudioPDDName ulRC=%u\n", ulRC); printf (" PddName=%s\n", szPddName); return (0); }
Example DosOpen:
Driver name in call to the open function should include "\\DEV\\ "
- Example: hPdd = DevOpen ("\\DEV\\BSAUD1$"); or
- Example: hPdd = DevOpen ("\\DEV\\CWCAUD1$");
HFILE DevOpen (char *ddName) { ULONG ulRC; ULONG OpenFlags; ULONG OpenMode; ULONG ulFileSize = 0; ULONG ulFileAttribute = 0; ULONG ulActionTaken = 0; HFILE hPdd = NULL; OpenFlags = OPEN_ACTION_OPEN_IF_EXISTS; // Do not create file OpenMode = OPEN_ACCESS_READWRITE + // Read/Write file OPEN_SHARE_DENYNONE + // Non-exclusive access OPEN_FLAGS_FAIL_ON_ERROR; // No system popups on errors ulRC = DosOpen (ddName, // in &hPdd, // out (handle) &ulActionTaken, // out ulFileSize, // in ulFileAttribute, // in OpenFlags, // in OpenMode, // in NULL); // in printf ("DosOpen RC = %x\n", ulRC); if (ulRC != 0) hPdd = NULL; return (hPdd); }
Example DosDevIOCTL:
ULONG SendIOCTL (HFILE hPdd, ULONG ulFunc, PMIXSTRUCT pMix) { ULONG ulRC; ULONG ulSizeOfStruct = = sizeof (MixStruct); ulRC = DosDevIOCtl (hPdd, // Device Handle 0x90, // Category (user defined >= 0x80) ulFunc, // Function Use defines in .H file NULL, // in Address of parm data (not used) 0, // in Max size of parm data structure NULL, // in out Actual size of parm data structure pMix, // in Address of command data ulSizeOfStruct, // in Maximum size of command data &ulSizeOfStruct); // in out Size of command data printf ("DosDevIOCtl ulRC = %d\n", ulRC); return (ulRC); }
Device Specific Information:
The Ioctl90 API is based on AC97 mixer architecture (common hardware for PCI bus audio). It does not necessarily exactly map to other mixer architectures. Where known, differences are documented below.
AC97 Definition CS4236B/7B/8B CS4235/9 PCI Bus designs ISA Mode 3 ISA Mode 3 --------------- ------------- -------- MonoIn MonoIn MonoIn Phone none none Microphone Mic Mic Line-In Aux1 Aux1 Aux1 = Line-In connector on card CD-ROM Aux2 Aux2 Aux2 = CD-ROM Analog cable Video none none Aux Line DAC2 CS4236B=FM Volume, CS4235=Digital vol
Record sources:
On the Crystal Semiconductor ISA Mode 3 device driver, (CS4236B/7B/8B, CS4235, CS4239):
MONO-IN is not a possible record source.