download MKNoteReceiver.m
Language: ObjectiveC
Copyright: (c) 1988-1992, NeXT Computer, Inc. (c) 1999-2004, The MusicKit Project. (c) 1994 NeXT Computer, Inc. and reproduced under license from NeXT (c) 1994 Stanford University
LOC: 191
Project Info
The MusicKit(musickit)
Server: SourceForge
Type: cvs
...sicKit\Frameworks\MusicKit\
   _ArielQP.h
   _DSPMK.h
   _error.h
   _midi.h
   _MKAppProxy.h
   _MKAppProxy.m
   _MKNameTable.h
   _MKNameTable.m
   _MKParameter.h
   _MTCHelper.h
   _MTCHelper.m
   _musickit.h
   _noteRecorder.h
   _OrchloopbeginUG.h
   _OrchloopbeginUG.m
   _ParName.h
   _ParName.m
   _scorefile.h
   _ScorefileVar.h
   _ScorefileVar.m
   _SharedSynthInfo.h
   _SharedSynthInfo.m
   _synthElementMethods.m
   _time.h
   ArielQP.h
   ArielQP.m
   classFuncs.h
   ConductorPrivate.h
   dsp_types.h
   DSPSerialPortDevice.h
   dspwrap.h
   EnvelopePrivate.h
   equalTempered.m
   errors.h
   fastFFT.c
   fastFFT.h
   GNUmakefile.postamble
   GNUmakefile.preamble.in
   InstrumentPrivate.h
   keynums.h
   libMusicKit.def
   Localized.strings
   make.sh
   Makefile.postamble
   Makefile.preamble
   midi_spec.h
   midifile.h
   midifile.m
   MidiPrivate.h
   midiTranslation.h
   MKConductor.h
   MKConductor.m
   MKConductorDelegate.h
   MKDeviceStatus.h
   MKEnvelope.h
   MKEnvelope.m
   MKFilePerformer.h
   MKFilePerformer.m
   MKFileWriter.h
   MKFileWriter.m
   MKInstrument.h
   MKInstrument.m
   MKMidi.h
   MKMidi.m
   MKMixerInstrument.h
   MKMixerInstrument.m
   MKMTCPerformer.h
   MKMTCPerformer.m
   MKNote.h
   MKNoteFilter.h
   MKNoteFilter.m
   MKNoteReceiver.h
   MKNoteReceiver.m
   MKNoteSender.h
   MKNoteSender.m
   MKOrchestra.h
   MKPart.m
   MKPartials.h
   MKPartials.m
   ...tialsWaveshapingTable.m
   MKPartPerformer.h
   MKPartPerformer.m
   MKPartRecorder.h
   MKPartRecorder.m
   MKPatch.h
   MKPatch.m
   MKPatchConnection.h
   MKPatchConnection.m
   MKPatchEntry.h
   MKPatchEntry.m
   MKPatchTemplate.h
   MKPatchTemplate.m
   MKPerformer.h
   MKPerformer.m
   MKPerformerDelegate.h
   MKPlugin.h
   MKSamplerInstrument.h
   MKSamplerInstrument.m
   MKSamples.h
   MKScore.h
   MKScore.m
   MKScorefileObject.h
   MKScorefilePerformer.h
   MKScorefilePerformer.m
   MKScorefileWriter.m
   MKScorePerformer.h
   MKScorePerformer.m
   MKScoreRecorder.h
   MKScoreRecorder.m
   MKSynthData.h
   MKSynthData.m
   MKSynthInstrument.h
   MKSynthPatch.h
   MKTimbre.h
   MKTimbre.m
   MKTuningSystem.h
   MKTuningSystem.m
   MKUnitGenerator.h
   MKUnitGenerator.m
   MKWaveTable.h
   MKWaveTable.m
   mtcMidi.m
   mtcMidiPrivate.m
   MusicKit-Info.plist
   MusicKit.h
   MusicKitConfig.h.in
   names.h
   noDVal.h
   noteDispatcherMethods.m
   NotePrivate.h
   noteRecorderCFuncs.m
   noteRecorderMethods.m
   orch.h
   OrchestraPrivate.h
   OrchloopbeginUG.h
   OrchloopbeginUG.m
   orchloopbeginUGInclude.m
   params.h
   parNames.m
   partialsDBInclude.m
   PartialsPrivate.h
   PartPerformerPrivate.h
   PartPrivate.h
   PartRecorderPrivate.h
   PatchTemplatePrivate.h
   PB.project
   PerformerPrivate.h
   pitches.h
   platform.make
   ...efilePerformerPrivate.h
   ScorePerformerPrivate.h
   ScorePrivate.h
   ScoreRecorderPrivate.h
   SynthDataPrivate.h
   synthElementCFuncs.m
   synthElementMethods.m
   SynthInstrumentPrivate.h
   SynthPatchList.h
   SynthPatchList.m
   SynthPatchPrivate.h
   timetagInclude.m
   timeunits.h
   tokenNames.m
   tokens.h
   trigonometry.c
   trigonometry.h
   TuningSystemPrivate.h
   UnitGeneratorPrivate.h
   win32-def.top
   writeBinary.m
   writeMidi.m
   writeScore.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/*
 $Id: MKNoteReceiver.m,v 1.19 2006/02/05 17:57:10 leighsmith Exp $
 Defined In: The MusicKit
 HEADER FILES: MusicKit.h
 
 Description:
 See comments in MKNoteReceiver.h.
 
 Original Author: David A. Jaffe
 
 Copyright (c) 1988-1992, NeXT Computer, Inc.
 Portions Copyright (c) 1994 NeXT Computer, Inc. and reproduced under license from NeXT
 Portions Copyright (c) 1994 Stanford University
 Portions Copyright (c) 1999-2004, The MusicKit Project.
 */
/* 
Modification history before commit to CVS:
 
 09/19/89/daj - Changed dataObject to type void *.
 03/13/90/daj - Moved private methods to category.
 03/21/90/daj - Added archiving.
 04/21/90/daj - Small mods to get rid of -W compiler warnings.
 08/23/90/daj - Zone API changes
 09/06/90/daj - Fixed bug in archiving again.
 */

#import "_musickit.h"
#import "InstrumentPrivate.h"

@implementation MKNoteReceiver

/* Gets the owner (an MKInstrument or MKNoteFilter). */
- owner
{
    return owner;
}

/* TYPE: Querying; YES if aNoteSender is a connection.
* Returns YES if aNoteSender is connected to the receiver.
*/
- (BOOL) isConnected: (MKNoteSender *) aNoteSender 
{
    return [noteSenders indexOfObject: aNoteSender] != NSNotFound; 
}

/* TYPE: Squelch; Turns off message-sending capability.
* Squelches the receiver.  While a receiver is squelched it can't send
* messages to its noteSenders.
*
* Note:  You can schedule a sendNote: message through
* sendNote:atTime: or sendNote:withDelay even if the
* receiver is squelched.
* However, if the receiver is still squelched when the
* sendNote: message is received, the MKNote isn't sent.
*
* Returns the receiver.
*/
- squelch
{
    isSquelched = YES;
    // This shuts down any sounding notes, otherwise it can be very annoying when
    // the instrument such as an MKSamplerInstrument is playing a long sounding note.
    [owner allNotesOff];  
    return self;
}

/* TYPE: Squelch; Turns on message-sending capability.
* Unsquelches and returns the receiver.
*/
- unsquelch
{
    isSquelched = NO;
    return self;
}

/* TYPE: Querying; YES if the receiver is squelched.
* Returns YES if the receiver is squelched.
*/
- (BOOL) isSquelched
{
    return isSquelched;
}

/* TYPE: Querying; Returns the number of noteSenders.
* Returns the number of noteSenders in the
* receiver's connection set.
*/
- (unsigned) connectionCount
{
    return [noteSenders count];
}

/* TYPE: Manipulating; Returns a copy of the List of the connections.
* Returns a copy of the NSArray of the receiver's noteSenders. 
* The noteSenders themselves are not
* copied. TODO at the moment it is the sender's responsibility to free the NSArray.
*/
- (NSArray *) connections
{
    return _MKLightweightArrayCopy(noteSenders);
    // TODO should become return [_MKLightweightArrayCopy(noteSenders) autorelease];
}

#define VERSION2 2

+ (void) initialize
{
    if (self != [MKNoteReceiver class])
	return;
    [MKNoteReceiver setVersion: VERSION2];//sb: suggested by Stone conversion guide (replaced self)
}

- init 
{
    self = [super init];
    if(self != nil) {
	noteSenders = [[NSMutableArray alloc] init];
	owner = nil;
	dataObject = nil;
    }
    return self;
}

/* TYPE: Creating; Frees the receiver.
 * Frees the receiver. Illegal while the receiver is sending.
 * Also removes the name, if any, from the name table.
 */
- (void) dealloc
{
    if(noteSenders != nil) {
	// We have a retain cycle between MKNoteSenders and MKNoteReceivers since instances of both classes hold
	// (retaining) NSArrays of an arbitary number of the other class. The traditional way of dealing with such
	// a retain cycle is to assign one object as subordinated to the other, with the subordinate holding a
	// non-retained weak reference to the "superior" (retaining) object.
	// However storing the references in NSArrays themselves create retention. We therefore have a modified
        // policy: MKNoteReceivers are subordinated to MKNoteSenders, and they should inform the noteSenders here,
	// in dealloc, that they are no longer valid.
	// However, we can't just disconnect them since that would cause the noteSenders to each
	// attempt to remove their MKNoteReceivers from their noteReceivers NSArray, causing this dealloc method
	// to be called recursively and endlessly.
	// Two options seem possible: we temporarily retain our note receivers held by each of the note senders (!)
	// or reset the noteSenders connections to this receiver nil. Unfortunately that can't be done without NSArray
	// releasing the MKNoteReceiver element. 
	// The best option is to leave noteSenders connected to this note receiver and then release noteSenders and
	// require that any MKNoteReceivers explictly connected to an MKNoteSender must be disconnected from that
	// MKNoteSender.
	// [self disconnect];
	// NSLog(@"In MKNoteReceiver dealloc of %p, have disconnected, releasing %p\n", self, noteSenders);
	[noteSenders release];
	// NSLog(@"Released noteSenders %p\n", noteSenders);
	noteSenders = nil;	
    }
    [dataObject release];
    dataObject = nil;
    MKRemoveObjectName(self);
    [super dealloc];
}

/* TYPE: Creating; Creates a new MKNoteReceiver as a copy of the receiver.
* Creates, initializes, and returns a new MKNoteReceiver with the same noteSenders as the receiver.
*/
- copyWithZone: (NSZone *) zone
{
    unsigned n = [noteSenders count], i;
    MKNoteReceiver *newObj = NSCopyObject(self, 0, zone);
    newObj->noteSenders = [[NSMutableArray arrayWithCapacity: [noteSenders count]] retain];
    for (i = 0; i < n; i++)
        [newObj connect: [noteSenders objectAtIndex: i]];
    newObj->dataObject = nil;
    newObj->owner = nil;
    return newObj;
}

// Disconnects aNoteSender from the receiver. We do this by requesting the MKNoteSender to disconnect from us.
// This concentrates responsibility (and more concretely object allocation management) with the MKNoteSender.
- disconnect: (MKNoteSender *) aNoteSender
{
    if (!aNoteSender)
	return self;
    
    // Inform the note sender to disconnect from us.
    if ([aNoteSender _disconnect: self]) {
        [self _disconnect: aNoteSender];
    }
    return self;
}	

- disconnect
{
    /* Need to copy since MKNoteSender -disconnect: modifies contents. */
    NSMutableArray *allOfOurNoteSenders = _MKLightweightArrayCopy(noteSenders);
    // NSLog(@"MKNoteReceiver %p disconnecting all note senders %@\n", self, allOfOurNoteSenders);
    [allOfOurNoteSenders makeObjectsPerformSelector: @selector(disconnect:) withObject: self];
    [allOfOurNoteSenders release];
    return self;
}

/* TYPE: Manipulating; Connects aNoteSender to the receiver.
* Connects aNoteSender to the receiver 
* and returns self.  
*/
- connect: (MKNoteSender *) aNoteSender 
{
    if (![aNoteSender isKindOfClass: [MKNoteSender class]])
	return self;
    if ([self _connect: aNoteSender])  /* Success ? */
	[aNoteSender _connect: self];    /* Make other-way link */
    return self;
}

// Receiving; Forwards note to its owner, unless squelched.
- receiveNote: (MKNote *) aNote
{
    if (isSquelched)
	return nil;
    [owner _realizeNote: aNote fromNoteReceiver: self];
    return self;
}

 /* TYPE: Receiving; Receive MKNote at time specified in beats.
Receives the specifed note at the specified time using
the note's Conductor for time coordination. */
- receiveNote: (MKNote *) aNote atTime: (double) time 
{
    [[aNote conductor] sel: @selector(receiveNote:) to: self atTime: time  argCount: 1, aNote];
    return self;
}

/* Receives the specifed note, delayed by delayTime from the
current time, as far as the note's conductor is concerned. 
Uses the note's Conductor for time coordination. */
- receiveNote: (MKNote *) aNote withDelay: (double) delayTime
{
    [[aNote conductor] sel: @selector(receiveNote:) to: self withDelay: delayTime argCount: 1, aNote];
    return self;
}

- (void) encodeWithCoder: (NSCoder *) aCoder
{
    // Check if decoding a newer keyed coding archive
    if([aCoder allowsKeyedCoding]) {
	NSString *objectName = MKGetObjectName(self);
	
	[aCoder encodeConditionalObject: noteSenders forKey: @"MKNoteReceiver_noteSenders"];
	[aCoder encodeObject: objectName forKey: @"MKNoteReceiver_objectName"];
	[aCoder encodeBool: isSquelched forKey: @"MKNoteReceiver_isSquelched"];
	[aCoder encodeConditionalObject: owner forKey: @"MKNoteReceiver_owner"];
    }
    else {
	NSString *str;
	
	str = MKGetObjectName(self);
	[aCoder encodeConditionalObject: noteSenders];
	[aCoder encodeValuesOfObjCTypes: "@c", &str, &isSquelched];
	[aCoder encodeConditionalObject: owner];	
    }
}

- (id) initWithCoder: (NSCoder *) aDecoder
{
    // Check if decoding a newer keyed coding archive
    if([aDecoder allowsKeyedCoding]) {
	NSString *objectName;

	[noteSenders release];
	noteSenders = [[aDecoder decodeObjectForKey: @"MKNoteReceiver_noteSenders"] retain];
	objectName = [aDecoder decodeObjectForKey: @"MKNoteReceiver_objectName"];
	if (objectName) {
	    MKNameObject(objectName, self);
	}
	isSquelched = [aDecoder decodeBoolForKey: @"MKNoteReceiver_isSquelched"];
	[owner release];
	owner = [[aDecoder decodeObjectForKey: @"MKNoteReceiver_owner"] retain];
    }
    else {
	NSString *str;
	
	if ([aDecoder versionForClassName: @"MKNoteReceiver"] == VERSION2) {
	    noteSenders = [[aDecoder decodeObject] retain];
	    
	    [aDecoder decodeValuesOfObjCTypes: "@c", &str, &isSquelched];
	    if (str) {
		MKNameObject(str, self);
	    }
	    owner = [[aDecoder decodeObject] retain];
	}	
    }
    return self;
}

@end

@implementation MKNoteReceiver(Private)

/* Sets the owner (an MKInstrument or MKNoteFilter). In most cases,
only the owner itself sends this message. 
*/
- _setOwner: obj
{
    owner = obj; // Don't retain as this is a weak reference.
    return self;
}

/* Facility for associating an arbitrary datum in a MKNoteReceiver */
- (void) _setData: (id) anObj 
{
    [dataObject release];
    dataObject = [anObj retain];
}

- (id) _getData
{
    return [[dataObject retain] autorelease];
}

- _connect: (MKNoteSender *) aNoteSender
{
    if ([noteSenders indexOfObject: aNoteSender] != NSNotFound)  /* Already there. */
	return nil;
    [noteSenders addObject: aNoteSender];
    return self;
}

- _disconnect: (MKNoteSender *) aNoteSender
{
    unsigned int returnedIndex;
    
    if ((returnedIndex = [noteSenders indexOfObjectIdenticalTo: aNoteSender]) != NSNotFound) {
        [noteSenders removeObjectAtIndex: returnedIndex];
        return self; /* Returns aNoteSender if success */
    }
    /*    if ([noteSenders removeObject:aNoteSender])       return self;
    */
    return nil;
}

@end

About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us