Re: Aggregate question device
Re: Aggregate question device
- Subject: Re: Aggregate question device
- From: Stéphane Letz <email@hidden>
- Date: Mon, 16 Nov 2009 22:40:46 +0100
L
>
>> But if aggregating devices in a more general sense, how can we know what should be done? Should "kAudioSubDevicePropertyDriftCompensation" property be used to know if devices do not share the same clock? Possibly warn the user (if resampling is not wanted..) or using "kAudioSubDevicePropertyDriftCompensationQuality" to activate resampling?
>>
>> What is the recommended strategy? Any code sample?
>
> The device property, kAudioDevicePropertyClockDomain, helps figure out which devices are synchronized in hardware and which aren't. The way it works is that if two devices have the same value for this property and that value is not 0, then the two devices are synchronized in hardware.
Ok, could make that works...
>
> When it is the case that you want to aggregate two devices that are not synchronized in hardware, you can tell the aggregate device to apply drift compensation. This can be done when you create the aggregate device by adding the key, kAudioSubDeviceDriftCompensationKey, with a non-zero value to the dictionary that describes the sub-device that requires the compensation. Note that no matter whether the drift compensation is enabled or not, the master sub-device will never have compensation applied to it. Also note that while kAudioSubDeviceDriftCompensationQualityKey is defined in the header, it doesn't do anything at the moment.
>
> I don't have any sample code, but here's something I pulled from a test tool I use. It makes heavy use of several C++ wrappers for both HAL objects and CF objects that can be found in PublicUtility. In this example, I'm building the sub-device list portion of an aggregate device description. I iterate through the device list and add entries for all the built-in devices. I am turning the drift compensation off explicitly here (it's also off by default). To turn it on, you would just change the value of kAudioSubDeviceDriftCompensationKey from 0 to 1.
>
> CACFArray theSubDeviceDictionaryList(true);
> UInt32 theNumberDevices = theAudioSystemObject.GetNumberAudioDevices();
> CAAutoFree<AudioObjectID> theDeviceList(theNumberDevices);
> theAudioSystemObject.GetAudioDevices(theNumberDevices, theDeviceList);
> for(UInt32 theDeviceIndex = 0; theDeviceIndex < theNumberDevices; ++theDeviceIndex)
> {
> CAHALAudioDevice theDevice(theDeviceList[theDeviceIndex]);
> if(theDevice.GetTransportType() == kAudioDeviceTransportTypeBuiltIn)
> {
> CACFDictionary theSubDevice(true);
> CACFString theDeviceUID(theDevice.CopyDeviceUID(), true);
> theSubDevice.AddString(CFSTR(kAudioSubDeviceUIDKey), theDeviceUID.GetCFString());
> theSubDevice.AddUInt32(CFSTR(kAudioSubDeviceDriftCompensationKey), 0);
> theSubDeviceDictionaryList.AppendDictionary(theSubDevice.GetCFDictionary());
> }
> }
>
> Hope this helps. Let me know if you have any questions.
>
Still don't get how this Dictionary has to be setup inside the aggregated device:
I have:
//-------------------------
// Set the sub-device list
//-------------------------
pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList;
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
outDataSize = sizeof(CFMutableArrayRef);
osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error");
printError(osErr);
goto error;
}
//-----------------------
// Set the master device
//-----------------------
// set the master device manually (this is the device which will act as the master clock for the aggregate device)
// pass in the UID of the device you want to use
pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice;
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
outDataSize = sizeof(CFStringRef);
osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master...
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error");
printError(osErr);
goto error;
}
But what property should be used to feed the aggregate device with "the dictionary that describes the sub-device that requires the compensation." ?
Thanks
Stéphane Letz _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden