home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v6.zip / MMPM2TK / TK / ADMCT / ADMCSET.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  13KB  |  423 lines

  1. /********************* START OF SPECIFICATulIONS *********************
  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.  
  41. #include <os2.h>                        // OS2 includes.
  42. #include <string.h>                     // String Functions
  43. #include <math.h>                       // Math Functions
  44. #include <os2medef.h>                   // MME includes files.
  45. #include <ssm.h>                        // SSM spi includes.
  46. #include <meerror.h>                    // MM Error Messages.
  47. #include <mmioos2.h>                    // MMIO Include.
  48. #include <mcios2.h>                     // MM System Include.
  49. #include <audio.h>                      // Audio DD Defines
  50. #include <mmdrvos2.h>                   // Mci Driver include.
  51. #include <mcd.h>                        // AUDIO IF DriverInterface.
  52. #include <hhpheap.h>                    // Heap Manager Definitions.
  53. #include <qos.h>
  54. #include <audiomcd.h>                   // Component Definitions.
  55. #include <admcfunc.h>                   // Function Prototypes
  56.  
  57. /********************* START OF SPECIFICATIONS *********************
  58. *
  59. * SUBROUTINE NAME:  MCISET.C
  60. *
  61. * DESCRIPTIVE NAME: Set Waveform Device Parameters.
  62. *
  63. * FUNCTION:
  64. *
  65. * NOTES:
  66. *
  67. * ENTRY POINTS:
  68. *
  69. * INPUT:
  70. *
  71. * EXIT-NORMAL: Return Code 0.
  72. *
  73. * EXIT_ERROR:  Error Code.
  74. *
  75. * EFFECTS:
  76. *
  77. * INTERNAL REFERENCES:  MCIERR ().
  78. *
  79. * EXTERNAL REFERENCES:  VSDIDriverInterface()  -  VSD
  80. *
  81. *********************** END OF SPECIFICATIONS **********************/
  82. RC MCISet (FUNCTION_PARM_BLOCK *pFuncBlock)
  83.  
  84. {
  85.   ULONG                ulrc;           // Error Value
  86.   ULONG                ulParam1;       // Msg Flags
  87.  
  88.   INSTANCE             *ulpInstance;   // Local Instance
  89.   ULONG                ulSetFlags;     // Mask For Incoming MCI Flags
  90.   MCI_AMP_SET_PARMS    AmpSetParms;    // Volume Cmnds
  91.   PMCI_WAVE_SET_PARMS  pSetParms;      // Ptr to set Parms
  92.   MCI_WAVE_SET_PARMS   AmpSet;         // Ptr to set Parms
  93.  
  94.  
  95.  
  96.   ulSetFlags = ulParam1 = pFuncBlock->ulParam1;
  97.  
  98.   pSetParms = ( PMCI_WAVE_SET_PARMS ) pFuncBlock->ulParam2;
  99.   ulpInstance= (INSTANCE *) pFuncBlock->ulpInstance;
  100.  
  101.   /**************************************
  102.   * Check For Validity of Flags
  103.   * For example, it is impossible to set
  104.   * something on AND off.
  105.   **************************************/
  106.  
  107.   if (ulParam1 & MCI_SET_ON && ulParam1 & MCI_SET_OFF)
  108.       return MCIERR_FLAGS_NOT_COMPATIBLE;
  109.  
  110.  
  111.   /*************************************
  112.   * The current wave driver does not
  113.   * support the following flags
  114.   *************************************/
  115.  
  116.   if ( ulParam1 & MCI_SET_DOOR_OPEN     ||
  117.        ulParam1 & MCI_SET_DOOR_CLOSED   ||
  118.        ulParam1 & MCI_SET_DOOR_LOCK     ||
  119.        ulParam1 & MCI_SET_DOOR_UNLOCK   ||
  120.        ulParam1 & MCI_SET_VIDEO         ||
  121.        ulParam1 & MCI_SET_ITEM          ||
  122.        ulParam1 &  MCI_WAVE_SET_BLOCKALIGN )
  123.  
  124.      {
  125.      return (MCIERR_UNSUPPORTED_FLAG);
  126.      }
  127.  
  128.   /***********************************************
  129.   * The caller cannot use the wave driver to set
  130.   * audio operations.  These must be done with the
  131.   * amp/mixer.  The amp/mixer connected to the
  132.   * wave driver can be accessed via mci_connection
  133.   *************************************************/
  134.  
  135.  
  136.   if ( ( ulParam1 & MCI_SET_AUDIO ) &&
  137.        (( ulParam1 & MCI_AMP_SET_BALANCE ) ||
  138.         ( ulParam1 & MCI_AMP_SET_TREBLE  ) ||
  139.         ( ulParam1 & MCI_AMP_SET_BASS    ) ||
  140.         ( ulParam1 & MCI_AMP_SET_GAIN    ) ||
  141.         ( ulParam1 & MCI_AMP_SET_PITCH))  )
  142.      {
  143.      return MCIERR_UNSUPPORTED_FLAG;
  144.      }
  145.  
  146.  
  147.  
  148.   if (ulParam1 & MCI_SET_TIME_FORMAT && ulParam1 & MCI_OVER )
  149.       return ( MCIERR_FLAGS_NOT_COMPATIBLE );
  150.  
  151.   if ((ulParam1 & MCI_SET_VOLUME) && !(ulParam1 & MCI_SET_AUDIO))
  152.      {
  153.      return MCIERR_MISSING_FLAG;
  154.      }
  155.  
  156.  
  157.   /*********************************
  158.   * The caller is required to send in
  159.   * a valid pointer to mci_set_parms
  160.   ***********************************/
  161.  
  162.   ulrc = CheckMem ((PVOID) pSetParms,
  163.                    sizeof (MCI_WAVE_SET_PARMS),
  164.                    PAG_READ);
  165.  
  166.   if (ulrc != MCIERR_SUCCESS)
  167.       return ( MCIERR_MISSING_PARAMETER );
  168.  
  169.   ulSetFlags &= ~(MCI_WAIT + MCI_NOTIFY );
  170.  
  171.   if (ulSetFlags == 0)
  172.       return MCIERR_MISSING_PARAMETER;
  173.  
  174.  
  175.   /***************************************
  176.   * Mask defining Known MCI Set Flags
  177.   ****************************************/
  178.  
  179.   ulSetFlags &= ~( MCI_SET_AUDIO + MCI_SET_TIME_FORMAT + MCI_SET_VOLUME +
  180.                    MCI_SET_ON    + MCI_SET_OFF         + MCI_WAVE_SET_CHANNELS +
  181.                    MCI_WAVE_SET_BITSPERSAMPLE          + MCI_WAVE_SET_SAMPLESPERSEC +
  182.                    MCI_WAVE_SET_FORMATTAG              + MCI_WAVE_SET_BLOCKALIGN +
  183.                    MCI_WAVE_SET_AVGBYTESPERSEC         + MCI_SET_DOOR_OPEN +
  184.                    MCI_SET_DOOR_CLOSED                 + MCI_SET_DOOR_LOCK +
  185.                    MCI_SET_DOOR_UNLOCK + MCI_SET_VIDEO + MCI_OVER );
  186.  
  187.  
  188.   /*******************************************
  189.   * Return invalid if any other bits are set
  190.   *******************************************/
  191.  
  192.   if (ulSetFlags > 0)
  193.       return MCIERR_INVALID_FLAG;
  194.  
  195.  
  196.  
  197.   /*******************************************
  198.   * We do allow certain audio sets to pass
  199.   * on to the amp/mixer that we are connected
  200.   * to (e.g. volume).  Thus crude audio control
  201.   * is possible via the audio mcd, however, more
  202.   * sophisticated stuff should be sent directly
  203.   * to the amp.
  204.   * Prepare and send the audio command to the
  205.   * amp via the mcisendcommand.
  206.   *******************************************/
  207.  
  208.   if (ulParam1 & MCI_SET_AUDIO)
  209.      {
  210.      /****************************
  211.      * Copy The Info to Amp Set
  212.      *****************************/
  213.  
  214.      AmpSetParms.ulLevel = pSetParms->ulLevel;
  215.      AmpSetParms.ulAudio = pSetParms->ulAudio;
  216.      AmpSetParms.ulOver = pSetParms->ulOver;
  217.  
  218.      /**************************************
  219.          * Send the Request To the Amp/Mixer
  220.      ***************************************/
  221.  
  222.      ulrc = mciSendCommand ( ulpInstance->usAmpDeviceID,
  223.                              MCI_SET,
  224.                              ulParam1&~(MCI_NOTIFY) |MCI_WAIT,
  225.                              (PVOID) &AmpSetParms,
  226.                              pFuncBlock->usUserParm);
  227.  
  228.      if ( ulrc )
  229.         {
  230.         return ( ulrc );
  231.         }
  232.  
  233.      } /* of Audio Flag */
  234.  
  235.  
  236.  
  237.   /******************************************
  238.   * The audio driver currently supports
  239.   * only mmtime, milliseconds, sampling rate
  240.   * and bytes as the time format, other
  241.   * requests will receive invalid time format
  242.   *******************************************/
  243.  
  244.   if (ulParam1 & MCI_SET_TIME_FORMAT)
  245.       {
  246.       switch (pSetParms->ulTimeFormat)
  247.          {
  248.          case MCI_FORMAT_MMTIME:
  249.               ulpInstance->ulTimeUnits = lMMTIME;
  250.               break;
  251.  
  252.          case MCI_FORMAT_MILLISECONDS:
  253.               ulpInstance->ulTimeUnits = lMILLISECONDS;
  254.               break;
  255.  
  256.          case MCI_FORMAT_SAMPLES:
  257.               ulpInstance->ulTimeUnits = lSAMPLES;
  258.               break;
  259.  
  260.          case MCI_FORMAT_BYTES:
  261.               ulpInstance->ulTimeUnits = lBYTES;
  262.               break;
  263.  
  264.          default: return MCIERR_INVALID_TIME_FORMAT_FLAG;
  265.  
  266.          } /* Switch time format */
  267.  
  268.       } /* Time Format flag was passed in */
  269.  
  270.   /******************************
  271.   * Check for wave specific flags
  272.   *******************************/
  273.  
  274.   ulSetFlags = ulParam1 & (  MCI_WAVE_SET_CHANNELS
  275.                            + MCI_WAVE_SET_BITSPERSAMPLE
  276.                            + MCI_WAVE_SET_SAMPLESPERSEC
  277.                            + MCI_WAVE_SET_FORMATTAG
  278.                            + MCI_WAVE_SET_AVGBYTESPERSEC );
  279.  
  280.  
  281.   /*************************************************************
  282.   ** If any of the wave set flags are greater than 0, then it is
  283.   ** possible we may have to destroy the stream to inform the
  284.   ** stream handlers of the change in the data rates.  This is
  285.   ** necessary since there is no method of to communicate the
  286.   ** date rate other than at stream creation--thus these set
  287.   ** operations can be rather expensive.
  288.   *************************************************************/
  289.  
  290.   if ( ulSetFlags > 0 )
  291.     {
  292.  
  293.     /*******************************************************
  294.     ** If the stream has been created, then we must destroy,
  295.     ** perform the set and set a flag to indicate that the
  296.     ** stream must be created
  297.     *******************************************************/
  298.  
  299.     if ( ulpInstance->ulCreateFlag == PREROLL_STATE )
  300.        {
  301.        /* if we are actually streaming, then we cannot perform the set */
  302.  
  303.        if ( STRMSTATE == MCI_PLAY   ||
  304.             STRMSTATE == MCI_RECORD ||
  305.             STRMSTATE == MCI_PAUSE )
  306.  
  307.           {
  308.           return ( MCIERR_INVALID_MODE );
  309.           }
  310.        else
  311.           {
  312.  
  313.           if ( !ulpInstance->ulOldStreamPos )
  314.             {
  315.             ulrc = SpiGetTime( STREAM.hStream,
  316.                                ( PMMTIME ) &ulpInstance->ulOldStreamPos );
  317.  
  318.             /************************************************
  319.             * if an error occurred, then don't remember our
  320.             * position in the stream
  321.             ************************************************/
  322.             if ( ulrc )
  323.               {
  324.               ulpInstance->ulOldStreamPos = 0;
  325.               }
  326.             }
  327.           /***********************************
  328.           ** set the stream into create state
  329.           ** following commands will recreate
  330.           ***********************************/
  331.  
  332.           ulpInstance->ulCreateFlag = CREATE_STATE;
  333.           }
  334.  
  335.        } /* If a stream has already been created */
  336.  
  337.     /* Set up a structure to call the VSD with */
  338.  
  339.     memcpy (&AmpSet, pSetParms, sizeof(MCI_WAVE_SET_PARMS));
  340.  
  341.  
  342.     ulSetFlags = 0;
  343.  
  344.     if (ulParam1 &  MCI_WAVE_SET_CHANNELS )
  345.        {
  346.        ulSetFlags = MCI_WAVE_SET_CHANNELS;
  347.        }
  348.  
  349.     if (ulParam1 &  MCI_WAVE_SET_SAMPLESPERSEC)
  350.       {
  351.       ulSetFlags |= MCI_WAVE_SET_SAMPLESPERSEC;
  352.       }
  353.  
  354.  
  355.  
  356.     if (ulParam1 & MCI_WAVE_SET_BITSPERSAMPLE)
  357.        {
  358.        ulSetFlags |= MCI_WAVE_SET_BITSPERSAMPLE;
  359.        }
  360.  
  361.     if (ulParam1 & MCI_WAVE_SET_FORMATTAG)
  362.        {
  363.        ulSetFlags |= MCI_WAVE_SET_FORMATTAG;
  364.        }
  365.  
  366.     ulrc = SetAudioDevice( ulpInstance,
  367.                            &AmpSet,
  368.                            ulSetFlags );
  369.  
  370.     if ( ulrc )
  371.        {
  372.        return ( ulrc );
  373.        }
  374.  
  375.    if (ulParam1 &  MCI_WAVE_SET_AVGBYTESPERSEC)
  376.      {
  377.      if ( pSetParms->ulAvgBytesPerSec < ( ULONG ) ( AMPMIX.lSRate * ( AMPMIX.lBitsPerSRate / 8 ) * AMPMIX.sChannels ) )
  378.         {
  379.         return ( MCIERR_OUTOFRANGE );
  380.         }
  381.        else
  382.         {
  383.         ulpInstance->ulAverageBytesPerSec = pSetParms->ulAvgBytesPerSec;
  384.         }
  385.      } /* if average bytes per sec are passed in */
  386.  
  387.    else
  388.      {
  389.      ulpInstance->ulAverageBytesPerSec = AMPMIX.lSRate * ( AMPMIX.lBitsPerSRate / 8 ) * AMPMIX.sChannels;
  390.      }
  391.  
  392.     STRMSTATE = STREAM_SET_STATE;
  393.  
  394.     } /* if a wave set is requested */
  395.  
  396.  
  397.   /******************************************************************
  398.   * If the caller has opened with an MCI_OPEN_MMIO or if a record
  399.   * has been done, the file header must be updated.  In the case of
  400.   * open mmio, applications such as the wave header are dependent
  401.   * on the information in the file header being valid at all times.
  402.   *******************************************************************/
  403.   if ( ulpInstance->fOpenMMIO )
  404. /*       ( AMPMIX.ulOperation == OPERATION_RECORD && STRMSTATE != MCI_RECORD ) ) */
  405.        {
  406.        /**************************************
  407.        * If the card is in record mode an a
  408.        * file has been loaded, then we can do
  409.        * the set header.
  410.        ***************************************/
  411.  
  412.        ulrc = SetAudioHeader (ulpInstance);
  413.        } /* Not Recording */
  414.  
  415.  
  416.  
  417.  
  418.   return (ulrc);
  419.  
  420. } /* MCISet */
  421.  
  422.  
  423.