Re: Problem creating and using aggregate device
Re: Problem creating and using aggregate device
- Subject: Re: Problem creating and using aggregate device
- From: "Glenn McCord" <email@hidden>
- Date: Wed, 30 Jul 2008 10:17:17 +1200
On Wed, Jul 30, 2008 at 7:04 AM, Jeff Moore <email@hidden> wrote:
> My first question involves the device. I'm not too familiar with any USB
> Audio class compliant devices that allow 6 input and 6 output channels to be
> used simultaneously. Wouldn't that require more bandwidth than the bus has
> available? Or is this a high speed USB device that has it's own drivers and
> what not? The reason I ask is that if IO isn't running, one possible cause
> could be that the driver wasn't able to reserve the bandwidth on the USB bus
> for that much data. This could also be why AMS is showing the input channels
> going away too.
This sound card has it's own drivers. 6in 6out work simultaneously
when I use the USB device as the two separate devices (an in and an
out device) as seen by OS X. I can also make an aggregate device in
AMS and use it so unless there is some code that says I want lots of
bandwidth, then I can't see that being the issue. Is there some kind
of error flag that can be raised when the bandwidth is exceeded?
>
> That said, the other reason why channels disappear from an aggregate device
> is that the sub-device that contains them is at a different sample rate from
> the aggregate's master sub-device. Although this would not explain why your
> IOProc wouldn't get called.
There must be something that I am doing programatically wrong, because
I can go to AMS, create the aggregate device there, and then use that
in my code instead. For my application though, I need to set it up in
the code so that the user doesn't have to do it in AMS.
In regards to setting sample rate, it can be set from the card's
control panel so the in and out should be the same. I've also tried
setting sample rate via the code.
Note, as soon as I close my audio application that has created the
aggregate device, AMS switches from seeing the aggregate device as
have 0in 6out to 6in 6out.
>
> On Jul 28, 2008, at 10:29 PM, Glenn McCord wrote:
>
>> I am trying to aggregate my USB 6 in 6 out sound card so that instead
>> of being regarded as two separate devices (in and out), it shows up as
>> one device.
>>
>> Courtesy of a previous question to the mailing list
>> (http://lists.apple.com/archives/coreaudio-api/2006/Apr/msg00103.html)
>> I am able to create an aggregate device in the code so that it shows
>> up in Audio MIDI Setup, unfortunately though, my input/output
>> callbacks never start.
>>
>> I have had some success though.
>>
>> - I can use the two USB devices (in and out) so that it uses the input
>> callback and output callback.
>> - I can create the aggregate device in the code, close my application
>> so that the aggregate device remains in Audio MIDI setup, then restart
>> the program using the name of the aggregate device to identify an
>> input/output device that requires only one callback. This works too.
>>
>> What I can't do is create my aggregate device in the code, 'then' use it.
>>
>> Here's the steps I've done:
>> - Identified the two separate USB devices (in and out) and set the
>> sample rate and frame size.
>> - Created a public aggregate device using the input and output ids of
>> the USB device.
>> - Tried to start the callbacks using AudioDeviceAddIOProc and
>> AudioDeviceStart using the id of the newly created aggregate device.
>>
>> Unfortunately, the callbacks never start and I've noticed that while
>> running my application, Audio MIDI Setup shows zero input channels but
>> 6 output channels for the device. When I close my application, it
>> changes to 6 in 6 out, which is what the card is supposed to be.
>>
>> Is that the problem? Should all 6 in and 6 outs be visible when I
>> create the aggregate device. I'm assuming there is a problem with the
>> way I have created the aggregate device, code which is unashamedly
>> copied from numerous sources. Unfortunately though, I can't identify
>> why it would drop access to the inputs, if that is indeed the problem.
>>
>> Any help would be great.
>>
>> OSStatus CCoreAudioHost::CreateAggregateDevice(AudioDeviceID
>> inputDeviceID, AudioDeviceID outputDeviceID, AudioDeviceID
>> &aggregateID)
>> {
>> OSStatus status = noErr;
>>
>> UInt32 size;
>> CFStringRef s;
>> AudioDeviceID coreaudioPlugin;
>>
>> size = sizeof(AudioValueTranslation);
>> AudioValueTranslation translation = { &s, sizeof(s),
>> &coreaudioPlugin, sizeof(coreaudioPlugin) };
>> s = CFStringCreateWithCString(NULL, "com.apple.audio.CoreAudio",
>> kCFStringEncodingUTF8);
>> status =
>> AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID,
>> &size, &translation);
>> CFRelease(s);
>>
>> if (status != kAudioHardwareNoError)
>> {
>> DEBUGSTR("Get kAudioHardwarePropertyPlugInForBundleID error
>> %4.4s\n", (char*)&status);
>> return status;
>> }
>>
>> CFStringRef inputUID;
>> CFStringRef outputUID;
>> unsigned long UIDsize = sizeof(inputUID);
>> AudioDeviceGetProperty(inputDeviceID, 0, 0,
>> kAudioDevicePropertyDeviceUID, &UIDsize, &inputUID);
>> AudioDeviceGetProperty(outputDeviceID, 0, 0,
>> kAudioDevicePropertyDeviceUID, &UIDsize, &outputUID);
>>
>>
>> CFMutableDictionaryRef dict =
>> CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
>> &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
>>
>> CFDictionarySetValue(dict, CFSTR(kAudioAggregateDeviceUIDKey),
>> CFSTR("AggregateDevice")); //Set the UID of the aggregate device
>>
>> CFDictionarySetValue(dict, CFSTR(kAudioAggregateDeviceNameKey),
>> CFSTR("AggregateDevice")); //Set the name of the aggregate device
>>
>> int privateness = 0; //0 is global, 1 is private
>> CFNumberRef privatenessRef =
>> CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType, &privateness);
>> CFDictionarySetValue(dict,
>> CFSTR(kAudioAggregateDeviceIsPrivateKey),
>> privatenessRef);
>> CFRelease(privatenessRef);
>>
>> UInt32 aggregateSize = sizeof(aggregateID);
>> AudioObjectPropertyAddress address = {
>> kAudioPlugInCreateAggregateDevice, kAudioObjectPropertyScopeGlobal,
>> kAudioObjectPropertyElementMaster };
>> status = AudioObjectGetPropertyData( coreaudioPlugin, &address,
>> sizeof(CFDictionaryRef), &dict, &aggregateSize, &aggregateID);
>>
>> CFRelease(dict);
>> if (status != kAudioHardwareNoError)
>> {
>> PrintError(status);
>> DEBUGSTR("Get kAudioPlugInCreateAggregateDevice error
>> %4.4s\n",
>> (char*)&status);
>> return false;
>> }
>>
>>
>> address.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList;
>> CFMutableArrayRef subdevices = CFArrayCreateMutable(NULL, 0, NULL);
>> CFArrayAppendValue(subdevices, (void *) inputUID);
>> CFArrayAppendValue(subdevices, (void *) outputUID);
>> status = AudioObjectSetPropertyData(aggregateID, &address, 0, NULL,
>> sizeof(subdevices), &subdevices);
>> CFRelease(subdevices);
>> if (status != kAudioHardwareNoError)
>> {
>> DEBUGSTR("Get
>> kAudioAggregateDevicePropertyFullSubDeviceList error
>> %4.4s\n", (char*)&status);
>> return false;
>> }
>>
>> address.mSelector = kAudioAggregateDevicePropertyMasterSubDevice;
>> status = AudioObjectSetPropertyData(aggregateID, &address, 0, NULL,
>> sizeof(outputUID), &outputUID);
>> if (status != kAudioHardwareNoError)
>> {
>> DEBUGSTR("Get kAudioAggregateDevicePropertyMasterSubDevice
>> error
>> %4.4s\n", (char*)&status);
>> return false;
>> }
>>
>> return noErr;
>> }
>
>
>
> --
>
> Jeff Moore
> Core Audio
> Apple
>
>
> _______________________________________________
> 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
>
_______________________________________________
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