MIDIPort / MIDIChannel 


A MIDI responder hierarchy that goes beyond MIDIresponder to add multiport, multichannel support.


The information provided here is for reference only. In most cases, you will never have to talk to MIDIPort or MIDIChannel directly. MIDI responders (sockets for note on and off messages, and controllers for continuous control messages) know how to initialize the entire hierarchy and create their MIDI channel objects if needed. See the help files for BasicMIDISocket and BasicMIDIControl for more information about normal use.


You may need some of the information in this file if you want to write your own MIDI sockets or MIDI controllers. 


For ordinary use, the only MIDIPort methods you will need are under “Initialization” and “Resetting” below. If you use others, you might break something.


Initialization: 


*putProtoCCAlloc(port, alloc) 


Provide a prototype for a CCAllocator that is specific to this port. You may assign one CCAllocator to each port (MIDI source). If none is given, the default settings in the CCAllocator class will be used. See the CCAllocator help file for details on configuring an allocator.


port may be the system-assigned unique identifier for for the desired MIDI source, or an integer index into the MIDIPort.sources array.


MIDIPort.putProtoCCAlloc(0, CCAllocator((10..20), [\test]));


*onInitAll

*onInitAll_(func) 


Specifies a function to be executed after MIDIPort initializes its connections to the MIDI interface. The primary usage is to specify prototypes for the default CCAllocators. Calling putProtoCCAlloc as above requires initializing the MIDI interface, which you may not want to do every time you start SuperCollider. This function allows the action to be defined at startup, but deferred until you actually need MIDI functionality. 


MIDIPort.onInitAll = {

MIDIPort.putProtoCCAlloc(0, CCAllocator((10..20), [\test]))

};


Resetting:


MIDIPort.removeAt(channelIndex) 


Resets the given MIDI channel, removing all sockets and control responders and resetting the channel's controller allocator.


channelIndex is specified in one of the following ways:


chan_num (simple integer): this number is the channel number; the port will be assumed 0

\omni: the omni channel on port 0

nil: assume port 0, channel 0

[port_num, chan_num]: specify a port as well as channel. port_num can be the uid belonging to the port (see MIDIClient and MIDIEndPoint), or an integer index to the sources initialized by MIDIClient.

[port_num, \omni]: the omni channel on the given port 


port_num here refers to an index into the MIDIPort.sources array, e.g., on my machine:


MIDIPort.init;


Sources: [ FastLane USB #2 : Port A, FastLane USB #2 : Port B, UltraLite : Midi Port ]

Destinations: [ FastLane USB #2 : Port A, FastLane USB #2 : Port B, UltraLite : Midi Port ]

MIDIPort


In this configuration,


port 0 = FastLane USB #2 : Port A

port 1 = FastLane USB #2 : Port B

port 2 = UltraLite : Midi Port


MIDIPort.resetAll 


Reset every channel on every port.


-hjh, jamshark70@dewdrop-world.net


MIDIPort


Class methods (involving the whole hierarchy):


*removeAt(channel) 


Frees and removes the MIDI channel object on the given channel number. 


*search(object) 


Searches each channel for a socket that is controlling the given object, and returns the socket.


v = Voicer(8, "mySynth");

k = VoicerMIDISocket(0, v);

MIDIPort.search(v); // returns k


*update 


Searches all MIDI channels for sockets whose destination is inactive and frees those sockets. A complex class that creates many MIDI controllers can clean itself up quickly by calling this method in its free method.


________________________________________


MIDIChannel 


free(callPortRemove = true) 


Stops and frees all players installed on this channel and cleans up all objects currently on the channel. If callPortRemove is true (the default behavior), the channel's slot in MIDIPort is cleared and this channel cannot be used again until you create a new MIDIChannel. If it's false, this channel object is left empty and ready to accept new sockets and controllers.


add(socket)

remove(socket)

removeAt(index) 


Add and remove new MIDI sockets. Currently the only kind of MIDI socket is VoicerMIDISocket, but any kind of socket can be written. See the BasicMIDISocket help file for details. 


search(player) 


Searches for a socket talking to the given player (such as a voicer) and returns the socket.


addControl(cc)

removeControl(cc) 


Add and remove continuous controller responders. These should be objects like VoicerMIDIController and MixerMIDIControl. See the BasicMIDIControl help file on writing your own MIDI controller classes.


searchControl(name) 


Searches through the current control responders for controllers talking to an object with a specific name. Since voicers can have several MIDI controllers talking to them, this method may not be very useful in its current incarnation. I may revise it in the future to return a collection of all controllers talking to this object.