?? pa_mac.c
字號:
static double * PaMac_GetSampleRatesFromHandle ( int numRates, Handle h ){ OSErr err = noErr; SInt8 hState; int i; UnsignedFixed *fixedRates; double *rates = (double *) malloc( numRates * sizeof(double) ); /* MEM_011 */ if( rates == NULL ) return NULL; /* Save and restore handle state as suggested by TechNote at: http://developer.apple.com/technotes/tn/tn1122.html */ hState = HGetState (h); if (!(err = MemError ())) { HLock (h); if (!(err = MemError ( ))) { fixedRates = (UInt32 *) *h; for( i=0; i<numRates; i++ ) { rates[i] = UnsignedFixedToDouble(fixedRates[i]); } HSetState (h,hState); err = MemError ( ); } } if( err ) { free( rates ); ERR_RPT(("Error in PaMac_GetSampleRatesFromHandle = %d\n", err )); } return rates;}/*************************************************************************/int Pa_CountDevices(){ PaError err; DBUG(("Pa_CountDevices()\n")); /* If no devices, go find some. */ if( sNumDevices <= 0 ) { err = PaMac_ScanOutputDevices(); if( err != paNoError ) goto error; err = PaMac_ScanInputDevices(); if( err != paNoError ) goto error; } return sNumDevices;error: PaHost_Term(); DBUG(("Pa_CountDevices: returns %d\n", err )); return err;}/*************************************************************************/const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ){ if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL; return &sDevices[id].pad_Info;}/*************************************************************************/PaDeviceID Pa_GetDefaultInputDeviceID( void ){ return sDefaultInputDeviceID;}/*************************************************************************/PaDeviceID Pa_GetDefaultOutputDeviceID( void ){ return sDefaultOutputDeviceID;}/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/static void PaMac_StartLoadCalculation( internalPortAudioStream *past ){ PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; UnsignedWide widePad; if( pahsc == NULL ) return; /* Query system timer for usage analysis and to prevent overuse of CPU. */ Microseconds( &widePad ); pahsc->pahsc_EntryCount = UnsignedWideToUInt64( widePad );}/******************************************************************************** Measure fractional CPU load based on real-time it took to calculate** buffers worth of output.*//**************************************************************************/static void PaMac_EndLoadCalculation( internalPortAudioStream *past ){ UnsignedWide widePad; UInt64 currentCount; long usecsElapsed; double newUsage; PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; if( pahsc == NULL ) return; /* Measure CPU utilization during this callback. Note that this calculation ** assumes that we had the processor the whole time. */#define LOWPASS_COEFFICIENT_0 (0.95)#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) Microseconds( &widePad ); currentCount = UnsignedWideToUInt64( widePad ); usecsElapsed = (long) U64Subtract(currentCount, pahsc->pahsc_EntryCount); /* Use inverse because it is faster than the divide. */ newUsage = usecsElapsed * pahsc->pahsc_InverseMicrosPerHostBuffer; past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) + (LOWPASS_COEFFICIENT_1 * newUsage); }/************************************************************************* Called by Pa_StartStream()*/PaError PaHost_StartInput( internalPortAudioStream *past ){ PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; pahsc->pahsc_IsRecording = 0; pahsc->pahsc_StopRecording = 0; pahsc->pahsc_InputMultiBuffer.nextWrite = 0; pahsc->pahsc_InputMultiBuffer.nextRead = 0; return PaMac_RecordNext( past );}/************************************************************************* Called by Pa_StopStream().** May be called during error recovery or cleanup code** so protect against NULL pointers.*/PaError PaHost_StopInput( internalPortAudioStream *past, int abort ){ int32 timeOutMsec; PaError result = paNoError; OSErr err = 0; long mRefNum; PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; if( pahsc == NULL ) return paNoError; (void) abort; mRefNum = pahsc->pahsc_InputRefNum; DBUG(("PaHost_StopInput: mRefNum = %d\n", mRefNum )); if( mRefNum ) { DBUG(("PaHost_StopInput: pahsc_IsRecording = %d\n", pahsc->pahsc_IsRecording )); if( pahsc->pahsc_IsRecording ) { /* PLB20010420 - Fix TIMEOUT in record mode. */ pahsc->pahsc_StopRecording = 1; /* Request that we stop recording. */ err = SPBStopRecording(mRefNum); DBUG(("PaHost_StopInput: then pahsc_IsRecording = %d\n", pahsc->pahsc_IsRecording )); /* Calculate timeOut longer than longest time it could take to play one buffer. */ timeOutMsec = (int32) ((1500.0 * pahsc->pahsc_FramesPerHostBuffer) / past->past_SampleRate); /* Keep querying sound channel until it is no longer busy playing. */ while( !err && pahsc->pahsc_IsRecording && (timeOutMsec > 0)) { Pa_Sleep(20); timeOutMsec -= 20; } if( timeOutMsec <= 0 ) { ERR_RPT(("PaHost_StopInput: timed out!\n")); return paTimedOut; } } } if( err ) { sPaHostError = err; result = paHostError; } DBUG(("PaHost_StopInput: finished.\n", mRefNum )); return result;}/***********************************************************************/static void PaMac_InitSoundHeader( internalPortAudioStream *past, CmpSoundHeader *sndHeader ){ sndHeader->numChannels = past->past_NumOutputChannels; sndHeader->sampleRate = DoubleToUnsignedFixed(past->past_SampleRate); sndHeader->loopStart = 0; sndHeader->loopEnd = 0; sndHeader->encode = cmpSH; sndHeader->baseFrequency = kMiddleC; sndHeader->markerChunk = nil; sndHeader->futureUse2 = nil; sndHeader->stateVars = nil; sndHeader->leftOverSamples = nil; sndHeader->compressionID = 0; sndHeader->packetSize = 0; sndHeader->snthID = 0; sndHeader->sampleSize = 8 * sizeof(int16); // FIXME - might be 24 or 32 bits some day; sndHeader->sampleArea[0] = 0; sndHeader->format = kSoundNotCompressed;}static void SetFramesDone( PaHostSoundControl *pahsc, PaTimestamp framesDone ){ UnsignedWide now; Microseconds( &now ); pahsc->pahsc_NumFramesDone = framesDone; pahsc->pahsc_WhenFramesDoneIncremented = UnsignedWideToUInt64( now );}/***********************************************************************/PaError PaHost_StartOutput( internalPortAudioStream *past ){ SndCommand pauseCommand; SndCommand resumeCommand; int i; OSErr error; PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; if( pahsc == NULL ) return paInternalError; if( pahsc->pahsc_Channel == NULL ) return paInternalError; past->past_StopSoon = 0; past->past_IsActive = 1; pahsc->pahsc_NumOutsQueued = 0; pahsc->pahsc_NumOutsPlayed = 0; SetFramesDone( pahsc, 0.0 ); /* Pause channel so it does not do back ground processing while we are still filling the queue. */ pauseCommand.cmd = pauseCmd; pauseCommand.param1 = pauseCommand.param2 = 0; error = SndDoCommand (pahsc->pahsc_Channel, &pauseCommand, true); if (noErr != error) goto exit; /* Queue all of the buffers so we start off full. */ for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++) { PaMac_PlayNext( past, i ); } /* Resume channel now that the queue is full. */ resumeCommand.cmd = resumeCmd; resumeCommand.param1 = resumeCommand.param2 = 0; error = SndDoImmediate( pahsc->pahsc_Channel, &resumeCommand ); if (noErr != error) goto exit; return paNoError;exit: past->past_IsActive = 0; sPaHostError = error; ERR_RPT(("Error in PaHost_StartOutput: SndDoCommand returned %d\n", error )); return paHostError;}/*******************************************************************/long PaHost_GetTotalBufferFrames( internalPortAudioStream *past ){ PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; return (long) (pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer);}/************************************************************************* Called by Pa_StopStream().** May be called during error recovery or cleanup code** so protect against NULL pointers.*/PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ){ int32 timeOutMsec; PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; if( pahsc == NULL ) return paNoError; if( pahsc->pahsc_Channel == NULL ) return paNoError; DBUG(("PaHost_StopOutput()\n")); if( past->past_IsActive == 0 ) return paNoError; /* Set flags for callback function to see. */ if( abort ) past->past_StopNow = 1; past->past_StopSoon = 1; /* Calculate timeOut longer than longest time it could take to play all buffers. */ timeOutMsec = (int32) ((1500.0 * PaHost_GetTotalBufferFrames( past )) / past->past_SampleRate); /* Keep querying sound channel until it is no longer busy playing. */ while( past->past_IsActive && (timeOutMsec > 0)) { Pa_Sleep(20); timeOutMsec -= 20; } if( timeOutMsec <= 0 ) { ERR_RPT(("PaHost_StopOutput: timed out!\n")); return paTimedOut; } else return paNoError;}/***********************************************************************/PaError PaHost_StartEngine( internalPortAudioStream *past ){ (void) past; /* Prevent unused variable warnings. */ return paNoError;}/***********************************************************************/PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ){ (void) past; /* Prevent unused variable warnings. */ (void) abort; /* Prevent unused variable warnings. */ return paNoError;}/***********************************************************************/PaError PaHost_StreamActive( internalPortAudioStream *past ){ PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; return (PaError) ( past->past_IsActive + pahsc->pahsc_IsRecording );}int Mac_IsVirtualMemoryOn( void ){ long attr; OSErr result = Gestalt( gestaltVMAttr, &attr ); DBUG(("gestaltVMAttr : 0x%x\n", attr )); return ((attr >> gestaltVMHasPagingControl ) & 1);}/******************************************************************** Determine number of host Buffers* and how many User Buffers we can put into each host buffer.*/static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past ){ PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; int32 minNumBuffers; int32 minFramesPerHostBuffer; int32 minTotalFrames; int32 userBuffersPerHostBuffer;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -