home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / mac / soundutl / vmtrs10s.hqx / VUMeters / Sources / SoundMonitor.c < prev    next >
Text File  |  1993-08-05  |  9KB  |  345 lines

  1. /*
  2.  *                  ARTA VUMeters for Macintosh
  3.  *                      Malcolm Slaney
  4.  *                 Advanced Technology Group
  5.  *                Apple Computer, Inc.
  6.  *                 malcolm@apple.com
  7.  *                     1992-1993
  8.  *
  9.  *    Warranty Information
  10.  *    Even though Apple has reviewed this software, Apple makes no warranty
  11.  *    or representation, either express or implied, with respect to this
  12.  *    software, its quality, accuracy, merchantability, or fitness for a 
  13.  *    particular purpose.  As a result, this software is provided "as is,"
  14.  *    and you, its user, are assuming the entire risk as to its quality
  15.  *    and accuracy.
  16.  *
  17.  *    Copyright (c) 1992-1993 by Apple Computer, Inc
  18.  *        All Rights Reserved.
  19.  */
  20.  
  21. /* SoundMonitor.c */
  22.  
  23. #include <DSPConstants.h>
  24. #include <DSPManager.h>
  25. #include <StandardSound.h>
  26. #include <Memory.h>
  27. #include <StdLib.h>
  28. #include "SoundMonitor.h"
  29.  
  30. pascal void  DSPMonitorTaskHandler ();
  31.  
  32. /*    SMOpenDSPSoundStream - Open a DSP sound stream. Return the stream
  33.  *    that is used for the Standard Sound System.
  34.  */
  35. SoundStream  SMOpenDSPSoundStream(){
  36.     SoundStream  sound_stream;
  37.  
  38.     StdSndGetIndexedStream (&sound_stream, kStdSndSystemStream);
  39.  
  40.     return (sound_stream);
  41. }
  42.  
  43. /*    SMOpenDSP3210 - Open a DSP client.  Given a sound stream, open
  44.  *    the proper DSP device and return its parameter block.  We'll need
  45.  *    this parameter block later when we want to reference it. 
  46.  */
  47. DSPCPUDeviceParamBlkPtr  SMOpenDSP3210(sound_stream)
  48. SoundStream  sound_stream;
  49. {
  50.     DSPCPUDeviceParamBlkPtr        pblock;
  51.     OSErr                err;
  52.     int                  i;
  53.  
  54. #ifdef    DONTDO
  55. #define    UNIMPL_TRAP_NUM        0x9F
  56.     if (NGetTrapAddress(0xBF5, ToolTrap) == 
  57.         NGetTrapAddress(UNIMPL_TRAP_NUM, ToolTrap)){
  58.         DoAlert("\pCathedral Toolbox is not installed.  Bye.");
  59.         exit(1);
  60.     }
  61. #endif    /* DONTDO */
  62.     
  63.                         /* Check manager version */
  64.     if (DSPManagerVersion () != kdspManagerBuildVersion)
  65.         return (NULL);
  66.  
  67.                         /* Allocate memory for 
  68.                          * parameter block record
  69.                          */
  70.     pblock = (DSPCPUDeviceParamBlkPtr)NewPtr(sizeof(DSPCPUDeviceParamBlk));
  71.     if (!pblock)
  72.         return (NULL);
  73.  
  74.                         /* Clear out parameter block 
  75.                          * so we don't have any surprises
  76.                          */
  77.     for (i = 0; i < sizeof(DSPCPUDeviceParamBlk); i++)
  78.         ((char *) pblock)[i] = 0;
  79.  
  80.                         /* Get the cpu index for 
  81.                          * this particular stream
  82.                          * and stuff it into parameter
  83.                          * block.
  84.                          */
  85.     StdSndGetStreamCPUIndex(sound_stream, 0, &(pblock->pbhDeviceIndex));
  86.  
  87.                         /* Now get the proper DSP using
  88.                          * using the manager.
  89.                          */
  90.     err = DSPGetIndexedCPUDevice(pblock);
  91.     if (err != noErr)
  92.         return (NULL);
  93.  
  94.                         /* Open DSP device */
  95.     pblock->pbhClientPermission = kdspReadPermission;
  96.     BlockMove("\pFrontEnd", pblock->pbhClientName, 32);
  97.     err = DSPOpenCPUDevice(pblock);
  98.     if (err != noErr)
  99.         return (NULL);
  100.  
  101.     return (pblock);
  102. }
  103.  
  104. /*    SMCloseDSP3210 - Close the DSP client.  When we're all done we close the
  105.  *    the DSP and dispose of the parameter block.
  106.  */
  107.  
  108. long  SMCloseDSP3210(pblock)
  109. DSPCPUDeviceParamBlkPtr  pblock;
  110. {
  111.     OSErr  err;
  112.     long  zerror = NO_ERROR;
  113.  
  114.     if (pblock == NULL)
  115.         return (ERROR);
  116.  
  117.     err = DSPCloseCPUDevice(pblock);
  118.     if (err != noErr)
  119.         zerror = ERROR;
  120.  
  121.     DisposPtr((Ptr) pblock);
  122.  
  123.     return (zerror);
  124. }
  125.  
  126. /*    SMCreateDSPMonitor - Create a sound monitor.  This does the real
  127.  *    work.  Given a DSP device (indicated by the parameter block) and a 
  128.  *    type name we can define a DSP task and load the appropriate module.
  129.  *    The type names are defined in the DSP code as NewModule().  Currently 
  130.  *    "\pMax" or "\pPower" are the only valid module types.
  131.  *
  132.  *    Once we have the module loaded into a task we can attach it to the
  133.  *    sound stream.  We use the soundStream to get access to the left and
  134.  *    right channels and we insert the new task at the location determined 
  135.  *    by the streamLocation parameter.
  136.  */
  137.  
  138. DSPMonitor  SMCreateDSPMonitor(dspParameterBlock, soundStream, 
  139.                     monitorType, streamLocation)
  140. DSPCPUDeviceParamBlkPtr        dspParameterBlock;
  141. SoundStream            soundStream;
  142. StringPtr            monitorType;
  143. long                streamLocation;
  144. {
  145.     DSPMonitor        monitor;
  146.     DSPModuleRefNum        MonitorModule;
  147.     DSPSectionRefNum    sectionLeft, sectionRight, section;
  148.     long            patchPoint;
  149.     OSErr            err;
  150.  
  151.                     /* alloc mem for monitor record */
  152.     monitor = (DSPMonitor) NewPtr(sizeof(DSPMonitorRec));
  153.     if (!monitor)
  154.         return (NULL);
  155.  
  156.     monitor->taskRef = 0;
  157.     monitor->dspParms = 0;
  158.     monitor->typeName = 0;
  159.     monitor->streamLocation = streamLocation;
  160.     monitor->taskActive = 0;
  161.   
  162.                     /* Create new monitor task */
  163.     err = DSPNewTask (dspParameterBlock, 
  164.             (MessageActionProc)DSPMonitorTaskHandler,
  165.             "\pDSPMonitorTask", &monitor->taskRef);
  166.     if (err != noErr)
  167.         return (NULL);
  168.  
  169.                     /* Load monitor module */
  170.     err = DSPLoadModule (monitorType, monitor->taskRef,
  171.                 kdspAnyPositionInsert, 0, 
  172.                 &MonitorModule, 240);
  173.     if (err != noErr)
  174.     return (NULL);
  175.  
  176.                     /* Connect to standard sound.  Figure
  177.                      * out the AIAO buffers (sections) that
  178.                      * correspond to the left and right
  179.                      * channel.  The DSP monitor which we
  180.                      * created above has two input buffers
  181.                      * that we want to connect to the 
  182.                      * standard sound buffers.
  183.                      */
  184.     StdSndGetStreamSections (soundStream, §ionLeft, §ionRight);
  185.     DSPGetSection (MonitorModule, "\pLeft", §ion);
  186.     err = DSPConnectSections(sectionLeft, section, kdspDirectConnection);
  187.     if (err != noErr)
  188.         return (NULL);
  189.  
  190.     DSPGetSection (MonitorModule, "\pRight", §ion);
  191.     err = DSPConnectSections(sectionRight, section, kdspDirectConnection);
  192.     if (err != noErr)
  193.         return (NULL);
  194.  
  195.                     /* Insert into standard sound 
  196.                      * task list at either input
  197.                      * or output.  This determines whether
  198.                      * this monitor will be monitoring the
  199.                      * microphone input or the speaker
  200.                      * output.
  201.                      */
  202.     if (streamLocation == SMMonitorInput)
  203.         patchPoint = kStdSndRecorder;
  204.     else
  205.         patchPoint = kStdSndPostProcessor;
  206.     err = StdSndInsertTask (soundStream, monitor->taskRef, patchPoint);
  207.     if (err != noErr)
  208.         return (NULL);
  209.  
  210.                     /* Get pointer to the DSP monitor 
  211.                      * parameters */
  212.     DSPGetSection(MonitorModule, "\pParams", §ion);
  213.     DSPGetSectionData (section, (Ptr *) &(monitor->dspParms));
  214.  
  215.                     /* set monitoring */
  216.     monitor->taskActive = FALSE;
  217.  
  218.     return (monitor);
  219. }
  220.  
  221. /*
  222.  *    SMDestroyDSPMonitor - Destroy the DSP monitor task.  When all done, remove
  223.  *    and dispose the DSP task that monitors the sound stream.
  224.  */
  225. long  SMDestroyDSPMonitor(monitor)
  226. DSPMonitor  monitor;
  227. {
  228.     long  zerror = NO_ERROR;
  229.     OSErr  err;
  230.  
  231.     if (monitor == NULL)
  232.         zerror = ERROR;
  233.  
  234.     err = DSPRemoveTask (monitor->taskRef);
  235.     if (err != noErr)
  236.         zerror = ERROR;
  237.  
  238.     err = DSPDisposeTask (monitor->taskRef);
  239.     if (err != noErr)
  240.         zerror = ERROR;
  241.  
  242.     DisposPtr ((Ptr) monitor);
  243.  
  244.     return (zerror);
  245. }
  246.  
  247. /*
  248.  *    SMStartDSPMonitor - Start a DSP task to monitor the sound.
  249.  */
  250. long  SMStartDSPMonitor(monitor)
  251. DSPMonitor  monitor;
  252. {
  253.     OSErr  err;
  254.  
  255.     err = DSPSetTaskActive (monitor->taskRef);
  256.     if (err != noErr)
  257.         return (ERROR);
  258.     monitor->taskActive = TRUE;
  259.  
  260.     return (NO_ERROR);
  261. }
  262.  
  263. /*
  264.  *    SMStopDSPMonitor - Stop a DSP task that is monitoring the sound.
  265.  */
  266. long  SMStopDSPMonitor(monitor)
  267. DSPMonitor  monitor;
  268. {
  269.     OSErr  err;
  270.  
  271.     err = DSPSetTaskInactive (monitor->taskRef);
  272.     if (err != noErr)
  273.         return (ERROR);
  274.     monitor->taskActive = FALSE;
  275.  
  276.     return (NO_ERROR);
  277. }
  278.  
  279. long  SMSetChannel(monitor, left, right)
  280. DSPMonitor        monitor;
  281. enum SMSetChannelParm    left, right;
  282. {
  283.     struct DSPMonitorParmStruct    *dspParms = monitor->dspParms;
  284.                         /* set left and right monitoring */
  285.     switch (left){
  286.     case SMChannelOff:            /* turn channel off */
  287.         dspParms->monitorLeft = FALSE;
  288.         break;
  289.  
  290.     case SMChannelOn:            /* turn channel on */
  291.         if (!(dspParms->monitorLeft))
  292.             dspParms->monitorLeft = TRUE;
  293.         break;
  294.     case SMChannelAddClient:        /* add client to left monitor */
  295.         dspParms->monitorLeft += 1;
  296.         break;
  297.     case SMChannelRemoveClient:        /* remove client from left monitor */
  298.         if (dspParms->monitorLeft)
  299.             dspParms->monitorLeft -= 1;
  300.         break;
  301.     default:                /* SMChannelDontChange : don't 
  302.                          * change channel state */
  303.         break;
  304.     }
  305.  
  306.     switch (right){
  307.     case SMChannelOff:            /* turn channel off */
  308.         dspParms->monitorRight = FALSE;
  309.         break;
  310.  
  311.     case SMChannelOn:            /* turn channel on */
  312.         if (!(dspParms->monitorRight))
  313.             dspParms->monitorRight = TRUE;
  314.         break;
  315.     case SMChannelAddClient:        /* add client to left monitor */
  316.         dspParms->monitorRight += 1;
  317.         break;
  318.     case SMChannelRemoveClient:        /* remove client from left monitor */
  319.         if (dspParms->monitorRight)
  320.             dspParms->monitorRight -= 1;
  321.         break;
  322.     default:                /* SMChannelDontChange: don't 
  323.                          * change channel state */
  324.         break;
  325.     }
  326.    
  327.             /* do we need to activate or deactivate task? */
  328.     if ((dspParms->monitorLeft || dspParms->monitorRight) &&
  329.         (monitor->taskActive == FALSE))
  330.         return SMStartDSPMonitor(monitor);
  331.  
  332.     if ((dspParms->monitorLeft == FALSE) &&
  333.         (dspParms->monitorRight == FALSE) &&
  334.         (monitor->taskActive == TRUE))
  335.         return SMStopDSPMonitor(monitor);
  336.  
  337.     return (NO_ERROR);
  338. }
  339.  
  340. static pascal void  DSPMonitorTaskHandler(){
  341. }
  342.  
  343. /* SoundMonitor.c */
  344.  
  345.