home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v6.zip / MMPM2TK / TK / ADMCT / ADMCSEEK.C < prev    next >
C/C++ Source or Header  |  1993-03-29  |  9KB  |  312 lines

  1. /********************* START OF SPECIFICATIONS *********************
  2. *
  3. * SUBROUTINE NAME: MCISEEK.C
  4. *
  5. * DESCRIPTIVE
  6. *
  7. *
  8. *              Copyright (c) IBM Corporation  1991, 1993
  9. *                        All Rights Reserved
  10. *
  11. *
  12. * FUNCTION:  Waveform Seek.
  13. *
  14. *  On a seek, a streaming MCD should perform the following commands:
  15. *
  16. *  A. Verify that the flags passed are valid.
  17. *  B. Verify the MCI_FROM, MCI_TO parameter if they were passed in.
  18. *  C. Ensure that any pointers passed are valid.
  19. *  D. Stop any commands which are active on another thread.
  20. *  E. If no stream has been created, then create one.
  21. *  F. If a stream had previously been created, ensure that it is in
  22. *     stopped state.
  23. *
  24. * NOTES:
  25. *
  26. * ENTRY POINTS:
  27. *
  28. * INPUT: MCI_SEEK message.
  29. *
  30. * EXIT-NORMAL: MCIERR_SUCCESS.
  31. *
  32. * EXIT_ERROR:  Error Code.
  33. *
  34. * EFFECTS:
  35. *
  36. * INTERNAL REFERENCES: MCIERR ().
  37. *
  38. * EXTERNAL REFERENCES: spiStopStream()     - SSM Spi
  39. *                      spiSeekStream()     - SSM Spi
  40. *
  41. *********************** END OF SPECIFICATIONS **********************/
  42.  
  43.  
  44. #define INCL_DOSSEMAPHORES
  45. #define INCL_DOSPROCESS
  46. #define INCL_ERRORS
  47.  
  48. #include <os2.h>                        // OS2 defines.
  49. #include <string.h>                     // String functions.
  50. #include <os2medef.h>                   // MME includes files.
  51. #include <audio.h>                      // Audio Device Defines.
  52. #include <ssm.h>                        // SSM spi includes.
  53. #include <mcios2.h>                     // MM Error Messages.
  54. #include <mmioos2.h>                    // MMIO Include.
  55. #include <mmdrvos2.h>                     // MCI Driver Include.
  56. #include <mcd.h>                        // AudioIFDriverInterface.
  57. #include <qos.h>
  58. #include <hhpheap.h>                    // Heap Manager Definitions
  59. #include <audiomcd.h>                   // Component Definitions
  60. #include "admcfunc.h"                   // Function Prototypes
  61.  
  62.  
  63.  
  64. RC MCISeek (FUNCTION_PARM_BLOCK *pFuncBlock)
  65.  
  66. {
  67.   ULONG         ulrc;                    // Return Code
  68.   ULONG         ulParam1;                // Flags For this message
  69.   ULONG         ulAbortNotify = FALSE;   // abort notification messages
  70.   ULONG         ulCnt;                    // Semaphore Post Count
  71.   ULONG         ulTemp1;                 // Temporary Variable
  72.   ULONG         ulSpiFlags;                // Flags For Spi Seek
  73.   ULONG         ulSeekFlags;             // Incoming Seek Flags From MCI
  74.   ULONG         ulFileLength;            // Element Length in MM
  75.  
  76.   PMCI_SEEK_PARMS pSeekParms;
  77.  
  78.   INSTANCE      * ulpInstance;           // Local Instance Ptr
  79.  
  80.   /********************************************
  81.   * Dereference Pointers From Thread Block
  82.   ********************************************/
  83.  
  84.   ulParam1 = pFuncBlock->ulParam1;
  85.   pSeekParms = ( PMCI_SEEK_PARMS ) pFuncBlock->ulParam2;
  86.  
  87.   /*******************************************
  88.   * Mask Wait and Notify Bits
  89.   ********************************************/
  90.  
  91.   ulParam1 &= ~( MCI_NOTIFY + MCI_WAIT);
  92.   ulSeekFlags = ulParam1;
  93.  
  94.   /********************************************
  95.   * Mask For Valid Flags on MCI_SEEK
  96.   *********************************************/
  97.  
  98.   ulSeekFlags &= ~(MCI_TO + MCI_TO_START + MCI_TO_END);
  99.  
  100.   /* If any excess flags are passed in, return an error */
  101.  
  102.   if (ulSeekFlags > 0)
  103.       return (MCIERR_INVALID_FLAG);
  104.  
  105.   /* We cannot seek in two different directions at once */
  106.  
  107.   if ( ( ulParam1 & MCI_TO_START && ulParam1 & MCI_TO_END ) ||
  108.        ( ulParam1 & MCI_TO_START && ulParam1 & MCI_TO     ) ||
  109.        ( ulParam1 & MCI_TO && ulParam1 & MCI_TO_END ) )
  110.      {
  111.      return (MCIERR_FLAGS_NOT_COMPATIBLE);
  112.      }
  113.  
  114.   /******************************************
  115.   * We MUST be able to seek to some point in
  116.   * the file, thus to, to end or to start
  117.   * must be passed in.
  118.   *******************************************/
  119.  
  120.   if ( !( ulParam1 & MCI_TO_START ||
  121.           ulParam1 & MCI_TO_END   ||
  122.           ulParam1 & MCI_TO))
  123.  
  124.       return (MCIERR_MISSING_FLAG);
  125.  
  126.   ulpInstance= (INSTANCE *)pFuncBlock->ulpInstance;
  127.  
  128.  
  129.   /*************************************************
  130.   ** If the to parameter was sent, then the caller
  131.   ** is required to pass in the seek parms struct
  132.   ** so ensure that the memory is valid
  133.   **************************************************/
  134.  
  135.   if (ulParam1 & MCI_TO)
  136.      {
  137.      ulrc = CheckMem ( (PVOID) pSeekParms,
  138.                        sizeof (MCI_SEEK_PARMS),
  139.                        PAG_READ);
  140.  
  141.      if (ulrc != MCIERR_SUCCESS)
  142.         {
  143.         return (MCIERR_MISSING_PARAMETER);
  144.         }
  145.  
  146.      }
  147.  
  148.   /************************************
  149.   * If a file has not been opened, then
  150.   * a seek is not possible
  151.   *************************************/
  152.  
  153.   // change to ulFile + only use TRUE/FALSE for variable
  154.  
  155.   if ( ulpInstance->fFileExists == FALSE )
  156.      {
  157.      return (MCIERR_FILE_NOT_FOUND);
  158.      }
  159.  
  160.   /*********************************************
  161.   * MCI_SEEK aborts any ongoing PLAY/RECORD.
  162.   * ensure that the play/record threads can be
  163.   * aborted by acquire a semaphore and then
  164.   * post the aborted message
  165.   *********************************************/
  166.  
  167.   GetNotifyAbortAccess ( ulpInstance, &ulAbortNotify );
  168.  
  169.   if ( ulAbortNotify )
  170.      {
  171.      /* Stop the command on another thread */
  172.  
  173.      GenericThreadAbort( ulpInstance, pFuncBlock, 0  );
  174.  
  175.      }  /* There was a pending Notify */
  176.  
  177.  
  178.   /***********************************************
  179.   * If a set was performed on an existing stream,
  180.   * destroy the stream and get new spcb keys
  181.   ***********************************************/
  182.  
  183.   DestroySetStream ( ulpInstance );
  184.  
  185.  
  186.  
  187.   /*******************************************
  188.   * In order to perform a seek, a stream must
  189.   * exist.  If it does not exist, create one.
  190.   ********************************************/
  191.  
  192.   if (ulpInstance->ulCreateFlag != PREROLL_STATE)
  193.     {
  194.     /*******************************
  195.     * Do stream set up work and then
  196.     * create the stream
  197.     *******************************/
  198.  
  199.     ulrc = PrepareAndCreateStream( ulpInstance, AMPMIX.ulOperation, TRUE );
  200.  
  201.     if ( ulrc )
  202.        {
  203.        return ( ulrc );
  204.        }
  205.  
  206.  
  207.     /******************************
  208.     * UpDate State to created
  209.     *******************************/
  210.  
  211.     ulpInstance->ulCreateFlag = PREROLL_STATE;
  212.  
  213.     }  /* Stream Creation */
  214.  
  215.   /*right now, we do a brute stop always, should
  216.   *  only do it if we are not in stopped state.*/
  217.  
  218.   DosResetEventSem (ulpInstance->hEventSem, &ulCnt);
  219.  
  220.   ulrc = SpiStopStream (ulpInstance->StreamInfo.hStream, SPI_STOP_DISCARD);
  221.  
  222.   if ( !ulrc )
  223.      {
  224.      DosWaitEventSem (ulpInstance->hEventSem, (ULONG) -1);
  225.      }
  226.  
  227.   /*************************************************
  228.   * Stream Seek.  Note, since we can not be sure how
  229.   * long a playlist is, do not bother to check the
  230.   * length
  231.   *************************************************/
  232.  
  233.   if (ulpInstance->usPlayLstStrm != TRUE)
  234.      {
  235.  
  236.      if (ulParam1 & MCI_TO)
  237.         {
  238.         /*
  239.         ** Convert whatever time format we are currently
  240.         ** in to mmtime
  241.         */
  242.  
  243.         ConvertTimeUnits ( ulpInstance,
  244.                            &ulFileLength,
  245.                            FILE_LENGTH );
  246.  
  247.         /*-------------------------------------------------
  248.         ** If the caller wants to seek past the end of the
  249.         ** file refuse the request
  250.         --------------------------------------------------*/
  251.  
  252.         ulTemp1 = pSeekParms->ulTo;
  253.  
  254.         if (ulTemp1 > ulFileLength)
  255.             return (MCIERR_OUTOFRANGE);
  256.  
  257.         } /* To Flag On */
  258.  
  259.      } /* Non PlayList */
  260.  
  261.   /********************************************************
  262.   * Parse Different Seek Flags to Translate into ulSpiFlags
  263.   ********************************************************/
  264.  
  265.   if (ulParam1 & MCI_TO_START)
  266.      {
  267.      ulTemp1 = 0;
  268.      ulSpiFlags = SPI_SEEK_ABSOLUTE;
  269.      }
  270.  
  271.   if (ulParam1 & MCI_TO_END)
  272.      {
  273.      ulTemp1 = 0;
  274.      ulSpiFlags = SPI_SEEK_FROMEND;
  275.      }
  276.  
  277.   if (ulParam1 & MCI_TO)
  278.      {
  279.      ulSpiFlags = SPI_SEEK_ABSOLUTE;
  280.      }
  281.  
  282.    /*********************************************
  283.    * Convert Seek Units to MMTime
  284.    * This translates Stream Seek units to MMTIME
  285.    * ONLY if the user requested a number
  286.    *********************************************/
  287.    if ( pSeekParms && ( ulParam1 & MCI_TO ) )
  288.       {
  289.       ConvertToMM ( ulpInstance,
  290.                     &ulTemp1,
  291.                     pSeekParms->ulTo);
  292.       }
  293.  
  294.   /* Do the seek */
  295.  
  296.   ulrc = SpiSeekStream ( ulpInstance->StreamInfo.hStream,
  297.                          ulSpiFlags,
  298.                          (LONG) ulTemp1);
  299.  
  300.   /**************************************************
  301.   * Update the stream state so that other routines
  302.   * such as status, play, record can take appropriate
  303.   * actions
  304.   **************************************************/
  305.  
  306.   STRMSTATE = MCI_STOP;
  307.  
  308.   return (ulrc);
  309.  
  310. } /* MCISeek */
  311.  
  312.