home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / admct / admcopen.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  19KB  |  596 lines

  1. /*********************** END OF SPECIFICATIONS *******************************
  2. *
  3. * SOURCE FILE NAME:  MCIOPEN.C
  4. *
  5. *
  6. *
  7. *              Copyright (c) IBM Corporation  1991, 1993
  8. *                        All Rights Reserved
  9. *
  10. * DESCRIPTIVE NAME:  WAVEFORM MCD (PLAYER)
  11. *
  12. * FUNCTION: Opens the waveaudio device.  Supports device only, elements,
  13. *           mmio file handles and play lists.
  14. *
  15. * On an MCI_OPEN, a streaming MCD should perform the following actions:
  16. *
  17. *
  18. * A. Check flags and validate pointers.
  19. * B. Get default values from the ini files (if necessary).
  20. * C. Process MCI_OPEN_PLAYLIST (if supported).
  21. * D. Process MCI_OPEN_MMIO (if supported).
  22. * E. Process MCI_OPEN_ELEMENT (if supported).
  23. * F. Get the stream protocol key (if necessary).
  24. *
  25. *********************** END OF SPECIFICATIONS ********************************/
  26. #define INCL_BASE
  27. #define INCL_DOSMODULEMGR
  28. #define INCL_DOSSEMAPHORES
  29. #define INCL_WINCLIPBOARD
  30. #define INCL_WINWINDOWMGR
  31.  
  32.  
  33. #include <os2.h>                        // OS2 defines.
  34. #include <string.h>
  35. #include <os2medef.h>                   // MME includes files.
  36. #include <stdlib.h>                     // Math functions
  37. #include <ssm.h>                        // SSM Spi includes.
  38. #include <meerror.h>                    // MM Error Messages.
  39. #include <mmioos2.h>                    // MMIO Include.
  40. #include <mcios2.h>                     // MM System Include.
  41. #include <mcipriv.h>                    // MCI Connection stuff
  42. #include <mmdrvos2.h>                   // MCI Driver include.
  43. #include <mcd.h>                        // AudioIFDriverInterface.
  44. #include <hhpheap.h>                    // Heap Manager Definitions
  45. #include <qos.h>
  46. #include <audiomcd.h>                   // Component Definitions.
  47. #include "admcfunc.h"                   // Function Prototypes.
  48. #include <sw.h>
  49. #include <checkmem.h>
  50.  
  51.  
  52.  
  53. /********************* START OF SPECIFICATIONS *******************************
  54. *
  55. * SUBROUTINE NAME: MCIOPEN.C
  56. *
  57. * DESCRIPTIVE NAME: Open Waveform Player.
  58. *
  59. * FUNCTION:
  60. *
  61. * NOTES: This function opens the device that we are connected to.
  62. *        It is called from the main switch statement (MCI_OPEN) and
  63. *        this function will do the following actions.
  64. *        A. Parse flags.
  65. *        B. Determine stream handlers to be used in streaming.
  66. *        C. Connect to a device (usually the amp/mixer).
  67. *        D. Open the file.
  68. *        E. Set up various variables.
  69. *
  70. * NO streams are created on the open.  This will be done only on
  71. * the streaming operations
  72. *
  73. * INPUT:
  74. *
  75. * EXIT-NORMAL: Return Code 0.
  76. *
  77. * EXIT_ERROR:  Error Code.
  78. *
  79. * EFFECTS:
  80. *
  81. * INTERNAL REFERNCES:   OpenFile (),
  82. *                       SetWaveDeviceDefaults (),
  83. *                       SetAudioDevice (),
  84. *                       InitAudioDevice,
  85. *                       SetAmpDefaults (),
  86. *                       CheckMem ().
  87. *
  88. *
  89. * EXTERNAL REFERENCES:  SpiGetHandler      ()   -       SSM Spi
  90. *                       AudioIFDriverEntry ()   -       Audio IF Interface
  91. *                       DosLoadModule      ()   -       OS/2 API
  92. *                       DosQueryProcAddr   ()   -       OS/2 API
  93. *                       mdmDriverNotify    ()   -       MDM  API
  94. *                       mciSendCommand     ()   -       MDM  API
  95. *                       mciConnection      ()   -       MDM  API
  96. *                       mciQueryDefaultConnections () - MDM  API
  97. *
  98. *********************** END OF SPECIFICATIONS ********************************/
  99.  
  100. RC MCIOpen (FUNCTION_PARM_BLOCK *pFuncBlock)
  101. {
  102.   ULONG                ulrc;                     // Propogated Error Code
  103.   INSTANCE             *ulpInstance;             // Full Blown Instance
  104.   ULONG                ulParam1;                 // Incoming Flags From MCI
  105.   ULONG                ulOpenFlags;              // Mask For Incoming Flags
  106.   MMDRV_OPEN_PARMS     *pDrvOpenParams;          // MCI Driver Open Parameter Block
  107.  
  108.   extern HID           hidA2Source;              // hid's for memory playlist
  109.   extern HID           hidA2Target;
  110. //  extern HID           hidBTarget;
  111.  
  112.   ulParam1 =  pFuncBlock->ulParam1;
  113.   ulpInstance = pFuncBlock->pInstance;
  114.   pDrvOpenParams = (MMDRV_OPEN_PARMS *) pFuncBlock->ulParam2;
  115.  
  116.  
  117.   ulOpenFlags = ulParam1;
  118.  
  119.   /**********************************
  120.   * Check For Validity of Flags
  121.   **********************************/
  122.  
  123.   ulOpenFlags &= ~(  MCI_WAIT          + MCI_NOTIFY       +
  124.                     MCI_OPEN_SHAREABLE + MCI_OPEN_TYPE_ID + MCI_OPEN_ELEMENT +
  125.                     MCI_OPEN_PLAYLIST  + MCI_OPEN_ALIAS   + MCI_OPEN_MMIO    +
  126.                     MCI_READONLY );
  127.  
  128.  
  129.   if (ulOpenFlags >  0)
  130.       return MCIERR_INVALID_FLAG;
  131.  
  132.  
  133.  
  134.   /*************************************
  135.   * Check Incoming MCI Flags
  136.   ************************************/
  137.   if ( ( ulParam1 & MCI_OPEN_PLAYLIST ) &&
  138.        ( ( ulParam1 & MCI_OPEN_ELEMENT )  ||
  139.          ( ulParam1 & MCI_OPEN_MMIO )
  140.        ) )
  141.      return ( MCIERR_FLAGS_NOT_COMPATIBLE );
  142.  
  143.   if ( ( ulParam1 & MCI_OPEN_ELEMENT ) &&
  144.        ( ulParam1 & MCI_OPEN_MMIO ) )
  145.      return ( MCIERR_FLAGS_NOT_COMPATIBLE );
  146.  
  147.   /***************************************
  148.   * Ensure that if read only flag is passed
  149.   * in that open element is too
  150.   ****************************************/
  151.   if ( ( ulParam1 & MCI_READONLY ) &&
  152.        !( ulParam1 & MCI_OPEN_ELEMENT || ulParam1 & MCI_OPEN_MMIO ) )
  153.      {
  154.      return ( MCIERR_MISSING_FLAG );
  155.      }
  156.  
  157.  
  158.   /***************************************
  159.   * Fill in information to return to the
  160.   * Media Device Manager (MDM).  It will
  161.   * store our instance for us for future
  162.   * messages such as save/restore/play etc.
  163.   ***************************************/
  164.  
  165.  
  166.   pDrvOpenParams->pInstance = (PVOID) pFuncBlock->pInstance;
  167.  
  168.   /*----------------------------------------------
  169.   * Resource units describe how many processes
  170.   * threads can open different instances of
  171.   * the streaming or non-streaming MCI driver.
  172.   * Since our streaming MCD consumes no resources
  173.   * (i.e. an infinite number of instances can be
  174.   * opened) set the resources used to 0.  Note:
  175.   * this is not true of the amp/mixer since it is
  176.   * constrained by the capabilities of the audio
  177.   * hardware it is attached to.
  178.   *---------------------------------------------*/
  179.   pDrvOpenParams->usResourceUnitsRequired = 0;
  180.  
  181.   pFuncBlock->ulpInstance = (PVOID) pFuncBlock->pInstance;
  182.  
  183.   if (ulParam1 & MCI_NOTIFY)
  184.      {
  185.      pFuncBlock->ulNotify = TRUE;
  186.      pFuncBlock->hwndCallBack = pDrvOpenParams->hwndCallback;
  187.      }
  188.   else
  189.      {
  190.      pFuncBlock->ulNotify = FALSE;
  191.      }
  192.  
  193.  
  194.   /* Get the default values that the user placed in the MMPM2.INI file */
  195.  
  196. //  ulrc = GetDefaults( pDrvOpenParams->pDevParm, ulpInstance );
  197. //
  198. //  if ( ulrc )
  199. //     {
  200. //     return ( ulrc );
  201. //     }
  202.  
  203.   /*----------------------------------
  204.   * Store device specific parms for
  205.   * future reference.
  206.   *----------------------------------*/
  207.  
  208.   strcpy( ulpInstance->szDevParm, pDrvOpenParams->pDevParm );
  209.  
  210.   /*----------------------------------
  211.   * Initialize appropriate variables
  212.   * which will be used for streaming
  213.   * and other needs.
  214.   *----------------------------------*/
  215.  
  216.   OpenInit( ulpInstance );
  217.  
  218.  
  219.   /*-----------------------------------
  220.   * Load the VSD which the ini file
  221.   * says we are connected to.  The name
  222.   * of this VSD is in the MMDRV_OPEN_PARMS
  223.   * structure.
  224.   *
  225.   * VSD's are used to implement device
  226.   * specific functions (such as setting
  227.   * attributes on an audio card).
  228.   *--------------------------------------*/
  229. // CONNECTOR FEATURE
  230. //  ulrc = DetermineConnections( ulpInstance, pDrvOpenParams );
  231. //
  232. //  if ( ulrc )
  233. //     {
  234. //    return ( ulrc );
  235. //     }
  236. // CONNECTOR FEATURE
  237.  
  238.   /*********************************************
  239.   * Create semaphores necessary for our operation
  240.   * This MCD uses semaphores to control access
  241.   * to memory operations, and synchronization.
  242.   *
  243.   * Note: One really neat thing about semaphores
  244.   * in OS/2 is that the process that creates
  245.   * them automatically has access to them without
  246.   * having to open them.
  247.   *********************************************/
  248.  
  249.   ulrc = CreateSemaphores( pFuncBlock );
  250.  
  251.   if ( ulrc )
  252.     {
  253.     return ( ulrc );
  254.     }
  255.  
  256.   /**************************************
  257.   * This MCD currently always attaches
  258.   * itself to an amp/mixer.  We want
  259.   * to open the ampmixer with the same
  260.   * flags that this MCD was opened with
  261.   * (i.e. if someone opened the audio MCD
  262.   * w/o the shareable flag) we should open
  263.   * the amp with the same flags so that
  264.   * the device cannot be taken away from
  265.   * the calling application.
  266.   ***************************************/
  267.  
  268.   if (ulParam1 & MCI_OPEN_SHAREABLE)
  269.       ulOpenFlags = MCI_OPEN_SHAREABLE;
  270.  
  271.   /* Check to see if the playlist flag was specified */
  272.  
  273.   if (ulParam1 & MCI_OPEN_PLAYLIST)
  274.      {
  275.      /*--------------------------------------------
  276.      * Streaming MCD's must perform the following
  277.      * operations with the playlist flag:
  278.      *
  279.      * A. Remember the callback handle with which the
  280.      *    playlist was opened.  All playlist cuepoints
  281.      *    and messages will be reported on this window
  282.      *    handle.
  283.      * B. Retrieve a pointer to the playlist instructions
  284.      *    in the pszElementName field.
  285.      * C. Load the appropriate memory stream handler.
  286.      *
  287.      *-----------------------------------------------------*/
  288.  
  289.       pFuncBlock->hwndCallBack  = pDrvOpenParams->hwndCallback;
  290.  
  291.       /* store an extra copy so that play list cue points can be remembered */
  292.  
  293.       pFuncBlock->pInstance->hwndOpenCallBack  = pDrvOpenParams->hwndCallback;
  294.  
  295.       /* Store the playlist pointer */
  296.  
  297.       ulpInstance->pPlayList = (PVOID) pDrvOpenParams->pszElementName;
  298.       ulpInstance->usPlayLstStrm = TRUE;
  299.       ulpInstance->fFileExists = TRUE;
  300.  
  301.      if (ulrc = SpiGetHandler((PSZ)MEM_PLAYLIST_SH,
  302.                               &hidA2Source,
  303.                               &hidA2Target ) )
  304.        {
  305.        return ( ulrc );
  306.        }
  307.  
  308.       /* The handler ids for the playlist were obtained in the dllinit */
  309.  
  310.       ulpInstance->StreamInfo.hidASource = hidA2Source;
  311.       ulpInstance->StreamInfo.hidATarget = hidA2Target;
  312.  
  313.  
  314.       /*****************************
  315.       * Default to playback
  316.       ******************************/
  317.  
  318. //      AMPMIX.ulOperation = OPERATION_PLAY;
  319.  
  320.       /* 6421--instance variable rather than amp instance */
  321.  
  322.       ulpInstance->ulOperation = MCIDRV_OUTPUT;
  323.  
  324.       /* Since playlists don't have a default header, obtain from ini file */
  325.  
  326.       ObtainDefaults( ulpInstance );
  327.  
  328.      } /* Play list flag was specified */
  329.  
  330.  
  331.  
  332.   /*****************************************
  333.   * if the caller did not pass in a playlist
  334.   * then maybe they passed in OPEN_ELEMENT
  335.   * or OPEN_MMIO.
  336.   *****************************************/
  337.   else
  338.      {
  339.  
  340.      /***************************************
  341.      * If the caller has passed in the open_element
  342.      * flag, then check to ensure that we have
  343.      * valid string.
  344.      ***************************************/
  345.  
  346.      if (ulParam1 & MCI_OPEN_ELEMENT)
  347.         {
  348.  
  349.         /*-------------------------------------------------------
  350.         * Readonly means we cannot write to the file, therefore,
  351.         * there is no need to create temporary files etc. since we
  352.         * cannot change the original file.
  353.         *--------------------------------------------------------*/
  354.  
  355.         if ( ulParam1 & MCI_READONLY )
  356.  
  357.            {
  358.            ulpInstance->ulOpenTemp = MCI_FALSE;
  359.            ulpInstance->ulCapabilities &= ~( CAN_SAVE | CAN_RECORD );
  360.            ulpInstance->ulFlags = READ_ONLY_FILE;
  361.            }
  362.         else
  363.            {
  364.            ulpInstance->ulOpenTemp = MCI_TRUE;
  365.            } /* else read only flag was NOT specified */
  366.  
  367.  
  368.         /* Ensure that the filename is valid */
  369.  
  370.         ulrc = CheckForValidElement( ulpInstance,
  371.                                      pDrvOpenParams->pszElementName,
  372.                                      ulParam1 );
  373.  
  374.         if ( ulrc )
  375.            {
  376.            return ( ulrc );
  377.            }
  378.  
  379.  
  380.         /* Open the file, and setup necessary flags */
  381.  
  382.         ulrc = ProcessElement( ulpInstance, ulParam1, MCI_OPEN );
  383.  
  384.         if ( ulrc )
  385.            {
  386.            return ( ulrc );
  387.            }
  388.  
  389.         } /* Open Element */
  390.  
  391.  
  392.  
  393.      if ( ulParam1 & MCI_READONLY )
  394.  
  395.         {
  396.         ulpInstance->ulCapabilities &= ~( CAN_SAVE | CAN_RECORD );
  397.         ulpInstance->ulFlags = READ_ONLY_FILE;
  398.         }
  399.  
  400.      } /* else not a play list open */
  401.  
  402.  
  403.  
  404.  
  405.   /*******************************************
  406.   * Check to see if the caller passed in
  407.   * open_mmio.  If so, then set up necessary
  408.   * flags etc.  From the caller's perspective
  409.   * it is advantageous to use OPEN_MMIO since
  410.   * it reduces the time it takes to perform
  411.   * an MCI_OPEN (i.e. all the MMIO work is
  412.   * done before the MCI work).
  413.   *******************************************/
  414.  
  415.   ulrc = OpenHandle( ulpInstance,
  416.                      ulParam1,
  417.                      (HMMIO) pDrvOpenParams->pszElementName);
  418.  
  419.   if ( ulrc )
  420.      {
  421.      return ( ulrc );
  422.      }
  423.  
  424.   /******************************************* 
  425.   * Performance optimization.
  426.   * If we haven't loaded a file (or playlist)
  427.   * then parse the ini file to  determine
  428.   * the default settings.
  429.   *******************************************/
  430.  
  431.   if ( !ulpInstance->fFileExists )
  432.      {
  433.      ObtainDefaults( ulpInstance );
  434.      }
  435.  
  436.   /*---------------------------------------------
  437.   * If the IO proc we are using
  438.   * has the ability to record with temp files,
  439.   * and this is not a MCI_READONLY open, then
  440.   * setup the temporary files.
  441.   *---------------------------------------------*/
  442.  
  443.   if ( ulpInstance->ulOpenTemp )
  444.      {
  445.      ulrc = SetupTempFiles( ulpInstance, ulParam1 );
  446.  
  447.      if ( ulrc )
  448.         {
  449.         CloseFile( ulpInstance );
  450.         return ( ulrc );
  451.         }
  452.  
  453.     } /* if ulOpenTemp */
  454.  
  455.  
  456.   /***********************
  457.   * Copy info from amp/mixer to streaming structures
  458.   ***********************/
  459.  
  460.   // 6421--use generic SPCB key rather than stuff from the VSD.
  461. // CONNECTOR FEATURE
  462.  
  463. //  STREAM.SpcbKey.ulDataType = WAVEHDR.usFormatTag;
  464. //  STREAM.SpcbKey.ulDataType += (WAVEHDR.usChannels << 16);
  465. //  STREAM.SpcbKey.ulDataType += (WAVEHDR.usBitsPerSample << 19);
  466. //  STREAM.SpcbKey.ulDataSubType = WAVEHDR.ulSamplesPerSec;
  467. //
  468. //  STREAM.SpcbKey.ulIntKey = 0;
  469. //
  470. //
  471. #ifndef CONNECTION
  472.   /*-------------------------------------------
  473.   * Connect ourselves to an amp/mixer.  This
  474.   * routine figures out which amp/mixer we are
  475.   * connected to, opens it and connects us to
  476.   * it.  Once we are connected to the amp, we
  477.   * will lose use and gain use of the device
  478.   * at the same time it does.
  479.   *--------------------------------------------*/
  480.  
  481.   ulrc = ConnectToAmp( ulpInstance, pDrvOpenParams, ulOpenFlags );
  482.  
  483.   if ( ulrc )
  484.      {
  485.      CloseFile( ulpInstance );
  486.      return ( ulrc );
  487.      }
  488.  
  489.   /* Store the fact that we have connected to another MCI driver */
  490.  
  491.   ulpInstance->fConnected = TRUE;
  492. #endif
  493. // CONNECTOR FEATURE
  494.  
  495. // CONNECTOR FEATURE
  496.  
  497. // CODEC change
  498. //  /****************************************************
  499. //  * Inform the io proc whether or not the data should
  500. //  * be translated real-time or not.
  501. //  *****************************************************/
  502. //
  503. #ifndef CONNECTION
  504.   if ( ulpInstance->fFileExists )
  505.      {
  506.      ulpInstance->ulCodecDescription = MAKE_SOURCE | SOURCE_CODEC;
  507.      ulrc = DataTranslation( ulpInstance );
  508.      if ( ulrc )
  509.         {
  510.  
  511.         CloseFile( ulpInstance );
  512.  
  513.         /*-----------------------------------------
  514.         * Ensure that the amp-mixer is CLOSED!!!!!!
  515.         * Else an error will lock the device.
  516.         *------------------------------------------*/
  517.  
  518.         mciSendCommand ((WORD)ulpInstance->usAmpDeviceID,
  519.                         MCI_CLOSE,
  520.                         MCI_WAIT,
  521.                         0,
  522.                         0);
  523.  
  524.  
  525.         /* If this call fails, their is no CODEC, so return error */
  526.  
  527.         return ( MCIERR_UNSUPP_FORMAT_TAG );
  528.  
  529.         }
  530.  
  531.      } /* if a file exists */
  532. #endif
  533.  
  534.  
  535.  
  536.   /*------------------------------------------------
  537.   * Connect ourselves to the amp/mixer.  This
  538.   * will enable us to stream and also allows us
  539.   * to receive the MCIDRV_SAVE and MCIDRV_RESTORE
  540.   * when the amp loses and gains use of the
  541.   * device (see audiomcd.c for more information).
  542.   *------------------------------------------------*/
  543.  
  544.   ulrc = mciConnection ( ulpInstance->usWaveDeviceID,
  545.                          1,
  546.                          ulpInstance->usAmpDeviceID,
  547.                          1,
  548.                          MCI_MAKECONNECTION);
  549.   if (ulrc)
  550.      {
  551.      CloseFile( ulpInstance );
  552.  
  553.      /*-----------------------------------------
  554.      * Ensure that the amp-mixer is CLOSED!!!!!!
  555.      * Else an error will lock the device. 
  556.      *------------------------------------------*/
  557.  
  558.      mciSendCommand ((WORD)ulpInstance->usAmpDeviceID,
  559.                      MCI_CLOSE,                       
  560.                      MCI_WAIT,                        
  561.                      0,                               
  562.                      0);                              
  563.      return ulrc;
  564.      }
  565. // CONNECTION FEATURE
  566.  
  567.   /***************************
  568.   * Flags & Other Stuff
  569.   ***************************/
  570.  
  571.   ulpInstance->ulTimeUnits = lMMTIME;
  572.   ulpInstance->StreamInfo.ulState = MCI_STOP;
  573.   ulpInstance->ulCreateFlag = CREATE_STATE;
  574.  
  575.   /*---------------------------------------------
  576.   * Initialize our custom event structure.
  577.   * SSM allows us to pass a pointer to an
  578.   * event control block when we create a
  579.   * stream.  ADMC has added some additional
  580.   * information to the end of this structure
  581.   * (such as window handles and instance pointers)
  582.   * so that the event routine can have access to
  583.   * our instance data.  See admcplay.c, admcrecd.c
  584.   * and audiosub.c for additional info.
  585.   *------------------------------------------------*/
  586.  
  587.   ulpInstance->StreamInfo.Evcb.evcb.ulSubType = EVENT_EOS|EVENT_ERROR;
  588. //  ulpInstance->ulFlags |= FIRST_RESTORE;
  589.  
  590.   return (MCIERR_SUCCESS);
  591.  
  592. }      /* end of Open */
  593.  
  594.  
  595.  
  596.