Jump to content

MMAPG - Media Control Interface: Difference between revisions

From EDM2
No edit summary
Line 538: Line 538:


===Time Formats for Device Commands===
===Time Formats for Device Commands===
Media position and time information are required as input and also returned as output by many multimedia commands. Time formats vary, depending on the device being used and the format of the data being operated on. The default time base for both the procedural and string interfaces is MMTIME. See MMTIME Format.
Other time formats, such as milliseconds, are also supported.
Time formats used by media control interface devices for measuring time are listed in the following table. The flags shown in the table are set with the MCI_SET command.
<pre>
┌───────────────┬─────────────────────────┬─────────────────────────┐
│Device        │Formats                  │Flags                    │
├───────────────┼─────────────────────────┼─────────────────────────┤
│CD-DA          │milliseconds            │MCI_FORMAT_MILLISECONDS  │
│              │mmtime                  │MCI_FORMAT_MMTIME        │
│              │minutes-seconds-frames  │MCI_FORMAT_MSF          │
│              │tracks-min-sec-frame    │MCI_FORMAT_TMSF          │
├───────────────┼─────────────────────────┼─────────────────────────┤
│CD-XA          │milliseconds            │MCI_FORMAT_MILLISECONDS  │
│              │mmtime                  │MCI_FORMAT_MMTIME        │
├───────────────┼─────────────────────────┼─────────────────────────┤
│digital video  │milliseconds            │MCI_FORMAT_MILLISECONDS  │
│              │mmtime                  │MCI_FORMAT_MMTIME        │
│              │frames                  │MCI_FORMAT_FRAMES        │
│              │hours-minutes-seconds    │MCI_FORMAT_HMS          │
│              │hours-min-sec-frames    │MCI_FORMAT_HMSF          │
├───────────────┼─────────────────────────┼─────────────────────────┤
│waveform audio │milliseconds            │MCI_FORMAT_MILLISECONDS  │
│              │mmtime                  │MCI_FORMAT_MMTIME        │
│              │bytes                    │MCI_FORMAT_BYTES        │
│              │samples                  │MCI_FORMAT_SAMPLES      │
├───────────────┼─────────────────────────┼─────────────────────────┤
│MIDI sequencer │milliseconds            │MCI_FORMAT_MILLISECONDS  │
│              │mmtime                  │MCI_FORMAT_MMTIME        │
│              │SMPTE 24                │MCI_SEQ_SET_SMPTE_24    │
│              │SMPTE 25                │MCI_SEQ_SET_SMPTE_25    │
│              │SMPTE 30                │MCI_SEQ_SET_SMPTE_30    │
│              │SMPTE 30                │MCI_SEQ_SET_SMPTE_30DROP │
│              │song pointer            │MCI_SEQ_SET_SONGPTR      │
└───────────────┴─────────────────────────┴─────────────────────────┘
</pre>
====MMTIME Format====
====MMTIME Format====
MMTIME is a standard time and media position format supported by the media control interface. This time unit is 1/3000 second, or 333 microseconds. Conversion macros are provided for convenient conversion of other popular time formats to and from this format. MMTIME values are passed as long (32-bit) integer values.
To use MMTIME on command messages, send the MCI_SET message specifying the MCI_SET_TIME_FORMAT flag. Use MCI_FORMAT_MMTIME in the ulTimeFormat field of the MCI_SET_PARMS structure.
The macros shown in the following figure are available for conversion to and from the MMTIME format.
<pre>
┌──────────────────────────────┬──────────────────────────────┐
│Conversion to MMTIME          │Conversion to Other Formats  │
├──────────────────────────────┼──────────────────────────────┤
│REDBOOKTOMM (ULONG)          │REDBOOKFROMMM (ULONG)        │
│FPS24TOMM (ULONG)            │FPS24FROMMM (ULONG)          │
│FPS25TOMM (ULONG)            │FPS25FROMMM (ULONG)          │
│FPS30TOMM (ULONG)            │FPS30FROMMM (ULONG)          │
│MSECTOMM (ULONG)              │MSECFROMMM (ULONG)            │
│HMSTOMM (ULONG)              │HMSFROMMM (ULONG)            │
└──────────────────────────────┴──────────────────────────────┘
</pre>
;Packed Time Formats
The packed time formats described in the following sections require that the application format the ULONG value passed in command message parameter structures. When these values are passed in string commands, any value containing a colon (:) is assumed to be a field-oriented value. For example, if the time format for a CD audio device is set to TMSF, and the value 4:10:00:00 is specified, this value is interpreted as track 4, 10 minutes, 0 seconds, and 0 frames. However, if the value 4100000 is specified, the integer is passed directly, and the assignment to byte fields is quite different.
It is not required that a field-oriented value contain specifications for all fields. For example, the following are equivalent specifications for track 4:
<pre>
4:00:00:00
4:00:00
4:00:
4:00
4:
4
</pre>
The interpretation of field-oriented values is left-justified with respect to the placement of colons. Values not specified default to zero. If a value has a colon, it is subject to field-oriented interpretation, regardless of the time format currently set for the device.
;HMSF (SMPTE) Packed Time Format
The HMSF packed time format represents elapsed hours, minutes, seconds, and frames from any specified point. This time format is packed into a 32-bit ULONG value as follows:
<pre>
┌───────────────┬───────────────┬───────────────┬───────────────┐
│High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
├───────────────┼───────────────┼───────────────┼───────────────┤
│Frames        │Seconds        │Minutes        │Hours          │
└───────────────┴───────────────┴───────────────┴───────────────┘
</pre>
;MSF Packed Time Format
The CD-DA MSF time format, also referred to as the Red Book time format, is based on the 75-frame-per-second CD digital audio standard. Media position values in this format are packed into a 32-bit ULONG value as follows:
<pre>
┌───────────────┬───────────────┬───────────────┬───────────────┐
│High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
├───────────────┼───────────────┼───────────────┼───────────────┤
│Reserved      │Frames        │Seconds        │Minutes        │
└───────────────┴───────────────┴───────────────┴───────────────┘
</pre>
The following macros aid in extracting information in packed MSF format:
<pre>
    Macro
        Description MSF_MINUTE(time)
        Gets the number of minutes. MSF_SECOND(time)
        Gets the number of seconds. MSF_FRAME(time)
        Gets the number of frames.
    For example, the following code fragment sets the time in ulTime to 6 minutes and 30 seconds (06:30:00).
    ULONG ulTime;.
    .
    .
    MSF_MINUTE(ulTime) = 6
    MSF_SECOND(ulTime) = 30;
    MSF_FRAME(ulTime) = 0;
    TMSF Packed Time Format
</pre>
The CD-DA TMSF time format is based on the 75-frame-per-second CD digital audio standard. Media position values in this format are packed into a 32-bit ULONG value as follows:
<pre>
    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
    ├───────────────┼───────────────┼───────────────┼───────────────┤
    │Frames        │Seconds        │Minutes        │Track          │
    └───────────────┴───────────────┴───────────────┴───────────────┘
</pre>
The following macros aid in extracting information in packed TMSF format:
    Macro
        Description TMSF_TRACK(time)
        Gets the number of tracks. TMSF_MINUTE(time)
        Gets the number of minutes. TMSF_SECOND(time)
        Gets the number of seconds. TMSF_FRAME(time)
        Gets the number of frames.
For example, the following code fragment sets the time in ulTime to 2 minutes into track 2 (02:02:00:00).
    ULONG ulTime;.
    .
    .
    TMSF_TRACK(ulTime) = 2;
    TMSF_MINUTE(ulTime) = 2;
    TMSF_SECOND(ulTime) = 0;
    TMSF_FRAME(ulTime) = 0;
;Note: MSF and TMSF macros can be found in the MCIOS2.H file.
;HMS Packed Time Format
The HMS packed time format, representing hours, minutes, and seconds, is packed into a 32-bit ULONG value as follows:
<pre>
    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
    ├───────────────┼───────────────┼───────────────┼───────────────┤
    │Reserved      │Seconds        │Minutes        │Hours          │
    └───────────────┴───────────────┴───────────────┴───────────────┘
</pre>


==Opening a Media Device==
==Opening a Media Device==

Revision as of 01:36, 5 November 2025

This section describes the services offered to applications by the media control interface for managing devices in the multimedia environment.

Command Message and Command String Interfaces

When a user activates a PM control to use a multimedia device function, the OS/2 multimedia application window procedure sends a command to the media control interface. Depending on the needs of the application, the window procedure can use the command message interface or the command string interface to implement these device commands. Messages for the command message interface (also referred to as procedural interface) are sent with mciSendCommand. Strings for the command string interface are sent to the Media Device Manager for parsing, using the mciSendString function. See the following figure.

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|         mciSendCommand                     mciSendString                  |
|                │                                 │                        |
|                │                                 │                        |
|                �                                 �                        |
|   ┌───────────────────────────────────────────────────────────┐           |
|   │          Media Device Manager Interface Layer             │           |
M   └──┬───────────────────────┬────────────────────────────────┘           |
D      │                       │                                            |
M      │                       │                           Default Tables   |
|      │                       │                            ┌──────────────┐|
|      │          ┌────────────┴──────────────┐         ┌───┤    System    │|
|      │          │    Table-Driven Parser    │-────────┤   ├──────────────┤|
|      │          └────────────┬──────────────┘         │   │   waveaudio  │|
|      └─────────────┬─────────┘            |           │   ├──────────────┤|
|                    │                      │           │   │   sequencer  │|
|                    |                      │           │   ├──────────────┤|
|    ┌───────────────────────────┐          │           │   │    cdaudio   │|
|    │    Media Device Manager   │          │           │   ├──────────────┤|
|    └──┬────────┬────────┬──────┘          │           │   │     cdxa     │|
|_ _ _ _│ _ _ _ _│ _ _ _ _│_ _ _ _ _ _ _ _ _│_ _ _      │   ├──────────────┤|
        │        │        │                 │    |      │   │    ampmix    │|
     ┌──┴───┐ ┌──┴───┐ ┌──┴───┐             │    |      │   ├──────────────┤|
     │Media │ │Media │ │Media │             │    |      │   │   videodisc  │|
     │Driver│ │Driver│ │Driver│             │    |      │   ├──────────────┤|
     └──────┘ └──────┘ └──────┘             │    |      │   │ digitalvideo │|
                       ┌──────┐             │    |      │   ├──────────────┤|
                       │Custom├─────────────┘    |      └───┤     other    │|
                       │Table │                  |          └──────────────┘|
                       └──────┘                  | _ _ _ _ _ _ _ _ _ _ _ _ _|

The string interface provides access to most functions of the message interface. However, operations that involve identifying multiple devices (for example, for the purpose of establishing connections), or operations that return complex data structures (such as a CD table of contents) are available only through the message interface.

Each time a message is sent to the Media Device Manager with mciSendCommand, flags are set and a pointer to a data structure is passed. Each time a string is passed with mciSendString, it must be converted to the message format understood by the media driver. The Media Device Manager calls the multimedia string parser, which is case insensitive, to interpret the strings. The time required for this conversion process makes the string method of control slightly slower than the message method. However, the string interface generally requires less application code than the command message interface. The string interface also lets users interactively control devices with a command line or PM interface. See Command Strings.


Command Messages

Command messages are used by the command message interface and specified with mciSendCommand. Most command messages have corresponding string commands that are used by the command string interface and specified with mciSendString. Command messages are sent either to a logical device or to the system. The following table lists the command messages sent to devices. Commands that cause asynchronous responses to be generated, such as cue point and position advise, can be called using the appropriate string command; however, their responses are returned to window procedures.
┌────────────────────────┬────────────────────────────────────┐
│Command Messages        │                                    │
│Supported by All Devices│                                    │
├────────────────────────┼────────────────────────────────────┤
│MCI_OPEN                │Establishes a specific instance of a│
│                        │multimedia device or file.          │
├────────────────────────┼────────────────────────────────────┤
│MCI_GETDEVCAPS          │Gets the capabilities of a device.  │
├────────────────────────┼────────────────────────────────────┤
│MCI_INFO                │Gets textual information from the   │
│                        │device.                             │
├────────────────────────┼────────────────────────────────────┤
│MCI_STATUS              │Gets the current status of the      │
│                        │device.                             │
├────────────────────────┼────────────────────────────────────┤
│MCI_CLOSE               │Closes the device.                  │
├────────────────────────┼────────────────────────────────────┤
│Device Setup Command    │                                    │
│Messages                │                                    │
├────────────────────────┼────────────────────────────────────┤
│MCI_SET                 │Changes the configuration of the    │
│                        │device.                             │
├────────────────────────┼────────────────────────────────────┤
│MCI_CONNECTOR           │Enables, disables, or queries the   │
│                        │state of a connector.               │
├────────────────────────┼────────────────────────────────────┤
│Playback and Recording  │                                    │
│Command Messages        │                                    │
├────────────────────────┼────────────────────────────────────┤
│MCI_CUE                 │Prerolls a device for playing or    │
│                        │recording.                          │
├────────────────────────┼────────────────────────────────────┤
│MCI_SEEK                │Seeks to a specified position in the│
│                        │file.                               │
├────────────────────────┼────────────────────────────────────┤
│MCI_PLAY                │Begins transmitting output data.    │
├────────────────────────┼────────────────────────────────────┤
│MCI_RECORD              │Begins recording data from the      │
│                        │specified position.                 │
├────────────────────────┼────────────────────────────────────┤
│MCI_PAUSE               │Suspends the playing or recording   │
│                        │operation.                          │
├────────────────────────┼────────────────────────────────────┤
│MCI_RESUME              │Resumes the playing or recording    │
│                        │operation.                          │
├────────────────────────┼────────────────────────────────────┤
│MCI_STOP                │Stops the playing or recording      │
│                        │operation.                          │
├────────────────────────┼────────────────────────────────────┤
│MCI_LOAD                │Loads a data element into a media   │
│                        │device. An example of a data element│
│                        │is a waveform file.                 │
├────────────────────────┼────────────────────────────────────┤
│MCI_SAVE                │Saves the current file to disk.     │
├────────────────────────┼────────────────────────────────────┤
│Synchronization Command │                                    │
│Messages                │                                    │
├────────────────────────┼────────────────────────────────────┤
│MCI_SET_CUEPOINT        │Sets run-time cue points.           │
├────────────────────────┼────────────────────────────────────┤
│MCI_SET_POSITION_ADVISE │Advises the application when time   │
│                        │elapses or position changes.        │
├────────────────────────┼────────────────────────────────────┤
│MCI_SET_SYNC_OFFSET     │Biases MCI_PLAY starting positions  │
│                        │and MCI_SEEK target positions for   │
│                        │group operations.                   │
├────────────────────────┼────────────────────────────────────┤
│Device-Specific Command │                                    │
│Messages                │                                    │
├────────────────────────┼────────────────────────────────────┤
│MCI_CAPTURE             │Captures the current video image and│
│                        │stores it as an image device        │
│                        │element.                            │
├────────────────────────┼────────────────────────────────────┤
│MCI_ESCAPE              │Sends a custom message directly to  │
│                        │the media driver.                   │
├────────────────────────┼────────────────────────────────────┤
│MCI_GETIMAGEBUFFER      │Gets the contents of the capture    │
│                        │video buffer or the current movie   │
│                        │frame.                              │
├────────────────────────┼────────────────────────────────────┤
│MCI_GETTOC              │Gets a contents structure for the   │
│                        │currently loaded CD-ROM disc.       │
├────────────────────────┼────────────────────────────────────┤
│MCI_PUT                 │Sets the source and destination     │
│                        │rectangles for the transformation of│
│                        │the video image.  It also sets the  │
│                        │size and position of the default    │
│                        │video.                              │
├────────────────────────┼────────────────────────────────────┤
│MCI_REWIND              │Seeks the media to the beginning    │
│                        │point.                              │
├────────────────────────┼────────────────────────────────────┤
│MCI_SETTUNER            │Causes the digital video MCD to     │
│                        │change the frequency the tuner      │
│                        │device is tuned to.                 │
├────────────────────────┼────────────────────────────────────┤
│MCI_SPIN                │Spins the videodisc player up or    │
│                        │down.                               │
├────────────────────────┼────────────────────────────────────┤
│MCI_STEP                │Advances or backs up the videodisc  │
│                        │player one or more frames.          │
├────────────────────────┼────────────────────────────────────┤
│MCI_WHERE               │Returns the source and destination  │
│                        │rectangles set by MCI_PUT. It also  │
│                        │returns the size and position of the│
│                        │video window.                       │
├────────────────────────┼────────────────────────────────────┤
│MCI_WINDOW              │Specifies the window in which to    │
│                        │display video output, and controls  │
│                        │the visibility of the default video │
│                        │window.                             │
├────────────────────────┼────────────────────────────────────┤
│Editing Command Messages│                                    │
├────────────────────────┼────────────────────────────────────┤
│MCI_COPY                │Copies specified data range into    │
│                        │clipboard or buffer.                │
├────────────────────────┼────────────────────────────────────┤
│MCI_CUT                 │Removes specified data range and    │
│                        │places it into clipboard or buffer. │
├────────────────────────┼────────────────────────────────────┤
│MCI_DELETE              │Deletes specified data range.       │
│                        │Clipboard or buffer is not used.    │
├────────────────────────┼────────────────────────────────────┤
│MCI_PASTE               │Deletes selected data range if      │
│                        │difference between FROM and TO is   │
│                        │more than zero, then inserts data   │
│                        │from buffer or clipboard.           │
├────────────────────────┼────────────────────────────────────┤
│MCI_REDO                │Reverses previous MCI_UNDO command. │
├────────────────────────┼────────────────────────────────────┤
│MCI_UNDO                │Cancels previous RECORD, CUT, PASTE,│
│                        │or DELETE.                          │
└────────────────────────┴────────────────────────────────────┘

The following table lists the system command messages specified with mciSendCommand.

┌────────────────────────┬────────────────────────────────────┐
│MCI_DEVICESETTINGS      │Provides a media control interface  │
│                        │driver the opportunity to insert    │
│                        │custom settings pages.              │
├────────────────────────┼────────────────────────────────────┤
│MCI_GROUP               │Makes and breaks device group       │
│                        │associations.                       │
├────────────────────────┼────────────────────────────────────┤
│MCI_MASTERAUDIO         │Sets the system master volume and   │
│                        │toggles speakers and headphones.    │
├────────────────────────┼────────────────────────────────────┤
│MCI_SYSINFO             │Gets and sets device and system     │
│                        │information.                        │
├────────────────────────┼────────────────────────────────────┤
│MCI_CONNECTORINFO       │Gets information regarding the      │
│                        │number and types of connectors      │
│                        │defined for a device.               │
├────────────────────────┼────────────────────────────────────┤
│MCI_DEFAULT_CONNECTION  │Makes, breaks, or queries default   │
│                        │connections established for a       │
│                        │device.                             │
├────────────────────────┼────────────────────────────────────┤
│MCI_CONNECTION          │Gets the device context connection  │
│                        │or establishes an alias for a       │
│                        │connected device.                   │
├────────────────────────┼────────────────────────────────────┤
│MCI_ACQUIREDEVICE       │Acquires a device for use.          │
├────────────────────────┼────────────────────────────────────┤
│MCI_RELEASEDEVICE       │Releases a device from use.         │
└────────────────────────┴────────────────────────────────────┘

Command Strings

String commands utilize a more English text format than command messages. Following is the valid syntax for passing string commands directly to the media control interface:

<COMMAND> <DEVICE_TYPE|DEVICE_NAME|ALIAS|ELEMENT> <PARAMETERS>

This format is used for all string commands except masteraudio, which does not require a device name. The format for the masteraudio command is:

<COMMAND> <PARAMETERS>

An application calls mciSendString to pass the string command to the Media Device Manager for parsing and execution. The String Test Sample program, provided in the Toolkit (\TOOLKIT\SAMPLES\MM\MCISTRNG), illustrates the interpretive string interface. The following code fragment shows the call to mciSendString in the String Test Sample.

ulSendStringRC =
  mciSendString(
   (PSZ) &acMCIString[ 0 ],          /* The MCI String Command     */
   (PSZ) &acMCIReturnString[ 0 ],    /* Place for return strings   */
   (USHORT) MCI_RETURN_STRING_LENGTH, /* Length of return space     */
   hwndDisplayDialogBox,              /* Window to receive notifies */
   usCountOfMCIStringSent );          /* The user parameter         */

The following is an example of the string commands required to open a CD player and play an entire CD.

open cdaudio01 alias cdaud1 shareable
status cdaud1 media present wait
status cdaud1 mode wait
set cdaud1 time format milliseconds
seek cdaud1 to start
play cdaud1 notify
.
.
.
** play the entire disc **
.
.
.
close cdaud1

The status commands let the application know if a CD is present and if the drive is ready. Notice that wait flags are used; otherwise the commands would return immediately with no status information. The set command sets the time base to milliseconds for all future commands. The close command is sent after the application receives an MM_MCINOTIFY message at the completion of the play command.

Note
The close command can be sent at any time.

Authoring languages that include support for the media control interface can integrate device command strings like these with authoring language syntax to create multimedia presentations. The string interface provides a 16-bit interface to enable developers to integrate multimedia function with the macro languages of existing 16-bit applications.

Wait and Notify Flags

An application can set a wait or a notify flag on a device command sent with mciSendString or mciSendCommand. These two flags are mutually exclusive and are available on all commands except some system commands.

┌───────────────┬─────────────────────────────────────────────┐
│Flag           │Description                                  │
├───────────────┼─────────────────────────────────────────────┤
│wait           │The command is executed synchronously.  The  │
│               │function waits until the requested action is │
│               │complete before returning to the application.│
├───────────────┼─────────────────────────────────────────────┤
│notify         │The command is executed asynchronously,      │
│               │allowing control to be returned immediately  │
│               │to the application.  When the requested      │
│               │action is complete, an MM_MCINOTIFY message  │
│               │is sent to the application window procedure. │
└───────────────┴─────────────────────────────────────────────┘
Note
If a command is issued without a wait flag or notify flag specified, the command is executed asynchronously, and the application is never notified.

The wait flag is useful for operations that are conducted quickly, like the playback of short sounds, which the application wants to complete before it continues. The wait flag is also useful for operations that return information, such as device capabilities, because the Media Device Manager parser converts the return code to a meaningful string. However, the conversion occurs only if the wait flag is specified.

The wait flag should be used with care when issuing commands from threads that read application input message queues as it ties up the thread, preventing all PM messages in the system from being processed while the command issued with the wait flag is executed.

The notify flag is useful for operations that are conducted over a period of time. For example, the playing of a waveform file often can take a while to complete. By specifying the notify flag, an application requests to be notified when processing of the command is complete. The application window procedure can then remain responsive to input queue processing.

OS/2 Multimedia Notification Messages

The system returns notification messages to applications to indicate OS/2 multimedia events such as completing a media device function or passing ownership of a media device from one process to another. Following is a list of OS/2 multimedia notification messages.

┌─────────────────────┬──────────────────────────────────────────────────┐
│Notification Message │Reason for Notification                           │
├─────────────────────┼──────────────────────────────────────────────────┤
│MM_MCICUEPOINT       │A cue point was detected. Cue points are set with │
│                     │the playlist CUEPOINT instruction or the          │
│                     │MCI_SET_CUEPOINT command message.                 │
├─────────────────────┼──────────────────────────────────────────────────┤
│MM_MCIEVENT          │A device has generated an event.                  │
├─────────────────────┼──────────────────────────────────────────────────┤
│MM_MCINOTIFY         │A device has completed an action, or an error has │
│                     │occurred.                                         │
├─────────────────────┼──────────────────────────────────────────────────┤
│MM_MCIPASSDEVICE     │A shared device is being lost or gained.          │
├─────────────────────┼──────────────────────────────────────────────────┤
│MM_MCIPLAYLISTMESSAGE│A MESSAGE instruction was encountered in a        │
│                     │playlist.                                         │
├─────────────────────┼──────────────────────────────────────────────────┤
│MM_MCIPOSITIONCHANGE │The time period or position specified with the    │
│                     │MCI_SET_POSITION_ADVISE command message has       │
│                     │passed.                                           │
└─────────────────────┴──────────────────────────────────────────────────┘

With the exception of MM_MCIEVENT, the system returns notification messages asynchronously to applications using WinPostMsg; MM_MCIEVENT notifications are returned synchronously with WinSendMsg.

A PM application receives notifications by passing its message queue window handle as a parameter on the mciSendCommand or mciSendString call. Applications can also receive notifications by passing a handle to a Control Program queue. For more information see Using a Control Program Queue for Notifications.

If an application sends a command message with mciSendCommand and specifies the MCI_NOTIFY flag, control returns immediately to the application. The media control interface posts a notification message to the window specified in the callback window handle after the command completes processing. The MM_MCINOTIFY message is returned asynchronously to the application using WinPostMsg. It can have any of the following values:

┌────────────────────────┬────────────────────────────────────┐
│Notification Code       │Meaning                             │
├────────────────────────┼────────────────────────────────────┤
│MCI_NOTIFY_SUCCESSFUL   │The command completed successfully. │
├────────────────────────┼────────────────────────────────────┤
│MCI_NOTIFY_SUPERSEDED   │Another command is being processed. │
├────────────────────────┼────────────────────────────────────┤
│MCI_NOTIFY_ABORTED      │Another command interrupted this    │
│                        │one.                                │
└────────────────────────┴────────────────────────────────────┘
Note
If none of the above notification codes are returned, an error code is returned, indicating that the asynchronous processing of the command ended in an error condition. To convert the error code to a textual description of the error, the application calls the mciGetErrorString function.

The following code fragment illustrates how the Audio Recorder Sample program, provided in the Toolkit (\TOOLKIT\SAMPLES\MM\RECORDER), handles the MM_MCINOTIFY notification message.

    case MM_MCINOTIFY:
     /*
      * This message is returned to an application when a device
      * successfully completes a command that was issued with a NOTIFY
      * flag, or when an error occurs with the command.
      *
      * This message returns two values. A user parameter (mp1) and
      * the command message (mp2) that was issued. The low word of mp1
      * is the Notification Message Code, which indicates the status of the
      * command like success or failure. The high word of mp2 is the
      * Command Message which indicates the source of the command.
      */

      usNotifyCode = (USHORT) SHORT1FROMMP( mp1);     /* low-word  */
      usCommandMessage = (USHORT) SHORT2FROMMP( mp2); /* high-word */

      switch (usCommandMessage)
      {
       case MCI_PLAY:
          switch (usNotifyCode)
          {
             case MCI_NOTIFY_SUCCESSFUL:
                if (eState != ST_STOPPED)
                {
                   /*
                    * Update the status line with appropriate message.
                    */
                   UpdateTheStatusLine(hwnd, IDS_STOPPED);
                   eState = ST_STOPPED;

                   /*
                    * Stop the play button animation
                    */
                   WinSendMsg( hwndPlayPB,        /* Play button handle */
                               GBM_ANIMATE,       /* Animation control  */
                               MPFROMSHORT(FALSE),/* Animation flag     */
                               NULL );            /* Ignore return data */
                }
                break;

             case MCI_NOTIFY_SUPERSEDED:
             case MCI_NOTIFY_ABORTED:
                /* we don't need to handle these messages. */
                break;

             default:
                /*
                 * If the message is none of the above, then it must be
                 * a notification error message.
                 */
                ShowMCIErrorMessage( usNotifyCode);
                eState = ST_STOPPED;

                /*
                 * Stop the play button animation and update the status
                 * line with appropriate text.
                 */
                WinSendMsg( hwndPlayPB,         /* Play button handle  */
                            GBM_ANIMATE,        /* Animation control   */
                            MPFROMSHORT(FALSE), /* Animation flag      */
                            NULL );             /* Ignore return data  */
                UpdateTheStatusLine(hwnd, IDS_STOPPED);
                break;
          }
          break;
    }
    return( (MRESULT) 0);

Using a Control Program Queue for Notifications

An OS/2 application that does not have a PM window, and therefore cannot use a PM message queue for receiving notification messages, can use an OS/2 Control Program queue instead. The Control Program queue method of notification should also be considered for time-critical PM applications, because it is faster than using the PM message queue.

To receive notifications on a Control Program queue, the application must specify the MCI_DOS_QUEUE flag with the MCI_OPEN command message when using mciSendCommand (or the dosqueue keyword with the open command when using mciSendString). This flag indicates that the window handle specified for receiving notification messages is actually a handle to a Control Program queue, not a PM window.

The application issues DosReadQueue, which mimics the PM message queue function by blocking until there is something in the queue to process. To place a notification message in the queue, the system issues DosWriteQueue and specifies the queue handle given to it by the application.

The syntax for Control Program queues and PM message queues varies slightly. A typical PM message queue process function has the following four parameters:

HWND         hwnd   /* Window handle       */
ULONG        msg    /* Notification type   */
MPARAM       mp1    /* Message parameter 1 */
MPARAM       mp2    /* Message parameter 2 */

The DosReadQueue call has eight parameters. The system uses the first four parameters of DosReadQueue in the same manner as a PM message queue process function.

HQUEUE       hq     /* Queue handle */
PREQUESTDATA pRD    /* Pointer to REQUESTDATA */
PULONG       pmp1   /* Pointer to mp1 information */
PPVOID       pmp2   /* Pointer to mp2 information */

The second parameter of DosReadQueue points to the REQUESTDATA structure, which contains a ulData field. This field corresponds to the msg field of PM message queues. The application can use the remaining parameters of DosReadQueue for its own purposes.

The following example code illustrates how an application can use Control Program queue functions to handle multimedia notification messages.

{
 PID      OwnerPID=0;
 HQUEUE   QHandle =0;
 char     ch, retstring[100], QueueName[100];

 strcpy(QueueName, "\\QUEUES\\");
 if (argc == 2) strcat(QueueName, argv[1]);
 else           strcat(QueueName, "DEFAULT");
 if (DosCreateQueue(&QHandle, QUE_FIFO, QueueName)) return(1L);
 if (DosOpenQueue(&OwnerPID, &QHandle, QueueName))  return(1L);
 _beginthread( QMonitor, (PVOID)NULL, 65536L, (PVOID)QHandle);
 SendString((LPSTR)"open d:\\mmos2\\sounds\\applause.wav shareable
             dosqueue wait alias a",
            (LPSTR)retstring, 100,
            (HWND)QHandle, 0);
 SendString((LPSTR)"setpositionadvise a on every 3000 wait",
            (LPSTR)retstring, 100,
            (HWND)QHandle, 0);
 SendString((LPSTR)"play a notify", (LPSTR)retstring, 100, (HWND)QHandle, 0);
 ch=(char)getch();
 SendString((LPSTR)"close a wait", (LPSTR)retstring, 100, (HWND)QHandle, 0);
 DosCloseQueue(QHandle);
 return(0L);
}

VOID _Optlink QMonitor( PVOID qh)
{
 APIRET      rc=0;
 BYTE        Priority;
 REQUESTDATA RD;
 ULONG       msg, mp1, mp2;

 printf("QMonitor Started!\n");
 while (1)
  {
   DosReadQueue((HQUEUE)qh, &RD, (PULONG)&mp1, (PPVOID)&mp2, 0L, (BOOL32)0,
                &Priority, (HEV)0);
   switch(RD.ulData)
     {
       case MM_MCINOTIFY:
          printf("   msg=MM_MCINOTIFY:\n");
          printf("   mp1=%d\n",mp1);
          printf("   mp2=%d\n",mp2);
          break;
       case MM_MCIPASSDEVICE:
          printf("   msg=MM_MCIPASSDEVICE:\n");
          printf("   Device id=%d\n",mp1);
          switch (mp2)
            {
              case MCI_LOSING_USE:
                 printf("   MCI_LOSING_USE:\n");
                 break;
              case MCI_GAINING_USE:
                 printf("   MCI_GAINING_USE:\n");
                 break;
              default:
                 printf("   mp2=%d\n",mp2);
                 break;
            }
          break;
       case MM_MCIPOSITIONCHANGE:
          printf("   msg=MM_MCIPOSITIONCHANGE:\n");
          printf("   mp1=%d\n",mp1);
          printf("   mp2=%d\n",mp2);
          break;
       case MM_MCICUEPOINT:
          printf("   msg=MM_MCICUEPOINT:\n");
          printf("   mp1=%d\n",mp1);
          printf("   mp2=%d\n",mp2);
          break;
       case MM_MCIPLAYLISTMESSAGE:
          printf("   msg=MM_MCIPLAYLISTMESSAGE:\n");
          printf("   mp1=%d\n",mp1);
          printf("   mp2=%d\n",mp2);
          break;
       case MM_MCIEVENT:
          printf("   msg=MM_MCIEVENT:\n");
          printf("   mp1=%d\n",mp1);
          printf("   mp2=%d\n",mp2);
          break;
       default:
          printf("   msg=%d\n",RD.ulData);
          printf("   mp1=%d\n",mp1);
          printf("   mp2=%d\n",mp2);
          break;
     }
  }   /* endwhile */
 return;
}


VOID SendString( LPSTR string, LPSTR retstring, ULONG retsize, HWND Handle,
                 ULONG userparm)
{
 ULONG rc;
 rc=mciSendString(string, retstring, retsize, Handle, userparm);
 if (rc) printf("Error: (%s) rc=%d\n",string,rc);
 return;
}
/* QUEUE.H */
#define INCL_BASE
#define INCL_32

#include<os2.h>
#include<os2me.h>
#include<mmioos2.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>

int           main(int argc, char *argv[], char *envp[]);
VOID          SendString(LPSTR string,
                         LPSTR retstring,
                         ULONG retsize,
                         HWND Handle,
                         ULONG userparm);
VOID _Optlink QMonitor( PVOID qh);

Time Formats for Device Commands

Media position and time information are required as input and also returned as output by many multimedia commands. Time formats vary, depending on the device being used and the format of the data being operated on. The default time base for both the procedural and string interfaces is MMTIME. See MMTIME Format.

Other time formats, such as milliseconds, are also supported.

Time formats used by media control interface devices for measuring time are listed in the following table. The flags shown in the table are set with the MCI_SET command.

┌───────────────┬─────────────────────────┬─────────────────────────┐
│Device         │Formats                  │Flags                    │
├───────────────┼─────────────────────────┼─────────────────────────┤
│CD-DA          │milliseconds             │MCI_FORMAT_MILLISECONDS  │
│               │mmtime                   │MCI_FORMAT_MMTIME        │
│               │minutes-seconds-frames   │MCI_FORMAT_MSF           │
│               │tracks-min-sec-frame     │MCI_FORMAT_TMSF          │
├───────────────┼─────────────────────────┼─────────────────────────┤
│CD-XA          │milliseconds             │MCI_FORMAT_MILLISECONDS  │
│               │mmtime                   │MCI_FORMAT_MMTIME        │
├───────────────┼─────────────────────────┼─────────────────────────┤
│digital video  │milliseconds             │MCI_FORMAT_MILLISECONDS  │
│               │mmtime                   │MCI_FORMAT_MMTIME        │
│               │frames                   │MCI_FORMAT_FRAMES        │
│               │hours-minutes-seconds    │MCI_FORMAT_HMS           │
│               │hours-min-sec-frames     │MCI_FORMAT_HMSF          │
├───────────────┼─────────────────────────┼─────────────────────────┤
│waveform audio │milliseconds             │MCI_FORMAT_MILLISECONDS  │
│               │mmtime                   │MCI_FORMAT_MMTIME        │
│               │bytes                    │MCI_FORMAT_BYTES         │
│               │samples                  │MCI_FORMAT_SAMPLES       │
├───────────────┼─────────────────────────┼─────────────────────────┤
│MIDI sequencer │milliseconds             │MCI_FORMAT_MILLISECONDS  │
│               │mmtime                   │MCI_FORMAT_MMTIME        │
│               │SMPTE 24                 │MCI_SEQ_SET_SMPTE_24     │
│               │SMPTE 25                 │MCI_SEQ_SET_SMPTE_25     │
│               │SMPTE 30                 │MCI_SEQ_SET_SMPTE_30     │
│               │SMPTE 30                 │MCI_SEQ_SET_SMPTE_30DROP │
│               │song pointer             │MCI_SEQ_SET_SONGPTR      │
└───────────────┴─────────────────────────┴─────────────────────────┘

MMTIME Format

MMTIME is a standard time and media position format supported by the media control interface. This time unit is 1/3000 second, or 333 microseconds. Conversion macros are provided for convenient conversion of other popular time formats to and from this format. MMTIME values are passed as long (32-bit) integer values.

To use MMTIME on command messages, send the MCI_SET message specifying the MCI_SET_TIME_FORMAT flag. Use MCI_FORMAT_MMTIME in the ulTimeFormat field of the MCI_SET_PARMS structure.

The macros shown in the following figure are available for conversion to and from the MMTIME format.

┌──────────────────────────────┬──────────────────────────────┐
│Conversion to MMTIME          │Conversion to Other Formats   │
├──────────────────────────────┼──────────────────────────────┤
│REDBOOKTOMM (ULONG)           │REDBOOKFROMMM (ULONG)         │
│FPS24TOMM (ULONG)             │FPS24FROMMM (ULONG)           │
│FPS25TOMM (ULONG)             │FPS25FROMMM (ULONG)           │
│FPS30TOMM (ULONG)             │FPS30FROMMM (ULONG)           │
│MSECTOMM (ULONG)              │MSECFROMMM (ULONG)            │
│HMSTOMM (ULONG)               │HMSFROMMM (ULONG)             │
└──────────────────────────────┴──────────────────────────────┘
Packed Time Formats

The packed time formats described in the following sections require that the application format the ULONG value passed in command message parameter structures. When these values are passed in string commands, any value containing a colon (:) is assumed to be a field-oriented value. For example, if the time format for a CD audio device is set to TMSF, and the value 4:10:00:00 is specified, this value is interpreted as track 4, 10 minutes, 0 seconds, and 0 frames. However, if the value 4100000 is specified, the integer is passed directly, and the assignment to byte fields is quite different.

It is not required that a field-oriented value contain specifications for all fields. For example, the following are equivalent specifications for track 4:

4:00:00:00
4:00:00
4:00:
4:00
4:
4

The interpretation of field-oriented values is left-justified with respect to the placement of colons. Values not specified default to zero. If a value has a colon, it is subject to field-oriented interpretation, regardless of the time format currently set for the device.


HMSF (SMPTE) Packed Time Format

The HMSF packed time format represents elapsed hours, minutes, seconds, and frames from any specified point. This time format is packed into a 32-bit ULONG value as follows:

┌───────────────┬───────────────┬───────────────┬───────────────┐
│High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
├───────────────┼───────────────┼───────────────┼───────────────┤
│Frames         │Seconds        │Minutes        │Hours          │
└───────────────┴───────────────┴───────────────┴───────────────┘
MSF Packed Time Format

The CD-DA MSF time format, also referred to as the Red Book time format, is based on the 75-frame-per-second CD digital audio standard. Media position values in this format are packed into a 32-bit ULONG value as follows:

┌───────────────┬───────────────┬───────────────┬───────────────┐
│High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
├───────────────┼───────────────┼───────────────┼───────────────┤
│Reserved       │Frames         │Seconds        │Minutes        │
└───────────────┴───────────────┴───────────────┴───────────────┘

The following macros aid in extracting information in packed MSF format:

    Macro
        Description MSF_MINUTE(time)
        Gets the number of minutes. MSF_SECOND(time)
        Gets the number of seconds. MSF_FRAME(time)
        Gets the number of frames. 

    For example, the following code fragment sets the time in ulTime to 6 minutes and 30 seconds (06:30:00).

    ULONG ulTime;.
    .
    .
    MSF_MINUTE(ulTime) = 6
    MSF_SECOND(ulTime) = 30;
    MSF_FRAME(ulTime) = 0;


    TMSF Packed Time Format

The CD-DA TMSF time format is based on the 75-frame-per-second CD digital audio standard. Media position values in this format are packed into a 32-bit ULONG value as follows:

    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
    ├───────────────┼───────────────┼───────────────┼───────────────┤
    │Frames         │Seconds        │Minutes        │Track          │
    └───────────────┴───────────────┴───────────────┴───────────────┘

The following macros aid in extracting information in packed TMSF format:

   Macro
       Description TMSF_TRACK(time)
       Gets the number of tracks. TMSF_MINUTE(time)
       Gets the number of minutes. TMSF_SECOND(time)
       Gets the number of seconds. TMSF_FRAME(time)
       Gets the number of frames. 

For example, the following code fragment sets the time in ulTime to 2 minutes into track 2 (02:02:00:00).

   ULONG ulTime;.
   .
   .
   TMSF_TRACK(ulTime) = 2;
   TMSF_MINUTE(ulTime) = 2;
   TMSF_SECOND(ulTime) = 0;
   TMSF_FRAME(ulTime) = 0;
Note
MSF and TMSF macros can be found in the MCIOS2.H file.


HMS Packed Time Format

The HMS packed time format, representing hours, minutes, and seconds, is packed into a 32-bit ULONG value as follows:

    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │High-Order Byte│Low-Order Byte │High-Order Byte│Low-Order Byte │
    ├───────────────┼───────────────┼───────────────┼───────────────┤
    │Reserved       │Seconds        │Minutes        │Hours          │
    └───────────────┴───────────────┴───────────────┴───────────────┘

Opening a Media Device

       File Type Associations
       Default and Specific Devices
       Shareable Flag
       Device Alias
       Using the Command Message Interface 

Memory Playlists

       Clock Sample Program Playlist Example
           Setting up the Playlist 
       Dynamic Playlist Modification
       Using a Playlist for Recording 

Editing Operations

       Clipboard and Resource Formats
       Audio Media Driver Clipboard Commands 

Device Sharing By Applications

       Getting Control of a Shared Device
       Using a Device Exclusively 

Device Groups

       Duet Player Sample Program Example
       Resource Allocation 

Event Synchronization

       Cue Points
       Position Advises 

System Values

       Clock Sample Program Caption Query