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

📄 pa_mac_core.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    VVDBUG(("IsFormatSupported(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld sampleRate=%g\n",                inputParameters  ? inputParameters->channelCount  : -1,                inputParameters  ? inputParameters->sampleFormat  : -1,                outputParameters ? outputParameters->channelCount : -1,                outputParameters ? outputParameters->sampleFormat : -1,                (float) sampleRate ));     /** These first checks are standard PA checks. We do some fancier checks        later. */    if( inputParameters )    {        inputChannelCount = inputParameters->channelCount;        inputSampleFormat = inputParameters->sampleFormat;        /* all standard sample formats are supported by the buffer adapter,            this implementation doesn't support any custom sample formats */        if( inputSampleFormat & paCustomFormat )            return paSampleFormatNotSupported;                    /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that input device can support inputChannelCount */        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )            return paInvalidChannelCount;    }    else    {        inputChannelCount = 0;    }    if( outputParameters )    {        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;        /* all standard sample formats are supported by the buffer adapter,            this implementation doesn't support any custom sample formats */        if( outputSampleFormat & paCustomFormat )            return paSampleFormatNotSupported;                    /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that output device can support outputChannelCount */        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )            return paInvalidChannelCount;    }    else    {        outputChannelCount = 0;    }     /* FEEDBACK */    /*        I think the only way to check a given format SR combo is     */    /*        to try opening it. This could be disruptive, is that Okay?   */    /*        The alternative is to just read off available sample rates,  */    /*        but this will not work %100 of the time (eg, a device that   */    /*        supports N output at one rate but only N/2 at a higher rate.)*/    /* The following code opens the device with the requested parameters to       see if it works. */    {       PaError err;       PaStream *s;       err = OpenStream( hostApi, &s, inputParameters, outputParameters,                           sampleRate, 1024, 0, (PaStreamCallback *)1, NULL );       if( err != paNoError && err != paInvalidSampleRate )          DBUG( ( "OpenStream @ %g returned: %d: %s\n",                  (float) sampleRate, err, Pa_GetErrorText( err ) ) );       if( err )           return err;       err = CloseStream( s );       if( err ) {          /* FEEDBACK: is this more serious? should we assert? */          DBUG( ( "WARNING: could not close Stream. %d: %s\n",                  err, Pa_GetErrorText( err ) ) );       }    }    return paFormatIsSupported;}static PaError OpenAndSetupOneAudioUnit(                                   const PaStreamParameters *inStreamParams,                                   const PaStreamParameters *outStreamParams,                                   const unsigned long requestedFramesPerBuffer,                                   unsigned long *actualInputFramesPerBuffer,                                   unsigned long *actualOutputFramesPerBuffer,                                   const PaMacAUHAL *auhalHostApi,                                   AudioUnit *audioUnit,                                   AudioConverterRef *srConverter,                                   AudioDeviceID *audioDevice,                                   const double sampleRate,                                   void *refCon ){    ComponentDescription desc;    Component comp;    /*An Apple TN suggests using CAStreamBasicDescription, but that is C++*/    AudioStreamBasicDescription desiredFormat;    OSErr result = noErr;    PaError paResult = paNoError;    int line = 0;    UInt32 callbackKey;    AURenderCallbackStruct rcbs;    unsigned long macInputStreamFlags  = paMacCorePlayNice;    unsigned long macOutputStreamFlags = paMacCorePlayNice;    SInt32 const *inChannelMap = NULL;    SInt32 const *outChannelMap = NULL;    unsigned long inChannelMapSize = 0;    unsigned long outChannelMapSize = 0;    VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n",                inStreamParams  ? inStreamParams->channelCount  : -1,                inStreamParams  ? inStreamParams->sampleFormat  : -1,                outStreamParams ? outStreamParams->channelCount : -1,                outStreamParams ? outStreamParams->sampleFormat : -1,                requestedFramesPerBuffer ));    /* -- handle the degenerate case  -- */    if( !inStreamParams && !outStreamParams ) {       *audioUnit = NULL;       *audioDevice = kAudioDeviceUnknown;       return paNoError;    }    /* -- get the user's api specific info, if they set any -- */    if( inStreamParams && inStreamParams->hostApiSpecificStreamInfo )    {       macInputStreamFlags=            ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)                  ->flags;       inChannelMap = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)                  ->channelMap;       inChannelMapSize = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)                  ->channelMapSize;    }    if( outStreamParams && outStreamParams->hostApiSpecificStreamInfo )    {       macOutputStreamFlags=            ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)                  ->flags;       outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)                  ->channelMap;       outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)                  ->channelMapSize;     }    /* Override user's flags here, if desired for testing. */    /*     * The HAL AU is a Mac OS style "component".     * the first few steps deal with that.     * Later steps work on a combination of Mac OS     * components and the slightly lower level     * HAL.     */    /* -- describe the output type AudioUnit -- */    /*  Note: for the default AudioUnit, we could use the     *  componentSubType value kAudioUnitSubType_DefaultOutput;     *  but I don't think that's relevant here.     */    desc.componentType         = kAudioUnitType_Output;    desc.componentSubType      = kAudioUnitSubType_HALOutput;    desc.componentManufacturer = kAudioUnitManufacturer_Apple;    desc.componentFlags        = 0;    desc.componentFlagsMask    = 0;    /* -- find the component -- */    comp = FindNextComponent( NULL, &desc );    if( !comp )    {       DBUG( ( "AUHAL component not found." ) );       *audioUnit = NULL;       *audioDevice = kAudioDeviceUnknown;       return paUnanticipatedHostError;    }    /* -- open it -- */    result = OpenAComponent( comp, audioUnit );    if( result )    {       DBUG( ( "Failed to open AUHAL component." ) );       *audioUnit = NULL;       *audioDevice = kAudioDeviceUnknown;       return ERR( result );    }    /* -- prepare a little error handling logic / hackery -- */#define ERR_WRAP(mac_err) do { result = mac_err ; line = __LINE__ ; if ( result != noErr ) goto error ; } while(0)    /* -- if there is input, we have to explicitly enable input -- */    if( inStreamParams )    {       UInt32 enableIO = 1;       ERR_WRAP( AudioUnitSetProperty( *audioUnit,                 kAudioOutputUnitProperty_EnableIO,                 kAudioUnitScope_Input,                 INPUT_ELEMENT,                 &enableIO,                 sizeof(enableIO) ) );    }    /* -- if there is no output, we must explicitly disable output -- */    if( !outStreamParams )    {       UInt32 enableIO = 0;       ERR_WRAP( AudioUnitSetProperty( *audioUnit,                 kAudioOutputUnitProperty_EnableIO,                 kAudioUnitScope_Output,                 OUTPUT_ELEMENT,                 &enableIO,                 sizeof(enableIO) ) );    }    /* -- set the devices -- */    /* make sure input and output are the same device if we are doing input and       output. */    if( inStreamParams && outStreamParams )    {       assert( outStreamParams->device == inStreamParams->device );    }    if( inStreamParams )    {       *audioDevice = auhalHostApi->devIds[inStreamParams->device] ;       ERR_WRAP( AudioUnitSetProperty( *audioUnit,                    kAudioOutputUnitProperty_CurrentDevice,                    kAudioUnitScope_Global,                    INPUT_ELEMENT,                    audioDevice,                    sizeof(AudioDeviceID) ) );    }    if( outStreamParams )    {       *audioDevice = auhalHostApi->devIds[outStreamParams->device] ;       ERR_WRAP( AudioUnitSetProperty( *audioUnit,                    kAudioOutputUnitProperty_CurrentDevice,                    kAudioUnitScope_Global,                    OUTPUT_ELEMENT,                    audioDevice,                    sizeof(AudioDeviceID) ) );    }    /* -- set format -- */    bzero( &desiredFormat, sizeof(desiredFormat) );    desiredFormat.mFormatID         = kAudioFormatLinearPCM ;    desiredFormat.mFormatFlags      = kAudioFormatFlagsNativeFloatPacked;    desiredFormat.mFramesPerPacket  = 1;    desiredFormat.mBitsPerChannel   = sizeof( float ) * 8;    result = 0;    /*  set device format first, but only touch the device if the user asked */    if( inStreamParams ) {       /*The callback never calls back if we don't set the FPB */       /*This seems wierd, because I would think setting anything on the device         would be disruptive.*/       paResult = setBestFramesPerBuffer( *audioDevice, FALSE,                                          requestedFramesPerBuffer,                                          actualInputFramesPerBuffer );       if( paResult ) goto error;       if( macInputStreamFlags & paMacCoreChangeDeviceParameters ) {          bool requireExact;          requireExact=macInputStreamFlags & paMacCoreFailIfConversionRequired;          paResult = setBestSampleRateForDevice( *audioDevice, FALSE,                                                 requireExact, sampleRate );          if( paResult ) goto error;       }       if( actualInputFramesPerBuffer && actualOutputFramesPerBuffer )          *actualOutputFramesPerBuffer = *actualInputFramesPerBuffer ;    }    if( outStreamParams && !inStreamParams ) {       /*The callback never calls back if we don't set the FPB */       /*This seems wierd, because I would think setting anything on the device         would be disruptive.*/       paResult = setBestFramesPerBuffer( *audioDevice, TRUE,                                          requestedFramesPerBuffer,                                          actualOutputFramesPerBuffer );       if( paResult ) goto error;       if( macOutputStreamFlags & paMacCoreChangeDeviceParameters ) {          bool requireExact;          requireExact=macOutputStreamFlags & paMacCoreFailIfConversionRequired;          paResult = setBestSampleRateForDevice( *audioDevice, TRUE,                                                 requireExact, sampleRate );          if( paResult ) goto error;       }    }    /* -- set the quality of the output converter -- */    if( outStreamParams ) {       UInt32 value = kAudioConverterQuality_Max;       switch( macOutputStreamFlags & 0x0700 ) {       case 0x0100: /*paMacCore_ConversionQualityMin:*/          value=kRenderQuality_Min;          break;       case 0x0200: /*paMacCore_ConversionQualityLow:*/          value=kRenderQuality_Low;          break;       case 0x0300: /*paMacCore_ConversionQualityMedium:*/          value=kRenderQuality_Medium;          break;       case 0x0400: /*paMacCore_ConversionQualityHigh:*/          value=kRenderQuality_High;          break;       }       ERR_WRAP( AudioUnitSetProperty( *audioUnit,                    kAudioUnitProperty_RenderQuality,                    kAudioUnitScope_Global,                    OUTPUT_ELEMENT,                    &value,                    sizeof(value) ) );    }    /* now set the format on the Audio Units. */    if( outStreamParams )    {       desiredFormat.mSampleRate    =sampleRate;       desiredFormat.mBytesPerPacket=sizeof(float)*outStreamParams->channelCount;       desiredFormat.mBytesPerFrame =sizeof(float)*outStreamParams->channelCount;       desiredFormat.mChannelsPerFrame = outStreamParams->channelCount;       ERR_WRAP( AudioUnitSetProperty( *audioUnit,                            kAudioUnitProperty_StreamFormat,                            kAudioUnitScope_Input,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -