home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Extras / MIDI / camd-37.1 / development / include / midi / camd.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  20.4 KB  |  561 lines

  1. #ifndef MIDI_CAMD_H
  2. #define MIDI_CAMD_H
  3. /************************************************************************
  4. *     C. A. M. D.       (Commodore Amiga MIDI Driver)                   *
  5. *************************************************************************
  6. *                                                                       *
  7. * Design & Development  - Roger B. Dannenberg                           *
  8. *                       - Jean-Christophe Dhellemmes                    *
  9. *                       - Bill Barton                                   *
  10. *                       - Darius Taghavy                                *
  11. *                                                                       *
  12. * Copyright 1990-1999 by Amiga, Inc.                                    *
  13. *************************************************************************
  14. *
  15. * camd.h      - General CAMD include files.
  16. *             - General CAMD definitions.
  17. *
  18. ************************************************************************/
  19.  
  20. #ifndef EXEC_LISTS_H
  21.   #include <exec/lists.h>
  22. #endif
  23.  
  24. #ifndef EXEC_TYPES_H
  25.   #include <exec/types.h>
  26. #endif
  27.  
  28. #ifndef UTILITY_TAGITEM_H
  29.   #include <utility/tagitem.h>
  30. #endif
  31.  
  32. #if 0       /* !!! old */
  33.  
  34. /***************************************************************
  35. *
  36. *   Library Name and Version
  37. *
  38. ***************************************************************/
  39.  
  40. #define CamdName    "camd.library"
  41. #define CamdVersion 2
  42.  
  43. #endif
  44.  
  45.  
  46. /***************************************************************
  47. *
  48. *   CAMD internal lists that can be locked
  49. *
  50. ***************************************************************/
  51.  
  52. enum {
  53.     CD_Linkages,                                /* internal linages */
  54.     CD_NLocks
  55. };
  56.  
  57. #if 0       /* !!! old */
  58. /***************************************************************
  59. *
  60. *   MIDI Port Definitions
  61. *
  62. *   The default Unit Ports are:
  63. *
  64. *              ports
  65. *       unit  in  out
  66. *       ----  --  ---
  67. *        0     1   0
  68. *        1     3   2
  69. *        2     5   4
  70. *        3     6   5
  71. *
  72. *   These are the values returned by CMP_Out() and CMP_In().
  73. *
  74. *   User ports are allocated starting at CMP_Max and descending.
  75. *
  76. ***************************************************************/
  77.  
  78. #define CMP_Out(unit)   ((unit) * 2)            /* Default port # of MIDI Output */
  79. #define CMP_In(unit)    (CMP_Out(unit) + 1)     /* Default port # of MIDI Input */
  80. #define CMP_Max         31                      /* highest port # */
  81. #endif
  82.  
  83. /***************************************************************
  84. *
  85. *   MidiMsg
  86. *
  87. ***************************************************************/
  88.  
  89. typedef union
  90. {
  91.     ULONG l[2];
  92.     UBYTE b[4];
  93. } MidiMsg;
  94.  
  95.     /* MidiMsg field definitions */
  96. #define mm_Msg    l[0]
  97. #define mm_Time   l[1]
  98. #define mm_Status b[0]
  99. #define mm_Data1  b[1]
  100. #define mm_Data2  b[2]
  101. #define mm_Port   b[3]
  102. #define mm_Data   b
  103.  
  104.     /* MidiMsg macros for quick message type detection.  MidiMsgType()
  105.        generally gives more precise results. */
  106.  
  107. #define voicemsg(m,a)   ( ((m)->mm_Status & MS_StatBits) == (a) )
  108. #define sysmsg(m)       ( (m)->mm_Status >= MS_System )
  109. #define noteon(m)       ( voicemsg(m,MS_NoteOn) && (m)->mm_Data2 )
  110. #define realtime(m)     ( (m)->mm_Status >= MS_RealTime )
  111. #define modemsg(m)      ( voicemsg(m,MS_Ctrl) && (m)->mm_Data1 >= MM_Min )
  112.  
  113. /***************************************************************
  114. *
  115. *   MidiCluster -- a meeting place for linkages
  116. *
  117. *   All fields are READ ONLY.  Modifications to fields may
  118. *   performed only through the appropriate library function
  119. *   calls.
  120. *
  121. ***************************************************************/
  122.  
  123. struct MidiCluster {
  124.     struct Node         mcl_Node;               /* linked list node */
  125.     WORD                mcl_Participants;
  126.     struct List         mcl_Receivers,          /* list of receivers */
  127.                         mcl_Senders;            /* list of senders */
  128.     WORD                mcl_PublicParticipants; /* if >0, cluster is public */
  129.     UWORD               mcl_Flags;              /* flags for this location */
  130.         /* NOTE: Cluster name follows structure, and is pointed to by ln_Name */
  131. };
  132.  
  133. /***************************************************************
  134. *
  135. *   MidiLink -- links a cluster and a MidiNode
  136. *
  137. *   All fields are READ ONLY.  Modifications to fields may
  138. *   performed only through the appropriate library function
  139. *   calls.
  140. *
  141. ***************************************************************/
  142.  
  143. struct MidiLink {
  144.     struct Node         ml_Node;                /* node for cluster list */
  145.     WORD                ml_Pad;
  146.     struct MinNode      ml_OwnerNode;           /* node for interface list */
  147.     struct MidiNode     *ml_MidiNode;           /* interface we belong to... */
  148.     struct MidiCluster  *ml_Location;           /* location we are a member of */
  149.     char                *ml_ClusterComment;     /* comment for cluster */
  150.     UBYTE               ml_Flags;               /* general flags */
  151.     UBYTE               ml_PortID;              /* number of this port */
  152.     UWORD               ml_ChannelMask;         /* mask flags for channel */
  153.     ULONG               ml_EventTypeMask;       /* mask flags for events */
  154.  
  155.     union SysExFilter {
  156.         UBYTE           b[4];                   /* 1 byte mode, 3 bytes for match id(s) */
  157.         ULONG           sxf_Packed;
  158.     } ml_SysExFilter;
  159.  
  160.     APTR                ml_ParserData;          /* private MIDI parser data */
  161.     APTR                ml_UserData;            /* attached to events... */
  162. };
  163.  
  164.     /* SysExFilter members */
  165. #define sxf_Mode b[0]           /* SXFM_ mode bits */
  166. #define sxf_ID1  b[1]           /* 3 1-byte id's or 1 3-byte id */
  167. #define sxf_ID2  b[2]
  168. #define sxf_ID3  b[3]
  169.  
  170.     /* MidiLink types */
  171. enum {
  172.     MLTYPE_Receiver,
  173.     MLTYPE_Sender,
  174.     MLTYPE_NTypes
  175. };
  176.  
  177.     /* ml_Flags */
  178. #define MLF_Sender      (1<<0)                  /* this link sends from app */
  179. #define MLF_PartChange  (1<<1)                  /* part change pending */
  180. #define MLF_PrivateLink (1<<2)                  /* make this link private */
  181. #define MLF_DeviceLink  (1<<3)                  /* set by devices only! */
  182.  
  183.     /* MidiLink tags */
  184. #define MLINK_Base          TAG_USER+65
  185.  
  186. #define MLINK_Location      (MLINK_Base+0)      /* rendezvous point */
  187. #define MLINK_ChannelMask   (MLINK_Base+1)      /* channel mask bits */
  188. #define MLINK_EventMask     (MLINK_Base+2)      /* event type mask bits */
  189. #define MLINK_UserData      (MLINK_Base+3)      /* user data for incoming events */
  190. #define MLINK_Comment       (MLINK_Base+4)      /* comment for cluster */
  191. #define MLINK_PortID        (MLINK_Base+5)      /* port id number for MidiMsg */
  192. #define MLINK_Private       (MLINK_Base+6)      /* not a public link */
  193. #define MLINK_Priority      (MLINK_Base+7)      /* priority of node */
  194. /* REM: Add tags to change Sysex filter stuff...*/
  195. #define MLINK_SysExFilter   (MLINK_Base+8)      /* three 1-byte headers */
  196. #define MLINK_SysExFilterX  (MLINK_Base+9)      /* one 3-byte header */
  197. #define MLINK_Parse         (MLINK_Base+10)     /* want a MIDI parser */
  198. #define MLINK_Reserved      (MLINK_Base+11)     /* reserved */
  199. #define MLINK_ErrorCode     (MLINK_Base+12)     /* (ULONG *) - Error Code buffer for returning CME_ error codes. */
  200. #define MLINK_Name          (MLINK_Base+13)     /* (STRPTR) - Link name */
  201.  
  202.  
  203. /***************************************************************
  204. *
  205. *   SysExFilter modes
  206. *
  207. *   Contents of sxf_Mode.
  208. *
  209. *   Bit packed as follows: 00000mcc
  210. *       m  - mode bit
  211. *       cc - count bits 0 - 3 (only used for SXFM_1Byte)
  212. *
  213. ***************************************************************/
  214.  
  215. #define SXF_ModeBits    0x04
  216. #define SXF_CountBits   0x03        /* mask for count bits for SXFM_1Byte */
  217.  
  218. #define SXFM_Off        0x00        /* don't filter (equal to SXFM_1Byte | 0) */
  219. #define SXFM_1Byte      0x00        /* match upto 3 1-byte id's */
  220. #define SXFM_3Byte      0x04        /* match a single 3-byte id */
  221.  
  222.  
  223. /***************************************************************
  224. *
  225. *   MidiNode
  226. *
  227. *   All fields are READ ONLY.  Modifications to fields may
  228. *   performed only through the appropriate library function
  229. *   calls.
  230. *
  231. ***************************************************************/
  232.  
  233. struct MidiNode
  234. {
  235.     struct Node         mi_Node;                /* linked list node */
  236.     UWORD               mi_ClientType;          /* type of application */
  237.     struct Image        *mi_Image;              /* image for patch panel */
  238.  
  239.     struct MinList      mi_OutLinks,            /* list of output links */
  240.                         mi_InLinks;             /* list of input links */
  241.  
  242.     struct Task         *mi_SigTask;            /* task to signal */
  243.     struct Hook         *mi_ReceiveHook,        /* hook (and list node) */
  244.                         *mi_ParticipantHook;    /* hook for participant change */
  245.     BYTE                mi_ReceiveSigBit,       /* signalmask for new data */
  246.                         mi_ParticipantSigBit;   /* signalmask for part change */
  247.     UBYTE               mi_ErrFilter;           /* CMEF_ error filter for ErrFlags */
  248.     UBYTE               mi_Alignment[1];        /* for longword alignment */
  249.  
  250.     ULONG               *mi_TimeStamp;          /* where timestamps come from */
  251.  
  252.     ULONG               mi_MsgQueueSize,        /* size of buffers */
  253.                         mi_SysExQueueSize;
  254.  
  255.     /* private stuff below here */
  256. };
  257.  
  258.         /* client types */
  259. #define CCType_Sequencer        (1<<0)
  260. #define CCType_SampleEditor     (1<<1)
  261. #define CCType_PatchEditor      (1<<2)
  262. #define CCType_Notator          (1<<3)          /* transcription of MIDI notes  */
  263. #define CCType_EventProcessor   (1<<4)          /* any data altering functions  */
  264. #define CCType_EventFilter      (1<<5)
  265. #define CCType_EventRouter      (1<<6)          /* e.g MIDI thru task */
  266. #define CCType_ToneGenerator    (1<<7)          /* i.e.using Amiga to make sound*/
  267. #define CCType_EventGenerator   (1<<8)          /* e.g algorithmic composition */
  268. #define CCType_GraphicAnimator  (1<<9)          /* e.g syncing animation software to MIDI */
  269.  
  270.         /* Tags for CreateMidi() and SetMidiAttrs() */
  271. #define MIDI_Base               (TAG_USER+65)
  272. #define MIDI_Name               (MIDI_Base+0)   /* name of application */
  273. #define MIDI_SignalTask         (MIDI_Base+1)   /* task to signal if not this one*/
  274. #define MIDI_RecvHook           (MIDI_Base+2)   /* hook for incoming data */
  275. #define MIDI_PartHook           (MIDI_Base+3)   /* hook for participant change */
  276. #define MIDI_RecvSignal         (MIDI_Base+4)   /* signal to use if incoming */
  277. #define MIDI_PartSignal         (MIDI_Base+5)   /* signal to use if incoming */
  278. #define MIDI_MsgQueue           (MIDI_Base+6)   /* size of event buffer */
  279. #define MIDI_SysExSize          (MIDI_Base+7)   /* size of sysex buffer */
  280. #define MIDI_TimeStamp          (MIDI_Base+8)   /* timer to timestamp with */
  281. #define MIDI_ErrFilter          (MIDI_Base+9)   /* error filter bits */
  282. #define MIDI_ClientType         (MIDI_Base+10)  /* client type mask */
  283. #define MIDI_Image              (MIDI_Base+11)  /* application image */
  284. #define MIDI_ErrorCode          (MIDI_Base+12)  /* (ULONG *) - Error Code buffer for returning CME_ error codes. */
  285.  
  286.  
  287. /***************************************************************
  288. *
  289. *   CreateMidi() Error Codes
  290. *
  291. *   These are the IoErr() codes that CreateMidi() can return
  292. *   on failure.
  293. *
  294. *   !!! need specific error code set for each function instead!
  295. *
  296. ***************************************************************/
  297.  
  298. #define CME_NoMem     801       /* memory allocation failed */
  299. #define CME_NoSignals 802       /* signal allocation failed */
  300. #define CME_NoTimer   803       /* timer (CIA) allocation failed */
  301. #define CME_BadPrefs  804       /* badly formed midi.prefs file */
  302.  
  303. #define CME_NoUnit(unit) (820 + (unit)) /* unit open failure */
  304.  
  305.  
  306. #if 0       /* !!! old */
  307. /***************************************************************
  308. *
  309. *   MidiNode tag items for use with CreateMidi().
  310. *
  311. ***************************************************************/
  312.  
  313. #define CMA_base        (TAG_USER + 64)
  314.  
  315. #define CMA_SysEx       (CMA_base + 0)  /* int - allocate a sys/ex buffer,
  316.                                            ti_Data specifies size in bytes.
  317.                                            Default is 0.  Only valid if
  318.                                            RecvSize is non-zero. */
  319.  
  320. #define CMA_Parse       (CMA_base + 1)  /* bool - enable usage of ParseMidi().
  321.                                            Default is FALSE. */
  322.  
  323. #define CMA_Alarm       (CMA_base + 2)  /* bool - enable usage of SetMidiAlarm().
  324.                                            Also allocates AlarmSigBit.  Default is FALSE. */
  325.  
  326. #define CMA_SendPort    (CMA_base + 3)  /* int - initial SendPort.  Default is CMP_Out(0). */
  327.  
  328. #define CMA_PortFilter  (CMA_base + 4)  /* int - initial PortFilter.  Default is 0. */
  329.  
  330. #define CMA_TypeFilter  (CMA_base + 5)  /* int - initial TypeFilter.  Default is 0. */
  331.  
  332. #define CMA_ChanFilter  (CMA_base + 6)  /* int - initial ChanFilter.  Default is 0. */
  333.  
  334. #define CMA_SysExFilter (CMA_base + 7)  /* packed - initial SysExFilter as returned
  335.                                            by one of the PackSysExFilterN() macros.
  336.                                            Default is no filtering (i.e. recv all). */
  337.  
  338. #define CMA_ErrFilter   (CMA_base + 8)  /* int - initial ErrFilter.  Default is 0. */
  339. #endif
  340.  
  341.  
  342. /***************************************************************
  343. *
  344. *   MIDI Message Type Bits
  345. *
  346. *   Returned by MidiMsgType() and used with SetMidiFilters().
  347. *
  348. ***************************************************************/
  349.  
  350. #define CMB_Note        0
  351. #define CMB_Prog        1
  352. #define CMB_PitchBend   2
  353.  
  354. #define CMB_CtrlMSB     3
  355. #define CMB_CtrlLSB     4
  356. #define CMB_CtrlSwitch  5
  357. #define CMB_CtrlByte    6
  358. #define CMB_CtrlParam   7
  359. #define CMB_CtrlUndef   8       /* for future ctrl # expansion */
  360.  
  361. #define CMB_Mode        9
  362. #define CMB_ChanPress   10
  363. #define CMB_PolyPress   11
  364.  
  365. #define CMB_RealTime    12
  366. #define CMB_SysCom      13
  367. #define CMB_SysEx       14
  368.  
  369.     /* (these need to be long for SetMidiFilters()) */
  370. #define CMF_Note        (1L << CMB_Note)
  371. #define CMF_Prog        (1L << CMB_Prog)
  372. #define CMF_PitchBend   (1L << CMB_PitchBend)
  373.  
  374. #define CMF_CtrlMSB     (1L << CMB_CtrlMSB)
  375. #define CMF_CtrlLSB     (1L << CMB_CtrlLSB)
  376. #define CMF_CtrlSwitch  (1L << CMB_CtrlSwitch)
  377. #define CMF_CtrlByte    (1L << CMB_CtrlByte)
  378. #define CMF_CtrlParam   (1L << CMB_CtrlParam)
  379. #define CMF_CtrlUndef   (1L << CMB_CtrlUndef)
  380.  
  381. #define CMF_Mode        (1L << CMB_Mode)
  382. #define CMF_ChanPress   (1L << CMB_ChanPress)
  383. #define CMF_PolyPress   (1L << CMB_PolyPress)
  384.  
  385. #define CMF_RealTime    (1L << CMB_RealTime)
  386. #define CMF_SysCom      (1L << CMB_SysCom)
  387. #define CMF_SysEx       (1L << CMB_SysEx)
  388.  
  389.     /* some handy type macros */
  390.  
  391. #define CMF_Ctrl        (CMF_CtrlMSB | CMF_CtrlLSB | CMF_CtrlSwitch | CMF_CtrlByte | CMF_CtrlParam | CMF_CtrlUndef)
  392. #define CMF_Channel     (CMF_Note | CMF_Prog | CMF_PitchBend | CMF_Ctrl | CMF_Mode | CMF_ChanPress | CMF_PolyPress)
  393. #define CMF_All         (CMF_Channel | CMF_RealTime | CMF_SysCom | CMF_SysEx)
  394.  
  395.  
  396. /***************************************************************
  397. *
  398. *   MIDI Error Flags
  399. *
  400. *   These are error flags that can arrive at a MidiNode.
  401. *   An application may choose to ignore or process any
  402. *   combination of error flags.  See SetMidiErrFilter() and
  403. *   GetMidiErr() for more information.
  404. *
  405. ***************************************************************/
  406.  
  407. #define CMEB_MsgErr         0   /* invalid message was sent */
  408. #define CMEB_BufferFull     1   /* MidiBuffer is full */
  409. #define CMEB_SysExFull      2   /* SysExBuffer is full */
  410. #define CMEB_ParseMem       3   /* sys/ex memory allocation failure during parse */
  411. #define CMEB_RecvErr        4   /* serial receive error */
  412. #define CMEB_RecvOverflow   5   /* serial receive buffer overflow */
  413. #define CMEB_SysExTooBig    6   /* Attempt to send a sys/ex message bigger than SysExBuffer */
  414.  
  415. #define CMEF_MsgErr         (1L << CMEB_MsgErr)
  416. #define CMEF_BufferFull     (1L << CMEB_BufferFull)
  417. #define CMEF_SysExFull      (1L << CMEB_SysExFull)
  418. #define CMEF_ParseMem       (1L << CMEB_ParseMem)
  419. #define CMEF_RecvErr        (1L << CMEB_RecvErr)
  420. #define CMEF_RecvOverflow   (1L << CMEB_RecvOverflow)
  421. #define CMEF_SysExTooBig    (1L << CMEB_SysExTooBig)
  422.  
  423.     /* a handy macro for SetMidiErrFilter() */
  424. #define CMEF_All            (CMEF_MsgErr | CMEF_BufferFull | CMEF_SysExFull | CMEF_SysExTooBig | CMEF_ParseMem | CMEF_RecvErr | CMEF_RecvOverflow)
  425.  
  426.  
  427. #if 0   /* !!! old */
  428. /***************************************************************
  429. *
  430. *   MidiTickHookMsg
  431. *
  432. *   Message structure passed to Tick Hooks
  433. *
  434. ***************************************************************/
  435.  
  436. struct MidiTickHookMsg
  437. {
  438.     ULONG ID;                   /* msg ID (always MTHM_Tick for now) */
  439.     ULONG Time;                 /* Time at tick */
  440. };
  441.  
  442. enum
  443. {
  444.     MTHM_Tick
  445. };
  446.  
  447.  
  448. /***************************************************************
  449. *
  450. *   MidiByteHookMsg
  451. *
  452. *   Message structure passed to Byte Hooks
  453. *
  454. ***************************************************************/
  455.  
  456. struct MidiByteHookMsg
  457. {
  458.     ULONG ID;                   /* msg ID (always MBHM_Byte for now) */
  459.     UBYTE UnitNum;              /* Midi Unit number where byte was received */
  460.     UBYTE pad0;
  461.     UWORD RecvData;             /* Data as it was received by the serial hardware.
  462.                                    Bits 0-7 are the MIDI byte.  Bit 15, when set,
  463.                                    indicates a hardware receive error. */
  464. };
  465.  
  466. enum
  467. {
  468.     MBHM_Byte
  469. };
  470. #endif
  471.  
  472. /***************************************************************
  473. *
  474. *   Hook Message ID's
  475. *
  476. *   Each Hook passes as the "msg" param a pointer to one of these (LONG)
  477. *   Can be extended for some types of messages
  478. *
  479. ***************************************************************/
  480.  
  481. enum {
  482.     CMSG_Recv,                  /* receive MIDI message                 */
  483.     CMSG_Link                   /* a linkage notification               */
  484. };
  485.  
  486.  
  487. /***************************************************************
  488. *
  489. *   CMSG_Link structure
  490. *
  491. ***************************************************************/
  492.  
  493. struct cmLink {
  494.     ULONG    cml_MethodID;
  495.     ULONG    cml_Action;
  496. };
  497.  
  498. enum {
  499.     CACT_Link,
  500.     CACT_Unlink
  501. };
  502.  
  503. /***************************************************************
  504. *
  505. *   ClusterNotifyNode
  506. *
  507. ***************************************************************/
  508.  
  509. struct ClusterNotifyNode {
  510.     struct MinNode  cnn_Node;        /* the usual node        */
  511.     struct Task        *cnn_Task;        /* task to signal        */
  512.     BYTE        cnn_SigBit;        /* sigbit to use        */
  513.     UBYTE        pad[3];
  514. };
  515.  
  516. /***************************************************************
  517. *
  518. *   CAMD Macros
  519. *
  520. *   See camd.doc for info.
  521. *
  522. ***************************************************************/
  523.  
  524. #define PackSysExFilter0()              ((ULONG)SXFM_Off << 24)
  525. #define PackSysExFilter1(id1)           ((ULONG)(SXFM_1Byte | 1) << 24 | (ULONG)(id1) << 16)
  526. #define PackSysExFilter2(id1,id2)       ((ULONG)(SXFM_1Byte | 2) << 24 | (ULONG)(id1) << 16 | (id2) << 8)
  527. #define PackSysExFilter3(id1,id2,id3)   ((ULONG)(SXFM_1Byte | 3) << 24 | (ULONG)(id1) << 16 | (id2) << 8 | (id3))
  528.  
  529. #define PutMidiMsg(ml,msg)              PutMidi((ml),(msg)->l[0])
  530.  
  531. #if 0       /* !!! old */
  532.     /* ---- MidiNode */
  533. #define PackSysExFilterX(xid)           ((ULONG)SXFM_3Byte << 24 | (xid))
  534.  
  535. #define ClearSysExFilter(mi)            SetSysExFilter ((mi), PackSysExFilter0())
  536. #define SetSysExFilter1(mi,id1)         SetSysExFilter ((mi), PackSysExFilter1(id1))
  537. #define SetSysExFilter2(mi,id1,id2)     SetSysExFilter ((mi), PackSysExFilter2(id1,id2))
  538. #define SetSysExFilter3(mi,id1,id2,id3) SetSysExFilter ((mi), PackSysExFilter3(id1,id2,id3))
  539. #define SetSysExFilterX(mi,xid)         SetSysExFilter ((mi), PackSysExFilterX(xid))
  540.  
  541. #define ClearSysExQueue(mi)             SetSysExQueue ((mi), NULL, 0L)
  542.  
  543.     /* ---- Message */
  544.     /* REM: These macros no longer exist... */
  545.     /* REM: We'll need to define a new macro to put MIDI bytes directly to a port */
  546. /* #define PutMidi(mi,msg)                 PutMidiToPort ((msg)->mm_Msg & ~0xff | (mi)->SendPort) */
  547. /* #define PutSysEx(mi,data)               PutSysExToPort ((long)(mi)->SendPort, data) */
  548.  
  549.     /* ---- Unit */
  550. #define GetMidiInPort(unit)             SetMidiInPort ((long)(unit), -1L)
  551. #define GetMidiOutMask(unit)            SetMidiOutMask ((long)(unit), 0L, 0L)
  552. #define AndMidiOutMask(unit,mask)       SetMidiOutMask ((long)(unit), 0L, ~(ULONG)mask)
  553. #define OrMidiOutMask(unit,mask)        SetMidiOutMask ((long)(unit), -1L, (ULONG)mask)
  554. #define MidiThru(unit,enable)           SetMidiOutMask ((long)(unit), (enable) ? -1L : 0L, 1L << CMP_Out(unit))
  555.  
  556.     /* ---- Timer */
  557. #define ClearMidiAlarm(mi)              SetMidiAlarm ((mi),0L)
  558. #endif
  559.  
  560. #endif /* MIDI_CAMD_H */
  561.