Allegro CL version 10.1
Unrevised from 10.0 to 10.1.
10.0 version

About MCI support in Common Graphics

This document contains the following sections:

1.0 Introduction to MCI functionality in Common Graphics
2.0 MCI functionality

1.0 Introduction to MCI functionality in Common Graphics

The Allegro CL Multimedia extension provides a high-level CLOS-based programmatic interface to the standard Windows Media Control Interface (MCI) functionality. Various multimedia devices such as the audio CD player, digital sound files (wave audio), MIDI files, and animation files, can be operated using a small amount of very straightforward lisp code.

Each type of multimedia device is represented by a CLOS class, and each particular multimedia device by a CLOS instance. A CLOS method is supplied for each operation that a device can perform, such as opening, playing, seeking to a new position, or asking about the current state of the device.

The following simple example is all the code that's needed in order to play an audio CD disc from its current position to the end:

(in-package :cg-user)
(setq cd (make-instance 'mci-cd-audio))
(mci-open cd)
(mci-play cd)

While cd-audio is a "simple device" which always plays whatever is loaded into the physical cd player, other types of multimedia devices (called "compound devices") can play sounds or animations from various files. For these devices, you can specify the filename to play when opening the device.

The next example would use one logical wave-audio device to play two sound files in succession (these calls assume the relavant files are in c:\\windows\\Media\\, which may be incorrect on your machine; evaluating (sys::windows-directory), using the internal function sys:windows-directory, should return the correct parent of the Media directory):

(setq wav (make-instance 'mci-wave-audio))
(mci-open wav :file "c:\\windows\\Media\\chord.wav")
(mci-play wav :wait-p t)
(mci-close wav)
(mci-open wav :file "c:\\windows\\Media\\tada.wav")
(mci-play wav :wait-p t)

The :wait-p flag above causes the mci-play function to not return until the sound is finished playing, so that the second file will not be played until the first one is done. By default, mci functions will return asynchronously so that you can continue other processing while the activity requested by the function call is being performed.

A related argument is the :notify-p flag. When this is passed, the mci-notify generic function will be called when the operation is complete, with a value indicating whether the operation completed successfully, failed, or was interrupted by the user. You can redefine the mci-notify method for your own subclasses or instances in order to look at the notification and act on it however you wish.

For finer control over device operation, various optional keyword arguments are provided by the methods. For example, to play the first minute of the third track on the cd:

(mci-device-set-time-format cd :tmsf)
(mci-play cd :from (tmsf-to-integer 3 0 0 0)
             :to (tmsf-to-integer 3 1 0 0))

The above code first tells the device to use the track-minute-second-frame (:tmsf) time format for describing its current location, and then tells the CD to play from "track 3 minute 0" to "track 3 minute 1". (The function tmsf-to-integer is required because there are various time formats that use different numbers of components.) To determine the current position of the CD device while it is playing, use:

(multiple-value-setq (track minute second frame)
  (integer-to-tmsf (mci-device-position cd)))

If mci-open is called when no device of the requested class is available, an error occurs with an error message from the operating system indicating why the device could not be opened. A device may not be available either because there is no such device installed on the computer, or because this application or other applications have all such devices open already. Since there is no way to know whether a device is available before attempting to open it, an application may want to trap the error and decide how to proceed rather than simply breaking. For example, the following function will either return an open cd-audio device, or nil to indicate that a cd-audio device could not be opened, along with the explanatory error message as a second value.

(defun get-a-cd-device ()
  (let* ((cd (make-instance 'mci-cd-audio)))
    (handler-case (mci-open cd)
      (error (c)
        (values nil (princ-to-string c))))))

To ensure that devices are available when needed, it is prudent to always close devices by calling mci-close when they are no longer needed. An error will occur if an already-closed device is closed again, so an application needs to either keep track of whether it has closed a device, or else check whether a device is still open. If a device's mci-device-id is 0, then the device is closed; otherwise the device is open, and the mci-device-id will be a positive integer (that value is of no interest to the application other than indicating the device is open).

When you are using a device that requires a window (such as displaying animation from a .avi file), you should use mci-set-window to specify the window to use. If you do not, the animation will appear in a new non-Common Graphics window over which Common Graphics has no control.

See also the example on the page describing mci-record.

2.0 MCI functionality

This section outlines the available set of MCI operators:

Basic operations

Capability inquiries

Most of these functions return true or nil as the device has or does not have the indicated capability or can or cannot perform the indicated task. Some return more specific information.

Status inquiries

These functions return information on the current state of a device.

Setting device status

These functions modify the state of a device.

Copyright (c) 1998-2022, Franz Inc. Lafayette, CA., USA. All rights reserved.
This page was not revised from the 10.0 page.
Created 2019.8.20.

Allegro CL version 10.1
Unrevised from 10.0 to 10.1.
10.0 version