MKInstruments are the agents through which MKNote objects are realized. Since realization is the ultimate destiny of a MKNote object, the MKInstrument class is the ultimate focus of a MusicKit performance: Every performance involves at least one MKInstrument.
At the heart of an MKInstrument is its realizeNote:fromNoteReceiver: method. The MKInstrument class itself is abstract and doesn't implement this method; it's the responsibility of each MKInstrument subclass to provide an implementation of realizeNote:fromNoteReceiver: to establish the manner in which instances of the subclass realize MKNotes. The MusicKit includes a number of MKInstrument subclasses (and pseudo-MKInstruments) that realize MKNotes by synthesizing them on the DSP or an external MIDI synthesizer, and that store MKNotes by adding them to a MKPart or MKScore or by writing them to a file.
One of the principals of MKInstrument design is that an MKInstrument doesn't create the MKNotes that it realizes. Instead, it realizes MKNotes that are sent to it by another object or by your application. The machinery by which an MKInstrument receives MKNotes is well defined by the MusicKit; unlike that for MKNote-realization, you don't reinvent the MKNote-reception mechanism for each MKInstrument subclass.
The following sections examine the MKInstrument class according to its two tasks: receiving and realizing MKNotes. The latter topic centers upon descriptions of the MKInstrument subclasses included in the MusicKit, followed by an example of MKInstrument subclass design.
An MKInstrument receives MKNotes through the same method that defines their realization, realizeNote:fromNoteReceiver:. However, you don't send MKNotes to an MKInstrument by invoking this method directly; instead, you send the MKNotes to one of the MKInstrument's MKNoteReceiver objects which, in turn, invokes realizeNote:fromNoteReceiver: for you.
MKNoteReceiver is an auxiliary class that acts as a “MKNote port” for an MKInstrument. This is manifested as the three features that a MKNoteReceiver brings to an MKInstrument:
It provides methods through which an MKInstrument receives MKNotes (in other words, methods that invoke MKInstrument's realizeNote:fromNoteReceiver:).
It lets you control the stream of MKNotes into an MKInstrument by allowing you to toggle its ability to forward MKNotes to an MKInstrument.
It acts as a jack into which you can plug a MKPerformer object's MKNoteSender. This connects the MKPerformer that owns the MKNoteSender to the MKInstrument that owns the MKNoteReceiver, such that the MKNotes generated by the MKPerformer are automatically delivered to and realized on the connected MKInstrument. The methods by which you marry a MKNoteReceiver to a MKNoteSender are described later in the section on MKPerformers and MKNoteSenders.
Creating and adding MKNoteReceivers is usually part of the design of the MKInstrument subclass, although some subclasses require you to create and add MKNoteReceivers yourself. In either case, the method by which a MKNoteReceiver is added to an MKInstrument is the same: MKInstrument's addNoteReceiver:. While an MKInstrument can own more than one MKNoteReceiver, a single MKNoteReceiver can belong to only one MKInstrument: An invocation of addNoteReceiver: removes the argument (the MKNoteReceiver) from its current owner.
The fundamental method through which a MKNoteReceiver itself receives MKNotes―and thereby forwards them to its owning MKInstrument―is called receiveNote:. However, before you can send receiveNote: to a MKNoteReceiver, you must be able to locate the object. If you created and added MKNoteReceivers to an MKInstrument yourself, finding these objects shouldn't pose a problem―you made them, you should know where they are. But keep in mind that many MKInstruments create and add MKNoteReceivers for you. Any MKInstrument's MKNoteReceivers can be retrieved as a NSArray object by sending the noteReceivers message to the MKInstrument; members of this NSArray can then be sent the receiveNote: message. As a convenience, the first MKNoteReceiver in this NSArray can be retrieved through the noteReceiver method. This is particularly handy for MKInstruments that define only one MKNoteReceiver, or in situations where you don't care which MKNoteReceiver you send the MKNote to. In the following example, an instance of MKSynthInstrument is created and a MKNote is sent to its MKNoteReceiver. MKSynthInstrument is a subclass of MKInstrument that realizes MKNotes by synthesizing them on the DSP; it creates a single MKNoteReceiver as part of its init method:
/* Create a MKSynthInstrument and send it a MKNote (assumed to exist). */ aSynthIns = [[MKSynthInstrument alloc] init]; [MKConductor lockPerformance]; [[aSynthIns noteReceiver] receiveNote:aNote]; [MKConductor unlockPerformance]; |
You'll note the presence of the MKConductor class methods lockPerformance and unlockPerformance; invocations of these two methods should bracket all invocations of receiveNote: (with some exceptions, as noted in the sections on MKConductors and MKPerformers, later in this chapter). Briefly, these methods ensure that your cast of characters are in synch and primed for timely MKNote realization. A fuller explanation of lockPerformance and unlockPerformance is given in the Section called Locking the Performance later in this chapter.
You can create and add any number of MKNoteReceivers to the MKInstruments that you allocate, even if these MKInstruments create MKNoteReceivers themselves. However, with some exceptions―notably that described in the next section―there isn't much reason to do so: One MKNoteReceiver is as good as the next. Any number of MKNote-producing agents―whether MKPerformers or different mechanisms in your application―can all send receiveNote: to the same MKNoteReceiver. In general, adding a gaggle of MKNoteReceivers to an MKInstrument doesn't make the MKInstrument more interesting, it simply makes it bigger.
You can throttle a MKNoteReceiver's ability to invoke realizeNote:fromNoteReceiver: by sending it the squelch message. To release this clench, you invoke unsquelch. Through this simple feature, you can easily and quickly mute an MKInstrument.
While a MKNoteReceiver is squelched, the receiveNote: method ceases to function: It immediately returns nil without forwarding the argument MKNote to the MKNoteReceiver's owner (unsquelched, receiveNote: returns self). Realization of the MKNote isn't merely deferred, it's abandoned for good. You can determine whether a MKNoteReceiver is squelched by sending it the isSquelched message: If the message returns YES, the object is squelched.
The squelch feature, in certain applications, argues for the use of multiple MKNoteReceivers for a single MKInstrument. For example, you can create an application in which MKNotes are generated from MIDI input and read from a MKPart object at the same time. If you feed these two MKNote sources to the same MKInstrument, you may want to create and add two distinct MKNoteReceivers, one for either source, so you can independently squelch the two streams of MKNotes.
An MKInstrument is considered to be in performance from the time that you send receiveNote: to any of its unsquelched MKNoteReceivers until the performance is over―in other words, until the MKConductor class receives the finishPerformance message. You can query an MKInstrument's performance status by sending it the inPerformance message, where a return of YES signifies that the object is currently in performance.
The performance status of an MKInstrument is significant because some MKInstrument methods aren't effective while the MKInstrument is in performance. This can be a particularly devilish source of confusion since the state of an MKInstrument's performance doesn't require a performance, in the larger sense, to be in progress. Specifically, if you send receiveNote: to an MKInstrument's MKNoteReceiver before the MKConductor class receives startPerformance, the MKInstrument will, nonetheless, be considered to be performing (and thus the aforementioned performance-status dependent methods will have no effect).
There are very few rules when it comes to realizing MKNotes: You can implement realizeNote:fromNoteReceiver: to realize a MKNote in almost any arbitrary manner. As mentioned earlier, the MusicKit includes MKInstruments that synthesize and store MKNotes as their forms of realization. For many performance applications, the MKInstruments provided by the MusicKit are sufficient. The following sections describe these subclasses.
A MKSynthInstrument is by far the most complicated MKInstrument; it realizes MKNotes by causing them to be synthesized on the DSP. It operates on three basic principles:
Every instance of MKSynthInstrument is associated with a single subclass of MKSynthPatch.
Before or during a performance, a MKSynthInstrument object allocates (through requests to the MKOrchestra) and manages instances of its MKSynthPatch subclass. These MKSynthPatch objects are used to synthesize the MKNotes that the MKSynthInstrument receives through its MKNoteReceiver.
Following these principles, the primary decisions you need to make regarding a MKSynthInstrument are which MKSynthPatch subclass to assign it and which of two schemes it should use to allocate instances of the MKSynthPatch subclass.
You set a MKSynthInstrument's MKSynthPatch subclass by invoking the setSynthPatchClass: method. As the method's argument you specify one of the MKSynthPatch classes included in the MusicKit, or one of your own. If you have a multiple-DSP system, the MKSynthInstrument will allocate its MKSynthPatch objects on the first DSP that has sufficient available resources. You can restrict allocation to a specific DSP by invoking setSynthPatchClass:orchestra:, passing an MKOrchestra object as the second argument.
MKNote: If you use a MKSynthPatch class included in the MusicKit, you must import the file <musickit/synthpatches/ClassName.h>, where ClassName is the name of the class you wish to use. Alternatively, the file <musickit/synthpatches/synthpatches.h> will import all the MusicKit MKSynthPatch interface files.
The setSynthPatchClass: method (and the ...orchestra: version) checks its (first) argument to ensure that it's a class that inherits from MKSynthPatch, returning nil if it doesn't.
You can also change the synthPatchClass by sending it a mute note with a parameter synthPatch:. The value of this parameter should be the name of the class (a string.)
MKSynthInstrument defines two allocation modes:
In automatic allocation mode the MKSynthInstrument allocates MKSynthPatch objects as it receives MKNotes, tagging each MKSynthPatch with the note tag of the MKNote for which it was allocated. As it receives subsequent MKNotes, the MKSynthInstrument compares each MKNote's note tag to those of the MKSynthPatches it has already allocated. If it finds a match, the MKNote is sent to that MKSynthPatch. If it doesn't match, the MKSynthInstrument allocates a new MKSynthPatch.
In manual allocation mode the MKSynthPatch objects are allocated all at once, before MKNotes begin to arrive. The number of MKSynthPatches to allocate is set through the method setSynthPatchCount:. The number of MKSynthPatches that are actually allocated may be less than the number requested, depending on the availability of DSP resources at the time that the message is sent. The method returns the number of MKSynthPatches that were actually allocated.
By default, a MKSynthInstrument is in automatic allocation mode. Simply sending setSynthPatchCount:places it in manual mode. To set it back to automatic mode, you send it the autoAlloc message.
You can query a MKSynthInstrument's allocation mode by invoking allocMode, a method that returns one of the following integer constants:
You can change the number of manually allocated MKSynthPatches at any time―even during a performance―simply by resending the setSynthPatchCount: message. Notice, however, that the argument is always taken as the total number of MKSynthPatches that are allocated to the MKSynthInstrument―it doesn't represent the number of new objects to allocate. For example, in the following sequence of messages, a total of four MKSynthPatches are allocated.
/* Allocate three MKSynthPatches. */ [aSynthIns setSynthPatchCount: 3]; . . . /* Allocate one more. */ [aSynthIns setSynthPatchCount: 4]; |
The synthPatchCount method returns the number of manually allocated MKSynthPatches. Thus, the previous example can be rewritten as:
/* Allocate three MKSynthPatches. */ [aSynthIns setSynthPatchCount: 3]; . . . /* Allocate one more. */ [aSynthIns setSynthPatchCount: [aSynthIns synthPatchCount]+1]; |
If the MKSynthInstrument is in automatic mode, synthPatchCount returns 0.
Deallocating MKSynthPatch objects is also possible:
/* Allocate three MKSynthPatches. */ [aSynthIns setSynthPatchCount: 3]; . . . /* Deallocate two of them. */ [aSynthIns setSynthPatchCount: [aSynthIns synthPatchCount]-2]; |
If the argument signifies a deallocation, the MKSynthInstrument's idle MKSynthPatches, if any, are deallocated first; the balance are deallocated as they become inactive.
You can also change the synthPatchCount by sending it a mute note with a parameter synthPatchCount.
Some MKSynthPatches come in a variety of configurations. For example, the Fm1vi MKSynthPatch (frequency modulation with optional vibrato) is configured differently depending on whether the MKNote it's synthesizing specifies vibrato. It does this to be as efficient as possible―excluding vibrato from Fm1vi's configuration means that it uses less of the MKOrchestra's resources.
A MKSynthPatch represents each of its configurations as a different MKPatchTemplate object. When you set a MKSynthInstrument to manual allocation mode, you can specify the number of MKSynthPatches with a particular MKPatchTemplate by invoking the setSynthPatchCount:forPatchTemplate: method. The second argument is the id of the MKPatchTemplate that you want. This is returned by sending the patchTemplateFor: message to the MKSynthInstrument's MKSynthPatch class, with a MKNote object as the argument. This is best explained by example:
/* Create a MKSynthInstrument. */ id aSynthIns = [[MKSynthInstrument alloc] init]; /* Create a variable to store the MKPatchTemplate. */ id noVibTemplate; /* Create a dummy MKNote. */ id aNote = [[MKNote alloc] init]; /* Set its vibrato amplitudes to 0.0. */ [aNote setPar: MK_svibAmp toDouble: 0.0]; [aNote setPar: MK_rvibAmp toDouble: 0.0]; /* Retrieve the MKPatchTemplate senza vibrato. */ noVibTemplate = [[aSynthIns synthPatchClass] patchTemplateFor:aNote]; /* Allocate three vibratoless MKSynthPatches. */ [aSynthIns setSynthPatchCount: 3 forPatchTemplate: noVibTemplate]; |
If the MKPatchTemplate isn't specified, the MKSynthPatches are created using the default MKPatchTemplate. Each subclass of MKSynthPatch designates one of its MKPatchTemplates as the default for that class; by convention, the most extravagant MKPatchTemplate is provided as the default. Thus, the default Fm1vi MKPatchTemplate includes vibrato. In the example, the Fm1vi MKPatchTemplate without vibrato is retrieved by passing (as the second argument to patchTemplateFor:) a MKNote that explicitly sets the vibrato parameters to 0.0.
Within the same MKSynthInstrument, you can manually allocate MKSynthPatches that use different MKPatchTemplates. The following extension of the previous example demonstrates this:
/* Allocate one vibratoless MKSynthPatch. */ [aSynthIns setSynthPatchCount: 1 forPatchTemplate: noVibTemplate]; /* And two with vibrato. */ [aSynthIns setSynthPatchCount: 2]; |
setSynthPatchCount: always uses the default MKPatchTemplate (which, as mentioned earlier, includes vibrato for Fm1vi). When the MKSynthInstrument in the example receives a MKNote that initiates a new phrase, it automatically forwards the MKNote to the proper MKSynthPatch: If the MKNote contains vibrato parameters with zero values (similar to the dummy MKNote used in the previous example), it's forwarded to the MKSynthPatch that excludes vibrato; otherwise, it's sent to one of the other two MKSynthPatches.
The MKSynthInstrument keeps a count of the number of MKSynthPatches it has manually allocated for each MKPatchTemplate. The count for a particular MKPatchTemplate is returned by the method synthPatchCountForPatchTemplate:. The synthPatchCount method, used in an example in the previous section, returns the count for the default MKPatchTemplate.
If the MKSynthPatch is in automatic mode, you don't need to specify which MKPatchTemplate to use. The MKSynthInstrument automatically creates a MKSynthPatch with the correct MKPatchTemplate to accommodate the parameters in the MKNotes it receives.
A MKSynthInstrument's primary task is to forward MKNotes to its MKSynthPatches. The MKSynthPatch class defines three methods that are designed to be invoked by a MKSynthInstrument for this purpose:
noteOn: is used to forward a noteOn type MKNote.
noteUpdate: forwards noteUpdates.
noteOff:, likely enough, forwards noteOffs.
The MKNote itself is passed as the argument to the method. Invocation of these methods is automatic; when a MKSynthInstrument receives a MKNote during a performance, it automatically invokes the appropriate method.
Notice that noteDurs and mutes aren't included in this scheme. A noteDur is split into a noteOn/noteOff pair. If the noteDur doesn't have a noteTag, a unique noteTag is created and given to the two new MKNotes. Mutes are simply ignored.
Besides forwarding MKNotes, the noteOn: and noteOff: methods also set a MKSynthPatch's synthesis status. This describes the object's current synthesis state as one of the following MKSynthStatus constants:
Table 6-2. MKSynthInstrument's synthesis states
Constant | Meaning |
---|---|
MK_idle | The MKSynthPatch is currently inactive. |
MK_running | The MKSynthPatch is synthesizing the body of a musical note. |
MK_finishing | The MKSynthPatch is in the release portions of its MKEnvelopes. |
The noteOn: message sets the synthesis status to MK_running; noteOff: sets it to MK_finishing. In either of these states, the MKSynthPatch is considered to be active. The status is set to MK_idle when the release portion of the MKSynthPatch's amplitude MKEnvelope (in other words, the object set as the value of the MK_ampEnv parameter of the MKNote that the MKSynthPatch is realizing) is complete. None of the other MKEnvelopes are taken into consideration when determining if the MKSynthPatch is idle: It's assumed that the amplitude MKEnvelope will ultimately fall to an amplitude of 0.0, thus whatever course the other MKEnvelopes take after that point is for nought since the MKSynthPatch will no longer be making any noise.
The MKSynthInstrument class gives special consideration to a noteUpdate that doesn't have a note tag:
The noteUpdate is forwarded to all the active MKSynthPatches (within the MKSynthInstrument that received the MKNote).
The MKNote's parameters are stored in the MKSynthInstrument's update state.
Every MKSynthInstrument has an update state. When a MKSynthInstrument begins a new phrase, the parameters in the update state are merged into the MKNote that initiated the phrase (always a noteOn, whether by nature or due to a noteDur split). The update state parameters never overwrite the value of a parameter already present in a noteOn―in the case of a parameter collision, the noteOn's parameter takes precedence. Conversely, a noteOn's parameters never affect the update state, it can only be changed by another noteUpdate with no note tag.
As a demonstration of these principles, consider the following scorefile excerpt:
/* Scorefile body excerpt. */ t 0.0; part1 (noteUpdate) amp:.25; t 1.0; part1 (noteOn 1) freq:c4; /* amplitude is .25 */ t 2.0; part1 (noteOff 1); t 3.0; part1 (noteOn 2) freq:d4 amp:.75; /* amplitude is .75 */ t 4.0; part1 (noteOff 2); t 5.0; part1 (noteOn 3) freq:e4; /* amplitude is, once again, .25 */ t 6.0; part1 (noteUpdate) amp:.5; t 7.0; part1 (noteUpdate 3) amp:.25; t 8.0; part1 (noteOff 3); t 9.0; part1 (noteOn 4) freq: f4; /* amplitude is .5 */ t 10.0; part1 (noteOff 4); |
The initial note tag-less noteUpdate sets the amplitude parameter in the MKSynthInstrument's update state; notice that the update state is set even though the MKSynthInstrument doesn't have any active MKSynthPatches. Of the four subsequent noteOns, the first, third, and fourth don't have amplitude parameters so they inherit the one in the update state. The second noteOn has its own amplitude; it ignores the parameter in the update state.
While the third musical note is sounding, two more noteUpdates arrive. The first has no note tag, so it affects both the active MKSynthPatch and the update state. The second noteUpdate's note tag matches that of the active MKSynthPatch; it's forwarded to the MKSynthPatch but doesn't affect the update state.
While the DSP makes a great synthesizer, its resources are by no means unlimited. It's possible to ask it to synthesize, at the same time, more MKNotes than it can accommodate. The number of MKNotes that can be synthesized at one time depends on a number of factors, the most significant being the sampling rate and the requirements of the MKSynthPatches that are being used. There sometimes comes a time in the life of a MKSynthInstrument when it tries to allocate just one more MKSynthPatch and finds that the well is empty.
When a MKSynthInstrument can't get the resources to synthesize a new MKNote, it tries to preempt an active MKSynthPatch rather than lose the MKNote. The following steps are taken to determine which MKSynthPatch to preempt:
The preempted MKSynthPatch should have sufficient resources to synthesize the MKNote, thus the MKSynthInstrument first looks for a MKSynthPatch that uses the same MKPatchTemplate that's needed to synthesize the new MKNote.
If there's more than one such MKSynthPatch, the one that first received a noteOff: message, if any, is preempted. In other words, the preemption scheme first looks for a MKSynthPatch whose synthesis status is MK_finishing.
If there aren't any finishing MKSynthPatches, the oldest MKSynthPatch is chosen.
If a MKSynthPatch with the appropriate MKPatchTemplate isn't available, the MKSynthInstrument tries other MKSynthPatches until one is found that has sufficient resources to synthesize the new MKNote.
A MKSynthInstrument object can only preempt its own MKSynthPatches―it can't steal one from another MKSynthInstrument. The search for a preemptible MKSynthPatch is sometimes unsuccessful; for example, if there are no more resources to build a new MKSynthPatch, the new MKNote can't be synthesized.
The determination of which MKSynthPatch to preempt is performed in the preemptSynthPatchFor:patches: method: The method's return value is taken as the MKSynthPatch to preempt. If you want to provide your own system for preempting MKSynthPatches, you have to create your own subclass of MKSynthInstrument in which to reimplement this method.
The method is automatically invoked when the MKSynthInstrument has to preempt a MKSynthPatch. The two arguments are:
The newly arrived MKNote
The first in a list of candidate MKSynthPatches
Notice that the second argument is a single MKSynthPatch object. To get to the next object in the list, you send next to the MKSynthPatch at hand.
The MKMidi class isn't a true MKInstrument―it inherits from NSObject. However, it creates MKNoteReceivers and implements realizeNote:fromNoteReceiver: and so can be used as an MKInstrument.
A MKMidi object creates 17 MKNoteReceivers, one for the Basic Channel and one each for the 16 Voice Channels. You can retrieve the MKNoteReceiver that corresponds to a particular channel through the channelNoteReceiver: message, passing the channel number that you want: 0 retrieves the MKNoteReceiver for System and Channel Mode Messages; 1-16 retrieves the MKNoteReceiver for the corresponding Voice Channel. You create a MKMidi object to correspond to a MIDI device (a serial port on NeXT hardware, MIDI card on Intel-based hardware, CoreMIDI port on MacOS X, DirectMusic port on Windows etc.), specified as “midi0”, “midi1,” etc., in the midiOnDevice: method.
When it receives a MKNote, the MKMidi object translates it into a series of MIDI messages, based on the MKNote's note type and parameters that it contains. It then sends the messages out the serial port.
A MKMidi object has a device status that's much like the device status of the MKOrchestra object, as described in Chapter 5 Before you can send MKNotes to a MKMidi object (more accurately, before the object will do anything with these MKNotes), you must open and run it, through the open and run methods.
A MKMidi object can be made to receive MIDI time code and provide it to a MKConductor so that a performance can be synchronized to MIDI time code. For further information, see the MKMidi and MKConductor class descriptions, as well as Appendix B.
MKPartRecorder is a fairly straightforward MKInstrument: The MKNotes that it receives through its single MKNoteReceiver are copied and added to the MKPart with which it's associated. The MKNoteReceiver is created automatically; the MKPart must be set by your application, through the setMKPart: method.
A MKPartRecorder sets a MKNote's time tag to the current time as it receives the MKNote; the measure of the current time is either in beats or seconds, depending on the value of its “time unit.” You can set the time unit through the setTimeUnit: method, passing either MK_second, MK_beat or MK_timeTag as the argument. Other than the manipulation of the time tag, the MKNote is unchanged by the MKPartRecorder.
MKScoreRecorder isn't actually an MKInstrument; it's used to correspond to MKScore just as a MKPartRecorder corresponds to a MKPart. A MKScoreRecorder actually creates and controls some number of MKPartRecorders, one for each MKPart in its MKScore.
A MKScorefileWriter object realizes MKNotes by writing them to a scorefile. It's the one MKInstrument defined by the MusicKit that requires you to create and add MKNoteReceivers from your application. Each MKNoteReceiver that you add corresponds to a MKPart that will be represented in the scorefile that's written. Typically, you name the MKNoteReceivers that you create; these names are used to identify the corresponding MKPart-representations in the scorefile:
/* Create a MKScorefileWriter and add to it 3 MKNoteReceivers. */ id aSFWriter = [[MKScorefileWriter alloc] init]; id fordReceiver = [[MKNoteReceiver alloc] init]; id pageReceiver = [[MKNoteReceiver alloc] init]; id quicklyReceiver = [[MKNoteReceiver alloc] init]; /* Name the MKNoteReceivers. */ MKNameObject("Ford", fordReceiver); MKNameObject("Page", pageReceiver); MKNameObject("Quickly", quicklyReceiver); /* Add the MKNoteReceivers. */ [aSFWriter addNoteReceiver: fordReceiver]; [aSFWriter addNoteReceiver: pageReceiver]; [aSFWriter addNoteReceiver: quicklyReceiver]; /* Set the MKScorefileWriter's file by name. */ [aSFWriter setFile: "Falstaff.score"]; |
While there are no strict rules governing realization, intelligent MKInstrument design should follow these guidelines:
An MKInstrument should realize MKNotes as it receives them. It's possible to design an MKInstrument that, for instance, reschedules its MKNotes to be realized later, but for the sake of generality, an MKInstrument should act immediately upon the MKNotes it receives.
If an MKInstrument needs to alter or store a MKNote, it should create a copy of the MKNote and act upon the copy.
An MKInstrument shouldn't be a source of MKNotes. The task of generating new MKNotes belongs to a MKPerformer or to your application. The role of an MKInstrument is to respond, not to conceive. This doesn't mean that an MKInstrument can't create MKNotes, but it should only do so in response to receiving a MKNote.
Along with these guidelines, keep in mind that an MKInstrument should, if possible, create and add to itself some number of MKNoteReceivers, usually in its init method.