download _SharedSynthInfo.m
Language: ObjectiveC
Copyright: (c) 1988-1992, NeXT Computer, Inc. (c) 1994 NeXT Computer, Inc. and reproduced under license from NeXT (c) 1994 Stanford University (c) 1999-2000 The MusicKit Project
LOC: 168
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: _SharedSynthInfo.m,v 1.7 2006/02/05 17:57:10 leighsmith Exp $
  Defined In: The MusicKit

  Description:
    Need to document that you must never free an object that was installed
    in the shared data table during a performance, even if its reference count 
    has gone to 0. You may free it after the performance.

    That's because I don't remove the mapping from the object (e.g partials
    object) to the List of sharedDataInfos.

  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-2000 The MusicKit Project
*/
/* 
Modification history:

  $Log: _SharedSynthInfo.m,v $
  Revision 1.7  2006/02/05 17:57:10  leighsmith
  Cleaned up prototypes for Xcode 2.2 as it is much more strict about mixing id with a defined type

  Revision 1.6  2002/01/29 16:05:59  sbrandon
  re-typed _MKOrchTrace calls to use NSString

  Revision 1.5  2000/10/01 06:37:16  leigh
  Changed NXHashTable functions to FoundationKit NSHashTable functions.

  Revision 1.4  2000/06/09 03:16:09  leigh
  Typed ivars

  Revision 1.3  1999/11/07 05:11:26  leigh
  Doco cleanup and removal of redundant HashTable include

  Revision 1.2  1999/07/29 01:26:01  leigh
  Added Win32 compatibility, CVS logs, SBs changes

  11/20/89/daj - Changed to do lazy garbage collection of synth data. 
  11/17/92/daj - Minor change to shut up compiler warning
  9/25/93/daj -  Updated for new typed sharedSynthInfo
*/ 
#import "_musickit.h"
#import "UnitGeneratorPrivate.h"
#import "_SharedSynthInfo.h"
#import "OrchestraPrivate.h"

@implementation _SharedSynthInfo: NSObject

/* The shared object table is a NSMutableDictionary that hashes from id (e.g. MKPartials
object) to a NSMutableArray object. The NSMutableArray is a NSMutableArray of _SharedSynthInfos.
Each _SharedSynthInfo contains a back-pointer to the NSMutableArray. */

enum {obj, objSegment, objSegmentLength};

/* Functions for freeing just the values of the table. */

#if 0
static void freeObject (void *aList) 
{
    _SharedSynthInfo *el;
    id myList = (id)aList;
    unsigned noteIndex;

    for (noteIndex = 0; noteIndex < [myList count]; noteIndex++) {
      el = [myList objectAtIndex: noteIndex];
      [el->synthObject _setShared:nil];
    }
    [myList removeAllObjects];
    [myList release];
};
    
static void noFree (void *item) {};
#endif

id _MKFreeSharedSet(NSMutableDictionary *sharedSet, NSHashTable **garbageTable)
{
    NSEnumerator *enumerator = [sharedSet objectEnumerator];
    id myList;
    unsigned noteIndex;

    while ((myList = [enumerator nextObject])) {
        for (noteIndex = 0; noteIndex < [myList count]; noteIndex++) {
            [((_SharedSynthInfo *)([myList objectAtIndex: noteIndex]))->synthObject _setShared:nil];
        }
        [myList removeAllObjects];
    }
    [sharedSet removeAllObjects];
//    [sharedSet freeKeys:noFree values:freeObject];
    NSFreeHashTable(*garbageTable);
    *garbageTable = NULL;
    [sharedSet release];
    return nil; /* sb: nil for compatibility with old -free method */
}

NSMutableDictionary* _MKNewSharedSet(NSHashTable **garbageTable)
{
    static NSHashTableCallBacks proto = {NULL, NULL, NULL, NULL, NULL};
    // proto.free = NXNoEffectFree
    *garbageTable = NSCreateHashTable(proto, 0);
    return [[NSMutableDictionary alloc] initWithCapacity:4];
}

static void reallyRelease(_SharedSynthInfo *aSharedSynthInfo)
{
    [aSharedSynthInfo->theList removeObject:aSharedSynthInfo];
    [aSharedSynthInfo release];
}

BOOL _MKReleaseSharedSynthClaim(_SharedSynthInfo *aSharedSynthInfo, BOOL lazy)
    /* Returns YES if still in use or slated for garbage collection.
       Returns NO if it can be deallocated now. */
{
    if (--aSharedSynthInfo->referenceCount > 0)
        return YES; /* Still in use */
#   define ORCH [aSharedSynthInfo->synthObject orchestra]
    if (lazy) {
	NSHashInsert(_MKGetSharedSynthGarbage(ORCH),
		     (const void *)aSharedSynthInfo); 
	return YES;
    }
    else reallyRelease(aSharedSynthInfo);
    return NO;
}

void _MKAddSharedSynthClaim(_SharedSynthInfo *aSharedSynthInfo)
{
    aSharedSynthInfo->referenceCount++;
}

int _MKGetSharedSynthReferenceCount(_SharedSynthInfo *aSharedSynthInfo)
{
    return aSharedSynthInfo->referenceCount;
}

static id findSharedSynthInfo(id aList,MKOrchMemSegment whichSegment,int howLong,MKOrchSharedType type)
{
    register _SharedSynthInfo *el;
    unsigned noteIndex;
    BOOL test = 0; /* Initialize it to shut up compiler warning */
    BOOL isEqualFlag = ((whichSegment == MK_noSegment) ? obj : 
			(howLong == 0) ? objSegment : objSegmentLength);
    for (noteIndex = 0; noteIndex < [aList count]; noteIndex++) {
        el = [aList objectAtIndex: noteIndex];
	switch (isEqualFlag) {
	  case obj:
	    test = YES;
	  case objSegment:
	    test = (whichSegment == (el)->segment);
	    break;
	  case objSegmentLength:
	    test = ((whichSegment == (el)->segment) && (howLong == (el)->length));
	    break;
	}
	if (test) {
	    if ((type == MK_noOrchSharedType) || (type == (el)->type))
	      return (el);
	}
    }
    return nil;
}

id _MKFindSharedSynthObj(NSMutableDictionary* sharedSet,NSHashTable *garbageTable,id aKeyObj,
			 MKOrchMemSegment whichSegment,int howLong,
			 MKOrchSharedType type)
{
    id aList = [sharedSet objectForKey:[NSValue valueWithNonretainedObject:aKeyObj]];
    id rtnVal;
    _SharedSynthInfo *aSharedSynthInfo;
    if (!aList)
      return nil;
    aSharedSynthInfo = findSharedSynthInfo(aList,whichSegment,howLong,type);
    if (!aSharedSynthInfo)
      return nil;
    rtnVal = aSharedSynthInfo->synthObject;
    if (aSharedSynthInfo->referenceCount == 0)   /* Was lazily deallocated */
      NSHashRemove(garbageTable,(const void *)aSharedSynthInfo);
    [rtnVal _addSharedSynthClaim];
    return rtnVal;
}	

BOOL _MKCollectSharedDataGarbage(id orch,NSHashTable *garbageTable)
    /* Deallocates all garbage and empties the table. */
{
    id dataObj;
    BOOL gotOne = NO;
    _SharedSynthInfo *infoObj;
    NSHashEnumerator state = NSEnumerateHashTable(garbageTable);
    if (_MK_ORCHTRACE(orch, MK_TRACEORCHALLOC)) {
        NSLog(@"MK OK\n");
        _MKOrchTrace(orch, MK_TRACEORCHALLOC,
		   @"Garbage collecting unreferenced shared data.");
    }
    while ((infoObj = (_SharedSynthInfo *) NSNextHashEnumeratorItem(&state))) {
	gotOne = YES;
	dataObj = infoObj->synthObject;
	[dataObj _setShared:nil];
	reallyRelease(infoObj);
	_MKDeallocSynthElement(dataObj,NO);
        [dataObj release];/* since we were holding the retain in the _SharedSynthInfo,
            		   * we don't release the dataObj in a -dealloc method, we do it here */
    }
    if (gotOne)
        NSResetHashTable(garbageTable);
    else if (_MK_ORCHTRACE(orch,MK_TRACEORCHALLOC))
        _MKOrchTrace(orch,MK_TRACEORCHALLOC,@"No unreferenced shared data found.");
    return gotOne;
}	

BOOL _MKInstallSharedObject(NSMutableDictionary* sharedSet,id aSynthObj,
			    id aKeyObj,MKOrchMemSegment whichSegment,
			    int howLong,MKOrchSharedType whichType)
    /* Returns NO if object is already in Set */
{
    _SharedSynthInfo *aSharedSynthInfo;
    NSMutableArray *aList = nil;
    id idKey = [NSValue valueWithNonretainedObject:aKeyObj];
    aList = [sharedSet objectForKey:idKey];
    if (!aList) {
	aList = [[NSMutableArray alloc] init];
        [sharedSet setObject:aList forKey:idKey];
        [aList release];/* retain is now held in sharedSet */
    }
    else if (findSharedSynthInfo(aList,whichSegment,howLong,whichType))
      return NO;
    aSharedSynthInfo = [_SharedSynthInfo new];
    aSharedSynthInfo->synthObject = [aSynthObj retain];
    aSharedSynthInfo->theList = aList;
    aSharedSynthInfo->theKeyObject = aKeyObj;
    aSharedSynthInfo->segment = whichSegment;
    aSharedSynthInfo->length = howLong;
    aSharedSynthInfo->type = whichType;
    aSharedSynthInfo->referenceCount = 0;
    [aList addObject:aSharedSynthInfo];
    [aSynthObj _setShared:aSharedSynthInfo];
    _MKAddSharedSynthClaim(aSharedSynthInfo);
    return YES;
}

@end

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