18 #include <CoreServices/CoreServices.h>
19 #include <CoreAudio/CoreAudio.h>
20 #include <AudioUnit/AudioUnit.h>
21 #include <AudioToolbox/AudioFormat.h>
26 #include "SoundTouch.h"
28 #define LOC QString("CoreAudio: ")
30 #define CHANNELS_MIN 1
31 #define CHANNELS_MAX 8
39 #define OSS_STATUS(x) UInt32ToFourCC((UInt32*)&(x))
43 char* pIn = (
char*)&inVal;
44 static char fourCC[5];
55 UInt32 formatId = desc.mFormatID;
59 switch (desc.mFormatID)
61 case kAudioFormatLinearPCM:
62 str = QString(
"[%1] %2%3 Channel %4-bit %5 %6 (%7Hz)")
64 .arg((desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ?
"" :
"Mixable ")
65 .arg(desc.mChannelsPerFrame)
66 .arg(desc.mBitsPerChannel)
67 .arg((desc.mFormatFlags & kAudioFormatFlagIsFloat) ?
"Floating Point" :
"Signed Integer")
68 .arg((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ?
"BE" :
"LE")
69 .arg((UInt32)desc.mSampleRate);
72 str = QString(
"[%1] AC-3/DTS (%2Hz)")
74 .arg((UInt32)desc.mSampleRate);
76 case kAudioFormat60958AC3:
77 str = QString(
"[%1] AC-3/DTS for S/PDIF %2 (%3Hz)")
79 .arg((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ?
"BE" :
"LE")
80 .arg((UInt32)desc.mSampleRate);
83 str = QString(
"[%1]").arg(fourCC);
127 AudioStreamBasicDescription format);
130 static void Debug(
const QString& msg)
131 {
LOG(VB_AUDIO, LOG_INFO,
"CoreAudioData::" + msg); }
133 static void Error(
const QString& msg)
134 {
LOG(VB_GENERAL, LOG_ERR,
"CoreAudioData Error:" + msg); }
136 static void Warn (
const QString& msg)
137 {
LOG(VB_GENERAL, LOG_WARNING,
"CoreAudioData Warning:" + msg); }
164 AudioUnitRenderActionFlags *ioActionFlags,
165 const AudioTimeStamp *inTimeStamp,
167 UInt32 inNumberFrames,
168 AudioBufferList *ioData);
170 const AudioTimeStamp *inNow,
171 const void *inInputData,
172 const AudioTimeStamp *inInputTime,
173 AudioBufferList *outOutputData,
174 const AudioTimeStamp *inOutputTime,
210 settings->AddSupportedRate(48000);
214 while (
int rate = settings->GetNextRate())
216 for (
auto entry : rates)
220 settings->AddSupportedRate(entry);
233 settings->AddSupportedChannels(2);
241 Debug(QString(
"Support %1 channels").
arg(i));
243 if (i == 8 && !channels[6])
244 settings->AddSupportedChannels(6);
245 settings->AddSupportedChannels(i);
252 settings->setPassthrough(1);
259 bool deviceOpened =
false;
264 Debug(
"OpenDevice: Entering");
267 Debug(
"OpenDevice() Trying Digital.");
274 Debug(
"OpenDevice() Trying Analog.");
279 Debug(QString(
"OpenDevice: OpenAnalog = %1").
arg(result));
283 usleep((1000 * 1000) - 1);
286 deviceOpened = (result > 0);
291 Error(
"Couldn't open any audio device!");
299 controlLabel +=
"MixerVolume";
308 VBAUDIO(QString(
"CloseDevice [%1]: Entering")
316 template <
class AudioDataType>
321 AudioDataType tmpRLs;
322 AudioDataType tmpRRs;
324 for (
uint i = 0; i < frames; i++)
326 buf = buf2 = buf + 4;
351 int size,
unsigned long long timestamp)
367 if (written_size && (size > written_size))
370 memset(aubuf + written_size, 0, size - written_size);
380 UInt64 nanos = AudioConvertHostTimeToNanos(timestamp -
381 AudioGetCurrentHostTime());
386 return (written_size > 0);
408 if (!audbuf_timecode)
413 return audbuf_timecode - (int)(totalbuffer * 100000.0 /
420 AudioUnitRenderActionFlags *ioActionFlags,
421 const AudioTimeStamp *inTimeStamp,
423 UInt32 inNumberFrames,
424 AudioBufferList *ioData)
427 (void)inNumberFrames;
431 if (!inst->
RenderAudio((
unsigned char *)(ioData->mBuffers[0].mData),
432 ioData->mBuffers[0].mDataByteSize,
433 inTimeStamp->mHostTime))
436 memset(ioData->mBuffers[0].mData, 0, ioData->mBuffers[0].mDataByteSize);
437 *ioActionFlags = kAudioUnitRenderAction_OutputIsSilence;
449 kHALOutputParam_Volume,
450 kAudioUnitScope_Global, 0, &volume))
451 return (
int)lroundf(volume * 100.0F);
460 AudioUnitSetParameter(
d->
mOutputUnit, kHALOutputParam_Volume,
461 kAudioUnitScope_Global, 0, (volume * 0.01F), 0);
466 const AudioTimeStamp *inNow,
467 const void *inInputData,
468 const AudioTimeStamp *inInputTime,
469 AudioBufferList *outOutputData,
470 const AudioTimeStamp *inOutputTime,
475 int index =
d->mStreamIndex;
486 if (
d->mBytesPerPacket > 0 &&
487 outOutputData->mBuffers[index].mDataByteSize >
d->mBytesPerPacket)
489 outOutputData->mBuffers[index].mDataByteSize =
d->mBytesPerPacket;
491 if (!a->
RenderAudio((
unsigned char *)(outOutputData->mBuffers[index].mData),
492 outOutputData->mBuffers[index].mDataByteSize,
493 inOutputTime->mHostTime))
496 memset(outOutputData->mBuffers[index].mData, 0,
497 outOutputData->mBuffers[index].mDataByteSize);
528 if (deviceName !=
"Default Output Device")
530 Warn(QString(
"CoreAudioData: \"%1\" not found, using default device %2.")
534 Debug(QString(
"CoreAudioData: device number is %1")
541 AudioDeviceID deviceID = 0;
542 AudioObjectPropertyAddress pa
544 kAudioHardwarePropertyDevices,
545 kAudioObjectPropertyScopeGlobal,
546 kAudioObjectPropertyElementMaster
549 OSStatus err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa,
553 Warn(QString(
"GetPropertyDataSize: Unable to retrieve the property sizes. "
559 UInt32 deviceCount = size /
sizeof(AudioDeviceID);
560 auto* pDevices =
new AudioDeviceID[deviceCount];
562 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa,
563 0,
nullptr, &size, pDevices);
566 Warn(QString(
"GetDeviceWithName: Unable to retrieve the list of available devices. "
572 for (UInt32 dev = 0; dev < deviceCount; dev++)
577 QString *name = device.
GetName();
578 if (name && name == deviceName)
580 Debug(QString(
"GetDeviceWithName: Found: %1").
arg(*name));
581 deviceID = pDevices[dev];
595 AudioDeviceID deviceId = 0;
596 AudioObjectPropertyAddress pa
598 kAudioHardwarePropertyDefaultOutputDevice,
599 kAudioObjectPropertyScopeGlobal,
600 kAudioObjectPropertyElementMaster
604 paramSize =
sizeof(deviceId);
605 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa,
606 0,
nullptr, ¶mSize, &deviceId);
608 Debug(QString(
"GetDefaultOutputDevice: default device ID = %1").
arg(deviceId));
611 Warn(QString(
"GetDefaultOutputDevice: could not get default audio device: [%1]")
624 AudioObjectPropertyAddress pa
626 kAudioDevicePropertyStreamConfiguration,
627 kAudioObjectPropertyScopeGlobal,
628 kAudioObjectPropertyElementMaster
631 OSStatus err = AudioObjectGetPropertyDataSize(
mDeviceID, &pa,
635 Warn(QString(
"GetTotalOutputChannels: Unable to get "
636 "size of device output channels - id: %1 Error = [%2]")
642 auto *pList = (AudioBufferList *)malloc(size);
643 err = AudioObjectGetPropertyData(
mDeviceID, &pa,
644 0,
nullptr, &size, pList);
647 for (UInt32 buffer = 0; buffer < pList->mNumberBuffers; buffer++)
648 channels += pList->mBuffers[buffer].mNumberChannels;
652 Warn(QString(
"GetTotalOutputChannels: Unable to get "
653 "total device output channels - id: %1 Error = [%2]")
657 Debug(QString(
"GetTotalOutputChannels: Found %1 channels in %2 buffers")
658 .
arg(channels).
arg(pList->mNumberBuffers));
668 AudioObjectPropertyAddress pa
670 kAudioObjectPropertyName,
671 kAudioObjectPropertyScopeGlobal,
672 kAudioObjectPropertyElementMaster
676 UInt32 propertySize =
sizeof(CFStringRef);
677 OSStatus err = AudioObjectGetPropertyData(
mDeviceID, &pa,
678 0,
nullptr, &propertySize, &name);
681 Error(QString(
"AudioObjectGetPropertyData for kAudioObjectPropertyName error: [%1]")
685 char *cname =
new char[CFStringGetLength(name) + 1];
686 CFStringGetCString(name, cname, CFStringGetLength(name) + 1, kCFStringEncodingUTF8);
687 auto *qname =
new QString(cname);
695 UInt32 size =
sizeof(val);
696 AudioObjectPropertyAddress pa
698 kAudioHardwarePropertyHogModeIsAllowed,
699 kAudioObjectPropertyScopeGlobal,
700 kAudioObjectPropertyElementMaster
703 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa, 0,
nullptr, &size, &val);
706 Warn(QString(
"GetAutoHogMode: Unable to get auto 'hog' mode. Error = [%1]")
715 UInt32 val = enable ? 1 : 0;
716 AudioObjectPropertyAddress pa
718 kAudioHardwarePropertyHogModeIsAllowed,
719 kAudioObjectPropertyScopeGlobal,
720 kAudioObjectPropertyElementMaster
723 OSStatus err = AudioObjectSetPropertyData(kAudioObjectSystemObject, &pa, 0,
nullptr,
727 Warn(QString(
"SetAutoHogMode: Unable to set auto 'hog' mode. Error = [%1]")
735 UInt32 PIDsize =
sizeof(
PID);
736 AudioObjectPropertyAddress pa
738 kAudioDevicePropertyHogMode,
739 kAudioObjectPropertyScopeGlobal,
740 kAudioObjectPropertyElementMaster
743 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa, 0,
nullptr,
749 Debug(QString(
"GetHogStatus: unable to check: [%1]")
758 AudioObjectPropertyAddress pa
760 kAudioDevicePropertyHogMode,
761 kAudioObjectPropertyScopeGlobal,
762 kAudioObjectPropertyElementMaster
775 Debug(QString(
"SetHogStatus: Setting 'hog' status on device %1")
777 OSStatus err = AudioObjectSetPropertyData(
mDeviceID, &pa, 0,
nullptr,
779 if (err ||
mHog != getpid())
781 Warn(QString(
"SetHogStatus: Unable to set 'hog' status. Error = [%1]")
785 Debug(QString(
"SetHogStatus: Successfully set 'hog' status on device %1")
793 Debug(QString(
"SetHogStatus: Releasing 'hog' status on device %1")
796 OSStatus err = AudioObjectSetPropertyData(
mDeviceID, &pa, 0,
nullptr,
797 sizeof(hogPid), &hogPid);
798 if (err || hogPid == getpid())
800 Warn(QString(
"SetHogStatus: Unable to release 'hog' status. Error = [%1]")
817 UInt32 mixEnable = mix ? 1 : 0;
818 Debug(QString(
"SetMixingSupport: %1abling mixing for device %2")
819 .
arg(mix ?
"En" :
"Dis")
822 AudioObjectPropertyAddress pa
824 kAudioDevicePropertySupportsMixing,
825 kAudioObjectPropertyScopeGlobal,
826 kAudioObjectPropertyElementMaster
828 OSStatus err = AudioObjectSetPropertyData(
mDeviceID, &pa, 0,
nullptr,
829 sizeof(mixEnable), &mixEnable);
832 Warn(QString(
"SetMixingSupport: Unable to set MixingSupport to %1. Error = [%2]")
833 .
arg(mix ?
"'On'" :
"'Off'")
847 UInt32 size =
sizeof(val);
848 AudioObjectPropertyAddress pa
850 kAudioDevicePropertySupportsMixing,
851 kAudioObjectPropertyScopeGlobal,
852 kAudioObjectPropertyElementMaster
854 OSStatus err = AudioObjectGetPropertyData(
mDeviceID, &pa, 0,
nullptr,
870 AudioObjectPropertyAddress pa
872 kAudioDevicePropertyStreams,
873 kAudioObjectPropertyScopeGlobal,
874 kAudioObjectPropertyElementMaster
877 err = AudioObjectGetPropertyDataSize(
d, &pa,
878 0,
nullptr, &listSize);
881 Error(QString(
"StreamsList: could not get list size: [%1]")
888 vec.reserve(listSize /
sizeof(AudioStreamID));
892 Error(
"StreamsList(): out of memory?");
896 err = AudioObjectGetPropertyData(
d, &pa,
897 0,
nullptr, &listSize, vec.data());
900 Error(QString(
"StreamsList: could not get list: [%1]")
914 AudioObjectPropertyAddress pa
916 kAudioStreamPropertyPhysicalFormats,
917 kAudioObjectPropertyScopeGlobal,
918 kAudioObjectPropertyElementMaster
922 err = AudioObjectGetPropertyDataSize(s, &pa, 0,
nullptr, &listSize);
925 Warn(QString(
"FormatsList(): couldn't get list size: [%1]")
932 vec.reserve(listSize /
sizeof(AudioStreamRangedDescription));
936 Error(
"FormatsList(): out of memory?");
940 err = AudioObjectGetPropertyData(s, &pa, 0,
nullptr, &listSize, vec.data());
943 Warn(QString(
"FormatsList: couldn't get list: [%1]")
953 8000.0, 11025.0, 12000.0,
954 16000.0, 22050.0, 24000.0,
955 32000.0, 44100.0, 48000.0,
956 64000.0, 88200.0, 96000.0,
957 128000.0, 176400.0, 192000.0 };
961 bool theAnswer =
false;
976 AudioObjectPropertyAddress pa
978 kAudioDevicePropertyAvailableNominalSampleRates,
979 kAudioObjectPropertyScopeGlobal,
980 kAudioObjectPropertyElementMaster
984 err = AudioObjectGetPropertyDataSize(
d, &pa, 0,
nullptr, &listSize);
987 Warn(QString(
"RatesList(): couldn't get data rate list size: [%1]")
994 ranges.reserve(listSize /
sizeof(AudioValueRange));
995 finalvec.reserve(listSize /
sizeof(AudioValueRange));
999 Error(
"RatesList(): out of memory?");
1003 err = AudioObjectGetPropertyData(
d, &pa, 0,
nullptr, &listSize, ranges.data());
1006 Warn(QString(
"RatesList(): couldn't get list: [%1]")
1012 UInt32 theFirstIndex;
1013 UInt32 theLastIndex = 0;
1014 for(
auto range : ranges)
1016 theFirstIndex = theLastIndex;
1024 theLastIndex = theFirstIndex;
1032 finalvec.push_back(range.mMinimum);
1034 finalvec.push_back(range.mMaximum);
1044 bool founddigital =
false;
1049 if (streams.empty())
1054 for (
auto stream : streams)
1063 if (format.mFormat.mFormatID ==
'IAC3' ||
1064 format.mFormat.mFormatID == kAudioFormat60958AC3)
1066 chans[format.mFormat.mChannelsPerFrame] =
true;
1067 founddigital =
true;
1075 for (
auto stream : streams)
1082 chans[format.mFormat.mChannelsPerFrame] =
true;
1090 AudioComponentDescription desc;
1091 AudioStreamBasicDescription DeviceFormat;
1092 AudioChannelLayout *layout;
1093 AudioChannelLayout new_layout;
1095 AudioObjectPropertyAddress pa
1097 kAudioHardwarePropertyDevices,
1098 kAudioObjectPropertyScopeGlobal,
1099 kAudioObjectPropertyElementMaster
1102 Debug(
"OpenAnalog: Entering");
1104 desc.componentType = kAudioUnitType_Output;
1107 desc.componentSubType = kAudioUnitSubType_DefaultOutput;
1111 desc.componentSubType = kAudioUnitSubType_HALOutput;
1113 desc.componentManufacturer = kAudioUnitManufacturer_Apple;
1114 desc.componentFlags = 0;
1115 desc.componentFlagsMask = 0;
1118 AudioComponent comp = AudioComponentFindNext(
nullptr, &desc);
1119 if (comp ==
nullptr)
1121 Error(
"OpenAnalog: AudioComponentFindNext failed");
1125 OSErr err = AudioComponentInstanceNew(comp, &
mOutputUnit);
1128 Error(QString(
"OpenAnalog: AudioComponentInstanceNew returned %1")
1135 UInt32 size_hasIO =
sizeof(hasIO);
1137 kAudioOutputUnitProperty_HasIO,
1138 kAudioUnitScope_Output,
1140 &hasIO, &size_hasIO);
1141 Debug(QString(
"OpenAnalog: HasIO (output) = %1").
arg(hasIO));
1144 UInt32 enableIO = 1;
1146 kAudioOutputUnitProperty_EnableIO,
1147 kAudioUnitScope_Global,
1149 &enableIO,
sizeof(enableIO));
1152 Warn(QString(
"OpenAnalog: failed enabling IO: %1")
1157 kAudioOutputUnitProperty_HasIO,
1158 kAudioUnitScope_Output,
1160 &hasIO, &size_hasIO);
1161 Debug(QString(
"HasIO = %1").
arg(hasIO));
1171 kAudioOutputUnitProperty_CurrentDevice,
1172 kAudioUnitScope_Global,
1177 Error(QString(
"OpenAnalog: Unable to set current device to %1. Error = %2")
1184 UInt32 param_size =
sizeof(AudioStreamBasicDescription);
1187 kAudioUnitProperty_StreamFormat,
1188 kAudioUnitScope_Input,
1194 Warn(QString(
"OpenAnalog: Unable to retrieve current stream format: [%1]")
1199 Debug(QString(
"OpenAnalog: current format is: %1")
1203 pa.mSelector = kAudioDevicePropertyPreferredChannelLayout;
1204 err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa,
1205 0,
nullptr, ¶m_size);
1209 layout = (AudioChannelLayout *) malloc(param_size);
1211 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa,
1212 0,
nullptr, ¶m_size, layout);
1215 if(layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
1218 err = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
1219 sizeof(UInt32), &layout->mChannelBitmap,
1223 Warn(
"OpenAnalog: Can't retrieve current channel layout");
1225 else if(layout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions )
1228 err = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
1229 sizeof(AudioChannelLayoutTag),
1230 &layout->mChannelLayoutTag,
1234 Warn(
"OpenAnalog: Can't retrieve current channel layout");
1237 Debug(QString(
"OpenAnalog: Layout of AUHAL has %1 channels")
1238 .
arg(layout->mNumberChannelDescriptions));
1240 int channels_found = 0;
1241 for(UInt32 i = 0; i < layout->mNumberChannelDescriptions; i++)
1243 Debug(QString(
"OpenAnalog: this is channel: %1")
1244 .
arg(layout->mChannelDescriptions[i].mChannelLabel));
1246 switch( layout->mChannelDescriptions[i].mChannelLabel)
1248 case kAudioChannelLabel_Left:
1249 case kAudioChannelLabel_Right:
1250 case kAudioChannelLabel_Center:
1251 case kAudioChannelLabel_LFEScreen:
1252 case kAudioChannelLabel_LeftSurround:
1253 case kAudioChannelLabel_RightSurround:
1254 case kAudioChannelLabel_RearSurroundLeft:
1255 case kAudioChannelLabel_RearSurroundRight:
1256 case kAudioChannelLabel_CenterSurround:
1260 Debug(QString(
"unrecognized channel form provided by driver: %1")
1261 .
arg(layout->mChannelDescriptions[i].mChannelLabel));
1264 if(channels_found == 0)
1266 Warn(
"Audio device is not configured. "
1267 "You should configure your speaker layout with "
1268 "the \"Audio Midi Setup\" utility in /Applications/"
1275 Warn(
"this driver does not support kAudioDevicePropertyPreferredChannelLayout.");
1278 memset (&new_layout, 0,
sizeof(new_layout));
1282 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
1285 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
1289 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_5_1;
1295 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_7_1_A;
1300 kAudioUnitProperty_AudioChannelLayout,
1301 kAudioUnitScope_Input,
1303 &new_layout,
sizeof(new_layout));
1306 Warn(QString(
"OpenAnalog: couldn't set channels layout [%1]")
1310 if(new_layout.mNumberChannelDescriptions > 0)
1311 free(new_layout.mChannelDescriptions);
1318 formatFlags = kLinearPCMFormatFlagIsSignedInteger;
1321 formatFlags = kLinearPCMFormatFlagIsFloat;
1324 formatFlags = kLinearPCMFormatFlagIsSignedInteger;
1328 AudioStreamBasicDescription conv_in_desc;
1329 memset(&conv_in_desc, 0,
sizeof(AudioStreamBasicDescription));
1331 conv_in_desc.mFormatID = kAudioFormatLinearPCM;
1332 conv_in_desc.mFormatFlags = formatFlags |
1333 kAudioFormatFlagsNativeEndian |
1334 kLinearPCMFormatFlagIsPacked;
1337 conv_in_desc.mFramesPerPacket = 1;
1340 conv_in_desc.mBitsPerChannel =
1345 kAudioUnitProperty_StreamFormat,
1346 kAudioUnitScope_Input,
1349 sizeof(AudioStreamBasicDescription));
1352 Error(QString(
"OpenAnalog: AudioUnitSetProperty returned [%1]")
1356 Debug(QString(
"OpenAnalog: set format as %1")
1360 kAudioUnitProperty_StreamFormat,
1361 kAudioUnitScope_Input,
1366 Debug(QString(
"OpenAnalog: the actual set AU format is %1")
1370 AURenderCallbackStruct input;
1372 input.inputProcRefCon =
this;
1375 kAudioUnitProperty_SetRenderCallback,
1376 kAudioUnitScope_Input,
1377 0, &input,
sizeof(input));
1380 Error(QString(
"OpenAnalog: AudioUnitSetProperty (callback) returned [%1]")
1387 ComponentResult res = AudioUnitInitialize(
mOutputUnit);
1390 Error(QString(
"OpenAnalog: AudioUnitInitialize error: [%1]")
1399 Error(QString(
"OpenAnalog: AudioOutputUnitStart error: [%1]")
1411 Debug(QString(
"CloseAnalog: Entering: %1")
1418 Debug(QString(
"CloseAnalog: AudioOutputUnitStop %1")
1424 Debug(QString(
"CloseAnalog: AudioUnitUninitialize %1")
1428 Debug(QString(
"CloseAnalog: CloseComponent %1")
1442 AudioStreamBasicDescription outputFormat {};
1444 Debug(
"OpenSPDIF: Entering");
1447 if (streams.empty())
1449 Warn(
"OpenSPDIF: Couldn't retrieve list of streams");
1453 for (
size_t i = 0; i < streams.size(); ++i)
1462 Debug(QString(
"OpenSPDIF: Considering Physical Format: %1")
1464 if ((format.mFormat.mFormatID ==
'IAC3' ||
1465 format.mFormat.mFormatID == kAudioFormat60958AC3) &&
1468 Debug(
"OpenSPDIF: Found digital format");
1471 outputFormat = format.mFormat;
1475 if (outputFormat.mFormatID)
1479 if (!outputFormat.mFormatID)
1481 Error(QString(
"OpenSPDIF: Couldn't find suitable output"));
1487 AudioObjectPropertyAddress pa
1489 kAudioStreamPropertyPhysicalFormat,
1490 kAudioObjectPropertyScopeGlobal,
1491 kAudioObjectPropertyElementMaster
1497 err = AudioObjectGetPropertyData(
mStreamID, &pa, 0,
nullptr,
1501 Warn(QString(
"OpenSPDIF - could not retrieve the original streamformat: [%1]")
1530 err = AudioDeviceCreateIOProcID(
mDeviceID,
1535 Error(QString(
"OpenSPDIF: AudioDeviceCreateIOProcID failed: [%1]")
1545 Error(QString(
"OpenSPDIF: AudioDeviceStart failed: [%1]")
1566 Error(QString(
"CloseSPDIF: AudioDeviceStop failed: [%1]")
1576 Error(QString(
"CloseSPDIF: AudioDeviceDestroyIOProcID failed: [%1]")
1590 AudioHardwareUnload();
1598 AudioStreamBasicDescription format)
1600 Debug(QString(
"AudioStreamChangeFormat: %1 -> %2")
1604 AudioObjectPropertyAddress pa
1606 kAudioStreamPropertyPhysicalFormat,
1607 kAudioObjectPropertyScopeGlobal,
1608 kAudioObjectPropertyElementMaster
1610 OSStatus err = AudioObjectSetPropertyData(s, &pa, 0,
nullptr,
1611 sizeof(format), &format);
1614 Error(QString(
"AudioStreamChangeFormat couldn't set stream format: [%1]")
1628 if (streams.empty())
1631 for (
auto stream : streams)
1639 if (format.mFormat.mFormatID ==
'IAC3' ||
1640 format.mFormat.mFormatID == kAudioFormat60958AC3)
1642 Debug(
"FindAC3Stream: found digital format");
1658 AudioObjectPropertyAddress pa
1660 kAudioHardwarePropertyDevices,
1661 kAudioObjectPropertyScopeGlobal,
1662 kAudioObjectPropertyElementMaster
1665 OSStatus err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa,
1669 Warn(QString(
"GetPropertyDataSize: Unable to retrieve the property sizes. "
1675 std::vector<AudioDeviceID> devices = {};
1676 devices.resize(size /
sizeof(AudioDeviceID));
1677 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa,
1678 0,
nullptr, &size, devices.data());
1681 Warn(QString(
"GetPropertyData: Unable to retrieve the list of available devices. "
1687 for (
const auto & dev : devices)
1692 if (streams.empty())
1694 for (
auto stream : streams)
1701 AudioStreamBasicDescription currentFormat;
1704 AudioObjectPropertyAddress pa
1706 kAudioStreamPropertyPhysicalFormat,
1707 kAudioObjectPropertyScopeGlobal,
1708 kAudioObjectPropertyElementMaster
1713 paramSize =
sizeof(currentFormat);
1714 AudioObjectGetPropertyData(s, &pa, 0,
nullptr,
1715 ¶mSize, ¤tFormat);
1718 if (currentFormat.mFormatID ==
'IAC3' ||
1719 currentFormat.mFormatID == kAudioFormat60958AC3)
1728 if (format.mFormat.mFormatID == kAudioFormatLinearPCM)
1730 err = AudioObjectSetPropertyData(s, &pa, 0,
nullptr,
1731 sizeof(format), &(format.mFormat));
1734 Warn(QString(
"ResetStream: could not set physical format: [%1]")
1747 auto *devs =
new QMap<QString, QString>();
1752 AudioObjectPropertyAddress pa
1754 kAudioHardwarePropertyDevices,
1755 kAudioObjectPropertyScopeGlobal,
1756 kAudioObjectPropertyElementMaster
1759 OSStatus err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa,
1763 VBAUDIO(QString(
"GetPropertyDataSize: Unable to retrieve the property sizes. "
1769 UInt32 deviceCount = size /
sizeof(AudioDeviceID);
1770 auto* pDevices =
new AudioDeviceID[deviceCount];
1771 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &pa,
1772 0,
nullptr, &size, pDevices);
1775 VBAUDIO(QString(
"AudioOutputCA::GetDevices: Unable to retrieve the list of "
1776 "available devices. Error [%1]")
1781 VBAUDIO(QString(
"GetDevices: Number of devices: %1").
arg(deviceCount));
1783 for (UInt32 dev = 0; dev < deviceCount; dev++)
1788 QString *name = device.
GetName();
1791 devs->insert(*name, QString());