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

📄 pa_mac_core.c

📁 IAX client库, 一个VOIP的库. 支持H.323和SIP, PBX就是采用的它
💻 C
📖 第 1 页 / 共 5 页
字号:
    UInt32        count;    int           i;    AudioDeviceID tempDeviceID = kAudioDeviceUnknown;    PaDeviceID    defaultDeviceID = paNoDevice;    // get the default output device for the HAL    // it is required to pass the size of the data to be returned    count = sizeof(tempDeviceID);    err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultInputDevice,  &count, (void *) &tempDeviceID);    if (err != noErr) goto error;        // scan input devices to see which one matches this device    defaultDeviceID = paNoDevice;    for( i=LOWEST_INPUT_DEVID; i<=HIGHEST_INPUT_DEVID; i++ )    {        DBUG(("PaOSX_QueryDefaultInputDevice: i = %d, aDevId = %ld\n", i, sDeviceInfos[i].audioDeviceID ));        if( sDeviceInfos[i].audioDeviceID == tempDeviceID )        {            defaultDeviceID = i;            break;        }    }error:    return defaultDeviceID;}/************************************************************************/static PaDeviceID PaOSX_QueryDefaultOutputDevice( void ){    OSStatus      err = noErr;    UInt32        count;    int           i;    AudioDeviceID tempDeviceID = kAudioDeviceUnknown;    PaDeviceID    defaultDeviceID = paNoDevice;    // get the default output device for the HAL    // it is required to pass the size of the data to be returned    count = sizeof(tempDeviceID);    err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice,  &count, (void *) &tempDeviceID);    if (err != noErr) goto error;        // scan output devices to see which one matches this device    defaultDeviceID = paNoDevice;    for( i=LOWEST_OUTPUT_DEVID; i<=HIGHEST_OUTPUT_DEVID; i++ )    {        DBUG(("PaOSX_QueryDefaultOutputDevice: i = %d, aDevId = %ld\n", i, sDeviceInfos[i].audioDeviceID ));        if( sDeviceInfos[i].audioDeviceID == tempDeviceID )        {            defaultDeviceID = i;            break;        }    }error:    return defaultDeviceID;}/******************************************************************/static PaError PaOSX_QueryDevices( void ){    OSStatus err = noErr;    UInt32   outSize;    Boolean  outWritable;    int      numBytes;    // find out how many Core Audio devices there are, if any    outSize = sizeof(outWritable);    err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &outSize, &outWritable);    if (err != noErr)    {        PRINT_ERR("Couldn't get info about list of audio devices", err);        sSavedHostError = err;        return paHostError;    }            // calculate the number of device available    sNumCoreDevices = outSize / sizeof(AudioDeviceID);    // Bail if there aren't any devices    if (sNumCoreDevices < 1)    {        PRINT(("No Devices Available"));        return paHostError;    }        // make space for the devices we are about to get    sCoreDeviceIDs =  (AudioDeviceID *)malloc(outSize);    // get an array of AudioDeviceIDs    err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &outSize, (void *)sCoreDeviceIDs);    if (err != noErr)    {        PRINT_ERR("Couldn't get list of audio device IDs", err);        sSavedHostError = err;        return paHostError;    }    // Allocate structures to hold device info pointers.    // There will be a maximum of two Pa devices per Core Audio device, input and/or output.    numBytes = sNumCoreDevices * 2 * sizeof(PaHostDeviceInfo);    sDeviceInfos = (PaHostDeviceInfo *) PaHost_AllocateFastMemory( numBytes );    if( sDeviceInfos == NULL ) return paInsufficientMemory;    // Scan all the Core Audio devices to see which support input and allocate a    // PaHostDeviceInfo structure for each one.    DBUG(("PaOSX_QueryDevices: scan for input ======================\n"));    PaOSX_ScanDevices( IS_INPUT );    sNumInputDevices = sNumPaDevices;    // Now scan all the output devices.    DBUG(("PaOSX_QueryDevices: scan for output ======================\n"));    PaOSX_ScanDevices( IS_OUTPUT );    sNumOutputDevices = sNumPaDevices - sNumInputDevices;    // Figure out which of the devices that we scanned is the default device.    sDefaultInputDeviceID = PaOSX_QueryDefaultInputDevice();    sDefaultOutputDeviceID = PaOSX_QueryDefaultOutputDevice();    return paNoError;}/*************************************************************************//* Query a device for its sample rate. * @return positive rate or 0.0 on error. */static Float64 PaOSX_GetDeviceSampleRate( AudioDeviceID deviceID, Boolean isInput ){    OSStatus  err = noErr;    AudioStreamBasicDescription formatDesc;    UInt32    dataSize;    dataSize = sizeof(formatDesc);    err = AudioDeviceGetProperty( deviceID, 0, isInput,        kAudioDevicePropertyStreamFormat, &dataSize, &formatDesc);    if( err != noErr ) return 0.0;    else return formatDesc.mSampleRate;}/*************************************************************************//* Allocate a string containing the device name. */static char *PaOSX_DeviceNameFromID(AudioDeviceID deviceID, Boolean isInput ){    OSStatus err = noErr;    UInt32  outSize;    Boolean  outWritable;    char     *deviceName = nil;        // query size of name    err =  AudioDeviceGetPropertyInfo(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, &outWritable);    if (err == noErr)    {        deviceName =  (char*)malloc( outSize + 1);        if( deviceName )        {            err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, deviceName);            if (err != noErr)                PRINT_ERR("Couldn't get audio device name", err);        }    }    return deviceName;}/*************************************************************************** Scan all of the Core Audio devices to see which support selected** input or output mode.** Changes sNumDevices, and fills in sDeviceInfos.*/static int PaOSX_ScanDevices( Boolean isInput ){    int coreDeviceIndex;    int result;    PaHostDeviceInfo  *hostDeviceInfo;    int numAdded = 0;    for(  coreDeviceIndex=0; coreDeviceIndex<sNumCoreDevices; coreDeviceIndex++ )    {        // try to fill in next PaHostDeviceInfo        hostDeviceInfo = &sDeviceInfos[sNumPaDevices];        result = PaOSX_QueryDeviceInfo( hostDeviceInfo, coreDeviceIndex, isInput );        DBUG(("PaOSX_ScanDevices: paDevId = %d, coreDevId = %d\n", sNumPaDevices, coreDeviceIndex ));        if( result > 0 )        {            sNumPaDevices += 1;  // bump global counter if we got one            numAdded += 1;        }        else if( result < 0 ) return result;    }    return numAdded;}/*************************************************************************** Try to fill in the device info for this device.** Return 1 if a good device that PA can use.** Return 0 if not appropriate** or return negative error.***/static int PaOSX_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput ){    OSStatus         err;    UInt32           outSize;    AudioStreamBasicDescription formatDesc;    AudioDeviceID    devID;    PaDeviceInfo    *deviceInfo = &hostDeviceInfo->paInfo;    deviceInfo->structVersion = 1;    deviceInfo->maxInputChannels = 0;    deviceInfo->maxOutputChannels = 0;    deviceInfo->sampleRates = supportedSampleRateRange; // because we use sample rate converter to get continuous rates    deviceInfo->numSampleRates = -1;    devID = sCoreDeviceIDs[ coreDeviceIndex ];    hostDeviceInfo->audioDeviceID = devID;    DBUG(("PaOSX_QueryDeviceInfo: coreDeviceIndex = %d, devID = %d, isInput = %d\n",        coreDeviceIndex, devID, isInput ));            // Get data format info from the device.    outSize = sizeof(formatDesc);    err = AudioDeviceGetProperty(devID, 0, isInput, kAudioDevicePropertyStreamFormat, &outSize, &formatDesc);    // This just may not be an appropriate device for input or output so leave quietly.    if( (err != noErr)  || (formatDesc.mChannelsPerFrame == 0) ) goto error;        DBUG(("PaOSX_QueryDeviceInfo: mFormatID = 0x%x\n", formatDesc.mFormatID));    DBUG(("PaOSX_QueryDeviceInfo: kAudioFormatLinearPCM = 0x%x\n", kAudioFormatLinearPCM));    DBUG(("PaOSX_QueryDeviceInfo: mFormatFlags = 0x%x\n", formatDesc.mFormatFlags));    DBUG(("PaOSX_QueryDeviceInfo: kLinearPCMFormatFlagIsFloat = 0x%x\n", kLinearPCMFormatFlagIsFloat));    // dmazzoni: all OS X devices support the float32 format.  When we open the    // device, if it isn't in this format, we will change it at that point.    deviceInfo->nativeSampleFormats = paFloat32;    // Determine maximum number of channels supported.    memset( &formatDesc, 0, sizeof(formatDesc));    formatDesc.mChannelsPerFrame = 256; // FIXME - what about device with > 256 channels    formatDesc.mFormatID = kAudioFormatLinearPCM;    formatDesc.mFormatFlags =       kAudioFormatFlagIsFloat |       kAudioFormatFlagIsBigEndian |       kAudioFormatFlagIsPacked;    outSize = sizeof(formatDesc);    err = AudioDeviceGetProperty( devID, 0,        isInput, kAudioDevicePropertyStreamFormatMatch, &outSize, &formatDesc);    if( err != noErr )    {        PRINT_ERR("PaOSX_QueryDeviceInfo: Could not get device format match", err);        sSavedHostError = err;        return paHostError;    }    if( isInput )    {        deviceInfo->maxInputChannels = formatDesc.mChannelsPerFrame;    }    else    {        deviceInfo->maxOutputChannels = formatDesc.mChannelsPerFrame;    }    // Get the device name    deviceInfo->name = PaOSX_DeviceNameFromID( devID, isInput );    return 1;error:    return 0;}/**********************************************************************/static PaError PaOSX_MaybeQueryDevices( void ){    if( sNumPaDevices == 0 )    {        return PaOSX_QueryDevices();    }    return 0;}static char zeroPad[256] = { 0 };/************************************************************************ This is the proc that supplies the data to the AudioConverterFillBuffer call.** We can pass back arbitrarily sized blocks so if the FIFO region is split** just pass back the first half.*/static OSStatus PaOSX_InputConverterCallbackProc (AudioConverterRef			inAudioConverter,								UInt32*						outDataSize,								void**						outData,								void*						inUserData){    internalPortAudioStream   *past = (internalPortAudioStream *) inUserData;    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;    void *dataPtr1;    long size1;    void *dataPtr2;    long size2;               /* Pass contiguous region from FIFO directly to converter. */    RingBuffer_GetReadRegions( &pahsc->ringBuffer, *outDataSize,            &dataPtr1, &size1, &dataPtr2, &size2 );    if( size1 > 0 )    {        *outData = dataPtr1;        *outDataSize = size1;        RingBuffer_AdvanceReadIndex( &pahsc->ringBuffer, size1 );        DBUGX(("PaOSX_InputConverterCallbackProc: read %ld bytes from FIFO.\n", size1 ));    }    else    {        DBUGBACK(("PaOSX_InputConverterCallbackProc: got no data!\n"));        *outData = zeroPad; /* Give it zero data to keep it happy. */        *outDataSize = sizeof(zeroPad);    }	return noErr;}/******************************************************************************* Get audio input, if any, from passed in buffer, or from converter or from FIFO,** then run PA callback and output data.*/static OSStatus PaOSX_LoadAndProcess( internalPortAudioStream   *past,    void *inputBuffer, void *outputBuffer ){    OSStatus err = noErr;    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;        if( past->past_StopSoon )    {        if( outputBuffer )        {            /* Clear remainder of audio buffer if we are waiting for stop. */            AddTraceMessage("PaOSX_LoadAndProcess: zero rest of wave buffer ", i );            memset( outputBuffer, 0, pahsc->output.bytesPerUserNativeBuffer );        }    }    else    {        /* Do we need data from the converted input? */        if( PA_USING_INPUT )        {

⌨️ 快捷键说明

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