home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / MIDI Manager Class Library / CMIDITimePort.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-04  |  7.7 KB  |  259 lines  |  [TEXT/KAHL]

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