home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / ADMCT / ADMCSTAT.C < prev    next >
C/C++ Source or Header  |  1993-04-12  |  19KB  |  555 lines

  1. /********************* START OF SPECIFICATIONS *********************
  2. *
  3. * SUBROUTINE NAME: MCISTAT.C
  4. *
  5. * DESCRIPTIVE NAME: Audio MCD status routine
  6. *
  7. *              Copyright (c) IBM Corporation  1991, 1993
  8. *                        All Rights Reserved
  9. *
  10. * FUNCTION: Get the status of several variables.
  11. *
  12. * NOTES: This source file illustrates the following concepts:
  13. *        A. When/If to report media position within a stream.
  14. *        B. How to determine the length of an existing file.
  15. *        C. How to determine the length of a file which is currently
  16. *           being recorded.
  17. *        D. Communicating with the amp/mixer to determine volume,
  18. *           and other amplifier specific commands.
  19. *        E. Reporting our current mode.
  20. *        F. Reporting the current time format.
  21. *
  22. *
  23. * INTERNAL REFERENCES:
  24. *                        ConvertTimeUnits ().
  25. *                        ConVertToMM
  26. *                        SetAudioDevice().
  27. *                        SetWaveDeviceDefaults().
  28. *                        CheckMem ().
  29. *
  30. * EXTERNAL REFERENCES:
  31. *                        SpiGetTime       ()        - MME API
  32. *                        mciSendCommand   ()        - MME API
  33. *
  34. *********************** END OF SPECIFICATIONS **********************/
  35.  
  36.  
  37. #define INCL_BASE                       // Base Dos APIs.
  38. #define INCL_ERRORS                     // All the errors.
  39. #define INCL_WINCLIPBOARD
  40. #define INCL_WINWINDOWMGR
  41. #define INCL_DOSSEMAPHORES
  42. #define INCL_DOSPROCESS
  43. #define INCL_ERRORS
  44. #define INCL_WINATOM
  45. #define INCL_HEAP
  46. #define INCL_DOSMEMMGR
  47.  
  48.  
  49. #include <os2.h>                        // OS2 includes.
  50. #include <string.h>                     // String Functions
  51. #include <math.h>                       // Math Functions
  52. #include <os2medef.h>                   // MME includes files.
  53. #include <ssm.h>                        // SSM spi includes.
  54. #include <meerror.h>                    // MM Error Messages.
  55. #include <mmioos2.h>                    // MMIO Include.
  56. #include <mcios2.h>                     // MM System Include.
  57. #include <audio.h>                      // Audio DD Defines
  58. #include <mmdrvos2.h>                   // Mci Driver include.
  59. #include <mcd.h>                        // AUDIO IF DriverInterface.
  60. #include <hhpheap.h>                    // Heap Manager Definitions.
  61. #include <qos.h>
  62. #include <audiomcd.h>                   // Component Definitions.
  63. #include <admcfunc.h>                   // Function Prototypes
  64.  
  65. /********************* START OF SPECIFICATIONS *******************************
  66. *
  67. * SUBROUTINE NAME: MCISTAT.C
  68. *
  69. * DESCRIPTIVE NAME: Waveform Status Routine.
  70. *
  71. * FUNCTION: Get Current Status of an Waveform Instance.
  72. *
  73. * NOTES: After the status is obtained from the device specific DLL
  74. *        the corresponding field in the instance structure is updated
  75. *        to reflect the most recent state.
  76. *
  77. * ENTRY POINTS:
  78. *     LINKAGE:   CALL FAR
  79. *
  80. * INPUT:
  81. *
  82. * EXIT-NORMAL: Return Code 0.
  83. *
  84. * EXIT_ERROR:  Error Code.
  85. *
  86. * EFFECTS:
  87. *
  88. * INTERNAL REFERENCES: VSDIDriverEntry().
  89. *
  90. * EXTERNAL REFERENCES: DosQueryProcAddr - OS/2 API.
  91. *
  92. *********************** END OF SPECIFICATIONS *******************************/
  93.  
  94. RC MCIStat (FUNCTION_PARM_BLOCK *pFuncBlock)
  95.  
  96. {
  97.  
  98.   ULONG               ulrc;                // Error Value
  99.   ULONG               ulParam1;            // MCI Msg Flags
  100.   ULONG               ulFormatInfo = 0;    // Format of Clipboard data
  101.   INSTANCE*           ulpInstance;         // Local Instance
  102.   ULONG               ulTemp1;             // Temporary Stuff
  103.   ULONG               ulTemp2;             // Temporary Stuff
  104.   ULONG               ulStatFlags;         // Mask For Incoming Flags
  105.  
  106.   PMCI_STATUS_PARMS   pParams;             // Msg Data Ptr
  107.  
  108.   HAB            habClipboard;
  109.  
  110.   /* Derefernce pointers */
  111.  
  112.   ulParam1    = pFuncBlock->ulParam1;
  113.   pParams     = (PMCI_STATUS_PARMS) pFuncBlock->ulParam2;
  114.   ulpInstance = (INSTANCE *) pFuncBlock->ulpInstance;
  115.  
  116.   /*********************************************
  117.   * Mask out only flags that this MCD supports.
  118.   **********************************************/
  119.   ulStatFlags = ulParam1;
  120.  
  121.   ulStatFlags &= ~ (MCI_STATUS_ITEM + MCI_TRACK + MCI_WAIT + MCI_NOTIFY);
  122.  
  123.   /**********************************
  124.   * Return error if caller passed in
  125.   * a flag we do not support.
  126.   ***********************************/
  127.  
  128.   if (ulStatFlags > 0 )
  129.      {
  130.      return ( MCIERR_INVALID_FLAG );
  131.      }
  132.  
  133.   /*******************************************
  134.   * The caller is required to pass in valid
  135.   * status parms--verify that this is true.
  136.   ********************************************/
  137.  
  138.   ulrc = CheckMem ( (PVOID)pParams,
  139.                     sizeof (MCI_STATUS_PARMS),
  140.                     PAG_READ);
  141.  
  142.   if (ulrc != MCIERR_SUCCESS)
  143.           return ( MCIERR_MISSING_PARAMETER );
  144.  
  145.   /* This MCD does not support the track flag */
  146.  
  147.   if (ulParam1 & MCI_TRACK)
  148.       return ( MCIERR_UNSUPPORTED_FLAG );
  149.  
  150.  
  151.   /*****************************************************************
  152.   * The waveaudio MCD only supports status requests with the
  153.   * STATUS_ITEM flag set.  All other requests will return an error
  154.   *****************************************************************/
  155.  
  156.   if (ulParam1 & MCI_STATUS_ITEM )
  157.     {
  158.  
  159.     switch (pParams->ulItem)
  160.       {
  161.       /* the caller wants to know the current media position */
  162.  
  163.       case MCI_STATUS_POSITION:
  164.           {
  165.  
  166.           /********************************************
  167.           * If a stream has been previously created,
  168.           * then determine our position within the
  169.           * stream. If no stream has been created, (i.e.
  170.           * a file has been loaded, however, there has
  171.           * been actions after that.
  172.           **********************************************/
  173.  
  174.           if (ulpInstance->ulCreateFlag != CREATE_STATE )
  175.              {
  176.              STREAM.mmStreamTime = 0;
  177.  
  178.              /********************************************
  179.              * Query the stream for current stream time
  180.              *********************************************/
  181.  
  182.              ulrc = SpiGetTime ( STREAM.hStream,
  183.                                  (PMMTIME) &STREAM.mmStreamTime);
  184.              if (!ulrc)
  185.  
  186.                 /*******************************************
  187.                 * Convert MMTIME units to current time base
  188.                 ********************************************/
  189.                 {
  190.                 ConvertTimeUnits ( ulpInstance,
  191.                                    &ulTemp1,
  192.                                    (ULONG) STREAM.mmStreamTime);
  193.                 }
  194.  
  195.              pParams->ulReturn = (ULONG) ulTemp1;
  196.              }
  197.            else
  198.              {
  199.              pParams->ulReturn = 0;  // No Stream Alive
  200.              }
  201.  
  202.            ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  203.  
  204.           } /* case STATUS_POSITION */
  205.  
  206.           break;
  207.  
  208.       /* The caller wants to know the length of the file */
  209.  
  210.       case MCI_STATUS_LENGTH:
  211.            {
  212.  
  213.            /* if we have not loaded a file, it can't have a length! */
  214.  
  215.            if (ulpInstance->fFileExists == FALSE)
  216.                return (MCIERR_FILE_NOT_FOUND);
  217.  
  218.            /*************************************************
  219.            * Playlist cannot report lengths, since they can
  220.            * contain infinite loops.
  221.            *************************************************/
  222.  
  223.            if (ulpInstance->usPlayLstStrm == TRUE)
  224.                return (MCIERR_INDETERMINATE_LENGTH );
  225.  
  226.            /*********************************************
  227.            * There is a big difference between record and
  228.            * playback lengths.  In the case of play, the
  229.            * file length will not change.  However, if
  230.            * a record is active, the file length could
  231.            * potentially be growing.
  232.            **********************************************/
  233.  
  234.            if (AMPMIX.ulOperation == OPERATION_PLAY)
  235.               {
  236.               ulrc = GetAudioHeader( ulpInstance );
  237.  
  238.               if ( ulrc )
  239.                  {
  240.                  return ( ulrc );
  241.                  }
  242.  
  243.               /******************************************
  244.               * the function ConvertTimeUnits also
  245.               * returns media element length in the
  246.               * current time units.
  247.               ******************************************/
  248.  
  249.               ConvertTimeUnits (ulpInstance, &ulTemp1, FILE_LENGTH);
  250.  
  251.               pParams->ulReturn = ulTemp1;
  252.  
  253.               } /* the card is in playback mode */
  254.  
  255.            /* else if the card is in record mode */
  256.  
  257.            else
  258.               {
  259.               /* Test and see if the stream has been prerolled */
  260.  
  261.               if (ulpInstance->ulCreateFlag == PREROLL_STATE)
  262.                    {
  263.                    /************************************
  264.                    * Are we currently recording?
  265.                    * (cue could preroll the stream also
  266.                    ************************************/
  267.  
  268.                    if ( STRMSTATE == MCI_RECORD )
  269.                       {
  270.                       ulrc = SpiGetTime ( STREAM.hStream,
  271.                                           ( PMMTIME)&STREAM.mmStreamTime);
  272.  
  273.                       if (!ulrc)
  274.                          {
  275.                          ulTemp2 = STREAM.mmStreamTime;
  276.                          }
  277.  
  278.                       ConvertTimeUnits (ulpInstance, &ulTemp1, ulTemp2);
  279.  
  280.                       /******************************************
  281.                       * the function ConvertTimeUnits also
  282.                       * returns media element length in the
  283.                       * current time units.
  284.                       ******************************************/
  285.                       ConvertTimeUnits (ulpInstance, &ulTemp2, FILE_LENGTH);
  286.  
  287.                       /******************************************
  288.                       * if the current record position is smaller
  289.                       * tham the file length, then report the
  290.                       * file length.
  291.                       ******************************************/
  292.                       if ( ulTemp1 < ulTemp2 )
  293.                          {
  294.                          ulTemp1 = ulTemp2;
  295.                          }
  296.  
  297.                       pParams->ulReturn = ulTemp1;
  298.                       } /* if we are currently recording */
  299.                    else
  300.                       {
  301.                       ulrc = GetAudioHeader( ulpInstance );
  302.  
  303.                       if ( ulrc )
  304.                          {
  305.                          return ( ulrc );
  306.                          }
  307.  
  308.                       /******************************************
  309.                       * the function ConvertTimeUnits also
  310.                       * returns media element length in the
  311.                       * current time units.
  312.                       *******************************************/
  313.                       ConvertTimeUnits (ulpInstance, &ulTemp1, FILE_LENGTH);
  314.  
  315.                       pParams->ulReturn = ulTemp1;
  316.  
  317.                       } /* else we not are currently recording */
  318.  
  319.                    } /* Stream Created and Recording */
  320.  
  321.               /* The stream is not currently active */
  322.               else
  323.                  {
  324.                  ulrc = GetAudioHeader( ulpInstance );
  325.  
  326.                  if ( ulrc )
  327.                     {
  328.                     return ( ulrc );
  329.                     }
  330.  
  331.                   /******************************************
  332.                   * the function ConvertTimeUnits also
  333.                   * returns media element length in the
  334.                   * current time units.
  335.                   ******************************************/
  336.                   ConvertTimeUnits (ulpInstance, &ulTemp1, FILE_LENGTH);
  337.  
  338.                   pParams->ulReturn = ulTemp1;
  339.  
  340.                  } /* else we are not currently recording */
  341.  
  342.               } /* else we are in record mode */
  343.  
  344.            ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  345.  
  346.            } /* status length */
  347.  
  348.            break;
  349.  
  350.       case MCI_STATUS_NUMBER_OF_TRACKS:
  351.       case MCI_STATUS_SPEED_FORMAT:
  352.       case MCI_STATUS_CURRENT_TRACK:
  353.       case MCI_STATUS_POSITION_IN_TRACK:
  354.  
  355.             return ( MCIERR_UNSUPPORTED_FLAG );
  356.  
  357.       /******************************************************
  358.       * For status volume, and of the amp commands should
  359.       * go the amp/mixer that we are connected to.
  360.       ******************************************************/
  361.  
  362.       case MCI_STATUS_VOLUME:
  363.             ulrc = mciSendCommand ( ulpInstance->usAmpDeviceID,
  364.                                     MCI_STATUS,
  365.                                     MCI_STATUS_ITEM | MCI_WAIT,
  366.                                     (PVOID) pParams,
  367.                                     pFuncBlock->usUserParm);
  368.  
  369.             ulrc = MAKEULONG (ulrc, MCI_COLONIZED2_RETURN);
  370.           break;
  371.       case MCI_AMP_STATUS_BALANCE:
  372.       case MCI_AMP_STATUS_BASS   :
  373.       case MCI_AMP_STATUS_TREBLE :
  374.       case MCI_AMP_STATUS_GAIN   :
  375.             ulrc = mciSendCommand ( ulpInstance->usAmpDeviceID,
  376.                                     MCI_STATUS,
  377.                                     MCI_STATUS_ITEM | MCI_WAIT,
  378.                                     (PVOID) pParams,
  379.                                     pFuncBlock->usUserParm );
  380.  
  381.             ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED );
  382.           break;
  383.  
  384.       case MCI_WAVE_STATUS_CHANNELS:
  385.             pParams->ulReturn = AMPMIX.sChannels;
  386.             ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  387.  
  388.           break;
  389.  
  390.       case MCI_WAVE_STATUS_SAMPLESPERSEC:
  391.             pParams->ulReturn = AMPMIX.lSRate;
  392.             ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  393.  
  394.           break;
  395.  
  396.       case MCI_WAVE_STATUS_AVGBYTESPERSEC:
  397.  
  398.              pParams->ulReturn = ulpInstance->ulAverageBytesPerSec;
  399.  
  400.              ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  401.  
  402.           break;
  403.  
  404.       case MCI_WAVE_STATUS_BITSPERSAMPLE:
  405.             pParams->ulReturn = AMPMIX.lBitsPerSRate;
  406.             ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  407.           break;
  408.  
  409.       case MCI_STATUS_CLIPBOARD :
  410.  
  411.          habClipboard = WinQueryAnchorBlock( HWND_DESKTOP );
  412.  
  413.          /*********************************************************************
  414.          * Check to see if there is a wave ( CF_WAVE is the defined type) in
  415.          * the clipboard.
  416.          *********************************************************************/
  417.  
  418.  
  419.           pParams->ulReturn = WinQueryClipbrdFmtInfo( habClipboard,
  420.                                         CF_WAVE,
  421.                                         &ulFormatInfo );
  422.  
  423.          ulrc = MAKEULONG(ulrc, MCI_TRUE_FALSE_RETURN);
  424.          break;
  425.  
  426.       case MCI_WAVE_STATUS_LEVEL:
  427.  
  428.             pParams->ulReturn = 0;
  429.             ulrc = MAKEULONG (ulrc, MCI_INTEGER_RETURNED);
  430.           break;
  431.  
  432.       case MCI_WAVE_STATUS_FORMATTAG:
  433.             pParams->ulReturn = AMPMIX.sMode;
  434.             ulrc = MAKEULONG (ulrc, MCI_FORMAT_TAG_RETURN);
  435.           break;
  436.  
  437.       case MCI_STATUS_MEDIA_PRESENT:
  438.             pParams->ulReturn = MCI_TRUE;
  439.             ulrc = MAKEULONG(ulrc, MCI_TRUE_FALSE_RETURN);
  440.           break;
  441.  
  442.       case MCI_WAVE_STATUS_BLOCKALIGN:
  443.            pParams->ulReturn = AMPMIX.ulBlockAlignment;
  444.            ulrc = MAKEULONG(ulrc, MCI_INTEGER_RETURNED);
  445.           break;
  446.  
  447.       case MCI_STATUS_MODE:
  448.            {
  449.               /********************************************
  450.                * Always Return an Integer for this case
  451.               ********************************************/
  452.               ulrc = MAKEULONG (ulrc, MCI_MODE_RETURN);
  453.  
  454.               /* if no file is loaded, we are not ready */
  455.              if (ulpInstance->fFileExists == FALSE)
  456.                 {
  457.                 pParams->ulReturn = MCI_MODE_NOT_READY;
  458.                 }
  459.              else
  460.                 {
  461.                   /* Our current mode depends on the action we are doing */
  462.  
  463.                   switch (STRMSTATE)
  464.                      {
  465.                       case MCI_PLAY:
  466.                             pParams->ulReturn = MCI_MODE_PLAY;
  467.                            break;
  468.  
  469.                       case MCI_RECORD:
  470.                             pParams->ulReturn = MCI_MODE_RECORD;
  471.                            break;
  472.  
  473.                       case MCI_STOP     :
  474.                       case STOP_PAUSED  :
  475.                       case CUEPLAY_STATE:
  476.                       case CUERECD_STATE:
  477.                             pParams->ulReturn = MCI_MODE_STOP;
  478.                            break;
  479.  
  480.                       case MCI_PAUSE:
  481.                             pParams->ulReturn = MCI_MODE_PAUSE;
  482.                            break;
  483.  
  484.                       default:
  485.                             pParams->ulReturn = MCI_MODE_NOT_READY;
  486.  
  487.                      } /* of Possible Modes (Switch) */
  488.                 }
  489.            }  /* Status Mode */
  490.           break;
  491.  
  492.       /* Return our current time format */
  493.  
  494.       case MCI_STATUS_TIME_FORMAT:
  495.            {
  496.             switch (ulpInstance->ulTimeUnits)
  497.             {
  498.              case lMMTIME:
  499.                    pParams->ulReturn = MCI_FORMAT_MMTIME;
  500.                   break;
  501.  
  502.              case lMILLISECONDS:
  503.                    pParams->ulReturn = MCI_FORMAT_MILLISECONDS;
  504.                   break;
  505.  
  506.              case lBYTES:
  507.                    pParams->ulReturn = MCI_FORMAT_BYTES;
  508.                   break;
  509.  
  510. /*case lSAMPLES:*/
  511.              default :
  512.                    pParams->ulReturn = MCI_FORMAT_SAMPLES;
  513.                   break;
  514.              } /* Switch */
  515.  
  516.              ulrc = MAKEULONG (ulrc, MCI_TIME_FORMAT_RETURN);
  517.  
  518.           }
  519.           break;
  520.  
  521.       case MCI_STATUS_READY:
  522.             if (ulpInstance->fFileExists == MCI_TRUE)
  523.                  {
  524.  
  525.                  /*****************************************
  526.                  * Check if Amp/Mixer is Ready and active
  527.                  *****************************************/
  528.                  ulrc = mciSendCommand ( ulpInstance->usAmpDeviceID,
  529.                                          MCI_STATUS,
  530.                                          MCI_STATUS_ITEM | MCI_WAIT,
  531.                                          (PVOID) pParams,
  532.                                          pFuncBlock->usUserParm );
  533.                  }
  534.             else
  535.                  pParams->ulReturn = MCI_FALSE;
  536.  
  537.             ulrc = MAKEULONG(ulrc, MCI_TRUE_FALSE_RETURN);
  538.           break;
  539.  
  540.       default:
  541.              return (MCIERR_INVALID_FLAG);
  542.  
  543.       } /* end of switch */
  544.  
  545.     } /* Status Item */
  546.   else
  547.     {
  548.     return ( MCIERR_MISSING_FLAG );
  549.  
  550.     } /* status item is not passed */
  551.  
  552.   return (ulrc);
  553.  
  554. } /* MCIStat */
  555.