download MKFilePerformer.m
Language: ObjectiveC
Copyright: (c) 1988-1992, NeXT Computer, Inc. (c) 1994 Stanford University. (c) 1994 NeXT Computer, Inc. and reproduced under license from NeXT (c) 1999-2005, The MusicKit Project.
LOC: 159
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
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
/*
  $Id: MKFilePerformer.m,v 1.14 2005/05/11 02:13:30 leighsmith Exp $
  Defined In: The MusicKit
  HEADER FILES: MusicKit.h

  Description:
    A MKFilePerformer reads data from a file on the disk,
    fashions a MKNote object from the data, and then performs
    the MKNote.  An abstract superclass, MKFilePerformer
    provides common functionality and declares subclass responsibilities
    for the subclasses
    MKMidifilePerformer and MKScorefilePerformer.
   
    Note: In release 1.0, MKMidifilePerformer is not provided. Use a MKScore object
    to read a Midifile.
   
    A MKFilePerformer is associated with a file, either by the
    file's name or with a file pointer.  If you assoicate
    a MKFilePerformer with a file name (through the setFile:
    method) the object will take care of opening and closing
    the file for you:  the file is opened for reading when the
    MKFilePerformer receives the activate message and closed when
    it receives deactivate.
   
    The setStream: method associates a MKFilePerformer with a file
    pointer.  In this case, opening and closing the file
    is the responsibility of the application.  The MKFilePerformer's
    file pointer is set to NULL after each performance
    so you must send another
    setStream: message in order to replay the file.
   
    Note:  The argument to -setStream: is a NSData or NSMutableData.
   
    The MKFilePerformer class declares two methods as subclass responsibilities:
    nextNote and performNote:.
    nextNote must be subclassed to access the next line of information
    from the file and from it create either a MKNote object or a
    time value.  It
    returns the MKNote that it creates, or, in the case of a time value,
    it sets the instance variable fileTime to represent
    the current time in the file
    and returns nil.
   
    The MKNote created by nextNote is passed as the argument
    to performNote: which
    is responsible
    for performing any manipulations on the
    MKNote and then sending it
    by invoking sendNote:.  The return value of performNote:
    is disregarded.
   
    Both nextNote and performNote: are invoked
    by the perform method, which, recall from the MKPerformer
    class, is itself never called directly but is sent by a Conductor.
    perform also checks and incorporates the time limit
    and performance offset established by the timing window
    variables inherited from MKPerformer; nextNote and
    performNote: needn't access nor otherwise be concerned
    about these variables.
   
    Two other methods, initFile and finishFile, can
    be redefined by a MKFilePerformer subclass, although neither
    must be.  initializeFile is invoked
    when the object is activated and should perform any special
    initialization such as reading the file's header or magic number.
    If initializeFile returns nil, the MKFilePerformer is deactivated.
    The default returns the receiver.
   
    finishFile is invoked when the MKFilePerformer is deactivated
    and should perform any post-performance cleanup.  Its return
    value is disregarded.
   
    A MKFilePerformer reads and performs one MKNote at a time.  This
    allows efficient performance of arbitrarily large files.
    Compare this to the MKScore object which reads and processes the entire file
    before performing the first note.  However, unlike the MKScore object,
    the MKFilePerformer doesn't allow individual timing control over the
    different MKNote streams in the file; the timing window
    specifications inherited from MKPerformer are applied to the entire
    file.
   
    Any number of MKFilePerformers can perform the
    same file concurrently.
 
  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-2005, The MusicKit Project. 
*/
/* 
Modification history prior to commit to CVS repository:

  10/26/89/daj - Added class method fileExtensions for binary scorefile
                 support.
  01/08/90/daj - Flushed _str method. 
  03/21/90/daj - Added archiving. Changed to use _extraVars struct.
  04/21/90/daj - Small mods to get rid of -W compiler warnings.
  08/23/90/daj - Changed to zone API.
  03/04/91/daj - Fixed bug in copy and free of _extraVars.
  11/17/92/daj - Flushed _extraPerformerVars to go along with MKPerformer change.
*/

#import "_musickit.h"
#import "_error.h"
#import "PerformerPrivate.h"
#import "MKFilePerformer.h"

@implementation MKFilePerformer

/* METHOD TYPES
 * Initializing a MKFilePerformer
 * Accessing files
 * Accessing MKNotes
 * Performing
 */

#import "timetagInclude.m"

/* Special factory methods. ---------------------------------------- */

#define VERSION2 2

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

- (void) encodeWithCoder: (NSCoder *) aCoder
  /* You never send this message directly.  
     Should be invoked with NXWriteRootObject(). 
     Invokes superclass write: method. Then archives filename, 
     firstTimeTag, and lastTimeTag. 
     */
{
    [super encodeWithCoder: aCoder];
    [aCoder encodeValuesOfObjCTypes: "*ddd", &filename, &firstTimeTag, &lastTimeTag];
}

- (id) initWithCoder: (NSCoder *) aDecoder
  /* You never send this message directly.  
     Should be invoked via NXReadObject(). 
     See write:. */
{
    [super initWithCoder: aDecoder];
    if ([aDecoder versionForClassName: @"MKFilePerformer"] == VERSION2) {
	[aDecoder decodeValuesOfObjCTypes: "*ddd", &filename, &firstTimeTag, &lastTimeTag];
    }
    return self;
}

- init
  /* TYPE: Initializing; Sent automatically on instance creation.
   * Initializes the receiver by setting stream and filename
   * to NULL.
   * Sent by the superclass upoon creation.
   * You never invoke this method directly.
   * An overriding subclass method should send [super initDefaults]
   * before setting its own defaults. 
   */
{
    self = [super init];
    if(self != nil) {
	lastTimeTag = MK_ENDOFTIME;	
    }
    return self;
}

- (void) dealloc
{
    [filename release];
    filename = nil;
    [super dealloc];
}

- setFile: (NSString *) aName
  /* TYPE: Modifying; Associates the receiver with file aName.
   * Associates the receiver with file aName. The string is copied.
   * The file is opened when the first MKNote is realized
   * (written to the file) and closed at the end of the
   * performance.
   * It's illegal to invoke this method during a performance. Returns nil
   * in this case. Otherwise, returns the receiver.
   */
{
    if (status != MK_inactive) 
      return nil;
    [filename autorelease];
    filename = [aName copy];
//    filename = _MKMakeStr(aName);
    stream = nil;
    return self;
}

- setStream: (id) aStream
/* * Either NSMutableData, or NSData
   * Sets stream to aStream and sets filename to NULL.
   * aStream must be open for
   * reading.  Returns the receiver.
   * Illegal while the receiver is active. Returns nil in this case, otherwise
   * self.
   */
{
    if (status != MK_inactive) 
        return nil;
    [self setFile: nil];
    [stream autorelease];
    stream = [aStream retain];
    return self;
}

- (id) stream
  /* Either NSMutableData, or NSData
   * Returns the file pointer associated with the receiver
   * or nil if it isn't set.
   * Note that if the file was specified with file: and
   * the performer is inactive (i.e. the file isn't open), this will return
   * nil.
   */
{
    return stream;
}

- (NSString *) file
  /* TYPE: Querying; Returns the name set through setFile:.
   * If the file associated with the receiver was set through 
   * setFile:,
   * returns the file name, otherwise returns NULL.
   */
{
    return filename;
}

+ (NSString *) fileExtension
  /* Returns default file extension for files managed by the subclass. The
     default implementation returns nil. Subclass may override this to
     specify a default file extension. */
{
    return nil;
}

+ (NSArray *) fileExtensions
  /* This method is used when several file extensions must be handled. 
     The value returned by this method is a pointer to a null-terminated
     array of strings, each of which is a valid file extension for files
     handled by the subclass.  Subclass may override this to specify a default 
     file extension.  The default implementation returns 
     an array with one element equal to [self fileExtension]. */
{
    return [NSArray arrayWithObject: [self fileExtension]];
}

/* Methods required by superclasses. ------------------------------- */

- activateSelf
  /* TYPE: Performing; Prepares the receiver for a performance.
   * Invoked by the activate method, this prepares the receiver 
   * for a performance by opening the associated file (if necessary)
   * and invoking nextNote until it returns 
   * an appropriate MKNote -- one with 
   * a timeTag between firstTimeTag
   * and lastTimeTag, inclusive.
   * If an appropriate MKNote isn't found 
   * [self\ deactivate] is sent. 
   *
   * You never send the activateSelf message directly to 
   * a MKFilePerformer.  
   */
{
    if (filename) {
	NSArray *fileExt = [[self class] fileExtensions];
        unsigned int fileExtensionsIndex;

        for (fileExtensionsIndex = 0; fileExtensionsIndex < [fileExt count]; fileExtensionsIndex++) {
/*	    stream = _MKOpenFileStream(filename,&(_fd(self)),NX_READONLY,
				       *fileExt,NO);
 */
            stream = _MKOpenFileStreamForReading(filename, [fileExt objectAtIndex: fileExtensionsIndex], NO);//sb
            if (stream) {
                [stream retain];
                break;
            }
	} 
	if (!stream)
	  MKErrorCode(MK_cantOpenFileErr, filename);
    }
    fileTime = 0;
    if ((!stream) || (![self initializeFile])) 
      return nil;
    [noteSenders makeObjectsPerformSelector: @selector(_setPerformer:) withObject: self];
    /* The first element in the file may be a time or a note. If it's a note,
       than its time is implicitly 0. Since we don't lookahead unless 
       firstTimeTag > 0, it is guaranteed that this note will not be overlooked.
       */
    if (firstTimeTag > 0) {
        for (; ;) {
            [self nextNote];
            if (fileTime > (MK_ENDOFTIME-1))  {
                [self deactivate];
                return nil;
            }
            if (fileTime >= firstTimeTag)
                break;
        }
    }
    /* Insure we run for the first time on our first note. */
//  nextPerform = fileTime - firstTimeTag;
    nextPerform = fileTime;
    return self;
}

- perform 
  /* TYPE: Performing
   * Grabs the next MKNote out of the file through nextNote,
   * processes it through 
   * performNote: (the method that sends the MKNote), and
   * sets the value of nextPerform. 
   * You may override this method to modify nextPerform, but you must
   * send [super perform].
   * You never send perform directly to an object.
   * Returns the receiver.
   */
{
    MKNote *aNote;
    double t = fileTime;
    
    while ((aNote = [self nextNote])) {
      [aNote retain]; /* to be on the safe side */
      [self performNote: aNote];
      [aNote release];
    }
    if (fileTime > (MK_ENDOFTIME-1) || fileTime >= lastTimeTag) 
      [self deactivate];
    else 
      nextPerform = fileTime - t;
    return self;
}

/* Methods which must be supplied by subclass. ---------------- */

- performNote: (MKNote *) aNote
  /* TYPE: Accessing MKNotes
   * This is a subclass responsibility expected to manipulate
   * and send aNote which was presumably just read from a file.
   * It's up to the subclass to free aNote. 
   *
   * You never send the performNote: message 
   * directly to a MKFilePerformer; it's invoked by the perform
   * method.
   */
{
    [NSException raise: NSInvalidArgumentException format: @"*** Subclass responsibility: %s", NSStringFromSelector(_cmd)];
    return nil;
}

- (MKNote *) nextNote     
  /* TYPE: Accessing MKNotes
   * This is a subclass responsibility expected to get the next MKNote
   * from the file.  Should return the MKNote or nil if the
   * next file entry is a performance time.  In the latter case,
   * this should update fileTime.
   *
   * You never send the nextNote message 
   * directly to a MKFilePerformer; it's invoked by the perform
   * method.
   */
{
    [NSException raise: NSInvalidArgumentException format: @"*** Subclass responsibility: %s", NSStringFromSelector(_cmd)];
    return nil;
}

- initializeFile
  /* TYPE: Performing; Preparing the file for a performance.
   * This is a subclass responsibility expected to perform 
   * any special file initialization and return the receiver.
   * If nil is returned, the receiver is deactivated.
   *
   * You never send the initializeFile message 
   * directly to a MKFilePerformer; it's invoked by the activateSelf
   * method.
   *
   */
{
    return self;
}

- (void) deactivate 
  /* TYPE: Performing; Cleans up after a performance.
   * Invokes finishFile, closes the file (if it was 
   * set through setFile:), and sets the file pointer
   * to NULL.
   */
{
   [super deactivate];  // added by LMS - never stopped the performance.
   if (stream)
     [self finishFile];
   if (filename) {
       [stream release];
   }
   stream = nil;
}

- finishFile
  /* TYPE: Performing; Cleans up after a performance.
   * Subclass should override this to do any cleanup
   * needed after a performance -- however, you shouldn't 
   * close the file pointer as part of this method.
   *
   * You never send the finishFile message directly to a
   * MKFilePerformer; it's invoked by the deactivate method.
   */
{
    return self;
} 

- copyWithZone: (NSZone *) zone
  /* The returned value is a copy of the receiver, with a copy of the filename
     and stream set to NULL. The MKNoteSenders are not copied (the superclass
     copy method is overridden); instead, an empty list is given.  */
{
    MKFilePerformer *newObj = [super _copyFromZone: zone];
    newObj->filename = [filename copy]; //_MKMakeStr(filename);
    newObj->stream = nil;
    return newObj;
}

@end

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