Maximizing the Audio Support in OS/2 2.1

From EDM2
Jump to: navigation, search

by Linden deCarmo

Introduction

One of the most notable additions to the OS/2 2.1 operating system is its exciting multimedia capabilities. This multimedia support, called MMPM/2, includes a robust, multithreaded transportation layer, seamless data translation support, and an ever-growing number of media drivers. Because considerable number of machines now come with audio cards, application developers must either take advantage of the new hardware or risk losing market share.

This article describes how you can incorporate key audio features to enhance your product - whether it's a REXX utility, shareware game, or mission-critical application.

Easy As a VCR

MMPM/2 uses the Media Control Interface as the primary method of incorporating multimedia into OS/2 programs. These commands are very similar to your VCR (for example, play, record, rewind, and stop), and if you use this 32-bit API set, your application will run not only on the current Intel x86 platform, but also RISC-based systems (such as the PowerPC) under Workplace OS. This portable API set has two primary interfaces: the string interface and the procedural interface.

The string interface lets applications send command strings to OS/2 without having to write any C or Pascal code. This method is excellent for batch languages, as well as for quickly creating programs in C or C++ (MMPM/2 even comes with some excellent REXX command examples). For instance, the string in quotes below can be used with REXX to play an audio file.

mciRxSendString("play \mmos2\sounds\laser.wav wait", 'RetSt', '0', '0')

If you want to experiment with the string interface without the overhead of compiling a program or writing a command file the MMPM/2 toolkit comes with an excellent testing application, MCISTRNG, that lets you send string commands. Check out the MMPM/2 Toolkit that is available on your CD-ROM.

MaxAudio-Fig-1.gif

Can REXX Learn New Tricks?

All string interface commands can be used from REXX through the mciRxSendString call. Syntax and theory of the string interface can be found in the Multimedia Presentation Programming Reference or Multimedia with REXX online reference provided with MMPM/2. The example command file that follows shows how to modify a makefile to boo if the compile is unsuccessful and cheer if things went well.

nmake
:main
if ERRORLEVEL 1 goto error
play FILE=\mmos2\sounds\cheer.wav
goto quit
:error
play FILE=\mmos2\sounds\boo.wav
:quit

You can use the new Multimedia Control Interface clipboard functions with PMREXX, VisPro/REXX, or VX REXX programs to communicate with other programs and edit audio files with very little code. These clipboard commands also work on Ultimotion or Indeo video files, if you have the Ultimedia Video IN product (the Video IN beta was included on the last Developer Connection and an evaluation copy is available on this quarter's CD-ROM). The following REXX example copies the start of the waveform (.WAV) file onto the clipboard and pastes that information repeatedly at the end of the file to create a Max Headroom effect.

RXFUNCADD ( 'mciRxInit', 'MCIAPI', 'mciRxInit')
InitRC=mciRxInit ();
mciRxSendString("open \mmos2\sounds\laser.wav alias a wait", 'RetSt', '0', '0')
mxiRxSendString("copy a from 0 to 3000 wait", 'RetSt', '0','0')
mciRxSendString("seek a to end wait", 'RetSt', '0','0')
mciRxSendString("paste a wait", 'RetSt', '0','0')
mciRxSendString("paste a wait", 'RetSt', '0','0')
mciRxSendString("paste a wait", 'RetSt', '0','0')

Procedural Interface

The procedural interface is the traditional means for accessing MMPM/2. It is available from C, C++, Smalltalk, and other languages that support dynamic link libraries. The procedural interface (or the string interface from C or C++) gives the developer complete access to all multimedia commands and messages, notification of all events, and the ability to maximize the multithreaded nature of MMPM/2.

Full Multimedia API

MMPM/2 contains a very sophisticated resource manager and is the first multimedia environment that lets an infinite number of applications simultaneously open an audio device. As a contrast to Windows, MMPM/2 does not force you to open and close the device on a constant basis to allow other applications to share the .WAV device. A good MMPM/2 program opens the device in a shareable mode and processes the MM_MCIPASSDEVICE message.

If the MCI_OPEN_SHAREABLE flag is not passed to MCI_OPEN, other devices cannot use the device while you have it open. Unless you need the device exclusively, use the shareable flag when opening. If you must have the device exclusively for a period of time (for example, recording audio data), always open the device in shareable mode, send an MCI_ACQUIRE to obtain it exclusively, and perform the necessary action. Use MCI_RELEASE to release the device.

If your application receives the MM_MCIPASSDEVICE message (with MCI_LOSING_USE in ulMsgParam2 field), another application has taken the device from you. Reacquire the device using MCI_ACQUIRE before sending another command. The following example illustrates this.

/*
 * The next two messages are handled so that the audio recorder
 * application can participate in device sharing.  We keep track of this device passing in
 * the fPassedDevice boolean variable.
 *
 * If we do not have access to the device when we receive an WM_ACTIVATE
 * message, then we will issue an acquire device command to gain
 * access to the device.
 *
 * For applications that are more complex
 * than this sample program, developers may wish to take
 * advantage of a more robust method of device sharing.
 * This can be done by using the MCI_ACQUIRE_QUEUE flag on
 * the MCI_ACQUIREDEVICE command.  Please refer to the MMPM/2
 * documentation for more information on this flag.
 */

   case MM_MCIPASSDEVICE:
     if (SHORT1FROMMP(mp2) == MCI_GAINING_USE)      /* GAINING USE */
     {
         fPassed Device = FALSE                     /* Gaining control of device.*/
// Once we receive the gaining use message, we can send commands to the device.  See the MMPM/2
// toolkit for more information.
     }
     else                                           /* LOSING USE */
     {
            fPassedDevice = TRUE;                      /* Losing control of device */

// Once we receive the losing use message, we can no longer send commands to
// the device until we re-acquire it.
     }
return ( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );

Although most Media Control Interface commands are available from the string interface, some are not. They require pointers or other items which don't translate into English. An example of such a command is MCI_COPY. The basic MCI_COPY command is available via the string interface; however, a more advanced version lets you actually transfer the contents of a buffer to the clipboard. The following code segment reads part of a .WAV file into a buffer so it can be copied into the clipboard.

HMMIO          hmmio;
MCI_EDIT_PARMS mep;
PVOID          pBuffer;
MMAUDIOHEADER  mmaudioheader;
USHORT         usDeviceID;

/* usDeviceID was obtained via MCI_OPEN */
/* mmaudioheader was filled in with mmioGetHeader call */

/* Read the info necessary to copy into the clipboard */

lReturnCode = mmioRead( hmmio,
                       ( PSZ ) pBuffer,
                       60000 );

if ( lReturnCode == MMIO_ERROR )
  {
  ulrc = mmioGetLastError( hmmio );
  return ( ulrc );
  }

A final advantage of using the procedural interface (or the string interface from C or C++) over REXX is the ability to take advantage of the multithreaded nature of the MMPM/2. In the DOS world, programmers must constantly poll the device to find out its current position in the file. By contrast, MMPM/2 offers a significant alternative to the polling approach - MCI_SETPOSITIONADVISE and MCI_SETCUEPOINT.

Using MCI_SETPOSITIONADVISE, MMPM/2 informs applications on a periodic basis the device's media position when playing or recording an audio or video file (this is similar to the WM_TIMER message, but much more accurate, because it is media based). MCI_SET CUEPOINT lets you set up single a notification, rather than recurring notifications, about the media position of the audio device.

Adventure is Just Beginning

We have only touched on the myriad of audio features available in the OS/2 2.1 operating system (not to mention the exciting software motion video support that will be covered in a future article). I encourage you to explore the multimedia toolkit and use the appropriate APIs in order to bring your application into the exciting age of multimedia computing!

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation