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 );