home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / CMIDI 2.2 / CMIDITimePort.cp < prev    next >
Encoding:
Text File  |  1994-11-30  |  8.2 KB  |  274 lines  |  [TEXT/KAHL]

  1. /*
  2.  *——— CMIDITimePort.cp —————————————————————————————————————————————————————————————————
  3.  * Copyright © Paul Ferguson, 1990-94.  All rights reserved.
  4.  *
  5.  * Description:
  6.  *    CMIDITimePort.c defines a MIDI Manager time port object.
  7.  *
  8.  *    For use with Symantec C++ 6.0, the accompanying THINK Class Library (TCL), and MIDI
  9.  *    Manager 2.0. Refer to the accompanying Microsoft Word document for complete
  10.  *    details about MIDI Manager objects.
  11.  *
  12.  *    If you have comments or questions about this code, you can reach me on
  13.  *    CompuServe at 70441,3055.
  14.  *
  15.  *——————————————————————————————————————————————————————————————————————————————————————
  16.  *———— NOTE ——— NOTE ——— NOTE ——— NOTE ——— NOTE ——— NOTE ——— NOTE ——— NOTE ——— NOTE ————
  17.  *——————————————————————————————————————————————————————————————————————————————————————
  18.  *    If you are not familiar with programming the Apple MIDI Manager, refer to the
  19.  *    "MIDI Management Tools" Version 2.0, available from APDA.  You MUST have the
  20.  *    software (MIDI.H and the library) from this package in order to use these objects.
  21.  *    It will not work without this.
  22.  *——————————————————————————————————————————————————————————————————————————————————————
  23.  *    REVISION HISTORY:
  24.  *        August ??, 1990            - Original release (1.0).
  25.  *        November 5, 1990        - Added checks for midiMgrVer to most methods.
  26.  *        August, 1991            - Updated for THINK C 5.0 as version 2.0
  27.  *        July, 1993                - Updated for Symantec C++ 6.0.
  28.  *——————————————————————————————————————————————————————————————————————————————————————
  29.  */
  30.  
  31. #include "CMIDITimePort.h"                    // This code's header file
  32. #include <CApplication.h>
  33.  
  34. extern CApplication *    gApplication;        // Used in SetConnection
  35. extern OSType            gSignature;            // Used to register client
  36. extern CMIDIClient *     gMIDIClient;        // Defined in CMIDIClient.c
  37.  
  38.  
  39. /*
  40.  *——— CMIDITimePort::IMIDITimePort —————————————————————————————————————————
  41.  * Initialize a time port object. This method sets up the MIDIPortParams
  42.  * data structure and calls CMIDIPort::IMIDIPort().
  43.  *——————————————————————————————————————————————————————————————————————————
  44.  */
  45.  
  46. OSErr CMIDITimePort::IMIDITimePort(StringPtr    theName,
  47.                                    OSType        thePortID,
  48.                                    Boolean        theVisibleFlag,
  49.                                    short        theFormat)
  50. {
  51.     MIDIPortParams    portParams;
  52.     OSErr            theResult;
  53.  
  54.     portParams.portID                = thePortID;
  55.     portParams.portType                = midiPortTypeTime;
  56.     if (theVisibleFlag == FALSE)
  57.     {
  58.         if (this->itsVersion >= 0x0200)
  59.             portParams.portType        |= midiPortInvisible;        // Use 2.0 preferred syntax
  60.         else
  61.             portParams.portType        = midiPortTypeTimeInv;        // Use 1.x syntax
  62.     }
  63.     portParams.timeBase                = 0;
  64.     portParams.offsetTime            = 0;
  65.     portParams.readHook                = (Ptr) 0;
  66.     portParams.refCon                = 0;
  67.     portParams.initClock.sync        = midiInternalSync;        // Always start out internal
  68.     portParams.initClock.curTime    = 0;
  69.     portParams.initClock.format        = theFormat;
  70.     BlockMove(theName, portParams.name, theName[0]+1);
  71.  
  72.     theResult = IMIDIPort(&portParams, 0);
  73.     if (theResult == noErr)
  74.     {
  75.         UpdateSync();        // Check for time base connections
  76.     }
  77.  
  78.     return theResult;
  79. }
  80.  
  81. /*
  82.  *——— CMIDITimePort::LoadPatches ————————————————————————————————————————————
  83.  * Load any time patches, and make connections.
  84.  * Patches are stored in the resource specified by the parameters. This may
  85.  * also return resNotFound error, which should be handled by the application.
  86.  *———————————————————————————————————————————————————————————————————————————
  87.  */
  88. OSErr CMIDITimePort::LoadPatches(ResType theResType, short theResID)
  89. {
  90.     OSErr                theErr = noErr;
  91.     MIDIPortInfoHdl        rsrcPortInfoH, ourPortInfoH;
  92.     short                i;
  93.     Str255                theName;
  94.  
  95.     if (this->itsVersion == 0)        // Couldn’t open the MIDI Manager for some reason
  96.         return ErrNoMIDI;
  97.  
  98.     if (this->itsResult != noErr)    // MM initialization had failed.
  99.         return this->itsResult;
  100.         
  101.     // Check for virtual connections stored in specified resource.    
  102.     // If resource not found, or wrong size return resource error.
  103.  
  104.     rsrcPortInfoH = (MIDIPortInfoHdl) GetResource(theResType, theResID);
  105.     if ( rsrcPortInfoH == (MIDIPortInfoHdl) 0 )
  106.         return resNotFound;
  107.  
  108.     // Make MIDI time connections.
  109.  
  110.     HLock((Handle) rsrcPortInfoH);
  111.     ourPortInfoH = GetPortInfo();
  112.     GetPortName(theName);
  113.     if ((**ourPortInfoH).type == (**rsrcPortInfoH).type)    // Is this resource a time port?
  114.     {
  115.         if ((**rsrcPortInfoH).timeBase.clientID != kNoClient)    // Were we supposed to be synchronized
  116.         {                                                        // to another client?
  117.             theErr = MIDIConnectTime(
  118.                         (**rsrcPortInfoH).timeBase.clientID,     // Yes, make that client our time base
  119.                         (**rsrcPortInfoH).timeBase.portID,
  120.                         gSignature,
  121.                         itsPortID);
  122.             if (theErr != midiVConnectErr)        // Is client still signed in?
  123.                 SetExternalSync();
  124.         }
  125.  
  126.         // Were we someone else's time base?
  127.  
  128.         for (i = 0; i < (**rsrcPortInfoH).numConnects; ++i)
  129.         {
  130.             theErr = MIDIConnectTime(gSignature, // We are the time base for them
  131.                         itsPortID,
  132.                         (**rsrcPortInfoH).cList[i].clientID,
  133.                         (**rsrcPortInfoH).cList[i].portID);
  134.             if (theErr) break;
  135.         }
  136.     }
  137.     HUnlock((Handle) rsrcPortInfoH);
  138.     ReleaseResource((Handle) rsrcPortInfoH);
  139.  
  140.     return theErr;
  141. }
  142.  
  143.  
  144. /*
  145.  *——— CMIDITimePort::UpdateSync ———————————————————————————————————————
  146.  * Set internal or external time base synchronization depending on
  147.  * current connections.  It returns the current synchronization setting
  148.  * (same as GetSync).
  149.  *—————————————————————————————————————————————————————————————————————
  150.  */
  151.  
  152. short CMIDITimePort::UpdateSync(void)
  153. {
  154.     MIDIPortInfoHdl        thePortInfoH;
  155.     register short        theResult;
  156.  
  157.     thePortInfoH = GetPortInfo();
  158.  
  159.     if (thePortInfoH)
  160.     {
  161.         theResult = GetSync();
  162.         if ( (**thePortInfoH).timeBase.clientID != kNoClient )
  163.         {
  164.             if (theResult != midiExternalSync)
  165.                 SetExternalSync();
  166.         }
  167.         else
  168.         {
  169.             if (theResult != midiInternalSync)
  170.                 SetInternalSync();
  171.         }
  172.         DisposHandle((Handle) thePortInfoH);
  173.     }
  174.     return (itsVersion ? MIDIGetSync(itsRefNum) : -1);
  175. }
  176.  
  177.  
  178. /*
  179.  *——— CMIDITimePort::Perform ——————————————————————————————————————
  180.  * This turns the time port into a CChore, so that you can call
  181.  * gApplication->AssignIdleChore() with this object.
  182.  *—————————————————————————————————————————————————————————————————
  183.  */
  184.  
  185. void CMIDITimePort::Perform(long * maxSleep)
  186. {
  187.     if ( gMIDIClient->WorldChanged() )
  188.         UpdateSync();
  189. }
  190.  
  191.  
  192. /*
  193.  *——— CMIDITimePort::SetConnection ————————————————————————————————
  194.  * This sets the connection procedure. Note that for pre-2.0 or
  195.  * a NULL connectionProc, the previous method, Perform(), will
  196.  * called at idle time, checking for a change in the wind.
  197.  *—————————————————————————————————————————————————————————————————
  198.  */
  199.  
  200. void CMIDITimePort::SetConnection(ProcPtr theConnectionProc)
  201. {
  202.     if ((gMIDIClient->GetShortVerNum() < 0x200 )        // If pre-2.0
  203.         || (theConnectionProc == NULL) )                // or a null pointer
  204.         gApplication->AssignIdleChore( (CChore *) this );
  205.     else                                                // else use connection proc
  206.         SetConnectionProc(theConnectionProc, GetRefCon());
  207. }
  208.  
  209.  
  210. /*
  211.  *——— CMIDITimePort:: trivial methods —————————————————————————————
  212.  * These are not inlined, because they are not likely to be
  213.  * called in a time critical situation--time base synchronization
  214.  * doesn't change often.
  215.  *—————————————————————————————————————————————————————————————————
  216.  */
  217.  
  218. short CMIDITimePort::GetSync(void)
  219. {
  220.     return (itsVersion ? MIDIGetSync(itsRefNum) : -1);
  221. }
  222.  
  223. void CMIDITimePort::SetExternalSync(void)
  224. {
  225.     if (itsVersion)
  226.         MIDISetSync(itsRefNum, midiExternalSync);
  227. }
  228.  
  229. void CMIDITimePort::SetInternalSync(void)
  230. {
  231.     if (itsVersion)
  232.         MIDISetSync(itsRefNum, midiInternalSync);
  233. }
  234.  
  235. #ifndef __cplusplus
  236.  
  237.     // if using THINK C compiler, not Symantec C++, these are non-inline methods.
  238.  
  239.     long CMIDITimePort::GetCurTime(void)
  240.     {
  241.         return (itsVersion ? MIDIGetCurTime(itsRefNum) : 0);
  242.     }
  243.     
  244.     void CMIDITimePort::SetCurTime(long theTime)
  245.     {
  246.         if (itsVersion) MIDISetCurTime(itsRefNum, theTime);
  247.     }
  248.     
  249.     void CMIDITimePort::StartTime(void)
  250.     {
  251.         if (itsVersion) MIDIStartTime(itsRefNum); 
  252.     }
  253.     void CMIDITimePort::StopTime(void)
  254.     {
  255.         if (itsVersion) MIDIStopTime(itsRefNum);
  256.     }
  257.     
  258.     long CMIDITimePort::GetOffsetTime(void)
  259.     {
  260.         return (itsVersion ? MIDIGetOffsetTime(itsRefNum) : 0);
  261.     }
  262.     
  263.     void CMIDITimePort::SetOffsetTime(long theOffset)
  264.     {
  265.         if (itsVersion) MIDISetOffsetTime(itsRefNum, theOffset);
  266.     }
  267.     
  268.     void CMIDITimePort::WakeUp(long theBaseTime, long thePeriod, ProcPtr theTimeProc)
  269.     {
  270.         if (itsVersion) MIDIWakeUp(itsRefNum, theBaseTime, thePeriod, theTimeProc);
  271.     }
  272. #endif
  273. // end of CMIDITimePort.cp
  274.