OS/2 IOCTL90 Mixer Programming Specification
Joe 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.
STATUS (Drivers known to implement this API)
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 progamming 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 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.
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(tm) SoundFusion(tm) Audio Codec '97 (CS4297A)
All Set/Get functions accept a single parameter (data block pointer) which has this definition:
typedef structThe IOCTLs in the 0x40 and 0x60 range are nearly self explanatory. (Get/Set volume).
{
ULONG Mute; // UnMute==0, Mute==1
ULONG VolumeL; // 0..100 percent
ULONG VolumeR; // 0..100 percent
} MIXSTRUCT, *PMIXSTRUCT;
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).
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).
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.
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.
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 |
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.
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.
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.
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).
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
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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).
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).
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).
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.
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.
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.
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;
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.
// 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
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);
}
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);
}
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);
}
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.