home *** CD-ROM | disk | FTP | other *** search
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: MCISEEK.C
- *
- * DESCRIPTIVE
- *
- *
- * Copyright (c) IBM Corporation 1991, 1993
- * All Rights Reserved
- *
- *
- * FUNCTION: Waveform Seek.
- *
- * On a seek, a streaming MCD should perform the following commands:
- *
- * A. Verify that the flags passed are valid.
- * B. Verify the MCI_FROM, MCI_TO parameter if they were passed in.
- * C. Ensure that any pointers passed are valid.
- * D. Stop any commands which are active on another thread.
- * E. If no stream has been created, then create one.
- * F. If a stream had previously been created, ensure that it is in
- * stopped state.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- *
- * INPUT: MCI_SEEK message.
- *
- * EXIT-NORMAL: MCIERR_SUCCESS.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiStopStream() - SSM Spi
- * spiSeekStream() - SSM Spi
- *
- *********************** 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 <mcios2.h> // MM Error Messages.
- #include <mmioos2.h> // MMIO Include.
- #include <mmdrvos2.h> // MCI Driver Include.
- #include <mcd.h> // AudioIFDriverInterface.
- #include <qos.h>
- #include <hhpheap.h> // Heap Manager Definitions
- #include <audiomcd.h> // Component Definitions
- #include "admcfunc.h" // Function Prototypes
-
-
-
- RC MCISeek (FUNCTION_PARM_BLOCK *pFuncBlock)
-
- {
- ULONG ulrc; // Return Code
- ULONG ulParam1; // Flags For this message
- ULONG ulAbortNotify = FALSE; // abort notification messages
- ULONG ulCnt; // Semaphore Post Count
- ULONG ulTemp1; // Temporary Variable
- ULONG ulSpiFlags; // Flags For Spi Seek
- ULONG ulSeekFlags; // Incoming Seek Flags From MCI
- ULONG ulFileLength; // Element Length in MM
-
- PMCI_SEEK_PARMS pSeekParms;
-
- INSTANCE * ulpInstance; // Local Instance Ptr
-
- /********************************************
- * Dereference Pointers From Thread Block
- ********************************************/
-
- ulParam1 = pFuncBlock->ulParam1;
- pSeekParms = ( PMCI_SEEK_PARMS ) pFuncBlock->ulParam2;
-
- /*******************************************
- * Mask Wait and Notify Bits
- ********************************************/
-
- ulParam1 &= ~( MCI_NOTIFY + MCI_WAIT);
- ulSeekFlags = ulParam1;
-
- /********************************************
- * Mask For Valid Flags on MCI_SEEK
- *********************************************/
-
- ulSeekFlags &= ~(MCI_TO + MCI_TO_START + MCI_TO_END);
-
- /* If any excess flags are passed in, return an error */
-
- if (ulSeekFlags > 0)
- return (MCIERR_INVALID_FLAG);
-
- /* We cannot seek in two different directions at once */
-
- if ( ( ulParam1 & MCI_TO_START && ulParam1 & MCI_TO_END ) ||
- ( ulParam1 & MCI_TO_START && ulParam1 & MCI_TO ) ||
- ( ulParam1 & MCI_TO && ulParam1 & MCI_TO_END ) )
- {
- return (MCIERR_FLAGS_NOT_COMPATIBLE);
- }
-
- /******************************************
- * We MUST be able to seek to some point in
- * the file, thus to, to end or to start
- * must be passed in.
- *******************************************/
-
- if ( !( ulParam1 & MCI_TO_START ||
- ulParam1 & MCI_TO_END ||
- ulParam1 & MCI_TO))
-
- return (MCIERR_MISSING_FLAG);
-
- ulpInstance= (INSTANCE *)pFuncBlock->ulpInstance;
-
-
- /*************************************************
- ** If the to parameter was sent, then the caller
- ** is required to pass in the seek parms struct
- ** so ensure that the memory is valid
- **************************************************/
-
- if (ulParam1 & MCI_TO)
- {
- ulrc = CheckMem ( (PVOID) pSeekParms,
- sizeof (MCI_SEEK_PARMS),
- PAG_READ);
-
- if (ulrc != MCIERR_SUCCESS)
- {
- return (MCIERR_MISSING_PARAMETER);
- }
-
- }
-
- /************************************
- * If a file has not been opened, then
- * a seek is not possible
- *************************************/
-
- // change to ulFile + only use TRUE/FALSE for variable
-
- if ( ulpInstance->fFileExists == FALSE )
- {
- return (MCIERR_FILE_NOT_FOUND);
- }
-
- /*********************************************
- * MCI_SEEK aborts any ongoing PLAY/RECORD.
- * ensure that the play/record threads can be
- * aborted by acquire a semaphore and then
- * post the aborted message
- *********************************************/
-
- GetNotifyAbortAccess ( ulpInstance, &ulAbortNotify );
-
- if ( ulAbortNotify )
- {
- /* Stop the command on another thread */
-
- GenericThreadAbort( ulpInstance, pFuncBlock, 0 );
-
- } /* There was a pending Notify */
-
-
- /***********************************************
- * If a set was performed on an existing stream,
- * destroy the stream and get new spcb keys
- ***********************************************/
-
- DestroySetStream ( ulpInstance );
-
-
-
- /*******************************************
- * In order to perform a seek, a stream must
- * exist. If it does not exist, create one.
- ********************************************/
-
- if (ulpInstance->ulCreateFlag != PREROLL_STATE)
- {
- /*******************************
- * Do stream set up work and then
- * create the stream
- *******************************/
-
- ulrc = PrepareAndCreateStream( ulpInstance, AMPMIX.ulOperation, TRUE );
-
- if ( ulrc )
- {
- return ( ulrc );
- }
-
-
- /******************************
- * UpDate State to created
- *******************************/
-
- ulpInstance->ulCreateFlag = PREROLL_STATE;
-
- } /* Stream Creation */
-
- /*right now, we do a brute stop always, should
- * only do it if we are not in stopped state.*/
-
- DosResetEventSem (ulpInstance->hEventSem, &ulCnt);
-
- ulrc = SpiStopStream (ulpInstance->StreamInfo.hStream, SPI_STOP_DISCARD);
-
- if ( !ulrc )
- {
- DosWaitEventSem (ulpInstance->hEventSem, (ULONG) -1);
- }
-
- /*************************************************
- * Stream Seek. Note, since we can not be sure how
- * long a playlist is, do not bother to check the
- * length
- *************************************************/
-
- if (ulpInstance->usPlayLstStrm != TRUE)
- {
-
- if (ulParam1 & MCI_TO)
- {
- /*
- ** Convert whatever time format we are currently
- ** in to mmtime
- */
-
- ConvertTimeUnits ( ulpInstance,
- &ulFileLength,
- FILE_LENGTH );
-
- /*-------------------------------------------------
- ** If the caller wants to seek past the end of the
- ** file refuse the request
- --------------------------------------------------*/
-
- ulTemp1 = pSeekParms->ulTo;
-
- if (ulTemp1 > ulFileLength)
- return (MCIERR_OUTOFRANGE);
-
- } /* To Flag On */
-
- } /* Non PlayList */
-
- /********************************************************
- * Parse Different Seek Flags to Translate into ulSpiFlags
- ********************************************************/
-
- if (ulParam1 & MCI_TO_START)
- {
- ulTemp1 = 0;
- ulSpiFlags = SPI_SEEK_ABSOLUTE;
- }
-
- if (ulParam1 & MCI_TO_END)
- {
- ulTemp1 = 0;
- ulSpiFlags = SPI_SEEK_FROMEND;
- }
-
- if (ulParam1 & MCI_TO)
- {
- ulSpiFlags = SPI_SEEK_ABSOLUTE;
- }
-
- /*********************************************
- * Convert Seek Units to MMTime
- * This translates Stream Seek units to MMTIME
- * ONLY if the user requested a number
- *********************************************/
- if ( pSeekParms && ( ulParam1 & MCI_TO ) )
- {
- ConvertToMM ( ulpInstance,
- &ulTemp1,
- pSeekParms->ulTo);
- }
-
- /* Do the seek */
-
- ulrc = SpiSeekStream ( ulpInstance->StreamInfo.hStream,
- ulSpiFlags,
- (LONG) ulTemp1);
-
- /**************************************************
- * Update the stream state so that other routines
- * such as status, play, record can take appropriate
- * actions
- **************************************************/
-
- STRMSTATE = MCI_STOP;
-
- return (ulrc);
-
- } /* MCISeek */
-
-