home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
warptlk3.zip
/
TOOLKIT
/
SAMPLES
/
MM
/
ADMCT
/
ADMCSEEK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-24
|
9KB
|
311 lines
/********************* 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 <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
#include <checkmem.h>
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 = 0L; // 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, ulpInstance->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 = ADMCStopStream (ulpInstance, 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 = ADMCSeekStream ( ulpInstance,
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 */