Re: Enumerating Airplay devices
Re: Enumerating Airplay devices
- Subject: Re: Enumerating Airplay devices
- From: Patrick Dehne <email@hidden>
- Date: Wed, 09 Apr 2014 19:27:55 +0200
Am 09.04.2014 um 09:03 schrieb Hendrik Schreiber <email@hidden>:
> On Apr 9, 2014, at 0:27, Lorenzo Thurman <email@hidden> wrote:
>
>> I would like to be able to stream audio to AirPlay devices, but it seems that Core Audio will not enumerate the available devices. I can get all the physically connected devices enumerated, but if there are multiple Airplay devices available, CoreAudio will list only a single "Airplay" entry. A cursory reading of the Bonjour docs suggests that I'll need to used that API to get a list of Airplay devices. Can someone confirm if that is indeed the case, or if there is a better way?
>> Thanks
>
> Perhaps this helps: http://joris.kluivers.nl/blog/2012/07/25/per-application-airplay-in-mountain-lion/
> Demo app at: https://bitbucket.org/kluivers/airplaystreaming
>
> (haven't tried any of this myself)
I have this working in my app.
First get the available data sources for the audio device:
int getDataSourceIDs(bool input, Array <OSType>& dataSourceIDs)
{
if (deviceID != 0)
{
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioDevicePropertyDataSources;
pa.mScope = ((input == true) ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
pa.mElement = kAudioObjectPropertyElementMaster;
UInt32 size = 0;
if ( OK(AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size)))
{
HeapBlock<OSType> sources;
sources.calloc (size, 1);
if ( OK(AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, sources)))
{
int num = size / (int) sizeof (OSType);
for(int i=0; i < num; i++)
dataSourceIDs.add(sources[i]);
return num;
}
}
}
return 0;
}
Then get the names of the data sources
String getDataSourceName(OSType dataSourceID, bool input)
{
AudioValueTranslation avt;
char buffer[256];
avt.mInputData = &dataSourceID;
avt.mInputDataSize = sizeof (UInt32);
avt.mOutputData = buffer;
avt.mOutputDataSize = 256;
UInt32 transSize = sizeof (avt);
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioDevicePropertyDataSourceNameForID;
pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
pa.mElement = kAudioObjectPropertyElementMaster;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &transSize, &avt)))
return CharPointer_UTF8(buffer);
return String::empty;
}
With the introduction of Mac OS 10.9 sending output to multiple airplay devices has stopped working though. So this code that worked previously has stopped to work if multiple data sources are supplied:
void selectDataSourcesForOutput(const Array<OSType>& dataSourcesToSelect)
{
if (deviceID != 0)
{
if(dataSourcesToSelect.size() > 0)
{
HeapBlock <OSType> dataSourcesToSelectMemory;
dataSourcesToSelectMemory.calloc(dataSourcesToSelect.size());
for(int i=0; i<dataSourcesToSelect.size(); i++)
dataSourcesToSelectMemory[i] = dataSourcesToSelect[i];
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioDevicePropertyDataSource;
pa.mScope = kAudioDevicePropertyScopeOutput;
pa.mElement = kAudioObjectPropertyElementMaster;
AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof(OSType) * dataSourcesToSelect.size(), dataSourcesToSelectMemory);
}
}
}
Hope that helps,
Patrick
_______________________________________________
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