⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pa_mac.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -