/* Copyright: © Copyright 2004 Apple Computer, Inc. All rights reserved. Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Computer, Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* File: SMACDispatch.c Contains: Common dispatching for SMAC Written by: Jim Reekes and Kip Olson Copyright: © 1992-1997, 1999-2001 by Apple Computer, Inc., all rights reserved. */ #include #include #if !TARGET_API_MAC_CARBON #include #include #include #include #include #include #include #include #include #endif #if TARGET_API_MAC_CARBON #define GLUE(a,b) a##b #define GLUE2(a,b) GLUE(a,b) #define GLUE3(a,b,c) GLUE2(GLUE2(a,b),c) #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Sound Component Function Prototypes //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // unless SoundComponentBaseName is define, none of the dispatching code will be included #ifdef SoundComponentBaseName // The SoundComponentBaseName is used to concatenate unique routine names. #define SoundComponentDispatch GLUE2(SoundComponentBaseName(), Dispatch) #define __SoundComponentOpen GLUE3(__, SoundComponentBaseName(), Open) #define __SoundComponentClose GLUE3(__, SoundComponentBaseName(), Close) #define __SoundComponentCanDo GLUE3(__, SoundComponentBaseName(), CanDo) #define __SoundComponentVersion GLUE3(__, SoundComponentBaseName(), Version) #define __SoundComponentRegister GLUE3(__, SoundComponentBaseName(), Register) #define __SoundComponentInitOutputDevice GLUE3(__, SoundComponentBaseName(), InitOutputDevice) #define __SoundComponentSetSource GLUE3(__, SoundComponentBaseName(), SetSource) #define __SoundComponentGetSource GLUE3(__, SoundComponentBaseName(), GetSource) #define __SoundComponentGetSourceData GLUE3(__, SoundComponentBaseName(), GetSourceData) #define __SoundComponentSetOutput GLUE3(__, SoundComponentBaseName(), SetOutput) #define __SoundComponentAddSource GLUE3(__, SoundComponentBaseName(), AddSource) #define __SoundComponentRemoveSource GLUE3(__, SoundComponentBaseName(), RemoveSource) #define __SoundComponentGetInfo GLUE3(__, SoundComponentBaseName(), GetInfo) #define __SoundComponentSetInfo GLUE3(__, SoundComponentBaseName(), SetInfo) #define __SoundComponentStartSource GLUE3(__, SoundComponentBaseName(), StartSource) #define __SoundComponentStopSource GLUE3(__, SoundComponentBaseName(), StopSource) #define __SoundComponentPauseSource GLUE3(__, SoundComponentBaseName(), PauseSource) #define __SoundComponentPlaySourceBuffer GLUE3(__, SoundComponentBaseName(), PlaySourceBuffer) #define __SoundComponentAddMChannelSource GLUE3(__, SoundComponentBaseName(), AddMChannelSource) #define __SoundComponentValidSource GLUE3(__, SoundComponentBaseName(), ValidSource) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // component stuff static pascal ComponentResult __SoundComponentOpen(void *unused1, ComponentInstance self); static pascal ComponentResult __SoundComponentClose(SoundComponentGlobalsPtr globals, ComponentInstance self); static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector); #ifdef __SoundComponentVersionRoutine static pascal ComponentResult __SoundComponentVersion(void *unused1); #endif #ifdef __SoundComponentRegisterRoutine static pascal ComponentResult __SoundComponentRegister(SoundComponentGlobalsPtr globals); #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // basic stuff #ifdef __SoundComponentInitOutputDeviceRoutine static pascal ComponentResult __SoundComponentInitOutputDevice(SoundComponentGlobalsPtr globals, long actions); #endif #ifdef __SoundComponentSetSourceRoutine static pascal ComponentResult __SoundComponentSetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance source); #endif static pascal ComponentResult __SoundComponentGetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance *source); #ifdef __SoundComponentGetSourceDataRoutine static pascal ComponentResult __SoundComponentGetSourceData(SoundComponentGlobalsPtr globals, SoundComponentDataPtr *sourceData); #endif #ifdef __SoundComponentSetOutputRoutine static pascal ComponentResult __SoundComponentSetOutput(SoundComponentGlobalsPtr globals, SoundComponentDataPtr requested, SoundComponentDataPtr *actual); #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // junction methods (i.e. the mixer) must be called at non-interrupt level #ifdef __SoundComponentAddSourceRoutine static pascal ComponentResult __SoundComponentAddSource(SoundComponentGlobalsPtr globals, SoundSource *sourceID); #endif #ifdef __SoundComponentRemoveSourceRoutine static pascal ComponentResult __SoundComponentRemoveSource(SoundComponentGlobalsPtr globals, SoundSource sourceID); #endif #ifdef __SoundComponentAddMChannelSourceRoutine static pascal ComponentResult __SoundComponentAddMChannelSource(SoundComponentGlobalsPtr globals, OSType streamID, SoundSource *sourceID); #endif #ifdef __SoundComponentValidSourceRoutine static pascal ComponentResult __SoundComponentValidSource(SoundComponentGlobalsPtr globals, SoundSource sourceID); #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // info methods #ifdef __SoundComponentGetInfoRoutine static pascal ComponentResult __SoundComponentGetInfo(SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr); #endif #ifdef __SoundComponentSetInfoRoutine static pascal ComponentResult __SoundComponentSetInfo(SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr); #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // control methods #ifdef __SoundComponentStartSourceRoutine static pascal ComponentResult __SoundComponentStartSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources); #endif #ifdef __SoundComponentStopSourceRoutine static pascal ComponentResult __SoundComponentStopSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources); #endif #ifdef __SoundComponentPauseSourceRoutine static pascal ComponentResult __SoundComponentPauseSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources); #endif #ifdef __SoundComponentPlaySourceBufferRoutine static pascal ComponentResult __SoundComponentPlaySourceBuffer(SoundComponentGlobalsPtr globals, SoundSource sourceID, SoundParamBlockPtr pb, long actions); #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // types //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #if PRAGMA_STRUCT_ALIGN #pragma options align=mac68k #elif PRAGMA_STRUCT_PACKPUSH #pragma pack(push, 2) #elif PRAGMA_STRUCT_PACK #pragma pack(2) #endif // These structs are use in PowerMac builds to cast the // ComponentParameters passed into our component's entry point. enum { uppSoundComponentDispatchProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ComponentParameters *))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *))) }; #define paramsHeader unsigned char flags; unsigned char paramSize; short what typedef struct { paramsHeader; ComponentInstance self; void *unused1; } OpenPB, *OpenPBPtr; typedef struct { paramsHeader; ComponentInstance self; } ClosePB, *ClosePBPtr; typedef struct { paramsHeader; long actions; } InitOutputDevicePB, *InitOutputDevicePBPtr; typedef struct { paramsHeader; ComponentInstance source; SoundSource sourceID; } SetSourcePB, *SetSourcePBPtr; typedef struct { paramsHeader; ComponentInstance *source; SoundSource sourceID; } GetSourcePB, *GetSourcePBPtr; typedef struct { paramsHeader; SoundComponentDataPtr *sourceData; } GetSourceDataPB, *GetSourceDataPBPtr; typedef struct { paramsHeader; SoundComponentDataPtr *actual; SoundComponentDataPtr requested; } SetOutputPB, *SetOutputPBPtr; typedef struct { paramsHeader; SoundSource *sourceID; } AddSourcePB, *AddSourcePBPtr; typedef struct { paramsHeader; SoundSource sourceID; } RemoveSourcePB, *RemoveSourcePBPtr; typedef struct { paramsHeader; void *infoPtr; OSType selector; SoundSource sourceID; } GetInfoPB, *GetInfoPBPtr; typedef struct { paramsHeader; void *infoPtr; OSType selector; SoundSource sourceID; } SetInfoPB, *SetInfoPBPtr; typedef struct { paramsHeader; SoundSource *sources; short count; } StartSourcePB, *StartSourcePBPtr; typedef struct { paramsHeader; SoundSource *sources; short count; } StopSourcePB, *StopSourcePBPtr; typedef struct { paramsHeader; SoundSource *sources; short count; } PauseSourcePB, *PauseSourcePBPtr; typedef struct { paramsHeader; long actions; SoundParamBlockPtr pb; SoundSource sourceID; } PlaySourcePB, *PlaySourcePBPtr; typedef struct { paramsHeader; SoundSource *sourceID; OSType streamID; } AddMChannelSourcePB, *AddMChannelSourcePBPtr; typedef struct { paramsHeader; SoundSource sourceID; } ValidSourcePB, *ValidSourcePBPtr; typedef struct { paramsHeader; TimeRecord *theTime; void * unused1; } GetTimePB, *GetTimePBPtr; typedef struct { paramsHeader; UnsignedFixed sampleRate; wide *sampleCount; void * unused1; } SoundTickPB, *SoundTickPBPtr; #if PRAGMA_STRUCT_ALIGN #pragma options align=reset #elif PRAGMA_STRUCT_PACKPUSH #pragma pack(pop) #elif PRAGMA_STRUCT_PACK #pragma pack() #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Sound Component Entry Point //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PowerPC dispatching, entry point is a routine descriptor #if TARGET_CPU_PPC || TARGET_API_MAC_CARBON #if TARGET_API_MAC_CARBON pascal ComponentResult SoundComponentDispatch(ComponentParameters *p, SoundComponentGlobalsPtr globals); pascal ComponentResult SoundComponentDispatch(ComponentParameters *p, SoundComponentGlobalsPtr globals) #else static pascal ComponentResult SoundComponentProc(ComponentParameters *params, SoundComponentGlobalsPtr globals); RoutineDescriptor SoundComponentDispatch = BUILD_ROUTINE_DESCRIPTOR(uppSoundComponentDispatchProcInfo, SoundComponentProc); static pascal ComponentResult SoundComponentProc(ComponentParameters *p, SoundComponentGlobalsPtr globals) #endif { ComponentResult result = badComponentSelector; switch (p->what) // standard component selectors { #ifdef __SoundComponentRegisterRoutine case kComponentRegisterSelect: result = __SoundComponentRegister(globals); break; #endif case kComponentVersionSelect: #ifdef __SoundComponentVersionRoutine result = __SoundComponentVersion(0); #else result = kSoundComponentVersion; #endif break; case kComponentCanDoSelect: result = __SoundComponentCanDo(0, *((short *) &p->params[0])); break; #ifdef __SoundComponentCloseRoutine case kComponentCloseSelect: result = __SoundComponentClose(globals, ((ClosePBPtr)p)->self); break; #endif #ifdef __SoundComponentOpenRoutine case kComponentOpenSelect: result = __SoundComponentOpen(globals, ((OpenPBPtr)p)->self); break; #endif // selectors that cannot be delegated #ifdef __SoundComponentInitOutputDeviceRoutine case kSoundComponentInitOutputDeviceSelect: result = __SoundComponentInitOutputDevice(globals, ((InitOutputDevicePBPtr)p)->actions); break; #endif #ifdef __SoundComponentSetSourceRoutine case kSoundComponentSetSourceSelect: result = __SoundComponentSetSource(globals, ((SetSourcePBPtr)p)->sourceID, ((SetSourcePBPtr)p)->source); break; #endif case kSoundComponentGetSourceSelect: result = __SoundComponentGetSource(globals, ((GetSourcePBPtr)p)->sourceID, ((GetSourcePBPtr)p)->source); break; #ifdef __SoundComponentGetSourceDataRoutine case kSoundComponentGetSourceDataSelect: result = __SoundComponentGetSourceData(globals, ((GetSourceDataPBPtr)p)->sourceData); break; #endif #ifdef __SoundComponentSetOutputRoutine case kSoundComponentSetOutputSelect: result = __SoundComponentSetOutput(globals, ((SetOutputPBPtr)p)->requested, ((SetOutputPBPtr)p)->actual); break; #endif // selectors that can be delegated #ifdef __SoundComponentAddSourceRoutine case kSoundComponentAddSourceSelect: result = __SoundComponentAddSource(globals, ((AddSourcePBPtr)p)->sourceID); break; #endif #ifdef __SoundComponentRemoveSourceRoutine case kSoundComponentRemoveSourceSelect: result = __SoundComponentRemoveSource(globals, ((RemoveSourcePBPtr)p)->sourceID); break; #endif #ifdef __SoundComponentGetInfoRoutine case kSoundComponentGetInfoSelect: #if SMInstrumentation_On if(((GetInfoPBPtr)p)->selector == '1984') { SMInstrumentationFlushTrace(globals->instrumentationTrace); } #endif result = __SoundComponentGetInfo(globals, ((GetInfoPBPtr)p)->sourceID, ((GetInfoPBPtr)p)->selector, ((GetInfoPBPtr)p)->infoPtr); break; #endif #ifdef __SoundComponentSetInfoRoutine case kSoundComponentSetInfoSelect: result = __SoundComponentSetInfo(globals, ((SetInfoPBPtr)p)->sourceID, ((SetInfoPBPtr)p)->selector, ((SetInfoPBPtr)p)->infoPtr); break; #endif #ifdef __SoundComponentStartSourceRoutine case kSoundComponentStartSourceSelect: result = __SoundComponentStartSource(globals, ((StartSourcePBPtr)p)->count, ((StartSourcePBPtr)p)->sources); break; #endif #ifdef __SoundComponentStopSourceRoutine case kSoundComponentStopSourceSelect: result = __SoundComponentStopSource(globals, ((StopSourcePBPtr)p)->count, ((StopSourcePBPtr)p)->sources); break; #endif #ifdef __SoundComponentPauseSourceRoutine case kSoundComponentPauseSourceSelect: result = __SoundComponentPauseSource(globals, ((PauseSourcePBPtr)p)->count, ((PauseSourcePBPtr)p)->sources); break; #endif #ifdef __SoundComponentPlaySourceBufferRoutine case kSoundComponentPlaySourceBufferSelect: result = __SoundComponentPlaySourceBuffer(globals, ((PlaySourcePBPtr)p)->sourceID, ((PlaySourcePBPtr)p)->pb, ((PlaySourcePBPtr)p)->actions); break; #endif #ifdef __SoundComponentAddMChannelSourceRoutine case kSoundComponentAddMChannelSourceSelect: result = __SoundComponentAddMChannelSource(globals, ((AddMChannelSourcePBPtr)p)->streamID, ((AddMChannelSourcePBPtr)p)->sourceID); break; #endif #ifdef __SoundComponentValidSourceRoutine case kSoundComponentValidSourceSelect: result = __SoundComponentValidSource(globals, ((ValidSourcePBPtr)p)->sourceID); break; #endif default: if (p->what > kDelegatedSoundComponentSelectors) result = DelegateComponentCall(p, globals->sourceComponent); break; } return (result); } #else /* !TARGET_CPU_PPC */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Mac 68k and non Mac OS dispatching pascal ComponentResult SoundComponentDispatch(ComponentParameters *params, SoundComponentGlobalsPtr globals); pascal ComponentResult SoundComponentDispatch(ComponentParameters *params, SoundComponentGlobalsPtr globals) { ComponentFunctionUPP theRtn; ComponentResult result; short selector = params->what; Boolean checkCanDo = false; #define kDelegateSoundComponentCall ((ComponentFunctionUPP) -1) SelectorSwitch: if (selector < 0) switch (selector - kComponentRegisterSelect) // standard component selectors { case kComponentRegisterSelect - kComponentRegisterSelect: #ifdef __SoundComponentRegisterRoutine theRtn = (ComponentFunctionUPP) __SoundComponentRegister; #else theRtn = (ComponentFunctionUPP)nil; #endif break; case kComponentVersionSelect - kComponentRegisterSelect: #ifdef __SoundComponentVersionRoutine theRtn = (ComponentFunctionUPP) __SoundComponentVersion; #else return (kSoundComponentVersion); #endif break; case kComponentCanDoSelect - kComponentRegisterSelect: #ifdef __SoundComponentCanDoRoutine theRtn = (ComponentFunctionUPP) __SoundComponentCanDo; #else selector = *((short *) ¶ms->params[0]); checkCanDo = true; goto SelectorSwitch; #endif break; case kComponentCloseSelect - kComponentRegisterSelect: #ifdef __SoundComponentCloseRoutine theRtn = (ComponentFunctionUPP) __SoundComponentClose; #else theRtn = (ComponentFunctionUPP)nil; #endif break; case kComponentOpenSelect - kComponentRegisterSelect: #ifdef __SoundComponentOpenRoutine theRtn = (ComponentFunctionUPP) __SoundComponentOpen; #else theRtn = (ComponentFunctionUPP)nil; #endif break; default: theRtn = (ComponentFunctionUPP)nil; break; } else if (selector < kDelegatedSoundComponentSelectors) // selectors that cannot be delegated switch (selector) { case kSoundComponentInitOutputDeviceSelect: #ifdef __SoundComponentInitOutputDeviceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentInitOutputDevice; #else theRtn = (ComponentFunctionUPP)nil; #endif break; case kSoundComponentSetSourceSelect: #ifdef __SoundComponentSetSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentSetSource; #else theRtn = (ComponentFunctionUPP)nil; #endif break; case kSoundComponentGetSourceSelect: #ifdef __SoundComponentGetSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentGetSource; #else theRtn = (ComponentFunctionUPP) __SoundComponentGetSource; #endif break; case kSoundComponentGetSourceDataSelect: #ifdef __SoundComponentGetSourceDataRoutine theRtn = (ComponentFunctionUPP) __SoundComponentGetSourceData; #else theRtn = (ComponentFunctionUPP)nil; #endif break; case kSoundComponentSetOutputSelect: #ifdef __SoundComponentSetOutputRoutine theRtn = (ComponentFunctionUPP) __SoundComponentSetOutput; #else theRtn = (ComponentFunctionUPP)nil; #endif break; default: theRtn = (ComponentFunctionUPP)nil; break; } else // selectors that can be delegated switch (selector) { case kSoundComponentAddSourceSelect: #ifdef __SoundComponentAddSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentAddSource; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentRemoveSourceSelect: #ifdef __SoundComponentRemoveSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentRemoveSource; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentGetInfoSelect: #ifdef __SoundComponentGetInfoRoutine theRtn = (ComponentFunctionUPP) __SoundComponentGetInfo; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentSetInfoSelect: #ifdef __SoundComponentSetInfoRoutine theRtn = (ComponentFunctionUPP) __SoundComponentSetInfo; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentStartSourceSelect: #ifdef __SoundComponentStartSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentStartSource; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentStopSourceSelect: #ifdef __SoundComponentStopSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentStopSource; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentPauseSourceSelect: #ifdef __SoundComponentPauseSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentPauseSource; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentPlaySourceBufferSelect: #ifdef __SoundComponentPlaySourceBufferRoutine theRtn = (ComponentFunctionUPP) __SoundComponentPlaySourceBuffer; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentAddMChannelSourceSelect: #ifdef __SoundComponentAddMChannelSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentAddMChannelSource; #else theRtn = kDelegateSoundComponentCall; #endif break; case kSoundComponentValidSourceSelect: #ifdef __SoundComponentValidSourceRoutine theRtn = (ComponentFunctionUPP) __SoundComponentValidSource; #else theRtn = kDelegateSoundComponentCall; #endif break; default: theRtn = kDelegateSoundComponentCall; break; } if (checkCanDo) result = ((theRtn == nil) || (theRtn == kDelegateSoundComponentCall)) ? 0 : 1; else { if (theRtn == nil) result = badComponentSelector; else if (theRtn == kDelegateSoundComponentCall) result = DelegateComponentCall(params, globals->sourceComponent); else result = CallComponentFunctionWithStorage((Handle) globals, params, theRtn); } return (result); } #endif /* !TARGET_CPU_PPC */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef __SoundComponentGetSourceRoutine static pascal ComponentResult __SoundComponentGetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance *source) { #pragma unused (sourceID) *source = globals->sourceComponent; return (noErr); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef __SoundComponentCanDoRoutine static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector) { #pragma unused (unused1) ComponentResult result; switch (selector) { #ifdef __SoundComponentRegisterRoutine case kComponentRegisterSelect: result = true; break; #endif case kComponentVersionSelect: result = true; break; case kComponentCanDoSelect: result = true; break; #ifdef __SoundComponentCloseRoutine case kComponentCloseSelect: result = true; break; #endif #ifdef __SoundComponentOpenRoutine case kComponentOpenSelect: result = true; break; #endif #ifdef __SoundComponentInitOutputDeviceRoutine case kSoundComponentInitOutputDeviceSelect: result = true; break; #endif #ifdef __SoundComponentSetSourceRoutine case kSoundComponentSetSourceSelect: result = true; break; #endif case kSoundComponentGetSourceSelect: result = true; break; #ifdef __SoundComponentGetSourceDataRoutine case kSoundComponentGetSourceDataSelect: result = true; break; #endif #ifdef __SoundComponentSetOutputRoutine case kSoundComponentSetOutputSelect: result = true; break; #endif // selectors that can be delegated #ifdef __SoundComponentAddSourceRoutine case kSoundComponentAddSourceSelect: result = true; break; #endif #ifdef __SoundComponentRemoveSourceRoutine case kSoundComponentRemoveSourceSelect: result = true; break; #endif #ifdef __SoundComponentGetInfoRoutine case kSoundComponentGetInfoSelect: result = true; break; #endif #ifdef __SoundComponentSetInfoRoutine case kSoundComponentSetInfoSelect: result = true; break; #endif #ifdef __SoundComponentStartSourceRoutine case kSoundComponentStartSourceSelect: result = true; break; #endif #ifdef __SoundComponentStopSourceRoutine case kSoundComponentStopSourceSelect: result = true; break; #endif #ifdef __SoundComponentPauseSourceRoutine case kSoundComponentPauseSourceSelect: result = true; break; #endif #ifdef __SoundComponentPlaySourceBufferRoutine case kSoundComponentPlaySourceBufferSelect: result = true; break; #endif #ifdef __SoundComponentAddMChannelSourceRoutine case kSoundComponentAddMChannelSourceSelect: result = true; break; #endif #ifdef __SoundComponentValidSourceRoutine case kSoundComponentValidSourceSelect: result = true; break; #endif default: result = false; break; } return (result); } #endif #endif /* SoundComponentBaseName */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // end of common code for sound component dispatching //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // misc utility routines used by sound components //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #if TARGET_API_MAC_CARBON #ifdef SoundComponentBaseName #ifndef PrimeSource #define PrimeSource GLUE3(__, SoundComponentBaseName(), PrimeSource) #endif #endif #endif static OSErr NewSoundComponentLocalStorage(long size, Handle *storageHandle, Ptr *storage); static OSErr NewSoundComponentGlobalStorage(long size, Handle *storageHandle, Ptr *storage, Boolean *inAppHeap); static void DisposeSoundComponentStorage(Handle storageHandle); #if !TARGET_API_MAC_CARBON static OSErr GetAppStorageWithRespect(Handle *storageHandle, long size); static OSErr GetSystemStorageWithRespect(Handle *storageHandle, long size); static OSErr HandleVMCFMCommon(CFragInitBlockPtr initInfo); OSErr HandleVMCFMInitialize(CFragInitBlockPtr initInfo); void HandleVMCFMTerminate(void); static OSErr SetClosureMemory(CFragContextID contextID, CFragClosureID closureID, Boolean holdMemory); #endif #if TARGET_API_MAC_CARBON static inline OSErr NewSoundComponentGlobalStorage(long size, Handle *storageHandle, Ptr *storage, Boolean *inAppHeap) { Handle h = NewHandle(size); if (h != NULL) { *storageHandle = h; *storage = *h; *inAppHeap = true; } return MemError(); } static inline OSErr NewSoundComponentLocalStorage(long size, Handle *storageHandle, Ptr *storage) { Boolean ignore; return NewSoundComponentGlobalStorage(size, storageHandle, storage, &ignore); } static inline void DisposeSoundComponentStorage(Handle storageHandle) { DisposeHandle(storageHandle); } #else /* !TARGET_API_MAC_CARBON */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // routines for Power Mac builds, which are simply in-lines for 68k //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ static long PurgeAppSpaceContiguous(void) { long totalPurgeSpace; long contigPurgeSpace; PurgeSpace(&totalPurgeSpace, &contigPurgeSpace); return (contigPurgeSpace); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ static unsigned long PurgeSpaceSystemContiguous(void) { long totalPurgeSpace; long contigPurgeSpace; #if !TARGET_API_MAC_CARBON THz curZone; curZone = GetZone(); SetZone(SystemZone()); #endif PurgeSpace(&totalPurgeSpace, &contigPurgeSpace); #if !TARGET_API_MAC_CARBON SetZone(curZone); #endif return (contigPurgeSpace); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Try to get space in application's heap and making sure we allocate the memory // allowing enough space in the heap for others. // Hold memory to make it safe for VM during interrupts. static OSErr GetAppStorageWithRespect(Handle *storageHandle, long size) { Handle h; OSErr result; ReserveMem(size); // create a low heap object h = NewHandle(size); if (h != nil) { result = noErr; if (PurgeAppSpaceContiguous() < kMinAppHeapFreeSpace) { DisposeHandle(h); result = memFullErr; } } else // NewHandle() failed result = MemError(); if (result == noErr) { HLock(h); #if !TARGET_OS_WIN32 && !TARGET_API_MAC_CARBON // no harm in always holding the memory // even when VM is off result = HoldMemory(*h, size); if (result != noErr) { DisposeHandle(h); h = nil; } // hold the master pointer result = HoldMemory(h, 4); if(result != noErr) { UnholdMemory(*h, size); DisposeHandle(h); h = nil; } #endif *storageHandle = h; } return (result); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Try to get space in system heap and making sure we allocate the memory // allowing enough space in the heap for others. static OSErr GetSystemStorageWithRespect(Handle *storageHandle, long size) { Handle h; Handle tempH; unsigned long neededContigSpace; unsigned long hiSysRoom; unsigned long lowTempRoom; OSErr result; #if TARGET_API_MAC_CARBON h = NewHandle(size); #else ReserveMemSys(size); h = NewHandleSys(size); #endif if (h != nil) { result = noErr; #if TARGET_API_MAC_CARBON || !TARGET_OS_MAC neededContigSpace = 32000; #else neededContigSpace = GetExpandMemMinSysHeapFreeSpace(); #endif #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON #ifdef INITVERSION if ( GetToolTrapAddress(_Unimplemented) != GetToolTrapAddress(_OSDispatch) ) #else if ( GetExpandMemProcessMgrExists() ) #endif { if (SysZoneFloatSizes(nil, &lowTempRoom) != noErr) lowTempRoom = 0; if (lowTempRoom < neededContigSpace) { if (SysZoneFloatSizes(&hiSysRoom, nil) != noErr) hiSysRoom = 0; if ((hiSysRoom + lowTempRoom) < neededContigSpace) { DisposeHandle(h); result = memFullErr; } } } else // we don't know if we can grow the system heap, so let's guess #endif // TARGET_OS_MAC && !TARGET_API_MAC_CARBON { if (PurgeSpaceSystemContiguous() < neededContigSpace) // that didn't work, try to force the system heap to compact and grow // by allocated the reserve amount and if that fails, then give up { #if TARGET_API_MAC_CARBON tempH = NewHandle(neededContigSpace); #else tempH = NewHandleSys(neededContigSpace); #endif if (tempH != nil) DisposeHandle(tempH); else { DisposeHandle(h); result = memFullErr; } } } } else // NewHandleSys() failed result = MemError(); if (result == noErr) { HLock(h); #if !TARGET_OS_WIN32 && !TARGET_API_MAC_CARBON // no harm in always holding the memory // even when VM is off result = HoldMemory(*h, size); if (result != noErr) { DisposeHandle(h); h = nil; } // hold the master pointer result = HoldMemory(h, 4); if(result != noErr) { UnholdMemory(*h, size); DisposeHandle(h); h = nil; } #endif *storageHandle = h; } return (result); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Try to allocate local component storage, usually in the application's heap // because the component is only being used by the application. But if we cannot // find available memory in the application's heap, then we'll try to find // it in the system. // returns a locked and deferenced handle static OSErr NewSoundComponentLocalStorage(long size, Handle *storageHandle, Ptr *storage) { Handle h; OSErr result; // check for expiration of development releases on Macs only result = GetSystemStorageWithRespect(&h, size); // try for system space if (result != noErr) // do we have storage? result = GetAppStorageWithRespect(&h, size); // try for app storage FailIf(result != noErr, Failure); *storageHandle = h; *storage = StripAddress(*h); return (noErr); Failure: return (result); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Try to allocate global component storage, usually in the system heap so that // the component can be shared by any application. If the system heap cannot be // used, then use the application's heap. If we do use the app heap, then return // this fact to the caller so it will know that it is using local storage. On entry // the caller must set the inAppHeap flag properly, and it will be return with a // setting that reflects whether or not the storage is global. // returns a locked and deferenced handle static OSErr NewSoundComponentGlobalStorage(long size, Handle *storageHandle, Ptr *storage, Boolean *inAppHeap) { Handle h; OSErr result; result = memFullErr; // assume we have no storage *inAppHeap = false; result = GetSystemStorageWithRespect(&h, size); if (result != noErr) // do we have storage? { result = GetAppStorageWithRespect(&h, size); if (result == noErr) *inAppHeap = true; } FailIf(result != noErr, Failure); *storageHandle = h; *storage = StripAddress(*h); return (noErr); Failure: return (result); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // define to be a real routine so we can unhold memory static void DisposeSoundComponentStorage(Handle storageHandle) { #if !TARGET_OS_WIN32 && !TARGET_API_MAC_CARBON UnholdMemory(*storageHandle, InlineGetHandleSize(storageHandle)); UnholdMemory(storageHandle, 4); #endif DisposeHandle(storageHandle); } #endif /* !TARGET_API_MAC_CARBON */