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

📄 pa_mac_core.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
    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( 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 ){    AudioStreamBasicDescription *allStreamFormats;    AudioStreamBasicDescription formatDesc;    OSStatus         err;    UInt32           outSize;    Boolean          outWritable;    AudioDeviceID    devID;    int              numStreamFormats;    int              maxChannels;    int              i;    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: name = %s\n", PaOSX_DeviceNameFromID( devID, isInput )));    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 = %4s\n", &formatDesc.mFormatID));    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 by looping through    // all possible supported stream formats    outSize = 0;    err = AudioDeviceGetPropertyInfo( devID, 0, isInput,                                      kAudioDevicePropertyStreamFormats,                                      &outSize, &outWritable );        allStreamFormats = (AudioStreamBasicDescription *)malloc(outSize);    numStreamFormats = outSize / sizeof(AudioStreamBasicDescription);    err = AudioDeviceGetProperty( devID, 0, isInput,                                  kAudioDevicePropertyStreamFormats,                                  &outSize, allStreamFormats);        DBUG(("%d supported formats!\n", numStreamFormats));    maxChannels = 0;    for(i=0; i<numStreamFormats; i++) {        DBUG(("Format %d: formatID=%4s flags=0x%x channels=%d rate=%.0f\n",              i,              &allStreamFormats[i].mFormatID,              allStreamFormats[i].mFormatFlags,              allStreamFormats[i].mChannelsPerFrame,              allStreamFormats[i].mSampleRate));                if (allStreamFormats[i].mChannelsPerFrame > maxChannels)            maxChannels = allStreamFormats[i].mChannelsPerFrame;    }        free(allStreamFormats);    #if 0    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;    }    #endif    if( isInput )    {        deviceInfo->maxInputChannels = maxChannels;    }    else    {        deviceInfo->maxOutputChannels = maxChannels;    }    // Get the device name    deviceInfo->name = PaOSX_DeviceNameFromID( devID, isInput );    return 1;    DBUG(("\n"));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 );

⌨️ 快捷键说明

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