home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / warptlk3.zip / TOOLKIT / SAMPLES / MM / ADMCT / LOADSUBS.C < prev    next >
C/C++ Source or Header  |  1995-08-24  |  45KB  |  1,626 lines

  1. /********************* STARTOF SPECIFICATIONS *********************
  2. *
  3. * SUBROUTINE NAME: LOADSUBS.C
  4. *
  5. * DESCRIPTIVE NAME: Audio MCD Load subroutine file.
  6. *
  7. *              Copyright (c) IBM Corporation  1991, 1993
  8. *                        All Rights Reserved
  9. *
  10. * FUNCTION: Contain subroutines for MCI_LOAD/MCI_OPEN.
  11. *
  12. * NOTES: Concepts illustrated in this source module.
  13. *
  14. *         A. Creating temporary filenames (CheckForValidElement)
  15. *         B. Aborting in process commands (LoadAbortNotify)
  16. *         C. Processing the OPEN_MMIO flag (OpenHandle)
  17. *         D. Rational as to when to open the card in record or
  18. *            playback mode (OpenHandle) (ProcessElement).
  19. *         E. Processing temp files (ProcessElement).
  20. *         F. Opening a file with MMIO (ProcessElement).
  21. *         G. Processing the MCI_READ_ONLY flag (ProcessElement).
  22. *         H. Creating a temporary file ( SetupTempFiles).
  23. *         I. Using mmioSendMessage API to talk to an IO Proc (SetupTempFiles).
  24. *         J. Loading a Vendor Specific Device (OpenInit).
  25. *         H. Retrieving a connection and opening the connected device.
  26. *         I. Stream Handler Setup (StreamSetup)
  27. *         J. Processing MCI_NOTIFY or MCI_WAIT and callback window handles
  28. *            (NotifyWaitSetup).
  29. *         K. Get streaming information from the amp-mixer (GetMixerInfo)
  30. *
  31. * ENTRY POINTS:
  32. *
  33. * INPUT: MCI_PLAY message.
  34. *
  35. * EXIT-NORMAL: Return Code 0.
  36. *
  37. * EXIT_ERROR:  Error Code.
  38. *
  39. * EFFECTS:
  40. *
  41. * FUNCTIONS DEFINED :  CopyParms
  42. *                      CheckForValidElement
  43. *                      LoadAbortNotifies
  44. *                      OpenHandle
  45. *                      ProcessElement
  46. *                      SetupTempFiles
  47. *                      OpenInit
  48. *                      DetermineConnections
  49. *                      ConnectToAmp
  50. *                      StreamSetup
  51. *                      NotifyWaitSetup
  52. *                      CreateSemaphores
  53. *                      AllocateInstance
  54. *
  55. *
  56. * INTERNAL REFERENCES:    CreateNAssocStream ().
  57. *
  58. * EXTERNAL REFERENCES:    SpiStopStream  ().
  59. *                         SpiAssociate   ().
  60. *                         SpiDisableEvent().
  61. *                         SpiSeekStream  ().
  62. *                         mmioSendMessage().
  63. *                         mmioClose ().
  64. *
  65. *********************** END OF SPECIFICATIONS **********************/
  66. #define INCL_BASE
  67. #define INCL_DOSMODULEMGR
  68. #define INCL_DOSSEMAPHORES
  69.  
  70. #include <os2.h>
  71. #include <string.h>
  72. #include <os2medef.h>                   // MME includes files.
  73. #include <ssm.h>                        // SSM spi includes.
  74. #include <meerror.h>                    // MM Error Messages.
  75. #include <mmioos2.h>                    // MMIO Include.
  76. #include <mcios2.h>                     // MM System Include.
  77. #include <mmdrvos2.h>                   // Mci Driver Include.
  78. #include <mcipriv.h>                    // MCI Connection stuff
  79. #include <mcd.h>                        // VSDIDriverInterface.
  80. #include <hhpheap.h>                    // Heap Manager Definitions
  81. #include <qos.h>
  82. #include <audiomcd.h>                   // Component Definitions.
  83. #include "admcfunc.h"                   // Function Prototypes
  84. #include <sw.h>
  85. #include <checkmem.h>
  86. #include <vsdcmds.h>
  87.  
  88.  
  89. /********************* START OF SPECIFICATIONS *******************************
  90. *
  91. * SUBROUTINE NAME: CheckForValidElement
  92. *
  93. * DESCRIPTIVE NAME: Ensures that file names are valid
  94. *
  95. * FUNCTION: If the users passed in a file name for open/load this routine
  96. *           will ensure that it is valid.  In addition, it will create a name
  97. *           if the user passed in open element w/no file name
  98. *
  99. *
  100. * NOTES:
  101. * ENTRY POINTS:
  102. *
  103. * INPUT:
  104. *
  105. * EXIT-NORMAL: Return Code 0.
  106. *
  107. * EXIT_ERROR:  Error Code.
  108. *
  109. * EFFECTS:
  110. *
  111. * INTERNAL REFERENCES: HhpAllocMem().
  112. *
  113. * EXTERNAL REFERENCES:
  114. *
  115. *********************** END OF SPECIFICATIONS *******************************/
  116.  
  117.  
  118.  
  119. ULONG CheckForValidElement( INSTANCE   *ulpInstance,
  120.                             PSZ        pszFileName,
  121.                             ULONG      ulParam1 )
  122.  
  123. {
  124.  
  125.   ULONG  ulrc;           // return code
  126.   ULONG  ulPathLength;   // Contains the max length
  127.   LONG   lReturnCode;
  128.  
  129.   /* Did the caller pass a filename on MCI_OPEN/MCI_LOAD */
  130.  
  131.   if ( pszFileName )
  132.      {
  133.  
  134.      /* Ensure that this filename is valid */
  135.  
  136.      if (ulrc = CheckMem ( (PVOID) pszFileName, 1, PAG_WRITE))
  137.         {
  138.         return (MCIERR_MISSING_PARAMETER);
  139.         }
  140.  
  141.      /*************************************************
  142.      * Store the filename for future reference -- i.e.
  143.      * MCI_INFO can request the name of the file
  144.      *************************************************/
  145.  
  146.      strcpy ( ulpInstance->pszAudioFile, pszFileName);
  147.  
  148.      /************************************************************
  149.      * Set flag to say that we did not create a new file--thus
  150.      * we do not have to clean up if the user doesn't save
  151.      ************************************************************/
  152.  
  153.      ulpInstance->ulCreatedName = FALSE;
  154.  
  155.      }
  156.    else
  157.      {
  158.      /**************************************
  159.      * if the user requests a read only file
  160.      * and we must create it, return error
  161.      **************************************/
  162.  
  163.      if ( ulParam1 & MCI_READONLY )
  164.         {
  165.         return ( MCIERR_MISSING_PARAMETER );
  166.         }
  167.  
  168.      /**********************************************
  169.      * Query the default path to place temp files and
  170.      * generate a temporary file name
  171.      **********************************************/
  172.  
  173.      ulrc = mciQuerySysValue( MSV_WORKPATH, &ulpInstance->pszAudioFile );
  174.  
  175.      if ( !ulrc )
  176.         {
  177.         return ( MCIERR_INI_FILE );
  178.         }
  179.  
  180.      ulrc = MCIERR_SUCCESS;
  181.  
  182.      ulPathLength = CCHMAXPATH;
  183.  
  184.      /* Have mmio generate a unique filename */
  185.  
  186.      lReturnCode = DBCSGenerateUniqueFile( ulpInstance->pszAudioFile,
  187.                                            &ulPathLength,
  188.                                            &ulpInstance->hTempFile );
  189.  
  190.      if ( lReturnCode != MMIO_SUCCESS )
  191.         {
  192.         return ( MCIERR_FILE_NOT_FOUND );
  193.         }
  194.  
  195.      /***************************************************
  196.      * Because we did create a temporary file we will
  197.      * be responsible for cleaning up in case the
  198.      * caller never calls MCI_SAVE (e.g. a bunch of
  199.      * temp files will be left in the workpath
  200.      * otherwise, so set a flag to indicate this fact.
  201.      **************************************************/
  202.  
  203.      ulpInstance->ulCreatedName = TRUE;
  204.  
  205.      ObtainDefaults( ulpInstance );
  206.  
  207.      } /* else the user did not pass in a name */
  208.  
  209.   return ( ulrc );
  210.  
  211.  
  212. } /* check for valid element */
  213.  
  214.  
  215.  
  216. /********************* START OF SPECIFICATIONS *******************************
  217. *
  218. * SUBROUTINE NAME: LoadAbortNotifies
  219. *
  220. * DESCRIPTIVE NAME: Ensures that notifies are aborted
  221. *
  222. * FUNCTION: Load will stop existing operations (i.e. like play/record ) and
  223. *           ensure that they can complete before loading the new file.
  224. *
  225. *
  226. * NOTES:
  227. * ENTRY POINTS:
  228. *
  229. * INPUT:
  230. *
  231. * EXIT-NORMAL: Return Code 0.
  232. *
  233. * EXIT_ERROR:  Error Code.
  234. *
  235. * EFFECTS:
  236. *
  237. * INTERNAL REFERENCES: HhpAllocMem().
  238. *
  239. * EXTERNAL REFERENCES:
  240. *
  241. *********************** END OF SPECIFICATIONS *******************************/
  242.  
  243. ULONG LoadAbortNotifies( INSTANCE             *ulpInstance,
  244.                          FUNCTION_PARM_BLOCK  *pFuncBlock,
  245.                          ULONG                ulAbortNotify )
  246.  
  247. {
  248.  
  249. //  ULONG ulrc;
  250.  
  251.  
  252.   if ( ulAbortNotify == TRUE)
  253.      {
  254.  
  255.      /*****************************************************
  256.      * Save cannot be interrupted or data will be lost, so
  257.      * if there is a save pending, wait for it to complete
  258.      ******************************************************/
  259.  
  260.      if ( ulpInstance->usNotPendingMsg == MCI_SAVE )
  261.         {
  262.         /* Wait for save to complete */
  263.  
  264.         DosWaitEventSem( ulpInstance->hThreadSem, (ULONG ) -1 );
  265.  
  266.         }
  267.       else
  268.         {
  269.         /*****************************************
  270.         * State that we are aborting the operation
  271.         * in process (i.e. play/record).
  272.         *****************************************/
  273.  
  274.         PostMDMMessage ( MCI_NOTIFY_ABORTED,
  275.                          ulpInstance->usNotPendingMsg,
  276.                          pFuncBlock);
  277.  
  278.         /******************************************
  279.         * The previous command was most a streaming
  280.         * command, so stop it from operating
  281.         *******************************************/
  282.  
  283.         ThreadedStop( ulpInstance );
  284.  
  285.         STRMSTATE = MCI_STOP;
  286.  
  287.         } /* if pending message not save */
  288.  
  289.  
  290.      } /* notify pending is true */
  291.  
  292.   else
  293.  
  294.      {
  295.      /***********************************************
  296.      * MCI_STOP may have done a stop_pause to prevent
  297.      * the loss of data--see MCIStop for a more detailed
  298.      * explanation of why--ensure that the stream is
  299.      * stopped before continuing.  If you don't the
  300.      * dreaded stream not stopped will result.
  301.      *************************************************/
  302.  
  303.      if ( STRMSTATE == STOP_PAUSED )
  304.         {
  305.         StopStream2( ulpInstance, MCIDRV_OUTPUT );
  306.  
  307.         }
  308.  
  309.      }
  310.  
  311.   return ( MCIERR_SUCCESS );
  312.  
  313. } /* LoadAbortNotifies */
  314.  
  315.  
  316. /********************* START OF SPECIFICATIONS *******************************
  317. *
  318. * SUBROUTINE NAME: OpenHandle
  319. *
  320. * DESCRIPTIVE NAME: Sets up for mmio handle passed in on the open
  321. *
  322. * FUNCTION: If a mmio handle is passed in on the open, this routine will
  323. *           do the appropriate setup for it.
  324. *
  325. *
  326. * NOTES:
  327. * ENTRY POINTS:
  328. *
  329. * INPUT:
  330. *
  331. * EXIT-NORMAL: Return Code 0.
  332. *
  333. * EXIT_ERROR:  Error Code.
  334. *
  335. * EFFECTS:
  336. *
  337. * INTERNAL REFERENCES: HhpAllocMem().
  338. *
  339. * EXTERNAL REFERENCES:
  340. *
  341. *********************** END OF SPECIFICATIONS *******************************/
  342.  
  343.  
  344. ULONG OpenHandle( INSTANCE  *ulpInstance,
  345.                   ULONG     ulParam1,
  346.                   HMMIO     hmmio )
  347.  
  348. {
  349.  
  350.   ULONG ulrc = MCIERR_SUCCESS;
  351.  
  352.   if (ulParam1 & MCI_OPEN_MMIO)
  353.      {
  354.       if ( !hmmio )
  355.          {
  356.          return ( MMIOERR_INVALID_HANDLE );
  357.          }
  358.  
  359.       /* Copy the mmio handle to our instance for future use */
  360.  
  361.       ulpInstance->hmmio = hmmio;
  362.  
  363.       /*****************************************************
  364.       * Set a flag which indicates that the caller provided
  365.       * a file handle--therefore NEVER close this handle
  366.       *****************************************************/
  367.  
  368.       ulpInstance->fOpenMMIO = TRUE;
  369.  
  370.       ulrc = GetAudioHeader (ulpInstance, MMIO_RAWHEADER);
  371.  
  372.       if ( ulrc == MMIOERR_UNSUPPORTED_MESSAGE )
  373.          {
  374.          ulrc = GetAudioHeader (ulpInstance, 0);
  375.          }
  376.  
  377.  
  378.       /***************************************************
  379.       * If the file is non-existent (no data), open the
  380.       * card in record mode so the user can hear if
  381.       * anything is plugged in line-in or the
  382.       * microphone jack (we will assume they want to
  383.       * record since there is no data to play back).
  384.       * By contrast, if there is data, then we will
  385.       * assume that the user wants to be in playback mode
  386.       ****************************************************/
  387.       if ( ulpInstance->ulDataSize != 0 )
  388.          {
  389. //         AMPMIX.ulOperation = OPERATION_PLAY;
  390.  
  391.          /* 6421--instance variable rather than amp instance */
  392.          ulpInstance->ulOperation = MCIDRV_OUTPUT;
  393.          }
  394.       else
  395.          {
  396. //         AMPMIX.ulOperation = OPERATION_RECORD;
  397.  
  398.          /* 6421--instance variable rather than amp instance */
  399.          ulpInstance->ulOperation = MCIDRV_INPUT;
  400.          }
  401.  
  402.       /* Set flag to state that an element has been loaded */
  403.  
  404.       ulpInstance->fFileExists = TRUE;
  405.  
  406.       /* Flag to indicate that card has been inited */
  407.  
  408.      ulpInstance->ulCapabilities =  ( CAN_INSERT | CAN_DELETE | CAN_UNDOREDO +
  409.                                  CAN_SAVE   | CAN_INSERT | CAN_RECORD  );
  410.  
  411.  
  412.      /*-------------------------------------------------------
  413.      * Readonly means we cannot write to the file, therefore,
  414.      * there is no need to create temporary files etc. since we
  415.      * cannot change the original file.
  416.      *--------------------------------------------------------*/
  417.  
  418.      if ( ulParam1 & MCI_READONLY )
  419.  
  420.         {
  421.         ulpInstance->ulOpenTemp = MCI_FALSE;
  422.         ulpInstance->ulCapabilities &= ~( CAN_SAVE | CAN_RECORD );
  423.         }
  424.      else
  425.         {
  426.         ulpInstance->ulOpenTemp = MCI_TRUE;
  427.         } /* else read only flag was NOT specified */
  428.  
  429.  
  430.  
  431.      } /* if open_mmio is passed in */
  432.  
  433.  
  434.   return ( ulrc );
  435.  
  436. } /* OpenHandle */
  437.  
  438.  
  439. /********************* START OF SPECIFICATIONS *******************************
  440. *
  441. * SUBROUTINE NAME: Process Element
  442. *
  443. * DESCRIPTIVE NAME: Opens a file element
  444. *
  445. * FUNCTION: Opens a file and prepares a device to play and record.
  446. *
  447. *
  448. * NOTES:
  449. * ENTRY POINTS:
  450. *
  451. * INPUT:
  452. *
  453. * EXIT-NORMAL: MCIERR_SUCCESS.
  454. *
  455. * EXIT_ERROR:  Error Code.
  456. *
  457. * EFFECTS:
  458. *
  459. *
  460. * EXTERNAL REFERENCES:
  461. *
  462. *********************** END OF SPECIFICATIONS *******************************/
  463.  
  464. ULONG ProcessElement( INSTANCE *ulpInstance,
  465.                       ULONG    ulParam1,
  466.                       ULONG    ulOperation )
  467. {
  468.  
  469.    ULONG   ulrc;
  470.    ULONG   ulmmioOpenFlag;
  471.  
  472.    /******************************************************
  473.    * If the caller wants to open temp, then modify the flags
  474.    * Temp files require that no one else be able to open
  475.    * the same file--so use exclusive.  If we are not
  476.    * using temp files (for instance, if the READ_ONLY flag
  477.    * is passed) then allow anyone to open the file.
  478.    ******************************************************/
  479.  
  480.    if ( ulpInstance->ulOpenTemp )
  481.       {
  482.       ulmmioOpenFlag = MMIO_READWRITE | MMIO_EXCLUSIVE;
  483.       }
  484.    else
  485.       {
  486.       ulmmioOpenFlag = MMIO_READ | MMIO_DENYNONE;
  487.       }
  488.  
  489.    /* Ask mmio to open the file */
  490.  
  491.    ulrc = OpenFile( ulpInstance, ulmmioOpenFlag );
  492.  
  493.    /* If open preceded smoothly, then the file exists!! */
  494.  
  495.    if ( !ulrc )
  496.      {
  497.      /* If we created the file, it has no data so go into record mode */
  498.  
  499.      if ( ulpInstance->ulCreatedName )
  500.         {
  501.         ulpInstance->ulOperation = MCIDRV_INPUT;
  502.         /* ensure that the header is up to date */
  503.  
  504.         ulrc = SetAudioHeader( ulpInstance );
  505.  
  506.         }
  507.  
  508.      else /* the file has data so default to playback mode */
  509.         {
  510. //        AMPMIX.ulOperation = OPERATION_PLAY;
  511.  
  512.         /* 6421--instance variable rather than amp instance */
  513.         ulpInstance->ulOperation = MCIDRV_OUTPUT;
  514.  
  515.         }
  516.      } /* if no error on OpenFile */
  517.    else
  518.      {
  519.      /******************************************
  520.      * We will get file not found error if the
  521.      * file does not exist, so try to create it.
  522.      *******************************************/
  523.  
  524.      if (ulrc == ERROR_FILE_NOT_FOUND)
  525.         {
  526.         /********************************
  527.         * If we need to create a file, then
  528.         * it is necessary to retrieve the
  529.         * default wave header from the
  530.         * ini file settings.
  531.         *********************************/
  532.         ObtainDefaults( ulpInstance );
  533.  
  534.  
  535.         /********************************
  536.         * if this is a read only file then
  537.         * we cannot create a new one
  538.         *********************************/
  539.  
  540.         if ( ulParam1 & MCI_READONLY )
  541.            {
  542.            return ( MCIERR_FILE_NOT_FOUND );
  543.            }
  544.  
  545. //        AMPMIX.ulOperation = OPERATION_RECORD;
  546.         /* 6421--instance variable rather than amp instance */
  547.         ulpInstance->ulOperation = MCIDRV_INPUT;
  548.  
  549.         ulpInstance->ulCreateFlag = CREATE_STATE;
  550.         ulmmioOpenFlag = MMIO_CREATE | MMIO_READWRITE | MMIO_EXCLUSIVE;
  551.  
  552.         /********************************
  553.         * Try to create the element
  554.         *******************************/
  555.  
  556.         ulrc = OpenFile ( ulpInstance, ulmmioOpenFlag);
  557.  
  558.         /* If we fail, try to return an MCI error */
  559.  
  560.         if (ulrc)
  561.            {
  562.            if ( ulrc == ERROR_FILE_NOT_FOUND )
  563.               {
  564.               return ( MCIERR_FILE_NOT_FOUND );
  565.               }
  566.            else
  567.               {
  568.               return (ulrc);
  569.               }
  570.            } /* if an error occurred */
  571.  
  572.         /* Ensure that the header is up to date */
  573.  
  574.         SetWaveDeviceDefaults (ulpInstance);
  575.         ulpInstance->ulOperation = MCIDRV_INPUT;
  576.         ulpInstance->mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes = 0;
  577.         ulrc = SetAudioHeader( ulpInstance );
  578.  
  579.         }
  580.      else
  581.         {
  582.         /* if open or load fail--we have no element */
  583.  
  584.         ulpInstance->fFileExists = FALSE;
  585.  
  586.         return ( ulrc );
  587.         }
  588.  
  589.      } /* else there was an error on the load open */
  590.  
  591.   /* Ensure header has correct media type */
  592.  
  593.   ulpInstance->mmAudioHeader.ulMediaType = MMIO_MEDIATYPE_AUDIO;
  594.  
  595.    return ( ulrc );
  596.  
  597. } /* ProcessElement */
  598.  
  599.  
  600.  
  601. /********************* START OF SPECIFICATIONS *******************************
  602. *
  603. * SUBROUTINE NAME: SetupTempFiles
  604. *
  605. * DESCRIPTIVE NAME: Prepares for temporary file work
  606. *
  607. * FUNCTION: If the io proc supports temp files and the user has not requested
  608. *           a readonly file, we will try to open a temp file
  609. *
  610. *
  611. * NOTES:
  612. * ENTRY POINTS:
  613. *
  614. * INPUT:
  615. *
  616. * EXIT-NORMAL: Return Code 0.
  617. *
  618. * EXIT_ERROR:  Error Code.
  619. *
  620. * EFFECTS:
  621. *
  622. * INTERNAL REFERENCES: HhpAllocMem().
  623. *
  624. * EXTERNAL REFERENCES:
  625. *
  626. *********************** END OF SPECIFICATIONS *******************************/
  627.  
  628.  
  629. ULONG SetupTempFiles( INSTANCE   *ulpInstance,
  630.                       ULONG      ulParam1 )
  631.  
  632.  
  633. {
  634.  
  635.   ULONG ulrc;
  636.  
  637.   CHAR  TempPath[ CCHMAXPATH ]; // holds path for temp files
  638.  
  639.  
  640.   /**********************************************
  641.   * Query the default path to place temp files and
  642.   * pass it on to the IO Proc
  643.   **********************************************/
  644.  
  645.   ulrc = mciQuerySysValue( MSV_WORKPATH, TempPath );
  646.  
  647.   if ( !ulrc )
  648.      {
  649.      return (MCIERR_INI_FILE);
  650.      }
  651.  
  652.   /*****************************************************
  653.   * This message illustrates the use of mmioSendMessage:
  654.   * we are asking the IO Proc that we have loaded to
  655.   * make all subsequent changes temporary (i.e. if no
  656.   * save message is sent, then the file will remain in
  657.   * the original condition.
  658.   *****************************************************/
  659.  
  660.   ulrc = mmioSendMessage( ulpInstance->hmmio,
  661.                           MMIOM_TEMPCHANGE,
  662.                           ( LONG ) TempPath,
  663.                           0 );
  664.   if (ulrc)
  665.      {
  666.      /* Use mmioGetLastError to get additional detail about the error */
  667.  
  668.      ulrc = mmioGetLastError( ulpInstance->hmmio );
  669.  
  670.      /* Cannot write means that the disk is full */
  671.  
  672.      if (ulrc == MMIOERR_CANNOTWRITE )
  673.         {
  674.         return MCIERR_TARGET_DEVICE_FULL;
  675.         }
  676.      else
  677.         {
  678.         return ( ulrc );
  679.         }
  680.  
  681.      } /* if there is an error */
  682.  
  683.   /* Flag to indicate that temporary changes are active */
  684.  
  685.   ulpInstance->ulUsingTemp = MCI_TRUE;
  686.  
  687.   return ( ulrc );
  688.  
  689.  
  690. } /* SetupTempFiles */
  691.  
  692.  
  693.  
  694. /********************* START OF SPECIFICATIONS *******************************
  695. *
  696. * SUBROUTINE NAME: OpenInit
  697. *
  698. * DESCRIPTIVE NAME: Sets up variables for open
  699. *
  700. * FUNCTION: Initializes variables to be used by the instance
  701. *
  702. *
  703. * NOTES:
  704. * ENTRY POINTS:
  705. *
  706. * INPUT:
  707. *
  708. * EXIT-NORMAL: Return Code 0.
  709. *
  710. * EXIT_ERROR:  Error Code.
  711. *
  712. * EFFECTS:
  713. *
  714. * INTERNAL REFERENCES: HhpAllocMem().
  715. *
  716. * EXTERNAL REFERENCES:
  717. *
  718. *********************** END OF SPECIFICATIONS *******************************/
  719.  
  720.  
  721. void OpenInit( INSTANCE  *ulpInstance )
  722.  
  723.  
  724. {
  725.  
  726.   extern     HID                 hidASource;
  727.   extern     HID                 hidATarget;
  728.   extern     HID                 hidBSource;
  729.   extern     HID                 hidBTarget;
  730.  
  731.   ULONG      ulrc;
  732.  
  733.  
  734.   ulpInstance->ulCapabilities = CAN_RECORD | CAN_SAVE | CAN_INSERT;
  735.  
  736.   /* Stream hid's */
  737.  
  738.   ulpInstance->StreamInfo.hidASource = hidASource;
  739.   ulpInstance->StreamInfo.hidATarget = hidATarget;
  740.   ulpInstance->StreamInfo.hidBSource = hidBSource;
  741.   ulpInstance->StreamInfo.hidBTarget = hidBTarget;
  742.  
  743.   /************************************
  744.   * Wave Record Defaults.
  745.   ***********************************/
  746.  
  747. //  SetWaveDeviceDefaults (ulpInstance, MCIDRV_INPUT );
  748.   ulpInstance->mmAudioHeader.ulMediaType = MMIO_MEDIATYPE_AUDIO;
  749.  
  750.   /*--------------------------------------------
  751.   * In case no device is opened, default to
  752.   * the mode requested in the ini file.
  753.   *--------------------------------------------*/
  754.  
  755. //  AMPMIX.ulOperation = ulpInstance->lDefaultOperation;// Play or Record
  756.  
  757.   /* 6421--instance variable rather than amp instance */
  758.   ulpInstance->ulOperation = ulpInstance->lDefaultOperation;
  759.  
  760.  
  761.   STRMSTATE = NO_STATE;
  762.  
  763.   /*---------------------------------------------
  764.   * The MMPM2.INI file contains two variables that
  765.   * a streaming MCD should retrieve.  The first one
  766.   * QOS_VALUE (Quality of Service) contains settings
  767.   * which describe the quality of service that the
  768.   * network the user is streaming from will try to
  769.   * support (e.g. GUARANTEED or DONTCARE).  If this
  770.   * quality of service is not available, then another
  771.   * variable (QOSERRORFLAG) describes whether or not
  772.   * to notify the caller.
  773.   *--------------------------------------------------*/
  774.  
  775. // CONNECTOR FEATURE--can this be moved to DLL init???
  776.  
  777.   ulrc = mciQuerySysValue( MSV_SYSQOSVALUE, &ulpInstance->lQosValue );
  778.  
  779.   if ( !ulrc )
  780.      {
  781.      ulpInstance->lQosValue = DONTRESERVE;
  782.      }
  783.  
  784.   ulrc = mciQuerySysValue( MSV_SYSQOSERRORFLAG, &ulpInstance->lQOSReporting );
  785.  
  786.   if ( !ulrc )
  787.      {
  788.      ulpInstance->lQOSReporting = ERROR_DEFAULT;
  789.      }
  790.  
  791.  
  792. } /* OpenInit */
  793.  
  794.  
  795.  
  796. /********************* START OF SPECIFICATIONS *******************************
  797. *
  798. * SUBROUTINE NAME: DetermineConnections
  799. *
  800. * DESCRIPTIVE NAME: Loads appropriate vendor specific device
  801. *
  802. * FUNCTION: In an ideal world, this function would determine who we are
  803. *           connected to from MDM, load it and let it set up the stream
  804. *           handlers( i.e. probably in the next release).  Currently,
  805. *           it just loads the VSD (i.e. MAJOR hardcode )
  806. *
  807. *
  808. *
  809. * NOTES:
  810. * ENTRY POINTS:
  811. *
  812. * INPUT:
  813. *
  814. * EXIT-NORMAL: Return Code 0.
  815. *
  816. * EXIT_ERROR:  Error Code.
  817. *
  818. * EFFECTS:
  819. *
  820. * INTERNAL REFERENCES: HhpAllocMem().
  821. *
  822. * EXTERNAL REFERENCES:
  823. *
  824. *********************** END OF SPECIFICATIONS *******************************/
  825.  
  826.  
  827. //ULONG DetermineConnections( INSTANCE           *ulpInstance,
  828. //                            MMDRV_OPEN_PARMS   *pDrvOpenParams )
  829. //
  830. //
  831. //  {
  832. //
  833. //// 6421--note: this is no longer necessary--all handled by the mixer.
  834. //
  835. //  // should this be max path????
  836. //
  837. //  CHAR szLoadError[MAX_ERROR_LENGTH];  // DosLoadModule
  838. //
  839. //  ULONG ulrc;
  840. //
  841. //  /*****************************************************
  842. //  * Note, this section will have to change when improved
  843. //  * connector support is added!!!
  844. //  ******************************************************/
  845. //
  846. //  /*******************************
  847. //  * Load the Devspcfc DLL
  848. //  ********************************/
  849. //
  850. //  if ( (ulrc = DosLoadModule ( szLoadError,
  851. //                               sizeof( szLoadError ),
  852. //                               pDrvOpenParams->szDevDLLName,
  853. //                               &(ulpInstance->hModHandle))))
  854. //     {
  855. //     return ( ulrc );
  856. //     }
  857. //
  858. ////  strcpy ((PSZ)AMPMIX.szDriverName, pDrvOpenParams->szDevDLLName );
  859. //
  860. //  /*****************************************
  861. //  * Get the AudioIF Driver Entry point
  862. //  ******************************************/
  863. //
  864. //  ulrc = DosQueryProcAddr ( ulpInstance->hModHandle,
  865. //                            0L,
  866. //                            VSDI,
  867. //                            (PFN *) &ulpInstance->pfnVSD) ;
  868. //
  869. //
  870. //  return ( ulrc );
  871. //
  872. //} /* DetermineConnections */
  873.  
  874.  
  875.  
  876. // CONNECTION FEATURE--this function is no longer used--
  877. // MDM handles all auto connections
  878. #ifndef CONNECTION
  879. /********************* START OF SPECIFICATIONS *******************************
  880. *
  881. * SUBROUTINE NAME: ConnectToAmp
  882. *
  883. * DESCRIPTIVE NAME: Connects wave audio to the amp mixer.
  884. *
  885. * FUNCTION: Do the work necessary to ensure that the ini file contains valid
  886. *           information about who we are connected to.  In addition,
  887. *           it will open the amp mixer and receive the associated stream
  888. *           handler from it (next release)?
  889. *
  890. *
  891. *
  892. * NOTES:
  893. * ENTRY POINTS:
  894. *
  895. * INPUT:
  896. *
  897. * EXIT-NORMAL: Return Code 0.
  898. *
  899. * EXIT_ERROR:  Error Code.
  900. *
  901. * EFFECTS:
  902. *
  903. * INTERNAL REFERENCES: HhpAllocMem().
  904. *
  905. * EXTERNAL REFERENCES:
  906. *
  907. *********************** END OF SPECIFICATIONS *******************************/
  908.  
  909.  
  910. ULONG ConnectToAmp( INSTANCE           *ulpInstance,
  911.                     MMDRV_OPEN_PARMS   *pDrvOpenParams,
  912.                     ULONG              ulOpenFlags )
  913.  
  914. {
  915.  
  916.   ULONG                ulDeviceTypeID;         // device id of connected device
  917.   ULONG                ulrc;                   // return code variable
  918. //  ULONG                ulHoldError;
  919.   USHORT               usConnLength;           // length of conn struct
  920.  
  921.   MCI_AMP_OPEN_PARMS   MCIAmpOpenParms;          // MCI AmpMixer Open Parameters
  922.   DEFAULTCONNECTIONS2  DefCon;                   // MCI Connections Block
  923. //  SPCB                 tempspcb;
  924.   MMAUDIOHEADER        mmaudioheader;
  925.   VSD_AUDIOOPEN_PARMS  vsdOpen;
  926.   CONCB                concb;
  927.  
  928.   /* Inform the amp how we wish to initialize the device */
  929.  
  930.   memmove( &mmaudioheader, &ulpInstance->mmAudioHeader, sizeof( MMAUDIOHEADER ));
  931.   vsdOpen.pHeader = ( PVOID) &mmaudioheader;
  932.   vsdOpen.ulFlags = VSD_AUDIO_OPEN;
  933.   vsdOpen.ulReserved2 = (ULONG) &concb;
  934.  
  935.  
  936.   /*****************************
  937.   * Obtain WaveAudio Device ID
  938.   *****************************/
  939.   ulpInstance->usWaveDeviceID = pDrvOpenParams->usDeviceID;
  940.  
  941.   ulDeviceTypeID = MAKEULONG ( MCI_DEVTYPE_WAVEFORM_AUDIO,
  942.                                pDrvOpenParams->usDeviceOrd);
  943.  
  944.   /******************************************************
  945.   * Ensure that the INI file contains the right device id
  946.   ******************************************************/
  947.  
  948.   if ( pDrvOpenParams->usDeviceType != MCI_DEVTYPE_WAVEFORM_AUDIO )
  949.      {
  950.      return ( MCIERR_INI_FILE );
  951.      }
  952.  
  953.   usConnLength = sizeof(DEFAULTCONNECTIONS2);
  954.  
  955.   ulrc =  mciQueryDefaultConnections ( ulDeviceTypeID,
  956.                                        &DefCon,
  957.                                        &usConnLength);
  958.  
  959.   /******************************************************
  960.   * Ensure that the INI file says that we are connected
  961.   * to an amp mixer.  If it says that we are connected
  962.   * to ourselves, return an error.
  963.   ******************************************************/
  964.  
  965.   if ( ULONG_LOWD( DefCon.dwDeviceTypeID2 ) == MCI_DEVTYPE_WAVEFORM_AUDIO )
  966.      {
  967.      return ( MCIERR_INI_FILE );
  968.      }
  969.  
  970.   /******************************
  971.   * Open an AMP/MIXER Instance
  972.   ******************************/
  973.  
  974.   MCIAmpOpenParms.pszDeviceType = (PSZ) DefCon.dwDeviceTypeID2;
  975.  
  976.   MCIAmpOpenParms.hwndCallback = (ULONG) NULL;
  977.  
  978. // 6421 --no need to retrive this information any more
  979. // we are truly device independent
  980.  
  981. //  GetPDDName (DefCon.dwDeviceTypeID2, szPDDName);
  982.  
  983. //  strcpy ( ulpInstance->szAudioDevName, szPDDName);
  984.  
  985.   /* Copy the name of the pdd + vsd dll to amp structure */
  986.  
  987. //  strcpy ((PSZ) AMPMIX.szDeviceName,
  988. //          ulpInstance->szAudioDevName);
  989.  
  990. //  strcpy ((PSZ) ulpInstance->StreamInfo.AudioDCB.szDevName,
  991. //          ulpInstance->szAudioDevName);
  992.  
  993.   /*******************************************
  994.   * The current amp/mixer uses an undocumented
  995.   * structure.  Pass this structure in on the
  996.   * open also.
  997.   ********************************************/
  998.  
  999.   MCIAmpOpenParms.pDevDataPtr = (PVOID) &vsdOpen;
  1000.  
  1001.  
  1002.   /* Open what we are connected to--usually the amp */
  1003.  
  1004.   ulrc = mciSendCommand (0,
  1005.                          MCI_OPEN,
  1006.                          MCI_OPEN_TYPE_ID| MCI_WAIT| ulOpenFlags,
  1007.                          (PVOID) &MCIAmpOpenParms,
  1008.                          0);
  1009.  
  1010. // CODEC change
  1011.    /*--------------------------------------------
  1012.    * It is possible that the VSD may require a
  1013.    * best fit.  Try with the best fit parameters.
  1014.    *-------------------------------------------*/
  1015.      if (ulrc)
  1016.  
  1017.         {
  1018. #ifndef CONNECTION
  1019.         if ( ulrc == MCIERR_UNSUPP_FORMAT_TAG )
  1020.            {
  1021.            /* Open what we are connected to--usually the amp */
  1022.  
  1023.            ulrc = mciSendCommand (0,
  1024.                                   MCI_OPEN,
  1025.                                   MCI_OPEN_TYPE_ID| MCI_WAIT| ulOpenFlags,
  1026.                                   (PVOID) &MCIAmpOpenParms,
  1027.                                   0);
  1028.            }
  1029.        if ( ulrc )
  1030. #endif
  1031.           {
  1032.           return ( ulrc );
  1033.           }
  1034.         ulpInstance->ulRealTimeTranslation = MMIO_REALTIME;
  1035.         memmove( &ulpInstance->mmAudioHeader, &mmaudioheader, sizeof( MMAUDIOHEADER ) );
  1036.         } /* If the amp-mixer could not deal with the data type */
  1037.      else
  1038.         {
  1039.         ulpInstance->ulRealTimeTranslation = MMIO_NONREALTIME;
  1040.         }
  1041. // CODEC feature--removed functionality
  1042.  
  1043.  
  1044.   /* Remember the amp device id so that we can close it */
  1045.  
  1046.   ulpInstance->usAmpDeviceID = MCIAmpOpenParms.usDeviceID;
  1047.  
  1048. #ifndef CONNECTION
  1049.   ulrc = GetMixerInfo( ulpInstance, &concb );
  1050.  
  1051.   if ( ulrc )
  1052.      {
  1053.      /*-----------------------------------------
  1054.      * Ensure that the amp-mixer is CLOSED!!!!!!
  1055.      * Else an error will lock the device.
  1056.      *------------------------------------------*/
  1057.  
  1058.      mciSendCommand ((WORD)ulpInstance->usAmpDeviceID,
  1059.                      MCI_CLOSE,
  1060.                      MCI_WAIT,
  1061.                      0,
  1062.                      0);
  1063.      }
  1064. #endif
  1065.  
  1066.   return ( ulrc );
  1067.  
  1068.  
  1069. } /* ConnectToAmp */
  1070. #endif
  1071.  
  1072.  
  1073. /********************* START OF SPECIFICATIONS *******************************
  1074. *
  1075. * SUBROUTINE NAME: StreamSetup
  1076. *
  1077. * DESCRIPTIVE NAME: Gets the stream handlers
  1078. *
  1079. * FUNCTION: Do the work necessary to load the correct stream handlers.  Currently
  1080. *           this is hardcoded, however, in the future we will obtain this info
  1081. *           from connections/ampmix etc(?)
  1082. *
  1083. *
  1084. *
  1085. * NOTES:
  1086. * ENTRY POINTS:
  1087. *
  1088. * INPUT:
  1089. *
  1090. * EXIT-NORMAL: Return Code 0.
  1091. *
  1092. * EXIT_ERROR:  Error Code.
  1093. *
  1094. * EFFECTS:
  1095. *
  1096. * INTERNAL REFERENCES: HhpAllocMem().
  1097. *
  1098. * EXTERNAL REFERENCES:
  1099. *
  1100. *********************** END OF SPECIFICATIONS *******************************/
  1101.  
  1102.  
  1103. ULONG StreamSetup ( void )
  1104.  
  1105. {
  1106. extern     HID                 hidASource;
  1107. extern     HID                 hidATarget;
  1108.  
  1109. extern     HID                 hidBSource;
  1110. extern     HID                 hidBTarget;
  1111.  
  1112.  
  1113.   ULONG ulrc = MCIERR_SUCCESS;
  1114.  
  1115.  
  1116.   /*********************************************************
  1117.   * Get 'A' stream Handler Handles for Source & target operations
  1118.   * The file system stream handler is the default 'A' handler
  1119.   * but the memory stream handler will be used for playlists.
  1120.   **********************************************************/
  1121.  
  1122.  
  1123.      if (ulrc = SpiGetHandler((PSZ)DEFAULT_SOURCE_HANDLER_NAME,
  1124.                                &hidASource,
  1125.                                &hidATarget))
  1126.         {
  1127.         return ( ulrc );
  1128.         }
  1129.  
  1130. // CONNECTION FEATURE
  1131.   /***********************************************************
  1132.   * Get 'B' stream Handler Handles for Source & target operations
  1133.   * The audio stream handler is considered the B stream handler
  1134.   * since it will usually be the target.
  1135.   *************************************************************/
  1136.  
  1137. //  ulrc = SpiGetHandler( (PSZ)DEFAULT_TARGET_HANDLER_NAME,
  1138. //                        &hidBSource,
  1139. //                        &hidBTarget);
  1140. // CONNECTION FEATURE
  1141.  
  1142.   return ( ulrc );
  1143.  
  1144. } /* StreamSetup */
  1145.  
  1146.  
  1147.  
  1148. /********************* START OF SPECIFICATIONS *******************************
  1149. *
  1150. * SUBROUTINE NAME: CreateSemaphores
  1151. *
  1152. * DESCRIPTIVE NAME: Creates semaphores for instance
  1153. *
  1154. * FUNCTION: Creates all the semaphores needed for playing, recording and
  1155. *           serializing access to necessary instance data.
  1156. *
  1157. *
  1158. *
  1159. * NOTES:
  1160. * ENTRY POINTS:
  1161. *
  1162. * INPUT:
  1163. *
  1164. * EXIT-NORMAL: Return Code 0.
  1165. *
  1166. * EXIT_ERROR:  Error Code.
  1167. *
  1168. * EFFECTS:
  1169. *
  1170. * INTERNAL REFERENCES: HhpAllocMem().
  1171. *
  1172. * EXTERNAL REFERENCES:
  1173. *
  1174. *********************** END OF SPECIFICATIONS *******************************/
  1175.  
  1176.  
  1177. ULONG CreateSemaphores( FUNCTION_PARM_BLOCK   *pFuncBlock )
  1178.  
  1179.  
  1180. {
  1181.  
  1182.    ULONG        ulrc;
  1183.    INSTANCE     *pInstance = ( INSTANCE * ) pFuncBlock->pInstance;
  1184.  
  1185.    /*********************************************
  1186.    * Create an event semaphore used in the
  1187.    * streaming operations (see admcplay, admcrecd).
  1188.    *********************************************/
  1189.  
  1190.    ulrc = DosCreateEventSem ( (ULONG) NULL,
  1191.                               (PHEV) &pInstance->hEventSem,
  1192.                               DC_SEM_SHARED,
  1193.                               FALSE );
  1194.  
  1195.    if (ulrc)
  1196.       {
  1197.       return (ulrc);
  1198.       }
  1199.  
  1200.    /************************************************
  1201.    * Create an event semaphore used to synchronize
  1202.    * various threads (See admcplay.c + admcrecd.c).
  1203.    *************************************************/
  1204.  
  1205.    ulrc = DosCreateEventSem ( (ULONG) NULL,
  1206.                               (PHEV) &pInstance->hThreadSem,
  1207.                               DC_SEM_SHARED,
  1208.                               FALSE );
  1209.    if (ulrc)
  1210.       {
  1211.       return (ulrc);
  1212.       }
  1213.  
  1214.    ulrc = DosCreateMutexSem ( (ULONG) NULL,
  1215.                               (PHEV) &pInstance->hmtxDataAccess,
  1216.                               DC_SEM_SHARED,
  1217.                               FALSE);
  1218.    if (ulrc)
  1219.       {
  1220.       return (ulrc);      /* Failed Sem Create */
  1221.       }
  1222.  
  1223.    /************************************************
  1224.    * Create semaphore which will prevent MCI_CLOSE
  1225.    * from freeing instance before all threads are
  1226.    * done processing.
  1227.    ************************************************/
  1228.  
  1229.    ulrc = DosCreateMutexSem ( (ULONG) NULL,
  1230.                               (PHEV) &pInstance->hmtxCloseAccess,
  1231.                               DC_SEM_SHARED,
  1232.                               FALSE);
  1233.    if (ulrc)
  1234.       {
  1235.       return (ulrc);      /* Failed Sem Create */
  1236.       }
  1237.  
  1238.  
  1239.  
  1240.    /* Create semaphore to ensure that only one thread can abort another */
  1241.  
  1242.    ulrc = DosCreateMutexSem ( NULL,
  1243.                               &pInstance->hmtxNotifyAccess,
  1244.                               DC_SEM_SHARED,
  1245.                               FALSE);
  1246.    if (ulrc)
  1247.       {
  1248.       return (ulrc);      /* Failed Sem Create */
  1249.       }
  1250.  
  1251.    /* Create semaphore to ensure that MCIDRV_SAVE is never locked out*/
  1252.  
  1253.    ulrc = DosCreateMutexSem ( NULL,
  1254.                               &pInstance->hmtxSaveAccess,
  1255.                               DC_SEM_SHARED,
  1256.                               FALSE);
  1257.  
  1258.  
  1259.    /***********************************************
  1260.    * No need to check the return code, since we have
  1261.    * to do a return to leave anyway
  1262.    ************************************************/
  1263.  
  1264.    return ( ulrc );
  1265.  
  1266.  
  1267. } /* Create Semaphores */
  1268.  
  1269.  
  1270. /********************* START OF SPECIFICATIONS *******************************
  1271. *
  1272. * SUBROUTINE NAME: NotifyWaitSetup
  1273. *
  1274. * DESCRIPTIVE NAME: Prepares instance for either notify/wait/asynchronous operation
  1275. *
  1276. * FUNCTION: Stores callbacks and sets up the instance for either notify, wait
  1277. *           or asynchronous operation.
  1278. *
  1279. *
  1280. *
  1281. * NOTES:
  1282. * ENTRY POINTS:
  1283. *
  1284. * INPUT:
  1285. *
  1286. * EXIT-NORMAL: MCIERR_SUCCESS.
  1287. *
  1288. * EXIT_ERROR:  Error Code.
  1289. *
  1290. * EFFECTS:
  1291. *
  1292. * INTERNAL REFERENCES: HhpAllocMem().
  1293. *
  1294. * EXTERNAL REFERENCES:
  1295. *
  1296. *********************** END OF SPECIFICATIONS *******************************/
  1297.  
  1298.  
  1299. void NotifyWaitSetup( FUNCTION_PARM_BLOCK *pFuncBlock,
  1300.                       USHORT              usMessage,
  1301.                       ULONG               ulParam1,
  1302.                       ULONG               ulParam2 )
  1303.  
  1304. {
  1305.  
  1306.  
  1307.   if (!(ulParam1 & MCI_WAIT) )
  1308.       {
  1309.  
  1310.       if (usMessage != MCI_OPEN)
  1311.           {
  1312.           pFuncBlock->pInstance->fFakeNotify = FALSE;
  1313.  
  1314.  
  1315.           /*****************************
  1316.           * Default to a Notify
  1317.           ******************************/
  1318.           pFuncBlock->ulParam1 |= MCI_NOTIFY;
  1319.  
  1320.  
  1321.           /********************************
  1322.           * Turn The Notify Flag On
  1323.           *********************************/
  1324.  
  1325.           pFuncBlock->ulNotify = TRUE;
  1326.  
  1327.           /*********************************
  1328.           * Get The Window Callback Handle
  1329.           *********************************/
  1330.  
  1331.           if ( ulParam1 & MCI_NOTIFY )
  1332.              {
  1333.              if ( usMessage == MCI_PLAY || usMessage == MCI_RECORD )
  1334.                {
  1335.                pFuncBlock->pInstance->hwndOldCallBack = pFuncBlock->pInstance->hwndCallBack;
  1336.                pFuncBlock->pInstance->hwndCallBack = (((PMCI_GENERIC_PARMS)ulParam2)->hwndCallback);
  1337.                }
  1338.              else
  1339.                {
  1340.                pFuncBlock->hwndCallBack = (((PMCI_GENERIC_PARMS)ulParam2)->hwndCallback);
  1341.                }
  1342.              }
  1343.           else
  1344.           /********************************************************
  1345.           * Even if the caller did not specify the MCI_NOTIFY
  1346.           * flag, and they didn't specify wait, we will treat
  1347.           * this call just like a notify, EXCEPT that when we
  1348.           * call MDMDriverNotify, we will pass a bogus
  1349.           * callback.  This prevents us from having to do a
  1350.           * tremendous amount of additional processing and the
  1351.           * caller is happy because the work is done asychronously
  1352.           *********************************************************/
  1353.  
  1354.              {
  1355.              /*---------------------------------------------------------
  1356.              * Set flag to indicate that although we are going
  1357.              * to act like it is a notify, the caller did not
  1358.              * really pass in the notify flag.  This will be
  1359.              * important when we have a situation like a play with
  1360.              * a notify, followed by a play without a wait or notify.
  1361.              * In this scenario, an aborted message should be
  1362.              * posted by the first play.
  1363.              *--------------------------------------------------------*/
  1364.  
  1365.              pFuncBlock->pInstance->fFakeNotify = TRUE;
  1366.  
  1367.              if ( usMessage == MCI_PLAY || usMessage == MCI_RECORD )
  1368.                {
  1369.                pFuncBlock->pInstance->hwndOldCallBack = pFuncBlock->pInstance->hwndCallBack;
  1370.                pFuncBlock->pInstance->hwndCallBack = 0;
  1371.                }
  1372.              else
  1373.                {
  1374.                pFuncBlock->hwndCallBack = 0;
  1375.                }
  1376.  
  1377.              } /* if !MCI_NOTIFY */
  1378.  
  1379.           } /* Message .NE. MCI Open */
  1380.  
  1381.        } /* Wait flag is not on */
  1382.  
  1383.   return;
  1384.  
  1385. } /* NotifyWaitSetup */
  1386.  
  1387.  
  1388. /********************* START OF SPECIFICATIONS *******************************
  1389. *
  1390. * SUBROUTINE NAME: AllocateInstance
  1391. *
  1392. * DESCRIPTIVE NAME: allocates memory for the instance etc.
  1393. *
  1394. * FUNCTION: Stores callbacks and sets up the instance for either notify, wait
  1395. *           or asynchronous operation.
  1396. *
  1397. *
  1398. *
  1399. * NOTES:
  1400. * ENTRY POINTS:
  1401. *
  1402. * INPUT:
  1403. *
  1404. * EXIT-NORMAL: Return Code 0.
  1405. *
  1406. * EXIT_ERROR:  Error Code.
  1407. *
  1408. * EFFECTS:
  1409. *
  1410. * INTERNAL REFERENCES: HhpAllocMem().
  1411. *
  1412. * EXTERNAL REFERENCES:
  1413. *
  1414. *********************** END OF SPECIFICATIONS *******************************/
  1415.  
  1416.  
  1417. ULONG AllocateInstance( FUNCTION_PARM_BLOCK *pFuncBlock )
  1418.  
  1419.  
  1420.  
  1421. {
  1422.  
  1423.   extern HHUGEHEAP     heap;                // Global MCD Heap
  1424.  
  1425.  
  1426.   AcquireProcSem ();
  1427.  
  1428.   /**************************************
  1429.   * Waveform audio instance structure
  1430.   ****************************************/
  1431.  
  1432.   if (!(pFuncBlock->pInstance = HhpAllocMem ( heap,
  1433.                                               sizeof (INSTANCE))))
  1434.      {
  1435.      ReleaseProcSem ();
  1436.      return ( MCIERR_OUT_OF_MEMORY );
  1437.      }
  1438.  
  1439.   ReleaseProcSem ();
  1440.  
  1441.   return ( MCIERR_SUCCESS );
  1442.  
  1443. } /* AllocateInstance */
  1444.  
  1445.  
  1446. /********************* START OF SPECIFICATIONS *******************************
  1447. *
  1448. * SUBROUTINE NAME: ObtainDefaults
  1449. *
  1450. * DESCRIPTIVE NAME: Determine default values from MMPM2.INI (if necessary)
  1451. *
  1452. * FUNCTION: This function will retrieve the default wave settings from the device
  1453. *           specific settings of the MMPM2.ini file.
  1454. *
  1455. *
  1456. *
  1457. * NOTES:
  1458. * ENTRY POINTS:
  1459. *
  1460. * INPUT:
  1461. *
  1462. * EXIT-NORMAL: Return Code 0.
  1463. *
  1464. * EXIT_ERROR:  Error Code.
  1465. *
  1466. * EFFECTS:
  1467. *
  1468. * INTERNAL REFERENCES: HhpAllocMem().
  1469. *
  1470. * EXTERNAL REFERENCES:
  1471. *
  1472. *********************** END OF SPECIFICATIONS *******************************/
  1473.  
  1474.  
  1475. ULONG ObtainDefaults(  INSTANCE   *ulpInstance)
  1476.  
  1477.  
  1478.  
  1479. {
  1480.  ULONG ulrc;
  1481.  
  1482.   if ( !(ulpInstance->ulFlags & OBTAINDEFAULTS ) )
  1483.      {
  1484.      ulrc = GetDefaults( ulpInstance->szDevParm, ulpInstance );
  1485.  
  1486.      if ( ulrc )
  1487.         {
  1488.         return ( ulrc );
  1489.         }
  1490.  
  1491.      SetWaveDeviceDefaults (ulpInstance );
  1492.      }
  1493.   ulpInstance->ulFlags |= OBTAINDEFAULTS;
  1494.   return ( MCIERR_SUCCESS );
  1495.  
  1496. } /* ObtainDefaults */
  1497.  
  1498.  
  1499. /********************* START OF SPECIFICATIONS *******************************
  1500. *
  1501. * SUBROUTINE NAME: GetMixerInfo
  1502. *
  1503. * DESCRIPTIVE NAME: Get streaming information from the amp-mixer
  1504. *
  1505. * FUNCTION: Obtain DCB, hid and other information necessary to create a stream
  1506. *           from the amp-mixer.
  1507. *
  1508. *
  1509. *
  1510. * NOTES:
  1511. * ENTRY POINTS:
  1512. *
  1513. * INPUT:
  1514. *
  1515. * EXIT-NORMAL: Return Code 0.
  1516. *
  1517. * EXIT_ERROR:  Error Code.
  1518. *
  1519. * EFFECTS:
  1520. *
  1521. * INTERNAL REFERENCES: HhpAllocMem().
  1522. *
  1523. * EXTERNAL REFERENCES:
  1524. *
  1525. *********************** END OF SPECIFICATIONS *******************************/
  1526.  
  1527. ULONG GetMixerInfo( INSTANCE   *ulpInstance, 
  1528.                     PCONCB     pconcb)
  1529. {
  1530. //  ULONG                ulConnectFlag;
  1531.   ULONG                ulrc;
  1532.  
  1533. //  CONCB                concb;
  1534.  
  1535.   extern     HID       hidBTarget;
  1536.   extern     HID       hidBSource;
  1537.   HID                  hidProtocol;
  1538.  
  1539.  
  1540.  
  1541. //  if ( ulpInstance->ulOperation == MCIDRV_INPUT )
  1542. //     {
  1543. //     ulConnectFlag = MCIDRV_CONNECT_SOURCE;
  1544. //     }
  1545. //  else
  1546. //     {
  1547. //     ulConnectFlag = MCIDRV_CONNECT_TARGET;
  1548. //     }
  1549. //
  1550. //  concb.pMediaHeader = (PVOID) &ulpInstance->mmAudioHeader;
  1551. //  concb.ulConnectorType = MCI_WAVE_STREAM_CONNECTOR;
  1552. //  concb.ulConnectorIndex = 1;
  1553. //
  1554. //  ulrc = mciSendCommand( ulpInstance->usAmpDeviceID,
  1555. //                       MCIDRV_CONNECT,
  1556. //                       ulConnectFlag,
  1557. //                       &concb,
  1558. //                       0);
  1559. //
  1560. //  if ( ULONG_LOWD(ulrc) != MCIERR_SUCCESS )
  1561. //       {
  1562. //       return ( ulrc );
  1563. //       }
  1564. //
  1565.  
  1566.  
  1567.   /* Save the hid from the connected device--use for spcbkeys etc. */
  1568.  
  1569.   if ( ulpInstance->ulOperation == MCIDRV_INPUT )
  1570.      {
  1571.      hidBSource = hidProtocol = pconcb->hid;
  1572.      }
  1573.   else
  1574.      {
  1575.      hidBTarget = hidProtocol = pconcb->hid;
  1576.      }
  1577.  
  1578.   memmove( &ulpInstance->StreamInfo.SpcbKey, pconcb->pspcbkey, sizeof( SPCBKEY) );
  1579.   ulpInstance->pdcb = pconcb->pdcb;
  1580.  
  1581.   /*----------------------------------------------------------
  1582.   * Retrieve the mmtime and byte per unit numbers from the
  1583.   * SPCB key so that can calculate values for seeks etc.
  1584.   * This information will also be used to communicate network
  1585.   * usage parameters to network io procs.
  1586.   *---------------------------------------------------------*/
  1587.   ulrc = SpiGetProtocol( hidProtocol, &STREAM.SpcbKey, &ulpInstance->StreamInfo.spcb );
  1588.  
  1589.   if ( ulrc )
  1590.      {
  1591.      return ( ulrc );
  1592.      }
  1593.  
  1594.   ulpInstance->ulBytes  = ulpInstance->StreamInfo.spcb.ulBytesPerUnit;
  1595.   ulpInstance->ulMMTime = ulpInstance->StreamInfo.spcb.mmtimePerUnit;
  1596.  
  1597.  
  1598. // CONNECTOR FEATURE--Generic Datatype
  1599. #ifdef CONNECTION
  1600.   ulpInstance->StreamInfo.SpcbKey.ulDataType = DATATYPE_GENERIC;
  1601.   ulpInstance->StreamInfo.SpcbKey.ulDataSubType = 0;
  1602.   ulpInstance->StreamInfo.SpcbKey.ulIntKey = 0;
  1603. #endif
  1604. // CONNECTOR FEATURE
  1605.  
  1606.  
  1607.   /* Stick in Instance Ptr in Modified EVCB */
  1608.  
  1609.   ulpInstance->StreamInfo.Evcb.ulpInstance = (ULONG)ulpInstance;
  1610.   /*---------------------------------------------------
  1611.   * If the file is readonly, we are guaranteed that
  1612.   * it will not change.  In addition, if the file
  1613.   * is small, SSM may be allocating too many buffers
  1614.   * (since they are unaware of the file size).
  1615.   * Check to see if we can reduce memory consumption.
  1616.   *--------------------------------------------------*/
  1617.   if ( ulpInstance->ulFlags & READ_ONLY_FILE )
  1618.      {
  1619.      InstallProtocol( ulpInstance );
  1620.      }
  1621.  
  1622.   return ( ulrc );
  1623.  
  1624. } /* GetMixerInfo */
  1625.  
  1626.