In addition to specifying files or Resource Interchange File Format (RIFF) chunks to be loaded by compound devices, you also can specify memory objects. You create memory objects, for example, to play synthesized audio using the waveform audio media driver. These memory objects can be placed under the control of the memory playlist.
The memory playlist is a data structure in an application. It contains an array of simple, machine-like instructions you formulate, each of which has a fixed format consisting of a 32-bit operation code and three 32-bit operands. Playlist instructions are described in the following table.
To have playlist instructions interpreted by the playlist processor, you specify the MCI_OPEN_PLAYLIST flag with the MCI_OPEN command message. This flag indicates that the pszElementName field in the MCI_OPEN_PARMS data structure is a pointer to a memory playlist.
Using playlist instructions, you can play audio objects in succession from one or more memory buffers. Instructions include branching to and returning from subroutines within the playlist. In addition, the playlist can be modified dynamically by the application while it is being played. Because less overhead is involved when playing audio data from memory, playlist programs will have higher performance. If your application requires speed or if it needs to modify the data before it is sent to the audio device, use playlists.
┌────────────────────┬──────────────────────────────────────────────────┐ │Command │Description │ ├────────────────────┼──────────────────────────────────────────────────┤ │BRANCH_OPERATION │Transfers control to another instruction in the │ │ │playlist. │ │ │Operand 1-Ignored. │ │ │Operand 2-The absolute instruction number in the │ │ │playlist to which control is being transferred. │ │ │Because the playlist is defined as an array of │ │ │structures (instruction, operation, and operand │ │ │values) its first instruction is referenced as │ │ │array element, index 0. Therefore, the first │ │ │instruction in the list is 0, the second │ │ │instruction is 1, and so on. │ │ │Operand 3-Ignored. │ │ │Branching out of a subroutine is not prohibited; │ │ │however, it is not recommended because an unused │ │ │return address is left on the stack maintained by │ │ │the playlist processor. │ │ │An application can enable or disable a │ │ │BRANCH_OPERATION by exchanging it with a │ │ │NOP_OPERATION. Operands for a NOP_OPERATION are │ │ │ignored. │ ├────────────────────┼──────────────────────────────────────────────────┤ │CALL_OPERATION │Transfers control to the absolute instruction │ │ │number specified in Operand 2, saving the number │ │ │of the instruction following the CALL for use on a│ │ │RETURN instruction. │ │ │CALL instructions may be nested up to 20 levels. │ │ │Operand 1-Ignored. │ │ │Operand 2-Absolute instruction number in the │ │ │playlist to which control is being transferred. │ │ │Operand 3-Ignored. │ ├────────────────────┼──────────────────────────────────────────────────┤ │CUEPOINT_OPERATION │Causes a cue point data record to be entered into │ │ │the data stream. Note that the cue point is │ │ │relative to the DATA_OPERATION that follows it. │ │ │Operand 1-User-defined parameter to be returned as│ │ │the low word of ulMsgParam1 in the MM_MCICUEPOINT │ │ │message. │ │ │Operand 2-Offset in MMTIME units for the actual │ │ │time the CUEPOINT message should be generated. │ │ │Operand 3-Ignored. │ │ │The MM_MCICUEPOINT message is returned to the │ │ │application as soon as possible after the cue │ │ │point data record is encountered in the data │ │ │stream. The message is sent to the window handle │ │ │specified when the device was originally opened. │ │ │Note: The CUEPOINT instruction is ignored when │ │ │used in a recording operation. │ ├────────────────────┼──────────────────────────────────────────────────┤ │DATA_OPERATION │Specifies a data buffer to be played from or │ │ │recorded into. │ │ │Operand 1-Long pointer to a buffer in the │ │ │application. │ │ │Operand 2-Length of the buffer pointed to by │ │ │Operand 1. │ │ │Operand 3-Current position in the buffer. This │ │ │operand is updated by the system during a │ │ │recording or playback operation. For a playback │ │ │operation, it is the number of bytes that have │ │ │been sent to the output device handler. For a │ │ │recording operation, it is the number of bytes │ │ │that have been placed into a user buffer. │ │ │The current position in the buffer is particularly│ │ │important after a recording operation, because │ │ │this field contains the number of bytes of │ │ │recorded data. The remaining bytes in the buffer │ │ │are not valid. This field is initialized to zero │ │ │when the DATA_OPERATION statement is first │ │ │encountered. │ │ │The buffer indicated by the DATA instruction must │ │ │only contain the raw data bytes from the device │ │ │and cannot include any header information. │ │ │Therefore, the precise meaning or format of the │ │ │data is dependent on the current settings of the │ │ │media device. For example, a wave audio data │ │ │element is assumed to have the format PCM or │ │ │ADPCM, number of bits per sample, and so on, that │ │ │is indicated by the settings of the audio device. │ ├────────────────────┼──────────────────────────────────────────────────┤ │EXIT_OPERATION │Indicates the end of the playlist. │ │ │Operand 1-Ignored. │ │ │Operand 2-Ignored. │ │ │Operand 3-Ignored. │ ├────────────────────┼──────────────────────────────────────────────────┤ │LOOP_OPERATION │Controls iteration in a playlist. It is the │ │ │responsibility of the application to initialize │ │ │the current iteration. The current iteration is │ │ │reset to zero following loop termination. │ │ │Operand 1-Number of times the loop is to be │ │ │executed. │ │ │Operand 2-Target instruction to branch to, when │ │ │the loop condition fails. │ │ │Operand 3-Current iteration. │ │ │The last instruction in a loop is a branch back to│ │ │the LOOP_OPERATION. The operation of the │ │ │LOOP_OPERATION instruction is as follows: │ │ │1. If Operand 3 is less than Operand 1, control is│ │ │transferred to the playlist instruction following │ │ │the LOOP instruction, and the iteration count in │ │ │Operand 3 is incremented. │ │ │2. Otherwise, the iteration count is reset to zero│ │ │and control is passed to the instruction specified│ │ │in Operand 2. │ │ │Typically, the application sets the iteration │ │ │count to zero when the playlist is passed to the │ │ │device, but this is not required. The loop │ │ │instruction merely compares the loop count with │ │ │the iteration count. If the iteration count is set│ │ │to a value other than zero when the playlist is │ │ │passed in, it is as if the loop has been executed │ │ │that number of times. Also, if a playback │ │ │operation is stopped, and then the same playlist │ │ │is loaded again, the loop iteration count is not │ │ │initialized by the playlist processor. │ │ │It is the application's responsibility to see that│ │ │iteration count values are what is required when │ │ │switching from play to record, record to play, and│ │ │when changing settings for the data (for example, │ │ │bitspersample, samplespersec, and so on) with the │ │ │set command. These commands cause the playlist │ │ │stream to be destroyed and re-created, and the │ │ │playlist to be reassociated as a new playlist with│ │ │the playlist processor. │ ├────────────────────┼──────────────────────────────────────────────────┤ │MESSAGE_OPERATION │Returns a message to the application during │ │ │playlist processing. │ │ │Operand 1-Ignored. │ │ │Operand 2-ULONG that is returned to the │ │ │application in the MM_MCIPLAYLISTMESSAGE message │ │ │MsgParam2. │ │ │Operand 3-Ignored. │ │ │Each time the playlist processor encounters a │ │ │MESSAGE instruction, MM_MCIPLAYLISTMESSAGE is │ │ │returned to the application. MESSAGE instructions │ │ │can be used by the application to trace specific │ │ │points during the execution of the playlist │ │ │processor. The message is sent to the window │ │ │handle specified when the device was originally │ │ │opened. │ │ │This function is not intended to be used for │ │ │timing of data production or consumption │ │ │identified by previously interpreted instructions.│ │ │Do not rely on the MESSAGE instruction to indicate│ │ │precisely when a particular piece of digital audio│ │ │has been played by an audio device; however, the │ │ │MESSAGE instruction can be used to indicate when a│ │ │buffer has been consumed and needs to be refilled.│ ├────────────────────┼──────────────────────────────────────────────────┤ │NOP_OPERATION │Used as a placeholder. │ │ │Operand 1-Ignored. │ │ │Operand 2-Ignored. │ │ │Operand 3-Ignored. │ ├────────────────────┼──────────────────────────────────────────────────┤ │RETURN_OPERATION │Transfers control to the playlist instruction │ │ │following the most recently executed CALL │ │ │instruction. │ │ │Operand 1-Ignored. │ │ │Operand 2-Ignored. │ │ │Operand 3-Ignored. │ ├────────────────────┼──────────────────────────────────────────────────┤ │SEMPOST_OPERATION │Causes the playlist processor to post an event │ │ │semaphore. The playlist processor will call │ │ │DosWaitEventSem. │ │ │Operand 1-Contains the semaphore to post. │ │ │Operand 2-Ignored. │ │ │Operand 3-Ignored. │ ├────────────────────┼──────────────────────────────────────────────────┤ │SEMWAIT_OPERATION │Causes the playlist processor to wait on a │ │ │semaphore. The playlist processor will call │ │ │DosWaitEventSem. │ │ │Operand 1-Contains the semaphore to perform the │ │ │wait on. │ │ │Operand 2-Amount of time the semaphore should │ │ │wait. │ │ │Operand 3-Boolean value indicating whether or not │ │ │the semaphore should be cleared before waiting. │ └────────────────────┴──────────────────────────────────────────────────┘