struct MidiLink * AddMidiLinkA(
struct MidiNode * midinode,
LONG type,
struct TagItem * tags );
struct MidiLink * AddMidiLink(
struct MidiNode * midinode,
LONG type,
TAG tag, ... );
Adds a midilink to a midinode.
midinode - Owner.
type - MLTYPE_Receiver or MLTYPE_Sender
tags - Tag-values supplied to SetMidiLinkAttrs.
struct MidiCluster * NextCluster(
struct MidiCluster * last );
Finds the next cluster in camds list of clusters.
last - cluster to start searching for.
Next cluster in list, or first if 'last' is NULL.
#include <stdio.h>
#include <proto/exec.h>
#include <proto/camd.h>
#include <midi/camd.h>
int main(){
APTR lock;
struct MidiCluster *cluster;
struct Library *CamdBase=OpenLibrary("camd.library",0L);
if(CamdBase!=NULL){
lock=LockCAMD(CD_Linkages);
cluster=NextCluster(NULL);
if(cluster==NULL){
printf("No clusters available.\n");
}else{
do{
printf("clustername: -%s-\n",cluster->mcl_Node.ln_Name);
cluster=NextCluster(cluster);
}while(cluster!=NULL);
}
UnlockCAMD(lock);
CloseLibrary(CamdBase);
}else{
printf("Could not open camd.library.\n");
return 1;
}
return 0;
}
- CL_Linkages must be locked.
- Often, a program wants to use this function for finding available
clusters a user can choose from. It is then recommended to also
let the user have the possibility to write in the name of a new cluster,
so that camd can make new clusters automatically to be used for
communication between various applications without having hardware-drivers
etc. interfere with the datastreams. Applications do
not need to make special concerns about how cluster works or
what they contain; that is all managed by camd.
struct MidiLink * NextClusterLink(
struct MidiCluster * cluster,
struct MidiLink * midilink,
LONG type );
Finds the next midilink of a specified type in a midicluster.
cluster - Pointer to the midicluster that the midilink belongs to.
midilink - Pointer to the midilink to begin searching from.
type - Either MLTYPE_Receiver or MLTYPE_Sender
Returns the next MidiLink of a spevified type, or NULL if the last
in the list. If midilink is NULL, returns the first.
CL_Linkages must be locked.
struct MidiNode * NextMidi(
struct MidiNode * midinode );
Returns the next midinode in the list of midinodes, or NULL
if midinode was the last one.
midinode - The midinode to begin searching from. If NULL,
returns the first midinode in the list.
CL_Linkages must be locked.
struct MidiLink * NextMidiLink(
struct MidiNode * midinode,
struct MidiLink * midilink,
LONG type );
Returns the next MidiLink of a specified type that belongs
to a midinode. Or NULL if midilink was the last. If midilink
is NULL, returns the first one.
type - MLTYPE_Sender or MLTYPE_Receiver.
CL_Linkages must be locked.
void ParseMidi(
struct MidiLink * midilink,
UBYTE * buffer,
ULONG length );
Puts a midibuffer to a midilinks clusters midilinks midinodes and hardware.
To help understand what it does, the following macro makes PutMidi
use ParseMidi instead of calling camd.library's PutMidi function for
small-endian cpus:
#define PutMidi(midilink,message) ParseMidi((midilink),&(message),MidiMsgLen(message))
(But please don't use this macro, since its not big-endian compatible,
and that PutMidi is faster than ParseMidi)
If its more convenient to use PutMidi and PutSysEx instead of ParseMidi,
do that. ParseMidi is a bit heavier function to use than PutMidi and
PutSysEx.
MLINK_Parse must have be set when calling either AddMidiLinkA or
SetMidiLinkAttrsA.
void PutMidi(
struct MidiLink * link,
ULONG msg );
Puts a midimessage to hardware and all sender-links that belongs
to the midilink's cluster. Does only wait if a hardware send-
buffer is full, and then tries again and again until the message
is sent. Else, the function should return immediately.
link - pointer to the midilink to send to.
msg - The complete message to send. A message can not hold more
than 3 bytes, so it fits fine in a ULONG integer. See NOTES
to see how a message is built up.
Sending an illegal message may have serious consequences. If you for
some reason are not completely sure whether your message is legal,
you could do the following test:
if((msg>>24)<0x80 || (msg>>24)==0xf0 || (msg>>24)==0xf7 || (msg>>16&0xff)>0x7f || (msg>>8&0xff)>0x7f){
debug("Warning, illegal midimessage: %x\n",msg);
}else{
PutMidi(midilink,msg);
}
void PutSysEx(
struct MidiLink * midilink,
UBYTE * buffer );
Distributes a SysEx message. First sends the message to the hardware
and all midinodes connected to the midilinks cluster, then waits
for the complete message to be sent to the hardware, if any. If
a midinodes sysex-buffer is to small to carry the message, it will
not be sent. If the buffer is big enough, but there is not enough
room, a sysex-full-error will be set to the node. The message is
sent to hardware regardless of transmit buffer size.
midilink - pointer to link.
buffer - message to send, must start with 0xf0 and end with 0xf7.
No bytes higher than 0x7f are allowed in the message.
BOOL SetMidiAttrsA(
struct MidiNode * midinode,
struct TagItem * tags );
BOOL SetMidiAttrs(
struct MidiNode * midinode,
TAG tag, ... );
tagList -- pointer to an array of tags describing the player's
attributes or NULL.
MIDI_Name (STRPTR) -- The name of the midinode; default is NULL or a pointer to a string.
MIDI_SignalTask (struct Task *) -- Task to signal whenever a midimessage is arriving to the node;
default is the task of the caller of this function. (FindTask(NULL))
MIDI_RecvHook (struct Hook *) -- Function to call whenever a midimessage is arriving to the node.
You should get the midimessage as the first argument in the function,
however, that has not yet been implemented. Default is NULL.
MIDI_PartHook (struct Hook *) -- Don't really know what this one is for. Have to check amigos-autodocs.
It does not currently do anything.
MIDI_RecvSignal (BYTE) -- Signal bit to use when signalling a task whenever a midimessage is
arriving at the node, or -1 to disable signalling. Default is -1.
MIDI_PartSignal (BYTE) -- Signal bit to use when signalling a task when..... Default is -1.
MIDI_MsgQueue (ULONG) -- Number of messages the messagequeue is able to hold.
MIDI_TimeStamp (ULONG *) -- Pointer to an ULONG value which value is copied directly into the timestamp
attribute in midimessages whenever a new message is received at the node.
MIDI_ErrFilter (UBYTE) -- Filters out the errors you don't want to see.
MIDI_ClientType (UWORD) -- What sort of application you that owns this node.
MIDI_Image (struct Image *) -- Pointer to an image representing this node.
MIDI_ErrorCode (ULONG *) -- Pointer to an ULONG which will be set if something went wrong.
TRUE if everything went okey, FALSE if not. Errorcode
is put in an ULONG pointed to by the MIDI_ErrorCode tag,
if supplied.
- If the midinode is not owned by yourself, please lock
camd to ensure it wont go away.
- Allthough you are able to modify midinodes owned by
others, please avoid it, its normally "non of your buziness",
and may lead to crashes and other "unexpected" behaviors.
However, if you have full control of the owner of the
midinode (f.ex when both you and the owner belongs to the
same probram and you are absolutely shure you know what
you are doing), there is no problem.
BOOL SetMidiLinkAttrsA(
struct MidiLink * midilink,
struct TagItem * tags );
BOOL SetMidiLinkAttrs(
struct MidiLink * midilink,
TAG tag, ... );
Remind me to fill in things here later.
- If the midilink is not owned by yourself, please lock
camd to ensure it wont go away.
- Allthough you are able to modify midilinks owned by
others, please avoid it, its normally "non of your buziness",
and may lead to crashes and other "unexpected" behaviours.
However, if you have full control of the owner of the
midilink (f.ex when both you and the owner belongs to the
same probram and you are absolutely shure you know what
you are doing), there is no problem.
- Warning! If another task have locked Camd and is waiting
for you to finish, there will be a deadlock if you try
to change priority or change/set cluster.
void StartClusterNotify(
struct ClusterNotifyNode * cn );
void StartClusterNotify(struct ClusterNotifyNode *cn)
pointer to initialized ClusterNotifyNode structure
struct ClusterNotifyNode cnn;
cnn.cnn_Task=IExec->FindTask(NULL);
cnn.cnn_SigBit=IExec->AllocSignal(-1);
StartClusterNotify(&cnn);
somewhere down the line...
Wait(1L<<cnn.cnn_SigBit)
printf("Cluster Changes have happened\n");
ClusterNotifyNode structure must remain valid until EndClusterNotify();
Will only signal added and removed clusters, not internal state changes.
BOOL WaitMidi(
struct MidiNode * midinode,
MidiMsg * msg );
Waits until a new message is received at the node, and
copy the message to msg.
msg - Pointer to a midimessage where the message will be copied.
Returns TRUE if a new message arrived or had arrived, FALSE, if there
was en error on the midinode.