MusicKit
0.0.0
|
MKPerformer is an abstract class that defines a mechanism for performing MKNotes during a MusicKit performance. More...
#include <MKPerformer.h>
Inherited by _MTCHelper, and _MTCHelper.
MKPerformer is an abstract class that defines a mechanism for performing MKNotes during a MusicKit performance.
Each subclass of MKPerformer implements the perform method to define how it obtains and performs MKNotes.
During a performance, a MKPerformer receives a series of perform messages. In its implementation of perform, a MKPerformer subclass must set the nextPerform variable. nextPerform indicates the number of beats to wait before the next perform message is sent. The messages are sent by the MKPerformer's MKConductor. Every MKPerformer is managed by a MKConductor; unless you set its MKConductor explicitly, through the setConductor: method, a MKPerformer is managed by the defaultConductor.
A MKPerformer contains a NSArray of MKNoteSenders, objects that send MKNotes (to MKNoteReceivers) during a performance. MKPerformer subclasses should implement the init method to create and add some number of MKNoteSenders to a newly created instance. As part of its perform method, a MKPerformer typically creates or otherwise obtains a MKNote (for example, by reading it from a MKPart or a scorefile) and sends it by invoking MKNoteSender's sendNote: method.
To use a MKPerformer in a performance, you must first send it the activate message. activate invokes the activateSelf method and then schedules the first perform message request with the MKConductor. activateSelf can be overridden in a subclass to provide further initialization of the MKPerformer. The performance begins when the MKConductor class receives the startPerformance message. It's legal to activate a MKPerformer after the performance has started.
Sending the deactivate message removes the MKPerformer from the performance and invokes the deactivateSelf method. This method can be overridden to implement any necessary finalization, such as freeing contained objects.
During a performance, a MKPerformer can be stopped and restarted by sending it the pause and resume messages, respectively. perform messages destined for a paused MKPerformer are delayed until the object is resumed.
You can shift a MKPerformer's performance timing by setting its timeShift variable. timeShift, measured in beats, is added to the initial setting of nextPerform. If the value of timeShift is negative, the MKPerformer's MKNotes are sent earlier than otherwise expected; this is particularly useful for a MKPerformer that's performing MKNotes starting from the middle of a MKPart or MKScore. A positive timeShift delays the performance of a MKNote.
You can also set a MKPerformer's maximum duration. A MKPerformer is automatically deactivated if its performance extends beyond duration beats.
A MKPerformer has a status, represented as one of the following MKPerformerStatus values:
Status | Meaning |
MK_inactive | A deactivated or not-yet-activated MKPerformer. |
MK_active | An activated, unpaused MKPerformer. |
MK_paused | The MKPerformer is activated but currently paused. |
Some messages can only be sent to an inactive (MK_inactive) MKPerformer. A MKPerformer's status can be queried with the status message.
If you subclass MKPerformer, some care is required to make sure that it synchronizes correctly to MIDI time code. To make your own MKPerformer subclass synchronize, you need to support a simple informal protocol called MKPerformer Time Code Protocol, which is described in the next section.
This is an informal protocol, required if a MKPerformer subclass is to synchronize correctly with incoming MIDI time code.
There are three parts to this protocol.
A Time Code-conforming MKPerformer must implement a method setFirstTimeTag:, which takes a double argument, represnting the starting value of MIDI time code in seconds. A common implementation of this method stores the value it is passed in an instance variable. The MKPerformer class provides a default implementation, which does nothing.
A Time Code-conforming MKPerformer's activateSelf method must position itself at the MKNote it wants to send at firstTimeTag. If there is no MKNote for that time, it should position itself at the first MKNote following that time. It then sets its nextPerforminstance variable to that MKNote's time (which will be greater than or equal to firstTimeTag.) In other words, it sets nextPerform to the first time it wants to run. Finally, it returns self. If there are no MKNotes to send after the specified time, it returns nil.
Here is an example of a simple, but complete, Time Code-conforming MKPerfomer. This example is a simplified version of the MusicKit MKPartPerformer:
#import <MusicKit/MusicKit.h> #import "MyPartPerformer.h" @implementation MyPartPerformer: MKPerformer { id part; // MKPart over which we're sequencing. double firstTimeTag; // Required by Time Code Protocol. int currentIndex; // Index of nextNote }