home *** CD-ROM | disk | FTP | other *** search
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: admccue.c
- *
- *
- *
- * Copyright (c) IBM Corporation 1991, 1993
- * All Rights Reserved
- *
- * DESCRIPTIVE NAME: Audio MCD WaveAudio cueing + event file
- *
- * FUNCTION:Cue an Waveform Audio Element for input or output
- * Set a cue point
- *
- * On an MCI_CUE, a streaming MCD should perform the following actions:
- *
- * Check flags and validate pointers.
- * Check to see if the stream is already in cue state. If it is, then
- * just return success.
- * If the caller wants to cue for output, execute the following:
- *
- * Stop any in process commands.
- * If the stream is going in the wrong direction (i.e. record), destroy it.
- * Create the stream if necessary.
- * Preroll start the stream.
- *
- * If the caller wants to cue for input, execute the following:
- *
- * Stop any in process commands.
- * If the stream is going in the wrong direction, destroy it.
- * Create the stream if necessary.
- * Preroll start the stream.
- *
- *
- * NOTES: Concepts illustrated in this source file.
- * A. Default flags for MCI_CUE processing.
- * B. When cueing is not necessary.
- * C. When to destroy a stream before a cue.
- * D. Why an MCI_SET before MCI_CUE requires stream
- * creation.
- * E. How to cue a stream for input or output.
- * F. How to create a cue point.
- * G. How/when to disable a cue point.
- *
- * ENTRY POINTS:
- *
- * INPUT:
- *
- *
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSPROCESS
- #define INCL_ERRORS
-
- #include <os2.h> // OS2 defines.
- #include <string.h> // String functions.
- #include <os2medef.h> // MME includes files.
- #include <audio.h> // Audio Device Defines.
- #include <ssm.h> // SSM spi includes.
- #include <meerror.h> // MM Error Messages.
- #include <mmioos2.h> // MMIO Include.
- #include <mcios2.h> // MM System Include.
- #include <mmdrvos2.h> // MCI Driver Include.
- #include <mcd.h> // AudioIFDriverInterface.
- #include <hhpheap.h> // Heap Manager Definitions
- #include <qos.h>
- #include <audiomcd.h> // Component Definitions
- #include "admcfunc.h" // Function Prototypes
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: MCICUE..C
- *
- * DESCRIPTIVE NAME: Cue Waveform Device.
- *
- * FUNCTION: Prepare a Waveform Device or an Device Element for Record/Playback.
- * Applications will usually call this function in order to reduce
- * the latency of an MCI_RECORD or MCI_PLAY
- *
- * NOTES: Cueing a Waveform Device translates to prerolling of streams
- * at the SSM level.
- * Preroll means source handler fills the buffers and is
- * to roll. The Target handlers are not started, meaning buffers are
- * are not consumed.
- *
- * ENTRY POINTS:
- *
- * INPUT: MCI_CUE message.
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES:
- *
- * EXTERNAL REFERENCES: AudioIFDriverEntry() - AudioDevice MCD
- *
- *********************** END OF SPECIFICATIONS **********************/
- RC MCICue (FUNCTION_PARM_BLOCK *pFuncBlock)
- {
- ULONG ulrc; // Error Value
- ULONG ulParam1; // Msg Flags
-
- BOOL fCueInput = FALSE; // Direction to cue
- BOOL fCueOutput = FALSE; // " " "
-
- INSTANCE * ulpInstance; // Local Instance
- ULONG ulCueFlags; // Mask For Incoming MCI Flags
-
- PMCI_GENERIC_PARMS pCueParms; // Msg data ptr
-
- MCI_AMP_INSTANCE BackupAmp; // Hold old amp values
-
-
-
- /******************************
- * Derefernce pointers.
- ******************************/
- ulParam1 = pFuncBlock->ulParam1;
- pCueParms = ( PMCI_GENERIC_PARMS ) pFuncBlock->ulParam2;
- ulpInstance= (INSTANCE *) pFuncBlock->ulpInstance;
-
-
- /*---------------------------------------------------------
- * Make a copy of the amp/mixer instance in case any errors
- * happened.
- *---------------------------------------------------------*/
-
- memmove( &BackupAmp, &MIX, sizeof( MCI_AMP_INSTANCE ) );
-
-
- /******************************
- * Check for Invalid Flags
- *******************************/
- ulCueFlags = ulParam1;
- ulCueFlags &= ~(MCI_NOTIFY + MCI_WAIT +
- MCI_CUE_INPUT + MCI_CUE_OUTPUT +
- MCI_WAVE_INPUT + MCI_WAVE_OUTPUT);
-
- /********************************************
- * If the caller passed any flags other
- * than the ones we masked out, return error
- ********************************************/
-
- if (ulCueFlags > 0)
- return ( MCIERR_INVALID_FLAG );
-
- /************************************************
- * Cue point parms are not required, however, if
- * they are there, ensure they are valid
- ************************************************/
- /*why do we check them then???????*/
-
- ulrc = CheckMem (((PVOID)pCueParms),
- sizeof (MCI_GENERIC_PARMS), PAG_READ);
-
- /******************************************
- * Check for incompatible flags
- *******************************************/
- if (((ulParam1 & MCI_WAVE_INPUT) || (ulParam1 & MCI_CUE_INPUT)) &&
- ((ulParam1 & MCI_WAVE_OUTPUT) || (ulParam1 & MCI_CUE_OUTPUT)))
-
- return (MCIERR_FLAGS_NOT_COMPATIBLE );
-
- /****************************************
- * If No Element return error
- *****************************************/
-
- if ( ulpInstance->fFileExists == FALSE )
- {
- return (MCIERR_FILE_NOT_FOUND);
- }
-
- /******************************************
- * If we do not have the ability to write then
- * cueing for input will be possible.
- *******************************************/
-
- if ( ( (ulParam1 & MCI_WAVE_INPUT) || (ulParam1 & MCI_CUE_INPUT) ) &&
- !ulpInstance->ulUsingTemp &&
- !ulpInstance->usPlayLstStrm )
- {
- return ( MCIERR_UNSUPPORTED_FUNCTION );
- }
-
- /******************************************
- * Waveaudio defaults to cueing for output
- * if no flags are passed.
- *******************************************/
-
- if (!(ulParam1 & MCI_WAVE_INPUT || ulParam1 & MCI_WAVE_OUTPUT ||
- ulParam1 & MCI_CUE_INPUT || ulParam1 & MCI_CUE_OUTPUT))
- {
- ulParam1 &= MCI_WAVE_OUTPUT;
-
- }
-
- if ( ulParam1 & MCI_CUE_INPUT || ulParam1 & MCI_WAVE_INPUT )
- {
- fCueInput = TRUE;
- }
- else
- {
- fCueOutput = TRUE;
- }
-
- /************************************
- * If the stream is paused, there is no
- * sense in cueing it since the buffers
- * are full anyway
- **************************************/
-
- if ( STRMSTATE == MCI_PAUSE ||
- STRMSTATE == STOP_PAUSED )
-
- {
- /***********************************************
- ** If the stream is going the right way
- ** then we have the ability to avoid the cue
- ** since the buffers have been filled up before
- ** we did the pause
- **********************************************/
-
- if ( AMPMIX.ulOperation == OPERATION_RECORD &&
- fCueInput )
- {
- ulpInstance->ulCreateFlag = PREROLL_STATE;
- STRMSTATE = CUERECD_STATE;
- return ( MCIERR_SUCCESS );
- }
-
- /*************************************************
- * If the current stream is cued for playback and
- * we have a cue_output request, our work is done
- **************************************************/
-
- else if ( AMPMIX.ulOperation == OPERATION_PLAY &&
- fCueOutput )
- {
-
- ulpInstance->ulCreateFlag = PREROLL_STATE;
- STRMSTATE = CUEPLAY_STATE;
- return ( MCIERR_SUCCESS );
- }
-
- } /* If the stream may be in cue state */
-
- /**********************************************
- * Create and cue the playback stream A --> B
- ***********************************************/
-
- if ( fCueOutput )
- {
- ulrc = CueSetup( pFuncBlock, MCI_PLAY );
-
- STRMSTATE = CUEPLAY_STATE;
-
- } /* default case is wave output */
-
- /********************************************
- * If the caller requested a cue for input, then
- * create and cue the record stream B --> A
- *********************************************/
-
- else
- {
- ulrc = CueSetup( pFuncBlock, MCI_RECORD );
-
- STRMSTATE = CUERECD_STATE;
-
- } /* Cue Input */
-
-
- if ( ulrc )
- {
- /* Ensure that our instance remains the same as before the cue attempt */
-
- memmove( &MIX, &BackupAmp, sizeof ( MCI_AMP_INSTANCE ) );
-
- }
-
- return (ulrc);
- }
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: CueSetup
- *
- * DESCRIPTIVE NAME: Creates a stream and cues it.
- *
- * FUNCTION: This function abort any in progress commands and
- * cue a stream.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- *
- * INPUT: INSTANCE ptr
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR:
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiCreateStream()
- * spiStartStream()
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- ULONG CueSetup( FUNCTION_PARM_BLOCK *pFuncBlock,
- ULONG ulMCIOperation )
-
- {
- ULONG ulAbortNotify = FALSE; // is there a command to abort?
- ULONG ulAmpDestroy;
- ULONG ulAmpOperation;
- ULONG ulrc;
-
- INSTANCE *pInstance;
-
-
- pInstance = (INSTANCE *) pFuncBlock->ulpInstance;
-
- if ( ulMCIOperation == MCI_RECORD )
- {
- ulAmpOperation = OPERATION_RECORD;
- /* If the amp is in play mode, we must destroy the stream */
- ulAmpDestroy = OPERATION_PLAY;
- }
- else
- {
- ulAmpOperation = OPERATION_PLAY;
- /* If the amp is in play mode, we must destroy the stream */
- ulAmpDestroy = OPERATION_RECORD;
-
- }
-
- /*****************************************
- * To ensure proper syncronization, acquire
- * the semaphore which is used to control
- * who can check to see which processes are
- * active. This function will also tell us
- * if there is an operation to abort or
- * supercede.
- ******************************************/
-
- GetNotifyAbortAccess ( pInstance, &ulAbortNotify );
-
- /*******************************************
- * If there is an operation active (i.e. a
- * play, record or save) then post a message
- * stating that the command has been
- * aborted ( play or record) or
- * wait for completion (save).
- ********************************************/
-
- if ( ulAbortNotify )
- {
- ulrc = CueAbortInProgressNotify( pInstance, pFuncBlock, ulMCIOperation );
- }
-
- /**********************************************
- * If the card is in record mode, or a record
- * stream is active, destroy the stream.
- ***********************************************/
-
- if ( pInstance->AmpInstance.ulOperation == ulAmpDestroy )
-
- {
- /******************************************
- * Stop The Previous stream
- *******************************************/
- SpiStopStream ( pInstance->StreamInfo.hStream,
- SPI_STOP_DISCARD);
-
- /**************************************
- * Destroy the previous stream
- **************************************/
- DestroyStream ( &pInstance->StreamInfo.hStream);
-
- /*******************************************
- * Set Stream Creation flag to create state
- ********************************************/
- pInstance->ulCreateFlag = CREATE_STATE;
-
- }
-
-
-
- /***********************************************
- * If a set was performed on an existing stream,
- * destroy the stream and get new spcb keys
- ***********************************************/
-
- DestroySetStream ( pInstance );
-
- /***********************************************
- * Set the stream up and cue it for play back!
- ***********************************************/
-
- ulrc = CueStream( pInstance, ulAmpOperation );
-
- return ( ulrc );
-
- } /* CueSetup */
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: CueStream
- *
- * DESCRIPTIVE NAME: Creates a stream and cues it.
- *
- * FUNCTION: This function will create and stream, and will
- * preroll start for playback. Since record buffers
- * will be filled with garbage, it is pointless to
- * preroll start it.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- *
- * INPUT: INSTANCE ptr
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR:
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiCreateStream()
- * spiStartStream()
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- ULONG CueStream( INSTANCE *ulpInstance,
- ULONG ulOperation )
-
-
- {
-
- ULONG ulrc; // return codes
- ULONG ulCount; // Semaphore variable
- BOOL fInitNeeded = FALSE;// Must we initialize the card?
-
- /****************************************
- * If no stream has been created, and the
- * card has not changed modes, there is no
- * need to reinit it!
- *****************************************/
-
- if ( AMPMIX.ulOperation != ulOperation ||
- ulpInstance->StreamInfo.ulState == STREAM_SET_STATE )
- {
- fInitNeeded = TRUE;
- }
-
-
-
- /*******************************
- * Do stream set up work and then
- * create the stream
- *******************************/
-
- ulrc = PrepareAndCreateStream( ulpInstance, ulOperation, fInitNeeded );
-
- if ( ulrc )
- {
- return ( ulrc );
- }
-
-
- /*******************************
- * Preroll Start the stream.
- *******************************/
- DosResetEventSem (ulpInstance->hEventSem, &ulCount);
-
- /********************************************************
- * We do not want to preroll start a record stream
- * since the buffers willbe filled with bogus information
- * so only fill the play stream with a preroll start.
- *********************************************************/
-
- if ( ( STRMSTATE != CUEPLAY_STATE && ulOperation == OPERATION_PLAY ) )
- {
-
- ulrc = SpiStartStream (ulpInstance->StreamInfo.hStream,
- SPI_START_PREROLL);
-
- if (ulrc)
- {
- return ulrc;
- }
-
- /*************************************
- * Wait till you Recieve PREROLL Event
- *************************************/
-
- DosWaitEventSem (ulpInstance->hEventSem, (ULONG) -1);
-
- } /* Preroll Start */
-
- /*************************************
- * Update state To preroll
- **************************************/
-
- ulpInstance->ulCreateFlag = PREROLL_STATE;
-
- return ( ulrc );
-
- } /* Cue Stream */
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: AbortInProgressNotify
- *
- * DESCRIPTIVE NAME: Stops a notify which was already in progress
- *
- * FUNCTION: Stops save, record and playback notifies
- *
- * NOTES:
- *
- * ENTRY POINTS:
- *
- * INPUT: INSTANCE ptr
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR:
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiStopStream() - SSM Spi
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- ULONG CueAbortInProgressNotify( INSTANCE *ulpInstance,
- FUNCTION_PARM_BLOCK *pFuncBlock,
- ULONG ulMessage )
-
-
- {
- ULONG ulrc = MCIERR_SUCCESS;
-
- /*****************************************************
- * If a stream is currently in use, destroy or stop it!
- ******************************************************/
-
- if ( ulpInstance->usNotPendingMsg == MCI_SAVE )
- {
- /***********************************
- * Can't interrupt a save because data
- * can be lost--wait till completion
- ************************************/
-
- DosWaitEventSem( ulpInstance->hThreadSem, (ULONG ) -1 );
-
- }
- else
- {
- PostMDMMessage ( MCI_NOTIFY_ABORTED,
- ulpInstance->usNotPendingMsg,
- pFuncBlock );
-
- /* Stop the pending thread */
-
- ThreadedStop ( ulpInstance );
-
- /**********************************************************
- * If we have a record stream and we are cueing for input
- * or if we have a playback stream and are cueing for output
- * then don't destroy the stream. Just place it in a
- * stopped state.
- **********************************************************/
-
- if ( ulpInstance->usNotPendingMsg != ulMessage )
- {
- /**************************************
- * Destroy the previous stream since it
- * was going the wrong way.
- ***************************************/
-
- DestroyStream ( &ulpInstance->StreamInfo.hStream);
-
- /***************************************
- * Update the stream state so that following
- * routines will be forced to create a new
- * stream.
- ****************************************/
-
- ulpInstance->ulCreateFlag = CREATE_STATE;
-
- } /* else this is a play stream */
-
- } /* notify pending was not a !save */
-
-
- return ( ulrc );
-
- } /* CueAbortInProgressNotify */
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: MCISCPT.C
- *
- * DESCRIPTIVE NAME: Set Cue Point Waveform Device.
- *
- * FUNCTION: Establish Cue points during playback on Waveform Device.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- * INPUT: MCI_SET_CUEPOINT message.
- *
- * EXIT-NORMAL: MCIERR_SUCCESS.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiEnableEvent() - SSM Spi
- *
- *********************** END OF SPECIFICATIONS **********************/
-
-
- RC MCISetCuePoint (FUNCTION_PARM_BLOCK *pFuncBlock)
- {
- ULONG ulrc; // Propogated MME Error Code
- ULONG ulParam1; // Incoming MCI Flag
- ULONG ulCuePointFlags; // Mask For Incoming Flags
- INSTANCE *ulpInstance; // Local Instance
-
- PID pid;
- TID tid;
-
- HWND hWnd;
-
- PMCI_CUEPOINT_PARMS pCueParms; // Msg MCI Data Structure
-
- /****************************
- * Dereference pointers
- *****************************/
-
- ulParam1 = pFuncBlock->ulParam1;
- pCueParms = ( PMCI_CUEPOINT_PARMS ) pFuncBlock->ulParam2;
- ulpInstance= (INSTANCE *) pFuncBlock->ulpInstance;
-
- /**************************
- * Mask out supported flags
- **************************/
- ulCuePointFlags = ulParam1;
- ulCuePointFlags &= ~( MCI_WAIT + MCI_NOTIFY +
- MCI_SET_CUEPOINT_ON + MCI_SET_CUEPOINT_OFF );
-
-
- /* If the caller passed in an invalid flag return an error */
-
- if (ulCuePointFlags > 0 )
- return ( MCIERR_INVALID_FLAG );
-
- /******************************************
- * Check to see if CuePoint parms are good
- ******************************************/
-
- ulrc = CheckMem (((PVOID) pCueParms ),
- sizeof (MCI_CUEPOINT_PARMS), PAG_READ);
-
- if (ulrc != MCIERR_SUCCESS)
- return ( MCIERR_MISSING_PARAMETER );
-
- /**********************************************
- * It is the MCD's responsibility to ensure that
- * the callback handle that the caller passed in
- * is valid--so ask PM if it is valid.
- **********************************************/
-
- hWnd = pCueParms->hwndCallback;
-
-
- if ( !WinQueryWindowProcess(hWnd, &pid, &tid) )
- return (MCIERR_INVALID_CALLBACK_HANDLE);
-
- /************************************************
- * Check for valid flags but invalid combination
- *************************************************/
-
- if (ulParam1 & MCI_SET_CUEPOINT_ON && ulParam1 & MCI_SET_CUEPOINT_OFF)
- return ( MCIERR_FLAGS_NOT_COMPATIBLE );
-
- /***************************************************
- * The caller must either turn a cue point on or off
- ****************************************************/
-
-
- if (!(ulParam1 & MCI_SET_CUEPOINT_ON || ulParam1 & MCI_SET_CUEPOINT_OFF))
- return ( MCIERR_MISSING_FLAG );
-
- /*****************************************
- * No media element loaded--reject cuepoint
- ******************************************/
-
- // make file exists to ulong--set to true/false.
-
- if ( ulpInstance->fFileExists == FALSE )
- {
- return (MCIERR_FILE_NOT_FOUND);
- }
-
- /*************************
- * Check for range errors
- *************************/
-
- if (pCueParms->ulCuepoint <= 0)
-
- return (MCIERR_OUTOFRANGE);
-
- /**************************************
- * Enable cuepoints if on flag is passed
- **************************************/
-
- if (ulParam1 & MCI_SET_CUEPOINT_ON)
- {
- /**********************************************
- * Enable CuePoints and add to linked list
- **********************************************/
-
- ulrc = CuePointAdd( ulpInstance, pCueParms );
-
- } /* Set Cue Point On */
-
-
- /*************************************
- * Disable cuepoint if off flag is set
- *************************************/
-
- if (ulParam1 & MCI_SET_CUEPOINT_OFF)
- {
- /**********************************************
- * Disable CuePoints and remove from linked list
- **********************************************/
-
- ulrc = CuePointDelete( ulpInstance, pCueParms );
-
- } /* CuePoint Off */
-
-
- return ( ulrc );
-
- } /* MCISetCuePoint */
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: CuePointAdd
- *
- * DESCRIPTIVE
- *
- * FUNCTION: Adds cuepoint to linked list of cue points
- *
- * NOTES: This function illustrates how to extend an
- * event control block to contain custom information.
- * For example, each cue point EVCB can contain its
- * own window callback handle.
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- * INPUT:
- *
- * EXIT-NORMAL: MCIERR_SUCCESS
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES:
- *
- *********************** END OF SPECIFICATIONS **********************/
- RC CuePointAdd ( INSTANCE *ulpInstance,
- PMCI_CUEPOINT_PARMS pCueParms )
-
- {
- MTIME_EVCB *pTempMCuePtEVCB; // temporary pointer to item in linked list
-
- ULONG ulTempTime; // time conversion variable
- ULONG ulFoundCuePoint=FALSE; // Find flag
- ULONG ulrc;
-
- extern HHUGEHEAP heap; // Global MCD Heap
-
- pTempMCuePtEVCB = CUEPOINT;
-
- /********************************************
- * Check to see if the cue point is already in
- * our linked list of cuepoints. Continue
- * checking while we have a list and we have
- * not found the cuepoint.
- *********************************************/
-
- while ( pTempMCuePtEVCB && !ulFoundCuePoint )
- {
-
- /*****************************************************
- * If the current node is the same as the cuepoint
- * that the caller wants to set, then its a duplicate
- *****************************************************/
-
- if (pTempMCuePtEVCB->mmCuePt == pCueParms->ulCuepoint)
- {
- ulFoundCuePoint = TRUE;
- }
-
- /* Keep progressing through the list */
-
- pTempMCuePtEVCB = pTempMCuePtEVCB->pNextEVCB;
-
- }
-
- /* If we found the cuepoint in the list--its a duplicate */
-
- if ( ulFoundCuePoint )
- {
- return MCIERR_DUPLICATE_CUEPOINT;
- }
-
- AcquireProcSem ();
-
-
- if ( !(pTempMCuePtEVCB = HhpAllocMem (heap, sizeof ( MTIME_EVCB ) ) ) )
- {
- return (MCIERR_OUT_OF_MEMORY);
- }
-
- ReleaseProcSem ();
-
- /********************************************
- * Fill In the window handle and device id
- *********************************************/
-
-
- pTempMCuePtEVCB->hwndCallback = pCueParms->hwndCallback;
- pTempMCuePtEVCB->usDeviceID = ulpInstance->usWaveDeviceID;
-
- /********************************************
- * Fill In Time event control block for a
- * cue point ( all of these fields are REQUIRED)
- * Note: We have altered the evcb to contain
- * additional information (such as our callback
- * userParm, instance etc.). See audiomcd.h
- * for an explanation of how this is done.
- *********************************************/
-
- pTempMCuePtEVCB->evcb.ulType = EVENT_CUE_TIME;
- pTempMCuePtEVCB->evcb.ulFlags = EVENT_SINGLE;
- pTempMCuePtEVCB->evcb.hstream = ulpInstance->StreamInfo.hStream;
-
- /*********************************************
- * Store the time at which the cue point
- * is to be generated ( this must be in MMTIME
- *********************************************/
-
- ulrc = ConvertToMM ( ulpInstance,
- &ulTempTime,
- pCueParms->ulCuepoint);
-
- pTempMCuePtEVCB->evcb.mmtimeStream = ulTempTime;
-
- /***************************************************
- * Store the callback handle that the caller wishes
- * the cuepoint notification to occur on.
- * Remember each cuepoint can have its own callback.
- ****************************************************/
-
- pTempMCuePtEVCB->mmCuePt = pCueParms->ulCuepoint;
-
- /*****************************************************
- * Stick In INSTANCE Pointer in The Time EVCB, this will
- * allow the event procedure to have access to our
- * instance--it ordinarily would not have access to it.
- * See comments in PlayEventProc and RecordEventProc.
- ******************************************************/
-
- pTempMCuePtEVCB->ulpInstance = (ULONG) ulpInstance;
-
-
- /*****************************************************
- * Copy CuePoint User Parm into EVCB Structure
- ******************************************************/
- pTempMCuePtEVCB->usCueUsrParm =pCueParms->usUserParm;
-
- /*****************************************************
- * Link this cue point into the list of cue points
- ******************************************************/
-
- pTempMCuePtEVCB->pNextEVCB = CUEPOINT;
- CUEPOINT = pTempMCuePtEVCB;
-
- /************************************************
- * We can only enable events after a stream has
- * been created--otherwise you will get errors.
- * If we cannot enable the event right now, store
- * this in a flag, and enable it before playback
- * or record.
- ************************************************/
-
- if (ulpInstance->ulCreateFlag == PREROLL_STATE)
- {
- ulrc = SpiEnableEvent( (PEVCB) pTempMCuePtEVCB,
- (PHEVENT) &pTempMCuePtEVCB->HCuePtHndl );
-
- ulpInstance->usCuePt = EVENT_ENABLED;
- }
- else
- {
- ulpInstance->usCuePt = TRUE;
- }
-
- return ( ulrc );
-
- } /* CuePointAdd */
-
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: CuePointDelete
- *
- * DESCRIPTIVE
- *
- * FUNCTION: Removes cuepoint from linked list of cue points
- *
- * NOTES:
- *
- * ENTRY POINTS:
- *
- * INPUT:
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES:
- *
- *********************** END OF SPECIFICATIONS **********************/
- RC CuePointDelete ( INSTANCE *ulpInstance,
- PMCI_CUEPOINT_PARMS pCueParms )
-
- {
- MTIME_EVCB *pTempMCuePtEVCB; // temporary pointer to item in linked list
- MTIME_EVCB *pPrevMCuePtEVCB; // temporary pointer to item in linked list
-
- ULONG ulFoundCuePoint = FALSE; // Flag to indicate whether the cpt was found
- ULONG ulrc;
-
- extern HHUGEHEAP heap; // Global MCD Heap
-
- /* If we have never enabled a cuepoint, we can't delete it */
-
- if ( !CUEPOINT )
- {
- return ( MCIERR_INVALID_CUEPOINT );
- }
-
- pTempMCuePtEVCB = pPrevMCuePtEVCB = CUEPOINT;
-
- /********************************************
- * Check to see if the cue point is already in
- * our linked list of cuepoints. Continue
- * checking while we have a list and we have
- * not found the cuepoint.
- *********************************************/
-
- while ( pTempMCuePtEVCB && !ulFoundCuePoint )
- {
- if ( pTempMCuePtEVCB->mmCuePt == pCueParms->ulCuepoint)
- {
-
- /********************************************
- * If we found a cuepoint and the stream is
- * active, remove the cuepoint. Simply
- * deleting it from our linked list is not
- * enough since the cuepoint will continue
- * to be reported until it is removed.
- ********************************************/
-
- if ( ulpInstance->usCuePt == EVENT_ENABLED )
-
- {
- /***********************************************
- * Check Validity of hCuePointEvent
- **********************************************/
- ulrc = SpiDisableEvent ( pTempMCuePtEVCB->HCuePtHndl );
-
- } /* CreateFlag == PrerollState */
-
- ulFoundCuePoint = TRUE;
-
- /***********************************************
- * Ensure that the previous node points to the
- * next node.
- *********************************************/
-
- if ( pTempMCuePtEVCB != pPrevMCuePtEVCB )
- {
- pPrevMCuePtEVCB->pNextEVCB = pTempMCuePtEVCB->pNextEVCB;
- }
- else
- {
- /***********************************************
- * If we are deleting the first item in the list
- * ensure that we have a valid initial pointer
- **********************************************/
-
- CUEPOINT = pTempMCuePtEVCB->pNextEVCB;
- }
-
- /* Toast the node to delete */
-
- CleanUp( pTempMCuePtEVCB );
-
-
- } /* Found the CuePoint Block */
-
- /**********************************************
- * Else we didn't find the requested cue point
- * so advance a node
- **********************************************/
-
- else
- {
- if ( pTempMCuePtEVCB != pPrevMCuePtEVCB )
- {
- pTempMCuePtEVCB = pTempMCuePtEVCB->pNextEVCB;
- pPrevMCuePtEVCB = pPrevMCuePtEVCB->pNextEVCB;
- }
- else
- {
- pTempMCuePtEVCB = pTempMCuePtEVCB->pNextEVCB;
- }
-
- } /* else we haven't found the requested cue point */
-
- } /* endwhile */
-
- /* If we couldn't find the cuepoint--report the error */
-
- if ( ulFoundCuePoint == FALSE)
- {
- return ( MCIERR_INVALID_CUEPOINT );
- }
-
- return ( ulrc );
-
- } /* CuePointDelete */
-
-
-