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

  1. /**************START OF SPECIFuICATulIONS ************u*********
  2. *
  3. * SUBROUTINE NAME: MCISet
  4. *
  5. * DESCRIPTIVE NAME: Audio MCD Set Routine
  6. *
  7. *              Copyright (c) IBM Corporation  1991, 1993
  8. *                        All Rights Reserved
  9. *
  10. * FUNCTION: Set various audio attributes.
  11. *
  12. * NOTES:
  13. *
  14. * ENTRY POINTS:
  15. *
  16. * INPUT: MCI_STATUS message.
  17. *
  18. * EXIT-NORMAL:Lo Word Return  Code MCIERR_SUCCESS, HighWord Contains
  19. *             constant defining type of quantity returned.
  20. *
  21. * EXIT_ERROR:  Error Code.
  22. *
  23. * EFFECTS:
  24. *
  25. *
  26. * INTERNAL REFERENCES:
  27. *                        ConvertTimeUnits ().
  28. *                        ConVertToMM
  29. *                        SetAudioDevice().
  30. *                        SetWaveDeviceDefaults().
  31. *                        CheckMem ().
  32. *
  33. * EXTERNAL REFERENCES:
  34. *                        SpiGetTime       ()        - MME API
  35. *                        mciSendCommand   ()        - MME API
  36. *
  37. *********************** END OF SPECIFICATIONS **********************/
  38. #define INCL_BASE                       // Base Dos APIs.
  39. #define INCL_ERRORS                     // All the errors.
  40. #define INCL_MMIO_CODEC
  41. #define INCL_AUDIO_CODEC_ONLY
  42.  
  43. #include <os2.h>                        // OS2 includes.
  44. #include <string.h>                     // String Functions
  45. #include <math.h>                       // Math Functions
  46. #include <os2medef.h>                   // MME includes files.
  47. #include <ssm.h>                        // SSM spi includes.
  48. #include <meerror.h>                    // MM Error Messages.
  49. #include <mmioos2.h>                    // MMIO Include.
  50. #include <mcios2.h>                     // MM System Include.
  51. #include <mmdrvos2.h>                   // Mci Driver include.
  52. #include <mcd.h>                        // AUDIO IF DriverInterface.
  53. #include <hhpheap.h>                    // Heap Manager Definitions.
  54. #include <qos.h>
  55. #include <audiomcd.h>                   // Component Definitions.
  56. #include <admcfunc.h>                   // Function Prototypes
  57. #include <checkmem.h>
  58.  
  59. // CODEC stuff
  60. #include <codec.h>
  61. //#include "wcodec.h"
  62.  
  63. /********************* START OF SPECIFICATIONS *********************
  64. *
  65. * SUBROUTINE NAME:  MCISET.C
  66. *
  67. * DESCRIPTIVE NAME: Set Waveform Device Parameters.
  68. *
  69. * FUNCTION:
  70. *
  71. * NOTES:
  72. *
  73. * ENTRY POINTS:
  74. *
  75. * INPUT:
  76. *
  77. * EXIT-NORMAL: Return Code 0.
  78. *
  79. * EXIT_ERROR:  Error Code.
  80. *
  81. * EFFECTS:
  82. *
  83. * INTERNAL REFERENCES:  MCIERR ().
  84. *
  85. * EXTERNAL REFERENCES:  VSDIDriverInterface()  -  VSD
  86. *
  87. *********************** END OF SPECIFICATIONS **********************/
  88. RC MCISet (FUNCTION_PARM_BLOCK *pFuncBlock)
  89.  
  90. {
  91.   ULONG                ulrc;           // Error Value
  92.   ULONG                ulParam1;       // Msg Flags
  93. //ULONG                ulFormatTag = 0;// Format tag flags--PCM etc.
  94.   ULONG                ulHoldError;
  95.   ULONG                ulHoldTag;       /* Backup copy of format tag */
  96.  
  97.   INSTANCE             *ulpInstance;   // Local Instance
  98.   ULONG                ulSetFlags;     // Mask For Incoming MCI Flags
  99.   MCI_AMP_SET_PARMS    AmpSetParms;    // Volume Cmnds
  100.   PMCI_WAVE_SET_PARMS  pSetParms;      // Ptr to set Parms
  101. //  MCI_WAVE_SET_PARMS   AmpSet;         // Ptr to set Parms
  102.   MMAUDIOHEADER        mmaudioheader;  // mode to set the device into
  103. //  BOOL                 fItemChanged = FALSE;  // Indicates if set item was modified.
  104.  
  105.  
  106.  
  107.   ulSetFlags = ulParam1 = pFuncBlock->ulParam1;
  108.  
  109.   pSetParms = ( PMCI_WAVE_SET_PARMS ) pFuncBlock->ulParam2;
  110.   ulpInstance= (INSTANCE *) pFuncBlock->ulpInstance;
  111.  
  112.   /**************************************
  113.   * Check For Validity of Flags
  114.   * For example, it is impossible to set
  115.   * something on AND off.
  116.   **************************************/
  117.  
  118.   if (ulParam1 & MCI_SET_ON && ulParam1 & MCI_SET_OFF)
  119.       return MCIERR_FLAGS_NOT_COMPATIBLE;
  120.  
  121.  
  122.   /*************************************
  123.   * The current wave driver does not
  124.   * support the following flags
  125.   *************************************/
  126.  
  127.   if ( ulParam1 & MCI_SET_DOOR_OPEN     ||
  128.        ulParam1 & MCI_SET_DOOR_CLOSED   ||
  129.        ulParam1 & MCI_SET_DOOR_LOCK     ||
  130.        ulParam1 & MCI_SET_DOOR_UNLOCK   ||
  131.        ulParam1 & MCI_SET_VIDEO         ||
  132.        ulParam1 & MCI_SET_ITEM          ||
  133.        ulParam1 &  MCI_WAVE_SET_BLOCKALIGN )
  134.  
  135.      {
  136.      return (MCIERR_UNSUPPORTED_FLAG);
  137.      }
  138.  
  139.   /***********************************************
  140.   * The caller cannot use the wave driver to set
  141.   * audio operations.  These must be done with the
  142.   * amp/mixer.  The amp/mixer connected to the
  143.   * wave driver can be accessed via mci_connection
  144.   *************************************************/
  145.  
  146.  
  147.   if ( ( ulParam1 & MCI_SET_AUDIO ) &&
  148.        (( ulParam1 & MCI_AMP_SET_BALANCE ) ||
  149.         ( ulParam1 & MCI_AMP_SET_TREBLE  ) ||
  150.         ( ulParam1 & MCI_AMP_SET_BASS    ) ||
  151.         ( ulParam1 & MCI_AMP_SET_GAIN    ) ||
  152.         ( ulParam1 & MCI_AMP_SET_PITCH))  )
  153.      {
  154.      return MCIERR_UNSUPPORTED_FLAG;
  155.      }
  156.  
  157.  
  158.  
  159.   if (ulParam1 & MCI_SET_TIME_FORMAT && ulParam1 & MCI_OVER )
  160.       return ( MCIERR_FLAGS_NOT_COMPATIBLE );
  161.  
  162.   if ((ulParam1 & MCI_SET_VOLUME) && !(ulParam1 & MCI_SET_AUDIO))
  163.      {
  164.      return MCIERR_MISSING_FLAG;
  165.      }
  166.  
  167.  
  168.   /*********************************
  169.   * The caller is required to send in
  170.   * a valid pointer to mci_set_parms
  171.   ***********************************/
  172.  
  173.   ulrc = CheckMem ((PVOID) pSetParms,
  174.                    sizeof (MCI_WAVE_SET_PARMS),
  175.                    PAG_READ);
  176.  
  177.   if (ulrc != MCIERR_SUCCESS)
  178.       return ( MCIERR_MISSING_PARAMETER );
  179.  
  180.   ulSetFlags &= ~(MCI_WAIT + MCI_NOTIFY );
  181.  
  182.   if (ulSetFlags == 0)
  183.       return MCIERR_MISSING_PARAMETER;
  184.  
  185.  
  186.   /***************************************
  187.   * Mask defining Known MCI Set Flags
  188.   ****************************************/
  189.  
  190.   ulSetFlags &= ~( MCI_SET_AUDIO + MCI_SET_TIME_FORMAT + MCI_SET_VOLUME +
  191.                    MCI_SET_ON    + MCI_SET_OFF         + MCI_WAVE_SET_CHANNELS +
  192.                    MCI_WAVE_SET_BITSPERSAMPLE          + MCI_WAVE_SET_SAMPLESPERSEC +
  193.                    MCI_WAVE_SET_FORMATTAG              + MCI_WAVE_SET_BLOCKALIGN +
  194.                    MCI_WAVE_SET_AVGBYTESPERSEC         + MCI_SET_DOOR_OPEN +
  195.                    MCI_SET_DOOR_CLOSED                 + MCI_SET_DOOR_LOCK +
  196.                    MCI_SET_DOOR_UNLOCK + MCI_SET_VIDEO + MCI_OVER );
  197.  
  198.  
  199.   /*******************************************
  200.   * Return invalid if any other bits are set
  201.   *******************************************/
  202.  
  203.   if (ulSetFlags > 0)
  204.       return MCIERR_INVALID_FLAG;
  205.  
  206.  
  207.  
  208.   /*******************************************
  209.   * We do allow certain audio sets to pass
  210.   * on to the amp/mixer that we are connected
  211.   * to (e.g. volume).  Thus crude audio control
  212.   * is possible via the audio mcd, however, more
  213.   * sophisticated stuff should be sent directly
  214.   * to the amp.
  215.   * Prepare and send the audio command to the
  216.   * amp via the mcisendcommand.
  217.   *******************************************/
  218.  
  219.   if (ulParam1 & MCI_SET_AUDIO)
  220.      {
  221.      /****************************
  222.      * Copy The Info to Amp Set
  223.      *****************************/
  224.  
  225.      AmpSetParms.ulLevel = pSetParms->ulLevel;
  226.      AmpSetParms.ulAudio = pSetParms->ulAudio;
  227.      AmpSetParms.ulOver = pSetParms->ulOver;
  228.  
  229.      /****************************
  230.      * Copy The Info to Amp Set
  231.      *****************************/
  232. // CONNECTOR FEATURE
  233. #ifdef CONNECTION
  234.      if ( !ulpInstance->fFoundMixer )
  235.         {
  236.         /********************************
  237.         * It is possbile that although we
  238.         * are connected, there is no amp
  239.         * in the network to forward the
  240.         * command to (i.e. cd->wave).
  241.         * Check to make sure.
  242.         *********************************/
  243.         ulrc = FindAmp( ulpInstance);
  244.         if ( !ulrc )
  245.            {
  246.            return (ulrc);
  247.            }
  248.         }
  249. #endif
  250. // CONNECTOR FEATURE
  251.  
  252.      /**************************************
  253.          * Send the Request To the Amp/Mixer
  254.      ***************************************/
  255.  
  256.      ulrc = mciSendCommand ( ulpInstance->usAmpDeviceID,
  257.                              MCI_SET,
  258.                              ulParam1&~(MCI_NOTIFY) |MCI_WAIT,
  259.                              (PVOID) &AmpSetParms,
  260.                              pFuncBlock->usUserParm);
  261.  
  262.      if ( ulrc )
  263.         {
  264.         return ( ulrc );
  265.         }
  266.  
  267.      } /* of Audio Flag */
  268.  
  269.  
  270.  
  271.   /******************************************
  272.   * The audio driver currently supports
  273.   * only mmtime, milliseconds, sampling rate
  274.   * and bytes as the time format, other
  275.   * requests will receive invalid time format
  276.   *******************************************/
  277.  
  278.   if (ulParam1 & MCI_SET_TIME_FORMAT)
  279.       {
  280.       switch (pSetParms->ulTimeFormat)
  281.          {
  282.          case MCI_FORMAT_MMTIME:
  283.               ulpInstance->ulTimeUnits = lMMTIME;
  284.               break;
  285.  
  286.          case MCI_FORMAT_MILLISECONDS:
  287.               ulpInstance->ulTimeUnits = lMILLISECONDS;
  288.               break;
  289.  
  290.          case MCI_FORMAT_SAMPLES:
  291.               ulpInstance->ulTimeUnits = lSAMPLES;
  292.               break;
  293.  
  294.          case MCI_FORMAT_BYTES:
  295.               ulpInstance->ulTimeUnits = lBYTES;
  296.               break;
  297.  
  298.          default: return MCIERR_INVALID_TIME_FORMAT_FLAG;
  299.  
  300.          } /* Switch time format */
  301.  
  302.       } /* Time Format flag was passed in */
  303.  
  304.   /******************************
  305.   * Check for wave specific flags
  306.   *******************************/
  307.  
  308.   ulSetFlags = ulParam1 & (  MCI_WAVE_SET_CHANNELS
  309.                            + MCI_WAVE_SET_BITSPERSAMPLE
  310.                            + MCI_WAVE_SET_SAMPLESPERSEC
  311.                            + MCI_WAVE_SET_FORMATTAG
  312.                            + MCI_WAVE_SET_AVGBYTESPERSEC );
  313.  
  314.  
  315.   /*************************************************************
  316.   ** If any of the wave set flags are greater than 0, then it is
  317.   ** possible we may have to destroy the stream to inform the
  318.   ** stream handlers of the change in the data rates.  This is
  319.   ** necessary since there is no method of to communicate the
  320.   ** date rate other than at stream creation--thus these set
  321.   ** operations can be rather expensive.
  322.   *************************************************************/
  323.  
  324.   if ( ulSetFlags > 0 )
  325.     {
  326.  
  327.     /*******************************************************
  328.     ** If the stream has been created, then we must destroy,
  329.     ** perform the set and set a flag to indicate that the
  330.     ** stream must be created
  331.     *******************************************************/
  332.  
  333.     if ( ulpInstance->ulCreateFlag == PREROLL_STATE )
  334.        {
  335.        /* if we are actually streaming, then we cannot perform the set */
  336.  
  337.        if ( STRMSTATE == MCI_PLAY   ||
  338.             STRMSTATE == MCI_RECORD ||
  339.             STRMSTATE == MCI_PAUSE )
  340.  
  341.           {
  342.           return ( MCIERR_INVALID_MODE );
  343.           }
  344.        else
  345.           {
  346.  
  347.           if ( !ulpInstance->ulOldStreamPos )
  348.             {
  349.             ulrc = SpiGetTime( STREAM.hStream,
  350.                                ( PMMTIME ) &ulpInstance->ulOldStreamPos );
  351.  
  352.             /************************************************
  353.             * if an error occurred, then don't remember our
  354.             * position in the stream
  355.             ************************************************/
  356.             if ( ulrc )
  357.               {
  358.               ulpInstance->ulOldStreamPos = 0;
  359.               }
  360.             }
  361.           /***********************************
  362.           ** set the stream into create state
  363.           ** following commands will recreate
  364.           ***********************************/
  365.  
  366. //        ulpInstance->ulCreateFlag = CREATE_STATE;
  367.           }
  368.  
  369.        } /* If a stream has already been created */
  370.  
  371.     /* Set up a structure to call the VSD with */
  372. // CONNECTION FEATURE
  373. //    memcpy (&AmpSet, pSetParms, sizeof(MCI_WAVE_SET_PARMS));
  374.  
  375.    if ( ulpInstance->ulRealTimeTranslation == MMIO_REALTIME )
  376.       {
  377.       memmove( &mmaudioheader, &ulpInstance->mmRealHeader, sizeof( MMAUDIOHEADER ) );
  378.       }
  379.    else
  380.       {
  381.       memmove( &mmaudioheader, &ulpInstance->mmAudioHeader, sizeof( MMAUDIOHEADER ) );
  382.       }
  383.  
  384.  
  385.     ulSetFlags = 0;
  386.  
  387.     if (ulParam1 &  MCI_WAVE_SET_CHANNELS )
  388.        {
  389. //       ulSetFlags = MCI_WAVE_SET_CHANNELS;
  390. //       if ( mmaudioheader.mmXWAVHeader.WAVEHeader.usChannels != pSetParms->usChannels )
  391. //          {
  392. //          fItemChanged = TRUE;
  393. //          }
  394.  
  395.        mmaudioheader.mmXWAVHeader.WAVEHeader.usChannels = pSetParms->usChannels ;
  396.        }
  397.  
  398.     if (ulParam1 &  MCI_WAVE_SET_SAMPLESPERSEC)
  399.       {
  400. //      ulSetFlags |= MCI_WAVE_SET_SAMPLESPERSEC;
  401. //      if ( mmaudioheader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec != pSetParms->ulSamplesPerSec )
  402. //          {
  403. //          fItemChanged = TRUE;
  404. //          }
  405.  
  406.  
  407.       mmaudioheader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec = pSetParms->ulSamplesPerSec;
  408.       }
  409.  
  410.  
  411.  
  412.     if (ulParam1 & MCI_WAVE_SET_BITSPERSAMPLE)
  413.        {
  414. //       ulSetFlags |= MCI_WAVE_SET_BITSPERSAMPLE;
  415. //       if ( mmaudioheader.mmXWAVHeader.WAVEHeader.usBitsPerSample != pSetParms->usBitsPerSample )
  416. //          {
  417. //          fItemChanged = TRUE;
  418. //          }
  419.        mmaudioheader.mmXWAVHeader.WAVEHeader.usBitsPerSample   =   pSetParms->usBitsPerSample;
  420.        }
  421.  
  422.     if (ulParam1 & MCI_WAVE_SET_FORMATTAG)
  423.        {
  424. //       ulSetFlags |= MCI_WAVE_SET_FORMATTAG;
  425. //       if ( mmaudioheader.mmXWAVHeader.WAVEHeader.usFormatTag != pSetParms->usFormatTag )
  426. //          {
  427. //          fItemChanged = TRUE;
  428. //          }
  429.        mmaudioheader.mmXWAVHeader.WAVEHeader.usFormatTag = pSetParms->usFormatTag;
  430.  
  431. // CONNECTOR FEATURE
  432. // CODEC change
  433.  
  434.        /*-----------------------------------------------
  435.        * If we have loaded a codec, it is no longer possible
  436.        * to switch to another codec.  Or if there is existing
  437.        * data in the file, it is not possible to switch.
  438.        *------------------------------------------------*/
  439.  
  440.  
  441.        if ( ulpInstance->ulRealTimeTranslation == MMIO_REALTIME &&
  442.             ulpInstance->ulDataSize != 0 )
  443.           {
  444.           return ( MCIERR_INVALID_MODE );
  445.           }
  446.        /* Store the format tag we are changing */
  447.  
  448.        ulHoldTag = mmaudioheader.mmXWAVHeader.WAVEHeader.usFormatTag;
  449.        /*-----------------------------------------------
  450.        * This flag tells us if we have to let the io proc
  451.        * know that since we changed format tags, potentially
  452.        * the codec will have to change too.
  453.        *------------------------------------------------*/
  454. //     if ( pSetParms->usFormatTag != DATATYPE_WAVEFORM )
  455. //        {
  456. //        ulFormatTag = NON_PCM;
  457. //        }
  458.  
  459. // CODEC change
  460.        }
  461.     else
  462.        {
  463.        ulHoldTag = ulpInstance->mmRealHeader.mmXWAVHeader.WAVEHeader.usFormatTag;
  464.        }
  465.  
  466.    /*-------------------------------------
  467.    * There is no need to set the device into
  468.    * a different mode, if the caller is setting
  469.    * the same parameters.
  470.    * ------------------------------------*/
  471.  
  472. //    if ( fItemChanged )
  473. //       {
  474.        /*-------------------------------------
  475.        * The SetAudioDevice function will
  476.        * be used to test and set the connection
  477.        * to the amp-mixer.
  478.        * ------------------------------------*/
  479.    
  480.        ulrc = SetAudioDevice( ulpInstance,
  481.                               &mmaudioheader );
  482.    
  483.        if ( ulrc )
  484.           {
  485.           ulHoldError = ulrc;
  486.     #ifndef CONNECTION
  487.           /*---------------------------------------------
  488.           * We will only perform this function if we
  489.           * get a best-fit error.  If there is a best-fit
  490.           * error, it will be one of the following:
  491.           * MCIERR_UNSUPP_FORMAT_TAG
  492.           * MCIERR_UNSUPP_SAMPLESPERSEC
  493.           * MCIERR_UNSUPP_BITSPERSAMPLE
  494.           * MCIERR_UNSUPP_CHANNELS
  495.           * MCIERR_UNSUPP_FORMAT_MODE
  496.           *---------------------------------------------*/
  497.           if ( ULONG_LOWD( ulrc)  == MCIERR_UNSUPP_FORMAT_TAG )
  498.              {
  499.    
  500.              /* ------------------------------------------
  501.              * If a codec has already been loaded, and data
  502.              * is in the file, we cannot switch codecs, else
  503.              * the result would be confusion.
  504.              *--------------------------------------------*/
  505.    
  506.              if ( ulpInstance->ulDataSize != 0 )
  507.                 {
  508.                 return ( MCIERR_INVALID_MODE );
  509.                 }
  510.    
  511.              /* ------------------------------------------
  512.              * Connected device updated the mmaudioheader to
  513.              * the nearest matching mode.
  514.              *--------------------------------------------*/
  515.    
  516.              ulrc = SetAudioDevice( ulpInstance,
  517.                                     &mmaudioheader );
  518.    
  519.              /*------------------------------------------
  520.              * Since the user has changed the format tag
  521.              * i.e. from pcm to dvi adpcm etc.
  522.              * We may have to change the codec we are using--
  523.              * so inform the io proc via choose CODEC message.
  524.              *------------------------------------------*/
  525.              ulrc = SetupCodec( ulpInstance, ulHoldTag );
  526.    
  527.              if ( ulrc )
  528.                 {
  529.    
  530.                 return ( ulHoldError );
  531.                 }
  532.    
  533.    
  534.              /****************************************************
  535.              * Inform the io proc whether or not the data should
  536.              * be translated real-time or not.
  537.              *****************************************************/
  538.              ulpInstance->ulRealTimeTranslation = MMIO_REALTIME;
  539.              ulpInstance->ulCodecDescription = MAKE_TARGET | TARGET_CODEC;
  540.    
  541.              }
  542.    
  543.           else
  544.     #endif
  545.              {
  546.              return ( ulHoldError );
  547.              }
  548.           }
  549.        else
  550.           {
  551.           ulpInstance->ulRealTimeTranslation = MMIO_NONREALTIME;
  552.    
  553.           /* Connected MCD may update MMAUDIOHEADER for correct mode */
  554.          memmove(  &ulpInstance->mmAudioHeader, &mmaudioheader,  sizeof( MMAUDIOHEADER ) );
  555.    
  556.           }
  557.    
  558.        // must still copy information from waveset parms to instance if ok
  559.    
  560.     // CONNECTOR FEATURE--changed meaning of SetAudioDevice
  561.    
  562.       if (ulParam1 &  MCI_WAVE_SET_AVGBYTESPERSEC)
  563.         {
  564.         if ( pSetParms->ulAvgBytesPerSec <
  565.                ( ULONG ) ( WAVEHDR.ulSamplesPerSec * ( WAVEHDR.usBitsPerSample / 8 ) * WAVEHDR.usChannels ) )
  566.            {
  567.            return ( MCIERR_OUTOFRANGE );
  568.            }
  569.           else
  570.            {
  571.            ulpInstance->ulAverageBytesPerSec = pSetParms->ulAvgBytesPerSec;
  572.            }
  573.         } /* if average bytes per sec are passed in */
  574.    
  575.       else
  576.         {
  577.         ulpInstance->ulAverageBytesPerSec =
  578.                ( ULONG ) ( WAVEHDR.ulSamplesPerSec * ( WAVEHDR.usBitsPerSample / 8 ) * WAVEHDR.usChannels );
  579.         }
  580.    
  581.        STRMSTATE = STREAM_SET_STATE;
  582.    
  583.        // 6421--ensure that audio header structure is ALWAYS accurate.
  584.    
  585.        //    SyncAudioHeader(ulpInstance);
  586. //       } /* If a set item changed */
  587.  
  588.     } /* if a wave set is requested */
  589.  
  590.  
  591.   /******************************************************************
  592.   * If the caller has opened with an MCI_OPEN_MMIO or if a record
  593.   * has been done, the file header must be updated.  In the case of
  594.   * open mmio, applications such as the wave header are dependent
  595.   * on the information in the file header being valid at all times.
  596.   *******************************************************************/
  597.   if ( ulpInstance->fOpenMMIO &&
  598.        ulpInstance->ulCapabilities & CAN_RECORD)
  599.  
  600.        {
  601.        /**************************************
  602.        * If the card is in record mode an a
  603.        * file has been loaded, then we can do
  604.        * the set header.
  605.        ***************************************/
  606.  
  607.        ulrc = SetAudioHeader (ulpInstance);
  608.        } /* Not Recording */
  609.  
  610.  
  611.  
  612.  
  613.   return (ulrc);
  614.  
  615. } /* MCISet */
  616.  
  617. #ifndef CONNECTION
  618. /********************* START OF SPECIFICATIONS *********************
  619. *
  620. * SUBROUTINE NAME: SetupCodec
  621. *
  622. * FUNCTION: Inform Io proc of new codec changes
  623. *
  624. * NOTES:
  625. *
  626. * ENTRY POINTS:
  627. *
  628. * INPUT: FUNCTION_PARM_BLOCK
  629. *
  630. * EXIT-NORMAL: MCIERR_SUCCESS
  631. *
  632. * EXIT_ERROR:
  633. *
  634. * EFFECTS:
  635. *
  636. * EXTERNAL REFERENCES: mmioSendMessage()    - MMIO function
  637. *
  638. *********************** END OF SPECIFICATIONS **********************/
  639.  
  640. ULONG   SetupCodec( INSTANCE      *pInstance,
  641.                     USHORT        usFormatTag )
  642.  
  643. {
  644. LONG          rc;
  645. MMAUDIOHEADER mmaudheader;
  646.   MMEXTENDINFO      mmExtInfo;
  647.   PCODECOPEN        pcodecopen;
  648.   CODECASSOC        codecAssoc;
  649.   PCODECINIFILEINFO pcodecini;
  650.   extern HHUGEHEAP     heap;                // Global MCD Heap
  651.  
  652.  
  653.   if ( !pInstance->pcodecini )
  654.      {
  655.  
  656.      pInstance->pcodecini = HhpAllocMem( heap,
  657.                                            sizeof( MMEXTENDINFO) +
  658.                                            sizeof( CODECINIFILEINFO ) +
  659.                                            sizeof( CODECASSOC ) +
  660.                                            sizeof( CODECOPEN ) +
  661.                                            sizeof( MMAUDIOOPEN ) +
  662.                                            4096 );    // Buffer 4096--can't determine how large.
  663.  
  664.      if ( !pInstance->pcodecini)
  665.         {
  666.         return( MCIERR_OUT_OF_MEMORY);
  667.         }
  668.      }
  669.  
  670.   pcodecini = pInstance->pcodecini;
  671.  
  672.   /***********************************************
  673.   * We allocated enough memory for the codecini +
  674.   * the codecopen structures.  Advanced (and store)
  675.   * pointer to get this accomplished.
  676.   ***********************************************/
  677.  
  678.   pInstance->pcodecopen = pcodecopen = ( PVOID ) ++pcodecini;
  679.  
  680.  
  681.   memmove( &mmaudheader, &pInstance->mmAudioHeader, sizeof (MMAUDIOHEADER ) );
  682.   mmaudheader.mmXWAVHeader.WAVEHeader.usFormatTag = usFormatTag;
  683.  
  684.  
  685.  
  686.   mmExtInfo.ulStructLen = sizeof( MMEXTENDINFO );
  687.  
  688. // note: need way to pass flag that codec must init own variables!!!
  689.   mmExtInfo.ulFlags = MMIO_CODEC_ASSOC | MMIO_REALTIME_CODEC;
  690.  
  691.  
  692.   mmExtInfo.ulNumCODECs = 1;
  693.   mmExtInfo.pCODECAssoc = &codecAssoc;
  694.   codecAssoc.pCodecOpen = pcodecopen;
  695.   pcodecopen->pSrcHdr = ( PVOID ) &pInstance->mmRealHeader;
  696.   memmove( &pInstance->mmRealHeader, &mmaudheader, sizeof( MMAUDIOHEADER ) );
  697.  
  698.   pcodecopen->pDstHdr = ( PVOID ) &pInstance->mmAudioHeader;
  699.   pcodecopen->ulFlags = INIT_CODEC;
  700.  
  701.   codecAssoc.pCODECIniFileInfo = pcodecini = pInstance->pcodecini;
  702.  
  703.  
  704.   memset( pcodecini, '\0', sizeof( CODECINIFILEINFO ));
  705.   pcodecini->ulStructLen = sizeof( CODECINIFILEINFO );
  706.   pcodecini->fcc = FOURCC_WAV;
  707.   pcodecini->ulCompressType =
  708.      mmaudheader.mmXWAVHeader.WAVEHeader.usFormatTag;
  709.   pcodecini->ulCompressSubType = 0;
  710.   pcodecini->ulMediaType = MMIO_MEDIATYPE_AUDIO;
  711.  
  712.   /* The Codec setup call informs the io proc of a new format tag */
  713.  
  714.  
  715.   rc = mmioSet( pInstance->hmmio,
  716.                 &mmExtInfo,
  717.                 MMIO_SET_EXTENDEDINFO );
  718.  
  719.  
  720.   /*-------------------------------------------------
  721.   * If we will be doing real-time translations
  722.   * then, it is important to examine the capabilities
  723.   * of the io proc.
  724.   *-------------------------------------------------*/
  725.   if ( pcodecini->ulCapsFlags & CODEC_COMPRESS )
  726.      {
  727.      pInstance->ulCapabilities |= CAN_SAVE;
  728.      }
  729.   else
  730.      {
  731.      pInstance->ulCapabilities &= ~CAN_SAVE;
  732.      }
  733.  
  734.   if ( pcodecini->ulCapsFlags & CODEC_COMP_REALTIME )
  735.      {
  736.      pInstance->ulCapabilities |= CAN_RECORD;
  737.      }
  738.   else
  739.      {
  740.      pInstance->ulCapabilities &= ~CAN_RECORD;
  741.      }
  742.  
  743.  
  744.  
  745. //  rc = mmioSendMessage( pInstance->hmmio,
  746. //                        MMIOM_SETUPCODEC,
  747. //                        ( LONG ) &mmaudheader,
  748. //                        0 );
  749.  
  750.   return ( rc );
  751.  
  752. } /* SetupCodec */
  753.  
  754. #endif
  755.