download MKPartPerformer.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: 158
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

/*
 $Id: MKPartPerformer.m,v 1.11 2004/01/29 22:30:16 leighsmith Exp $
 Defined In: The MusicKit
 HEADER FILES: MusicKit.h

 CF: MKScorePerformer, MKPart

 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 commital to the CVS repository:

04/21/90/daj - Small mods to get rid of -W compiler warnings.
08/23/90/daj - Changed to zone API.
12/04/90/daj - Fixed bug in copyFromZone: (thanks to lbj)
02/06/92/daj - Fixed bug in activate that could cause note before
firstTimeTag to play, if it's the last note.
06/29/93/daj - Fixed bug in activate that would cause the MKPerformer to
wait unnecessarily in the case where there are no notes
between firstTimeTag and lastTimeTag, but where there
is a note after lastTimeTag.
11/01/94/daj - Added argument to _partPerformerDidDeactivate:.
06/19/98/sb  - Changed noteIndex and noteCount to Array indices rather than addresses
this is because we can't use NX_ADDRESS to step through the
array contents any more. (OpenStep conversion)
*/

#import "_musickit.h"

#import "PartPrivate.h"
#import "ScorePerformerPrivate.h"
#import "MKPartPerformer.h"

@implementation MKPartPerformer

#import "timetagInclude.m"

void _MKSetScorePerformerOfPartPerformer(MKPartPerformer *aPP, id aSP)
{
  aPP->scorePerformer = aSP;
}

#define VERSION2 2

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

static BOOL fastActivation = NO;

+ setFastActivation: (BOOL) yesOrNo
{
    fastActivation = YES;
    return self;
}

+ (BOOL) fastActivation
{
    return fastActivation;
}

- init
  /* You never send this message. Subclass may implement it but must
  send [super initialize] before doing its own initialization. Sent
  once when an instance is created. Creates the single noteSender
  and adds the noteSender to the superclass cltn. */
{
    self = [super init];
    if (self) {
	lastTimeTag = MK_ENDOFTIME;
	[self addNoteSender: [MKNoteSender new]];    /* The object's only MKNoteSender. */
    }
    return self;
}

- (void) encodeWithCoder: (NSCoder *) aCoder
/* TYPE: Archiving; Writes object.
  You never send this message directly.
  Should be invoked with NXWriteRootObject(). 
     Invokes superclass write: then archives firstTimeTag and lastTimeTag.
  Optionally archives part using NXWriteObjectReference().
  */
{
  [aCoder encodeConditionalObject: part];
  [aCoder encodeValuesOfObjCTypes: "dd", &firstTimeTag, &lastTimeTag];
  [aCoder encodeConditionalObject: scorePerformer];
}

- (id) initWithCoder: (NSCoder *) aDecoder
  /* You never send this message directly.
  Should be invoked via NXReadObject().
          See write:. */
{
  if ([aDecoder versionForClassName: @"MKPartPerformer"] == VERSION2) {
    part = [[aDecoder decodeObject] retain];
    [aDecoder decodeValuesOfObjCTypes: "dd", &firstTimeTag, &lastTimeTag];
    scorePerformer = [[aDecoder decodeObject] retain];
  }

  return self;
}

- (void) dealloc
  /* If receiver is a member of a MKScorePerformer or is active, returns self
  and does nothing. Otherwise frees the receiver. */
{
  /*sb: FIXME!!! This is not the right place to decide whether or not to dealloc.
  * maybe need to put self in a global list of non-dealloced objects for later cleanup */
  if ((status != MK_inactive) || scorePerformer) {
    NSLog(@"MkPart::dealloc  dealloc aborted - in performance. Fix!");
    return;
  }
  if (part)
    [part release];
  [super dealloc];
}

- copyWithZone: (NSZone *) zone;
       /* TYPE: Copying: Returns a copy of the receiver.
  * Creates and returns a new inactive MKPerformer as
  * a copy of the receiver.
  * The new object has the same timeShift and
  * duration values as the reciever. Its
  * time and nextPerform variables
  * are set to 0.0. It has its own noteSenders which contains
  * copies of the values in the receiver's collection. The copies are
* added to the collection by addNoteSender:.
  */
{
    MKPartPerformer *newObj = [super copyWithZone:zone];
    newObj->noteArray = nil;
    newObj->noteIndex = -1; /* sb: was NULL */
    newObj->noteCount = -1; /* sb: was NULL */
    newObj->scorePerformer = nil;
    //sb: do we need to retain and autorelease this? Or is this done
    // as part of [super copyWithZone:zone] ?
    return newObj;
}

- setPart: (MKPart *) aPart
    /* Sets MKPart over which we sequence.
    If the receiver is active, does nothing and returns nil. Otherwise
    returns self. */
{
    if (status != MK_inactive)
	return nil;
    [part release];
    part = [aPart retain];
    return self;
}

- (MKPart *) part
{
    return [[part retain] autorelease];
}

- activateSelf
  /* TYPE: Performing
  * Activates the receiver for a performance. The MKPart is snapshotted at
  * this time. Any subsequent changes to the MKPart will not affect the
  * current performance. Returns the receiver.
  */
     /*sb: I have had to change noteIndex and noteCount to Array indices rather than addresses.
  * this is because we can't use NX_ADDRESS to step through the array contents any more.
  */
{
    MKNote *tmpNote;
    double tTag = 0;
    
    if (!part)
	return nil;
    [part _addPerformanceObj: self];
    if (!fastActivation)
	noteArray = [[part notes] retain]; // notes returns an autoreleased array of new notes and needs retaining */
    else {
	[part sort];
	noteArray = [part notesNoCopy]; // this is autoreleased
    }
    
    noteIndex = 0;
    noteCount = [noteArray count];
    nextNote = nil;
    while (noteIndex != noteCount) {
	tmpNote = [noteArray objectAtIndex: noteIndex++];
	tTag = [tmpNote timeTag];
	if (tTag >= firstTimeTag) {
	    nextNote = tmpNote;
	    break;
	}
    }
    if (!nextNote || tTag > lastTimeTag) {
	if (!fastActivation)
	    [noteArray release];
	noteArray = nil;
	noteIndex = -1;
	noteCount = -1;
	[part _removePerformanceObj: self];
	return nil;
    }
    nextPerform = tTag;
    return self;
}

- (void) deactivate
  /* TYPE: Performing
    * Finalization method sent when receiver is deactivated.
    */
{
    [super deactivate];  // need to stop the performance.
    // TODO we have to do the casting since notesNoCopy returns an NSMutableArray
    // and noteArray is an NSArray, we should investigate why notesNoCopy returns a
    // mutable array, it should be the job of the method using the result to
    // reset it's mutability.
    if ((NSArray *) [part notesNoCopy] != noteArray) /* Was copied. */
	[noteArray release];
    noteArray = nil;
    noteIndex = noteCount = -1;
    [part _removePerformanceObj: self];
    [scorePerformer _partPerformerDidDeactivate: self];
}

-perform
  /* TYPE: Performing
    * Sends nextNote and specifies the next time to perform.
    * Returns the receiver. You never send this message directly to an instance.
    * Rather, it is invoked by the MKConductor.
    * You may override this method, e.g. to modify the note before it is
    * performed or to modify nextPerform,
    * but you must send [super perform] to perform the note.
    */
{
    double t = [nextNote timeTag];
    double tNew;
    MKNoteSender *noteSender = [self noteSender];
    
    if (performCount == 1 && (firstTimeTag > 0)) {  /* Send all noteUpdates up to now */
	int noteType;
	NSEnumerator *enumerator = [noteArray objectEnumerator];
	MKNote *aNote;
	
	while ((aNote = [enumerator nextObject])) {
	    if (aNote == nextNote)
		break;
	    noteType = [aNote noteType];
	    if (noteType == MK_noteUpdate || noteType == MK_mute)
		[noteSender sendNote: aNote];
	}
    }
    [noteSender sendNote: nextNote];
    if (noteIndex < noteCount) {
	nextNote = [noteArray objectAtIndex: noteIndex++];
	tNew = [nextNote timeTag];	
	nextPerform = tNew - t;
	if (tNew > lastTimeTag) {
	    [self deactivate];	
	}
    }
    else
	[self deactivate];	

    return self;
}

@end

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