Aros/Developer/Docs/Libraries/CAMD

      Introduction

      Commodore Amiga MIDI Driver (CAMD) is a shared library for AmigaOS which provides a general device driver for MIDI data, so that applications can share MIDI data with each other in real-time, and interface to MIDI hardware in a device-independent way.

      AmigaOS itself did not support MIDI until release 3.1 when Roger Dannenberg's CAMD library was adapted as the standard MIDI API. Commodore's version of CAMD also included a built-in driver for the Amiga serial port.

      Read more here



      ↑Jump back a section

      Examples

      
      
      #include <stdio.h>
      #include <proto/exec.h>
      #include <proto/camd.h>
      #include <midi/camd.h>
      
      #define TABSIZE 4
      
      struct Library *CamdBase=NULL;
      
      #ifndef GetMidiLinkAttrs
      ULONG GetMidiLinkAttrs(struct MidiLink *ml, Tag tag, ...){
              return GetMidiLinkAttrsA(ml, (struct TagItem *)&tag );
      }
      #endif
      
      #ifndef GetMidiAttrs
      ULONG GetMidiAttrs(struct MidiNode *ml, Tag tag, ...){
              return GetMidiAttrsA(ml, (struct TagItem *)&tag );
      }
      #endif
      
      struct MidiLink *GetMidiLinkFromOwnerNode(struct MinNode *node){
              struct MidiLink dummy;
              return (struct MidiLink *)((char *)((char *)(node)-((char *)&dummy.ml_OwnerNode-(char *)&dummy)));
      }
      
      void printSpaces(int level){
              int lokke;
              for(lokke=0;lokke<level*TABSIZE;lokke++){
                      printf(" ");
              }
      }
      
      void printLink_brancheNodes(struct MidiLink *midilink,int level,int maxlevel);
      void printLink_brancheClusters(struct MidiLink *midilink,int level,int maxlevel);
      void printCluster(struct MidiCluster *cluster,int level,int maxlevel);
      
      
      void printNode(struct MidiNode *midinode,int level,int maxlevel){
              char *nodename=NULL;
              struct MinNode *node;
      
              if(level==maxlevel) return;
      
              GetMidiAttrs(midinode,MIDI_Name,(IPTR)&nodename,TAG_END);
      
              printSpaces(level);
              printf(
                      "%p, -%s-\n",
                      midinode,
                      nodename
              );
      
              if(level+1==maxlevel) return;
      
              if( ! (IsListEmpty((struct List *)&midinode->mi_OutLinks))){
                      printSpaces(level);
                      printf("  -OutLinks:\n");
                      node=midinode->mi_OutLinks.mlh_Head;
                      while(node->mln_Succ!=NULL){
                              printLink_brancheClusters(GetMidiLinkFromOwnerNode(node),level+1,maxlevel);
                              node=node->mln_Succ;
                      }
              }
      
              if( ! (IsListEmpty((struct List *)&midinode->mi_InLinks))){
                      printSpaces(level);
                      printf("  -InLinks:\n");
                      node=midinode->mi_InLinks.mlh_Head;
                      while(node->mln_Succ!=NULL){
                              printLink_brancheClusters(GetMidiLinkFromOwnerNode(node),level+1,maxlevel);
                              node=node->mln_Succ;
                      }
              }
      }
      
      
      BOOL printLink(struct MidiLink *midilink){
              char *linkname=NULL;
      
              if(midilink->ml_Node.ln_Type==NT_USER-MLTYPE_Receiver || midilink->ml_Node.ln_Type==NT_USER-MLTYPE_Sender){
                      GetMidiLinkAttrs(midilink,MLINK_Name,(IPTR)&linkname,TAG_END);
                      printf(
                              "%p, -%s-\n",
                              midilink,
                              linkname
                      );
                      return TRUE;
              }
      
              printf("%p, <driverdata> (private)\n",midilink);
              return FALSE;
      }
      
      void printLink_brancheNodes(struct MidiLink *midilink,int level,int maxlevel){
              struct MidiNode *midinode;
      
              if(level==maxlevel) return;
      
              printSpaces(level);
              if(printLink(midilink)==TRUE){
                      midinode=midilink->ml_MidiNode;
                      printSpaces(level);
                      printf("  -Owner (MidiNode): \n");
                      printNode(midinode,level+1,maxlevel);
              }
      }
      
      void printLink_brancheClusters(struct MidiLink *midilink,int level,int maxlevel){
              if(level==maxlevel) return;
      
              printSpaces(level);
              printLink(midilink);
      
              if(level+1==maxlevel) return;
      
              printSpaces(level);
              printf("  -Cluster: \n");
              printCluster(midilink->ml_Location,level+1,maxlevel);
      }
      
      
      void printCluster(struct MidiCluster *cluster,int level,int maxlevel){
              struct MidiLink *midilink;
      
              if(level==maxlevel) return;
      
              printSpaces(level);
              printf("clustername: -%s-\n",cluster->mcl_Node.ln_Name);
      
              if(level+1==maxlevel) return;
      
              if(!(IsListEmpty(&cluster->mcl_Receivers))){
                      printSpaces(level);
                      printf("  ");
                      printf("-Receiver links:\n");
      
                      midilink=(struct MidiLink *)cluster->mcl_Receivers.lh_Head;
                      while(midilink->ml_Node.ln_Succ!=NULL){
                              printLink_brancheNodes(midilink,level+1,maxlevel);
                              midilink=(struct MidiLink *)midilink->ml_Node.ln_Succ;
                      }
              }
      
              if(!(IsListEmpty(&cluster->mcl_Senders))){
                      printSpaces(level);
                      printf("  ");
                      printf("-Sender links:\n");
                      midilink=(struct MidiLink *)cluster->mcl_Senders.lh_Head;
                      while(midilink->ml_Node.ln_Succ!=NULL){
                              printLink_brancheNodes(midilink,level+1,maxlevel);
                              midilink=(struct MidiLink *)midilink->ml_Node.ln_Succ;
                      }
              }
      }
      
      
      int main(){
      
              APTR lock;
              struct MidiCluster *cluster;
      
              CamdBase=OpenLibrary("camd.library",40L);
      
              if(CamdBase!=NULL){
      
                      lock=LockCAMD(CD_Linkages);
      
                      cluster=NextCluster(NULL);
                      if(cluster==NULL){
      
                              printf("No clusters available.\n");
      
                      }else{
      
                              printf("-Clusters:\n\n");
                              do{
                                      printCluster(cluster,1,6);
                                      printf("\n");
                                      cluster=NextCluster(cluster);
                              }while(cluster!=NULL);
      
                      }
      
                      UnlockCAMD(lock);
                      CloseLibrary(CamdBase);
      
              }else{
                      printf("Could not open at least V40 of camd.library.\n");
                      return 1;
              }
      
              return 0;
      }
      



      ↑Jump back a section

      Reference

      APTR LockCAMD(ULONG locktype) 
      void UnlockCAMD(APTR lock) 
      
      struct MidiNode *CreateMidiA(struct TagItem *tags) 
      void DeleteMidi(struct MidiNode *midinode) 
      BOOL SetMidiAttrsA(struct MidiNode *midinode, struct TagItem *tags) 
      ULONG GetMidiAttrsA(struct MidiNode *midinode, struct TagItem *tags) 
      struct MidiNode *NextMidi(struct MidiNode *midinode) 
      struct MidiNode *FindMidi(STRPTR name) 
      void FlushMidi(struct MidiNode *midinode) 
      
      struct MidiLink *AddMidiLinkA(struct MidiNode *midinode, LONG type, struct TagItem *tags) 
      void RemoveMidiLink(struct MidiLink *midilink) 
      BOOL SetMidiLinkAttrsA(struct MidiLink *midilink, struct TagItem *tags) 
      ULONG GetMidiLinkAttrsA(struct MidiLink *midilink, struct TagItem *tags) 
      struct MidiLink *NextClusterLink(struct MidiCluster *cluster, struct MidiLink *midilink, LONG type) 
      struct MidiLink *NextMidiLink(struct MidiNode *midinode, struct MidiLink *midilink, LONG type) 
      BOOL MidiLinkConnected(struct MidiLink *midilink) 
      
      struct MidiCluster *NextCluster(struct MidiCluster *last)
      struct MidiCluster *FindCluster(STRPTR name)
      
      void PutMidi(struct MidiLink *link, ULONG msg) 
      BOOL GetMidi(struct MidiNode *midinode, MidiMsg *msg) 
      BOOL WaitMidi(struct MidiNode *midinode, MidiMsg *msg) 
      
      void PutSysEx(struct MidiLink *midilink, UBYTE *buffer) 
      ULONG GetSysEx(struct MidiNode *midinode, UBYTE *Buf, ULONG len) 
      ULONG QuerySysEx(struct MidiNode *midinode) 
      void SkipSysEx(struct MidiNode *midinode) 
      
      UBYTE GetMidiErr(struct MidiNode *midinode)
      WORD MidiMsgType(MidiMsg *msg) 
      WORD MidiMsgLen(ULONG msg) 
      
      void ParseMidi(struct MidiLink *midilink, UBYTE *buffer, ULONG length) 
      struct MidiDeviceData *OpenMidiDevice(UBYTE *name) 
      void CloseMidiDevice(struct MidiDeviceData *mididevicedata) 
      LONG RethinkCAMD() 
      
      void StartClusterNotify(struct ClusterNotifyNode *cn) 
      void EndClusterNotify(struct ClusterNotifyNode *cn) 
      APTR GoodPutMidi(struct MidiLink *midilink, ULONG msg, ULONG maxbuff) 
      BOOL Midi2Driver(APTR driverdata, ULONG msg, ULONG maxbuff) 
      
      ↑Jump back a section
      Last modified on 19 June 2010, at 05:14