Setting Up the Mixer

The application sends the MCI_MIX_SETUP message to the amp mixer to initialize the device for direct reading and writing of audio data in the correct mode and format-for example, PCM, MIDI, or MPEG audio.

If waveform audio data will be played or recorded, the application fills in the ulDeviceType field with MCI_DEVICETYPE_WAVEFORM_AUDIO. It must also provide values for the following digital-audio-specific fields: format tag, bits per sample, number of samples per second, and number of channels.

If MIDI data will be played, the application fills in the ulDeviceType field with a value of MCI_DEVICETYPE_SEQUENCER and places zeroes in the format specifications fields.

typedef struct_MCI_MIXSETUP_PARMS
  {
  HWND        hwndCallback;    /* IN  Window for notifications */
  ULONG       ulBitsPerSample; /* IN  Number of bits per sample */
  ULONG       ulFormatTag;     /* IN  Format tag */
  ULONG       ulSamplesPerSec  /* IN  Sampling rate */
  ULONG       ulChannels;      /* IN  Number of channels */
  ULONG       ulFormatMode;    /* IN  MCI_RECORD or MCI_PLAY */
  ULONG       ulDeviceType;    /* IN  MCI_DEVTYPE */
  ULONG       ulMixHandle;     /* OUT Read/Write handle */
  PMIXERPROC  pmixWrite;       /* OUT Write routine entry point */
  PMIXERPROC  pmixRead;        /* OUT Read routine entry point */
  PMIXEREVENT pmixEvent;       /* IN  Event routine entry point */
  PVOID       pExtendedInfo;   /* IN  Media-specific info */
  ULONG       ulBufferSize;    /* OUT Recommended buffer size */
  ULONG       ulNumBuffers;    /* OUT Recommended num buffers */
  } MCI_MIXSETUP_PARMS;

The application must also fill in the pmixEvent field of the MCI_MIXSETUP_PARMS structure with a function pointer for the mixer to use for event notification, such as a full buffer, empty buffer, or an error condition. If the call to the mixer is successful, it returns two function pointers to the application-one for reading data (mixRead) and the other for writing data (mixWrite) to the audio device.

An application can use the MCI_MIXSETUP_QUERYMODE flag to query a device to see if a particular mode is supported. The following example illustrates using MCI_MIXSETUP to query and prepare the audio device for playing 16-bit, 22050 KHz stereo mode.

   // MCI_MIXSETUP informs the mixer device of the entry point
   // to report buffers being read or written.
   // We will also need to tell the mixer which media type
   // we will be streaming.  In this case, we'll use
   // MCI_DEVTYPE_WAVEFORM_AUDIO.

    memset( &MixSetupParms, '\0', sizeof( MCI_MIXSETUP_PARMS ) );

   MixSetupParms.ulBitsPerSample = 16;
   MixSetupParms.ulFormatTag     = MCI_WAVE_FORMAT_PCM;
   MixSetupParms.ulSamplesPerSec = 22050;
   MixSetupParms.ulChannels = 2;    /* Stereo */
   MixSetupParms.ulFormatMode = MCI_PLAY;
   MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;


    rc = mciSendCommand( usDeviceID,
                         MCI_MIXSETUP,
                         MCI_WAIT | MCI_MIXSETUP_QUERYMODE,
                         ( PVOID ) &MixSetupParms,
                         0 );


    if ( ULONG_LOWD( rc ) != MCIERR_SUCCESS )
           {
           CHAR  szError[255];
             // The device can't handle this format
             // get an English error message for the caller.
           mciGetErrorString( ULONG_LOWD( rc ), szError, 255 );
           printf("Can't play because of %s", szError );
           exit( 1 );
           }

   // The mixer will inform us of entry points to
   // read/write buffers to and also give us a
   // handle to use with these entry points.

   MixSetupParms.pmixEvent = MyEvent;


    rc = mciSendCommand( usDeviceID,
                         MCI_MIXSETUP,
                         MCI_WAIT | MCI_MIXSETUP_INIT,
                         ( PVOID ) &MixSetupParms,
                         0 );


[Back: Using the DART Interface]
[Next: Allocating Memory Buffers]