📄 pa_mac_core.c
字号:
/* Low pass filter result. */
past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +
(LOWPASS_COEFFICIENT_1 * newUsage);
}
/****************************************** END CPU UTILIZATION *******/
/************************************************************************/
static PaDeviceID PaOSX_QueryDefaultInputDevice( 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( 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, result = %d\n", sNumPaDevices, coreDeviceIndex, result ));
if( result > 0 )
{
sNumPaDevices += 1; // bump global counter if we got one
numAdded += 1;
}
else if( result < 0 ) return result;
}
return numAdded;
}
/*************************************************************************
** Determine the maximum number of channels based on the configuration.
** @return maxChannels or negative error.
*/
static int PaOSX_GetMaxChannels_Config( AudioDeviceID devID, Boolean isInput )
{
OSStatus err;
UInt32 outSize;
Boolean outWritable;
AudioBufferList *list;
int numChannels;
int i;
// Determine maximum number of channels supported.
// dmazzoni: new method
outSize = 0;
err = AudioDeviceGetPropertyInfo(devID, 0, isInput,
kAudioDevicePropertyStreamConfiguration,
&outSize, &outWritable);
if ( err != noErr )
{
PRINT_ERR("PaOSX_GetMaxChannels_Config: Could not get stream configuration info", err);
sSavedHostError = err;
return paHostError;
}
list = (AudioBufferList *)PaHost_AllocateFastMemory( outSize );
err = AudioDeviceGetProperty(devID, 0, isInput,
kAudioDevicePropertyStreamConfiguration,
&outSize, list);
if ( err != noErr )
{
PRINT_ERR("PaOSX_GetMaxChannels_Config: Could not get stream configuration", err);
sSavedHostError = err;
return paHostError;
}
numChannels = 0;
for( i=0; i<list->mNumberBuffers; i++ )
{
int bufChannels = list->mBuffers[i].mNumberChannels;
DBUG(("PaOSX_GetMaxChannels_Config: buffer %d has %d channels.\n", i, bufChannels ));
numChannels += bufChannels;
}
PaHost_FreeFastMemory( list, outSize );
return numChannels;
}
/*************************************************************************
** Determine the maximum number of channels a device will support based on scanning the format.
** @return maxChannels or negative error.
*/
static int PaOSX_GetMaxChannels_Format( AudioDeviceID devID, Boolean isInput )
{
OSStatus err;
UInt32 outSize;
AudioStreamBasicDescription formatDesc;
int maxChannels;
int numChannels;
Boolean gotMax;
// Scan to find highest matching format.
// Unfortunately some devices won't just return maxChannels for the match.
// For example, some 8 channel devices return 2 when given 256 as input.
gotMax = false;
maxChannels = 0;
numChannels = 0;
while( !gotMax )
{
memset( &formatDesc, 0, sizeof(formatDesc));
numChannels = numChannels + 1;
DBUG(("PaOSX_GetMaxChannels: try numChannels = %d = %d + 1\n",
numChannels, numChannels ));
formatDesc.mChannelsPerFrame = numChannels;
outSize = sizeof(formatDesc);
err = AudioDeviceGetProperty( devID, 0,
isInput, kAudioDevicePropertyStreamFormatMatch, &outSize, &formatDesc);
DBUG(("PaOSX_GetMaxChannels: err 0x%0x, formatDesc.mChannelsPerFrame= %d\n",
err, formatDesc.mChannelsPerFrame ));
if( err != noErr )
{
if (numChannels > (maxChannels + 4)) // Try several possibilities above current max
{
gotMax = true;
}
}
else
{
// This value worked so we have a new candidate for maxChannels.
if (formatDesc.mChannelsPerFrame > numChannels)
{
maxChannels = formatDesc.mChannelsPerFrame;
}
else if(formatDesc.mChannelsPerFrame < numChannels)
{
if (numChannels > (maxChannels + 4)) // Try several possibilities above current max
{
gotMax = true;
}
}
else
{
maxChannels = numChannels;
}
}
}
return maxChannels;
}
/*************************************************************************
** Determine the maximum number of channels a device will support.
** It is not clear at this point which the better technique so
** we do both and use the biggest result.
**
** @return maxChannels or negative error.
*/
static int PaOSX_GetMaxChannels( AudioDeviceID devID, Boolean isInput )
{
int maxChannelsFormat;
int maxChannelsConfig;
maxChannelsFormat = PaOSX_GetMaxChannels_Format( devID, isInput );
maxChannelsConfig = PaOSX_GetMaxChannels_Config( devID, isInput );
return (maxChannelsFormat > maxChannelsConfig) ? maxChannelsFormat : maxChannelsConfig;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -