20 #include "JackCoreAudioDriver.h"
21 #include "JackEngineControl.h"
22 #include "JackMachThread.h"
23 #include "JackGraphManager.h"
24 #include "JackError.h"
25 #include "JackClientControl.h"
26 #include "JackDriverLoader.h"
27 #include "JackGlobals.h"
28 #include "JackTools.h"
29 #include "JackLockedEngine.h"
30 #include "JackAC3Encoder.h"
34 #include <CoreServices/CoreServices.h>
35 #include <CoreFoundation/CFNumber.h>
40 static void Print4CharCode(
const char* msg,
long c)
42 UInt32 __4CC_number = (c);
44 *((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number);
46 jack_log(
"%s'%s'", (msg), __4CC_string);
49 static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
51 jack_log(
"- - - - - - - - - - - - - - - - - - - -");
52 jack_log(
" Sample Rate:%f", inDesc->mSampleRate);
53 jack_log(
" Format ID:%.*s", (
int)
sizeof(inDesc->mFormatID), (
char*)&inDesc->mFormatID);
54 jack_log(
" Format Flags:%lX", inDesc->mFormatFlags);
55 jack_log(
" Bytes per Packet:%ld", inDesc->mBytesPerPacket);
56 jack_log(
" Frames per Packet:%ld", inDesc->mFramesPerPacket);
57 jack_log(
" Bytes per Frame:%ld", inDesc->mBytesPerFrame);
58 jack_log(
" Channels per Frame:%ld", inDesc->mChannelsPerFrame);
59 jack_log(
" Bits per Channel:%ld", inDesc->mBitsPerChannel);
60 jack_log(
"- - - - - - - - - - - - - - - - - - - -");
63 static void printError(OSStatus err)
66 case kAudioHardwareNoError:
67 jack_log(
"error code : kAudioHardwareNoError");
69 case kAudioConverterErr_FormatNotSupported:
70 jack_log(
"error code : kAudioConverterErr_FormatNotSupported");
72 case kAudioConverterErr_OperationNotSupported:
73 jack_log(
"error code : kAudioConverterErr_OperationNotSupported");
75 case kAudioConverterErr_PropertyNotSupported:
76 jack_log(
"error code : kAudioConverterErr_PropertyNotSupported");
78 case kAudioConverterErr_InvalidInputSize:
79 jack_log(
"error code : kAudioConverterErr_InvalidInputSize");
81 case kAudioConverterErr_InvalidOutputSize:
82 jack_log(
"error code : kAudioConverterErr_InvalidOutputSize");
84 case kAudioConverterErr_UnspecifiedError:
85 jack_log(
"error code : kAudioConverterErr_UnspecifiedError");
87 case kAudioConverterErr_BadPropertySizeError:
88 jack_log(
"error code : kAudioConverterErr_BadPropertySizeError");
90 case kAudioConverterErr_RequiresPacketDescriptionsError:
91 jack_log(
"error code : kAudioConverterErr_RequiresPacketDescriptionsError");
93 case kAudioConverterErr_InputSampleRateOutOfRange:
94 jack_log(
"error code : kAudioConverterErr_InputSampleRateOutOfRange");
96 case kAudioConverterErr_OutputSampleRateOutOfRange:
97 jack_log(
"error code : kAudioConverterErr_OutputSampleRateOutOfRange");
99 case kAudioHardwareNotRunningError:
100 jack_log(
"error code : kAudioHardwareNotRunningError");
102 case kAudioHardwareUnknownPropertyError:
103 jack_log(
"error code : kAudioHardwareUnknownPropertyError");
105 case kAudioHardwareIllegalOperationError:
106 jack_log(
"error code : kAudioHardwareIllegalOperationError");
108 case kAudioHardwareBadDeviceError:
109 jack_log(
"error code : kAudioHardwareBadDeviceError");
111 case kAudioHardwareBadStreamError:
112 jack_log(
"error code : kAudioHardwareBadStreamError");
114 case kAudioDeviceUnsupportedFormatError:
115 jack_log(
"error code : kAudioDeviceUnsupportedFormatError");
117 case kAudioDevicePermissionsError:
118 jack_log(
"error code : kAudioDevicePermissionsError");
120 case kAudioHardwareBadObjectError:
121 jack_log(
"error code : kAudioHardwareBadObjectError");
123 case kAudioHardwareUnsupportedOperationError:
124 jack_log(
"error code : kAudioHardwareUnsupportedOperationError");
127 Print4CharCode(
"error code : unknown ", err);
132 static bool CheckAvailableDeviceName(
const char* device_name, AudioDeviceID* device_id)
139 err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
144 deviceNum = size /
sizeof(AudioDeviceID);
145 AudioDeviceID devices[deviceNum];
147 err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
152 for (i = 0; i < deviceNum; i++) {
153 char device_name_aux[256];
156 err = AudioDeviceGetProperty(devices[i], 0,
false, kAudioDevicePropertyDeviceName, &size, device_name_aux);
161 if (strcmp(device_name_aux, device_name) == 0) {
162 *device_id = devices[i];
171 static bool CheckAvailableDevice(AudioDeviceID device_id)
178 err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
183 deviceNum = size /
sizeof(AudioDeviceID);
184 AudioDeviceID devices[deviceNum];
186 err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
191 for (i = 0; i < deviceNum; i++) {
192 if (device_id == devices[i]) {
201 static OSStatus DisplayDeviceNames()
209 err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
214 deviceNum = size /
sizeof(AudioDeviceID);
215 AudioDeviceID devices[deviceNum];
217 err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
222 for (i = 0; i < deviceNum; i++) {
223 char device_name[256];
224 char internal_name[256];
226 size =
sizeof(CFStringRef);
228 err = AudioDeviceGetProperty(devices[i], 0,
false, kAudioDevicePropertyDeviceUID, &size, &UIname);
230 CFStringGetCString(UIname, internal_name, 256, CFStringGetSystemEncoding());
236 err = AudioDeviceGetProperty(devices[i], 0,
false, kAudioDevicePropertyDeviceName, &size, device_name);
241 jack_info(
"Device ID = \'%d\' name = \'%s\', internal name = \'%s\' (to be used as -C, -P, or -d parameter)", devices[i], device_name, internal_name);
247 if (UIname != NULL) {
253 static CFStringRef GetDeviceName(AudioDeviceID
id)
255 UInt32 size =
sizeof(CFStringRef);
257 OSStatus err = AudioDeviceGetProperty(
id, 0,
false, kAudioDevicePropertyDeviceUID, &size, &UIname);
258 return (err == noErr) ? UIname : NULL;
261 static void ParseChannelList(
const string& list, vector<int>& result,
int max_chan)
263 stringstream ss(list);
267 while (ss >> token) {
271 if (chan < 0 || chan >= max_chan) {
272 jack_error(
"Ignore incorrect channel mapping value = %d", chan);
274 result.push_back(chan);
279 OSStatus JackCoreAudioDriver::Render(
void* inRefCon,
280 AudioUnitRenderActionFlags* ioActionFlags,
281 const AudioTimeStamp* inTimeStamp,
283 UInt32 inNumberFrames,
284 AudioBufferList* ioData)
286 JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inRefCon;
287 driver->fActionFags = ioActionFlags;
288 driver->fCurrentTime = inTimeStamp;
289 driver->fDriverOutputData = ioData;
292 if (set_threaded_log_function()) {
294 jack_log(
"JackCoreAudioDriver::Render : set_threaded_log_function");
295 JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint);
297 if (driver->fComputationGrain > 0) {
298 jack_log(
"JackCoreAudioDriver::Render : RT thread computation setup to %d percent of period",
int(driver->fComputationGrain * 100));
299 driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain;
304 driver->fState =
true;
306 driver->CycleTakeBeginTime();
308 if (driver->Process() < 0) {
310 driver->NotifyFailure(JackBackendError,
"Process error, stopping driver");
312 kill(JackTools::GetPID(), SIGINT);
313 return kAudioHardwareUnsupportedOperationError;
319 int JackCoreAudioDriver::Read()
321 if (fCaptureChannels > 0) {
322 return (AudioUnitRender(fAUHAL, fActionFags, fCurrentTime, 1, fEngineControl->fBufferSize, fJackInputData) == noErr) ? 0 : -1;
328 int JackCoreAudioDriver::Write()
333 jack_default_audio_sample_t* AC3_inputs[MAX_AC3_CHANNELS];
334 jack_default_audio_sample_t* AC3_outputs[2];
335 for (
int i = 0; i < fPlaybackChannels; i++) {
336 AC3_inputs[i] = GetOutputBuffer(i);
338 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) == 0) {
339 memset(AC3_inputs[i], 0,
sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
342 AC3_outputs[0] = (jack_default_audio_sample_t*)fDriverOutputData->mBuffers[0].mData;
343 AC3_outputs[1] = (jack_default_audio_sample_t*)fDriverOutputData->mBuffers[1].mData;
344 fAC3Encoder->Process(AC3_inputs, AC3_outputs, fEngineControl->fBufferSize);
349 for (
int i = 0; i < fPlaybackChannels; i++) {
350 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
351 jack_default_audio_sample_t* buffer = GetOutputBuffer(i);
352 int size =
sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize;
353 memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size);
355 if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) {
356 memcpy(GetMonitorBuffer(i), buffer, size);
359 memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0,
sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
366 OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice,
369 AudioDevicePropertyID inPropertyID,
372 JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData;
374 switch (inPropertyID) {
376 case kAudioDevicePropertyNominalSampleRate: {
377 jack_log(
"JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate");
379 Float64 tmp_sample_rate;
380 UInt32 outSize =
sizeof(Float64);
381 OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &tmp_sample_rate);
386 jack_log(
"JackCoreAudioDriver::SRNotificationCallback : checked sample rate = %f", tmp_sample_rate);
388 driver->fState =
true;
396 OSStatus JackCoreAudioDriver::BSNotificationCallback(AudioDeviceID inDevice,
399 AudioDevicePropertyID inPropertyID,
402 JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData;
404 switch (inPropertyID) {
406 case kAudioDevicePropertyBufferFrameSize: {
407 jack_log(
"JackCoreAudioDriver::BSNotificationCallback kAudioDevicePropertyBufferFrameSize");
409 UInt32 tmp_buffer_size;
410 UInt32 outSize =
sizeof(UInt32);
411 OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size);
416 jack_log(
"JackCoreAudioDriver::BSNotificationCallback : checked buffer size = %d", tmp_buffer_size);
418 driver->fState =
true;
427 OSStatus JackCoreAudioDriver::AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID,
void* inClientData)
429 JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData;
431 switch (inPropertyID) {
433 case kAudioHardwarePropertyDevices: {
434 jack_log(
"JackCoreAudioDriver::AudioHardwareNotificationCallback kAudioHardwarePropertyDevices");
435 DisplayDeviceNames();
436 AudioDeviceID captureID, playbackID;
437 if (CheckAvailableDevice(driver->fDeviceID) ||
438 (CheckAvailableDeviceName(driver->fCaptureUID, &captureID)
439 && CheckAvailableDeviceName(driver->fPlaybackUID, &playbackID))) {
449 OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
452 AudioDevicePropertyID inPropertyID,
455 JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData;
457 switch (inPropertyID) {
459 case kAudioDevicePropertyDeviceIsRunning: {
460 UInt32 isrunning = 0;
461 UInt32 outsize =
sizeof(UInt32);
462 if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, &outsize, &isrunning) == noErr) {
463 jack_log(
"JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsRunning = %d", isrunning);
468 case kAudioDevicePropertyDeviceIsAlive: {
470 UInt32 outsize =
sizeof(UInt32);
471 if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsAlive, &outsize, &isalive) == noErr) {
472 jack_log(
"JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsAlive = %d", isalive);
477 case kAudioDevicePropertyDeviceHasChanged: {
478 UInt32 hachanged = 0;
479 UInt32 outsize =
sizeof(UInt32);
480 if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceHasChanged, &outsize, &hachanged) == noErr) {
481 jack_log(
"JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceHasChanged = %d", hachanged);
486 case kAudioDeviceProcessorOverload: {
487 jack_error(
"DeviceNotificationCallback kAudioDeviceProcessorOverload");
488 jack_time_t cur_time = GetMicroSeconds();
489 driver->NotifyXRun(cur_time,
float(cur_time - driver->fBeginDateUst));
493 case kAudioDevicePropertyStreamConfiguration: {
494 jack_error(
"Cannot handle kAudioDevicePropertyStreamConfiguration : server will quit...");
495 driver->NotifyFailure(JackBackendError,
"Another application has changed the device configuration");
496 driver->CloseAUHAL();
497 kill(JackTools::GetPID(), SIGINT);
498 return kAudioHardwareUnsupportedOperationError;
501 case kAudioDevicePropertyNominalSampleRate: {
502 Float64 sample_rate = 0;
503 UInt32 outsize =
sizeof(Float64);
504 OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate);
506 return kAudioHardwareUnsupportedOperationError;
509 char device_name[256];
510 const char* digidesign_name =
"Digidesign";
511 driver->GetDeviceNameFromID(driver->fDeviceID, device_name);
513 if (sample_rate != driver->fEngineControl->fSampleRate) {
516 if (strncmp(device_name, digidesign_name, 10) == 0) {
518 jack_log(
"JackCoreAudioDriver::DeviceNotificationCallback Digidesign HW = %s", device_name);
521 sample_rate = driver->fEngineControl->fSampleRate;
522 err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sample_rate);
524 jack_error(
"Cannot set sample rate = %f", sample_rate);
527 jack_log(
"JackCoreAudioDriver::DeviceNotificationCallback : set sample rate = %f", sample_rate);
531 outsize =
sizeof(Float64);
532 err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate);
537 jack_log(
"JackCoreAudioDriver::DeviceNotificationCallback : checked sample rate = %f", sample_rate);
542 driver->NotifyFailure(JackBackendError,
"Another application has changed the sample rate");
543 driver->CloseAUHAL();
544 kill(JackTools::GetPID(), SIGINT);
545 return kAudioHardwareUnsupportedOperationError;
554 OSStatus JackCoreAudioDriver::GetDeviceIDFromUID(
const char* UID, AudioDeviceID*
id)
556 UInt32 size =
sizeof(AudioValueTranslation);
557 CFStringRef inIUD = CFStringCreateWithCString(NULL, UID, CFStringGetSystemEncoding());
558 AudioValueTranslation value = { &inIUD,
sizeof(CFStringRef),
id,
sizeof(AudioDeviceID) };
561 return kAudioHardwareUnspecifiedError;
563 OSStatus res = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value);
565 jack_log(
"JackCoreAudioDriver::GetDeviceIDFromUID %s %ld", UID, *
id);
566 return (*
id == kAudioDeviceUnknown) ? kAudioHardwareBadDeviceError : res;
570 OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID*
id)
573 UInt32 theSize =
sizeof(UInt32);
574 AudioDeviceID inDefault;
575 AudioDeviceID outDefault;
577 if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
581 if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
585 jack_log(
"JackCoreAudioDriver::GetDefaultDevice : input = %ld output = %ld", inDefault, outDefault);
588 if (inDefault != outDefault) {
589 jack_error(
"Default input and output devices are not the same !!");
590 return kAudioHardwareBadDeviceError;
591 }
else if (inDefault == 0) {
592 jack_error(
"Default input and output devices are null !!");
593 return kAudioHardwareBadDeviceError;
600 OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID*
id)
603 UInt32 theSize =
sizeof(UInt32);
604 AudioDeviceID inDefault;
606 if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
610 if (inDefault == 0) {
611 jack_error(
"Error default input device is 0, please select a correct one !!");
614 jack_log(
"JackCoreAudioDriver::GetDefaultInputDevice : input = %ld ", inDefault);
619 OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID*
id)
622 UInt32 theSize =
sizeof(UInt32);
623 AudioDeviceID outDefault;
625 if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
629 if (outDefault == 0) {
630 jack_error(
"Error default output device is 0, please select a correct one !!");
633 jack_log(
"JackCoreAudioDriver::GetDefaultOutputDevice : output = %ld", outDefault);
638 OSStatus JackCoreAudioDriver::GetDeviceNameFromID(AudioDeviceID
id,
char* name)
641 return AudioDeviceGetProperty(
id, 0,
false, kAudioDevicePropertyDeviceName, &size, name);
644 OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device,
int& channelCount,
bool isInput)
646 OSStatus err = noErr;
651 err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable);
653 int stream_count = outSize /
sizeof(AudioBufferList);
654 jack_log(
"JackCoreAudioDriver::GetTotalChannels stream_count = %d", stream_count);
655 AudioBufferList bufferList[stream_count];
656 err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList);
658 for (uint i = 0; i < bufferList->mNumberBuffers; i++) {
659 channelCount += bufferList->mBuffers[i].mNumberChannels;
660 jack_log(
"JackCoreAudioDriver::GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels);
667 OSStatus JackCoreAudioDriver::GetStreamLatencies(AudioDeviceID device,
bool isInput, vector<int>& latencies)
669 OSStatus err = noErr;
670 UInt32 outSize1, outSize2, outSize3;
673 err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, &outWritable);
675 int stream_count = outSize1 /
sizeof(UInt32);
676 AudioStreamID streamIDs[stream_count];
677 AudioBufferList bufferList[stream_count];
678 UInt32 streamLatency;
679 outSize2 =
sizeof(UInt32);
681 err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, streamIDs);
683 jack_error(
"GetStreamLatencies kAudioDevicePropertyStreams err = %d", err);
687 err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, &outWritable);
689 jack_error(
"GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err);
693 for (
int i = 0; i < stream_count; i++) {
694 err = AudioStreamGetProperty(streamIDs[i], 0, kAudioStreamPropertyLatency, &outSize2, &streamLatency);
696 jack_error(
"GetStreamLatencies kAudioStreamPropertyLatency err = %d", err);
699 err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, bufferList);
701 jack_error(
"GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err);
705 for (uint k = 0; k < bufferList->mBuffers[i].mNumberChannels; k++) {
706 latencies.push_back(streamLatency);
713 bool JackCoreAudioDriver::IsDigitalDevice(AudioDeviceID device)
715 OSStatus err = noErr;
717 bool is_digital =
false;
720 AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
721 err = AudioObjectGetPropertyDataSize(device, &streamsAddress, 0, NULL, &outSize1);
723 jack_error(
"IsDigitalDevice kAudioDevicePropertyStreams err = %d", err);
727 int stream_count = outSize1 /
sizeof(AudioStreamID);
728 AudioStreamID streamIDs[stream_count];
730 err = AudioObjectGetPropertyData(device, &streamsAddress, 0, NULL, &outSize1, streamIDs);
733 jack_error(
"IsDigitalDevice kAudioDevicePropertyStreams list err = %d", err);
737 AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 };
739 for (
int i = 0; i < stream_count ; i++) {
745 err = AudioObjectGetPropertyDataSize(streamIDs[i], &physicalFormatsAddress, 0, NULL, &outSize1);
748 jack_error(
"IsDigitalDevice kAudioStreamPropertyAvailablePhysicalFormats err = %d", err);
752 format_num = outSize1 /
sizeof(AudioStreamRangedDescription);
753 AudioStreamRangedDescription format_list[format_num];
755 err = AudioObjectGetPropertyData(streamIDs[i], &physicalFormatsAddress, 0, NULL, &outSize1, format_list);
758 jack_error(
"IsDigitalDevice could not get the list of streamformats err = %d", err);
763 for (
int j = 0; j < format_num; j++) {
765 PrintStreamDesc(&format_list[j].mFormat);
767 if (format_list[j].mFormat.mFormatID ==
'IAC3' ||
768 format_list[j].mFormat.mFormatID ==
'iac3' ||
769 format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ||
770 format_list[j].mFormat.mFormatID == kAudioFormatAC3)
781 JackCoreAudioDriver::JackCoreAudioDriver(
const char* name,
const char* alias, JackLockedEngine* engine, JackSynchro* table)
782 : JackAudioDriver(name, alias, engine, table),
784 fJackInputData(NULL),
785 fDriverOutputData(NULL),
790 fComputationGrain(-1.f),
791 fClockDriftCompensate(false),
792 fDigitalPlayback(false)
795 JackCoreAudioDriver::~JackCoreAudioDriver()
800 OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
802 OSStatus osErr = noErr;
803 AudioObjectPropertyAddress pluginAOPA;
804 pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice;
805 pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
806 pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
811 osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
812 if (osErr != noErr) {
813 jack_error(
"DestroyAggregateDevice : AudioObjectGetPropertyDataSize error");
818 osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID);
819 if (osErr != noErr) {
820 jack_error(
"DestroyAggregateDevice : AudioObjectGetPropertyData error");
830 OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice)
832 OSStatus err = noErr;
833 AudioObjectID sub_device[32];
834 UInt32 outSize =
sizeof(sub_device);
836 err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
837 vector<AudioDeviceID> captureDeviceIDArray;
840 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : input device does not have subdevices");
841 captureDeviceIDArray.push_back(captureDeviceID);
843 int num_devices = outSize /
sizeof(AudioObjectID);
844 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice :Input device has %d subdevices", num_devices);
845 for (
int i = 0; i < num_devices; i++) {
846 captureDeviceIDArray.push_back(sub_device[i]);
850 err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
851 vector<AudioDeviceID> playbackDeviceIDArray;
854 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : output device does not have subdevices");
855 playbackDeviceIDArray.push_back(playbackDeviceID);
857 int num_devices = outSize /
sizeof(AudioObjectID);
858 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : output device has %d subdevices", num_devices);
859 for (
int i = 0; i < num_devices; i++) {
860 playbackDeviceIDArray.push_back(sub_device[i]);
864 return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice);
867 OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice)
869 OSStatus osErr = noErr;
875 AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
876 AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
877 UInt32 theQualifierDataSize =
sizeof(AudioObjectID);
878 AudioClassID inClass = kAudioSubDeviceClassID;
879 void* theQualifierData = &inClass;
880 UInt32 subDevicesNum = 0;
885 UInt32 keptclockdomain = 0;
886 UInt32 clockdomain = 0;
887 outSize =
sizeof(UInt32);
888 bool need_clock_drift_compensation =
false;
890 for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
891 if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) {
892 jack_error(
"CreateAggregateDevice : cannot set SR of input device");
895 osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
897 jack_error(
"CreateAggregateDevice : kAudioDevicePropertyClockDomain error");
900 keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
901 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain);
902 if (clockdomain != 0 && clockdomain != keptclockdomain) {
903 jack_error(
"CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...");
904 need_clock_drift_compensation =
true;
910 for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
911 if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) {
912 jack_error(
"CreateAggregateDevice : cannot set SR of output device");
915 osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
917 jack_error(
"CreateAggregateDevice : kAudioDevicePropertyClockDomain error");
920 keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
921 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain);
922 if (clockdomain != 0 && clockdomain != keptclockdomain) {
923 jack_error(
"CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...");
924 need_clock_drift_compensation =
true;
931 if (keptclockdomain == 0) {
932 need_clock_drift_compensation =
true;
939 char device_name[256];
940 for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
941 GetDeviceNameFromID(captureDeviceID[i], device_name);
942 jack_info(
"Separated input = '%s' ", device_name);
945 for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
946 GetDeviceNameFromID(playbackDeviceID[i], device_name);
947 jack_info(
"Separated output = '%s' ", device_name);
950 osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable);
951 if (osErr != noErr) {
952 jack_error(
"CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error");
957 AudioValueTranslation pluginAVT;
959 CFStringRef inBundleRef = CFSTR(
"com.apple.audio.CoreAudio");
961 pluginAVT.mInputData = &inBundleRef;
962 pluginAVT.mInputDataSize =
sizeof(inBundleRef);
963 pluginAVT.mOutputData = &fPluginID;
964 pluginAVT.mOutputDataSize =
sizeof(fPluginID);
966 osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT);
967 if (osErr != noErr) {
968 jack_error(
"CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error");
977 CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
979 CFStringRef AggregateDeviceNameRef = CFSTR(
"JackDuplex");
980 CFStringRef AggregateDeviceUIDRef = CFSTR(
"com.grame.JackDuplex");
983 CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef);
986 CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef);
990 CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value);
993 Gestalt(gestaltSystemVersion, &system);
995 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054);
998 if (system < 0x00001054) {
999 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : public aggregate device....");
1001 jack_log(
"JackCoreAudioDriver::CreateAggregateDevice : private aggregate device....");
1002 CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef);
1006 CFMutableArrayRef subDevicesArrayClock = NULL;
1049 CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1051 vector<CFStringRef> captureDeviceUID;
1052 for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
1053 CFStringRef ref = GetDeviceName(captureDeviceID[i]);
1057 captureDeviceUID.push_back(ref);
1059 CFArrayAppendValue(subDevicesArray, ref);
1062 vector<CFStringRef> playbackDeviceUID;
1063 for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
1064 CFStringRef ref = GetDeviceName(playbackDeviceID[i]);
1068 playbackDeviceUID.push_back(ref);
1070 CFArrayAppendValue(subDevicesArray, ref);
1077 AudioObjectPropertyAddress pluginAOPA;
1078 pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice;
1079 pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
1080 pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
1083 osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
1084 if (osErr != noErr) {
1085 jack_error(
"CreateAggregateDevice : AudioObjectGetPropertyDataSize error");
1090 osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA,
sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice);
1091 if (osErr != noErr) {
1092 jack_error(
"CreateAggregateDevice : AudioObjectGetPropertyData error");
1099 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1,
false);
1105 pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList;
1106 pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
1107 pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
1108 outDataSize =
sizeof(CFMutableArrayRef);
1109 osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray);
1110 if (osErr != noErr) {
1111 jack_error(
"CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error");
1117 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1,
false);
1125 pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice;
1126 pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
1127 pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
1128 outDataSize =
sizeof(CFStringRef);
1129 osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]);
1130 if (osErr != noErr) {
1131 jack_error(
"CreateAggregateDevice : AudioObjectSetPropertyData for master device error");
1137 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1,
false);
1142 if (fClockDriftCompensate) {
1143 if (need_clock_drift_compensation) {
1144 jack_info(
"Clock drift compensation activated...");
1147 osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize);
1148 if (osErr != noErr) {
1149 jack_error(
"CreateAggregateDevice kAudioObjectPropertyOwnedObjects error");
1154 subDevicesNum = outSize /
sizeof(AudioObjectID);
1155 jack_info(
"JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum);
1156 AudioObjectID subDevices[subDevicesNum];
1157 outSize =
sizeof(subDevices);
1159 osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices);
1160 if (osErr != noErr) {
1161 jack_error(
"CreateAggregateDevice kAudioObjectPropertyOwnedObjects error");
1166 for (UInt32 index = 0; index < subDevicesNum; ++index) {
1167 UInt32 theDriftCompensationValue = 1;
1168 osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL,
sizeof(UInt32), &theDriftCompensationValue);
1169 if (osErr != noErr) {
1170 jack_error(
"CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error");
1175 jack_info(
"Clock drift compensation was asked but is not needed (devices use the same clock domain)");
1180 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1,
false);
1187 CFRelease(AggregateDeviceNumberRef);
1190 CFRelease(aggDeviceDict);
1191 CFRelease(subDevicesArray);
1193 if (subDevicesArrayClock) {
1194 CFRelease(subDevicesArrayClock);
1198 for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
1199 CFRelease(captureDeviceUID[i]);
1202 for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) {
1203 CFRelease(playbackDeviceUID[i]);
1206 jack_log(
"JackCoreAudioDriver::CreateAggregateDeviceAux : new aggregate device %ld", *outAggregateDevice);
1210 DestroyAggregateDevice();
1214 int JackCoreAudioDriver::SetupDevices(
const char* capture_driver_uid,
1215 const char* playback_driver_uid,
1216 char* capture_driver_name,
1217 char* playback_driver_name,
1218 jack_nframes_t samplerate,
1221 capture_driver_name[0] = 0;
1222 playback_driver_name[0] = 0;
1225 if (strcmp(capture_driver_uid,
"") != 0 && strcmp(playback_driver_uid,
"") != 0) {
1226 jack_log(
"JackCoreAudioDriver::SetupDevices : duplex");
1229 if (strcmp(capture_driver_uid, playback_driver_uid) == 0) {
1231 if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) {
1232 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default in/out");
1233 if (GetDefaultDevice(&fDeviceID) != noErr) {
1238 if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) {
1239 jack_error(
"Cannot get device name from device ID");
1244 if (!TakeHogAux(fDeviceID,
false)) {
1248 fDigitalPlayback = IsDigitalDevice(fDeviceID);
1255 AudioDeviceID captureID = -1;
1256 AudioDeviceID playbackID = -1;
1258 if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) {
1259 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default input");
1260 if (GetDefaultInputDevice(&captureID) != noErr) {
1261 jack_error(
"Cannot open default input device");
1266 if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) {
1267 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default output");
1268 if (GetDefaultOutputDevice(&playbackID) != noErr) {
1269 jack_error(
"Cannot open default output device");
1274 if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) {
1278 GetDeviceNameFromID(captureID, fCaptureUID);
1279 GetDeviceNameFromID(playbackID, fPlaybackUID);
1282 if (!TakeHogAux(captureID,
true)) {
1283 jack_error(
"Cannot take hog mode for capture device");
1285 if (!TakeHogAux(playbackID,
false)) {
1286 jack_error(
"Cannot take hog mode for playback device");
1289 fDigitalPlayback = IsDigitalDevice(playbackID);
1296 }
else if (strcmp(capture_driver_uid,
"") != 0) {
1297 jack_log(
"JackCoreAudioDriver::SetupDevices : capture only");
1298 if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) {
1299 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default input");
1300 if (GetDefaultInputDevice(&fDeviceID) != noErr) {
1301 jack_error(
"Cannot open default input device");
1305 if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr) {
1306 jack_error(
"Cannot get device name from device ID");
1311 if (!TakeHogAux(fDeviceID,
true)) {
1312 jack_error(
"Cannot take hog mode for capture device");
1317 }
else if (strcmp(playback_driver_uid,
"") != 0) {
1318 jack_log(
"JackCoreAudioDriver::SetupDevices : playback only");
1319 if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) {
1320 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default output");
1321 if (GetDefaultOutputDevice(&fDeviceID) != noErr) {
1322 jack_error(
"Cannot open default output device");
1326 if (GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) {
1327 jack_error(
"Cannot get device name from device ID");
1332 if (!TakeHogAux(fDeviceID,
false)) {
1333 jack_error(
"Cannot take hog mode for playback device");
1336 fDigitalPlayback = IsDigitalDevice(fDeviceID);
1342 jack_log(
"JackCoreAudioDriver::SetupDevices : default driver");
1343 if (GetDefaultDevice(&fDeviceID) != noErr) {
1344 jack_error(
"Cannot open default device in duplex mode, so aggregate default input and default output");
1347 AudioDeviceID captureID = -1;
1348 AudioDeviceID playbackID = -1;
1350 if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) {
1351 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default input");
1352 if (GetDefaultInputDevice(&captureID) != noErr) {
1353 jack_error(
"Cannot open default input device");
1358 if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) {
1359 jack_log(
"JackCoreAudioDriver::SetupDevices : will take default output");
1360 if (GetDefaultOutputDevice(&playbackID) != noErr) {
1361 jack_error(
"Cannot open default output device");
1366 if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) {
1370 GetDeviceNameFromID(captureID, fCaptureUID);
1371 GetDeviceNameFromID(playbackID, fPlaybackUID);
1374 if (!TakeHogAux(captureID,
true)) {
1375 jack_error(
"Cannot take hog mode for capture device");
1377 if (!TakeHogAux(playbackID,
false)) {
1378 jack_error(
"Cannot take hog mode for playback device");
1381 fDigitalPlayback = IsDigitalDevice(playbackID);
1393 int JackCoreAudioDriver::SetupChannels(
bool capturing,
bool playing,
int& inchannels,
int& outchannels,
int& in_maxChannels,
int& out_maxChannels,
bool strict)
1395 OSStatus err = noErr;
1398 err = GetTotalChannels(fDeviceID, in_maxChannels,
true);
1400 jack_error(
"SetupChannels : cannot get input channel number");
1404 jack_log(
"JackCoreAudioDriver::SetupChannels : max input channels : %d", in_maxChannels);
1409 err = GetTotalChannels(fDeviceID, out_maxChannels,
false);
1411 jack_error(
"Cannot get output channel number");
1415 jack_log(
"JackCoreAudioDriver::SetupChannels : max output channels : %d", out_maxChannels);
1419 if (inchannels > in_maxChannels) {
1420 jack_error(
"This device hasn't required input channels inchannels = %d in_maxChannels = %d", inchannels, in_maxChannels);
1426 if (outchannels > out_maxChannels) {
1427 jack_error(
"This device hasn't required output channels outchannels = %d out_maxChannels = %d", outchannels, out_maxChannels);
1433 if (inchannels == -1) {
1434 jack_log(
"JackCoreAudioDriver::SetupChannels : setup max in channels = %d", in_maxChannels);
1435 inchannels = in_maxChannels;
1438 if (outchannels == -1) {
1439 jack_log(
"JackCoreAudioDriver::SetupChannels : setup max out channels = %d", out_maxChannels);
1440 outchannels = out_maxChannels;
1446 int JackCoreAudioDriver::SetupBufferSize(jack_nframes_t buffer_size)
1449 OSStatus err = noErr;
1450 UInt32 tmp_buffer_size = buffer_size;
1451 UInt32 outSize =
sizeof(UInt32);
1453 err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size);
1455 jack_error(
"Cannot get buffer size %ld", buffer_size);
1459 jack_log(
"JackCoreAudioDriver::SetupBufferSize : current buffer size = %ld", tmp_buffer_size);
1463 if (buffer_size != tmp_buffer_size) {
1464 tmp_buffer_size = buffer_size;
1467 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback,
this);
1469 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyBufferFrameSize");
1478 err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, outSize, &tmp_buffer_size);
1480 jack_error(
"SetupBufferSize : cannot set buffer size = %ld", tmp_buffer_size);
1485 while (!fState && count++ < WAIT_NOTIFICATION_COUNTER) {
1487 jack_log(
"JackCoreAudioDriver::SetupBufferSize : wait count = %d", count);
1490 if (count >= WAIT_NOTIFICATION_COUNTER) {
1491 jack_error(
"Did not get buffer size notification...");
1496 outSize =
sizeof(UInt32);
1497 err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size);
1499 jack_error(
"Cannot get current buffer size");
1502 jack_log(
"JackCoreAudioDriver::SetupBufferSize : checked buffer size = %ld", tmp_buffer_size);
1506 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback);
1514 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback);
1518 int JackCoreAudioDriver::SetupSampleRate(jack_nframes_t sample_rate)
1520 return SetupSampleRateAux(fDeviceID, sample_rate);
1523 int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t sample_rate)
1525 OSStatus err = noErr;
1527 Float64 tmp_sample_rate;
1530 outSize =
sizeof(Float64);
1531 err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &tmp_sample_rate);
1533 jack_error(
"Cannot get current sample rate");
1537 jack_log(
"JackCoreAudioDriver::SetupSampleRateAux : current sample rate = %f", tmp_sample_rate);
1541 if (sample_rate != (jack_nframes_t)tmp_sample_rate) {
1542 tmp_sample_rate = (Float64)sample_rate;
1545 err = AudioDeviceAddPropertyListener(inDevice, 0,
true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback,
this);
1547 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate");
1556 err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &tmp_sample_rate);
1558 jack_error(
"Cannot set sample rate = %ld", sample_rate);
1563 while (!fState && count++ < WAIT_NOTIFICATION_COUNTER) {
1565 jack_log(
"JackCoreAudioDriver::SetupSampleRateAux : wait count = %d", count);
1568 if (count >= WAIT_NOTIFICATION_COUNTER) {
1569 jack_error(
"Did not get sample rate notification...");
1574 outSize =
sizeof(Float64);
1575 err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &tmp_sample_rate);
1577 jack_error(
"Cannot get current sample rate");
1580 jack_log(
"JackCoreAudioDriver::SetupSampleRateAux : checked sample rate = %f", tmp_sample_rate);
1584 AudioDeviceRemovePropertyListener(inDevice, 0,
true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
1592 AudioDeviceRemovePropertyListener(inDevice, 0,
true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
1596 int JackCoreAudioDriver::OpenAUHAL(
bool capturing,
1601 int out_maxChannels,
1602 const vector<int>& chan_in_list,
1603 const vector<int>& chan_out_list,
1604 jack_nframes_t buffer_size,
1605 jack_nframes_t sample_rate)
1607 ComponentResult err1;
1609 AudioStreamBasicDescription srcFormat, dstFormat;
1610 AudioDeviceID currAudioDeviceID;
1613 jack_log(
"JackCoreAudioDriver::OpenAUHAL : capturing = %d playing = %d inchannels = %d outchannels = %d in_maxChannels = %d out_maxChannels = %d chan_in_list = %d chan_out_list = %d",
1614 capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, chan_in_list.size(), chan_out_list.size());
1616 if (inchannels == 0 && outchannels == 0) {
1617 jack_error(
"No input and output channels...");
1622 #ifdef MAC_OS_X_VERSION_10_5
1623 ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
1624 Component HALOutput = FindNextComponent(NULL, &cd);
1625 err1 = OpenAComponent(HALOutput, &fAUHAL);
1626 if (err1 != noErr) {
1632 AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
1633 AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd);
1634 err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL);
1635 if (err1 != noErr) {
1636 jack_error(
"Error calling AudioComponentInstanceNew");
1642 err1 = AudioUnitInitialize(fAUHAL);
1643 if (err1 != noErr) {
1650 if (capturing && inchannels > 0) {
1652 jack_log(
"JackCoreAudioDriver::OpenAUHAL : setup AUHAL input on");
1655 jack_log(
"JackCoreAudioDriver::OpenAUHAL : setup AUHAL input off");
1658 err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO,
sizeof(enableIO));
1659 if (err1 != noErr) {
1660 jack_error(
"Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input");
1665 if (playing && outchannels > 0) {
1667 jack_log(
"JackCoreAudioDriver::OpenAUHAL : setup AUHAL output on");
1670 jack_log(
"JackCoreAudioDriver::OpenAUHAL : setup AUHAL output off");
1673 err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO,
sizeof(enableIO));
1674 if (err1 != noErr) {
1675 jack_error(
"Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output");
1680 size =
sizeof(AudioDeviceID);
1681 err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size);
1682 if (err1 != noErr) {
1683 jack_error(
"Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice");
1687 jack_log(
"JackCoreAudioDriver::OpenAUHAL : AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID);
1691 err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID,
sizeof(AudioDeviceID));
1692 if (err1 != noErr) {
1693 jack_error(
"Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice");
1699 if (capturing && inchannels > 0) {
1700 err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size,
sizeof(UInt32));
1701 if (err1 != noErr) {
1702 jack_error(
"Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice");
1708 if (playing && outchannels > 0) {
1709 err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&buffer_size,
sizeof(UInt32));
1710 if (err1 != noErr) {
1711 jack_error(
"Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice");
1718 if (capturing && inchannels > 0 && inchannels <= in_maxChannels) {
1719 SInt32 chanArr[in_maxChannels];
1720 for (
int i = 0; i < in_maxChannels; i++) {
1724 if (chan_in_list.size() > 0) {
1725 for (uint i = 0; i < chan_in_list.size(); i++) {
1726 int chan = chan_in_list[i];
1727 if (chan < out_maxChannels) {
1730 jack_info(
"Input channel = %d ==> JACK input port = %d", chan, i);
1732 jack_info(
"Error input channel number is incorrect : %d", chan);
1737 for (
int i = 0; i < inchannels; i++) {
1739 jack_info(
"Input channel = %d ==> JACK input port = %d", chanArr[i], i);
1743 AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr,
sizeof(SInt32) * in_maxChannels);
1744 if (err1 != noErr) {
1745 jack_error(
"Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for input");
1752 if (playing && outchannels > 0 && outchannels <= out_maxChannels) {
1753 SInt32 chanArr[out_maxChannels];
1754 for (
int i = 0; i < out_maxChannels; i++) {
1758 if (chan_out_list.size() > 0) {
1759 for (uint i = 0; i < chan_out_list.size(); i++) {
1760 int chan = chan_out_list[i];
1761 if (chan < out_maxChannels) {
1764 jack_info(
"JACK output port = %d ==> output channel = %d", i, chan);
1766 jack_info(
"Error output channel number is incorrect : %d", chan);
1771 for (
int i = 0; i < outchannels; i++) {
1773 jack_info(
"JACK output port = %d ==> output channel = %d", i, chanArr[i]);
1777 err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr,
sizeof(SInt32) * out_maxChannels);
1778 if (err1 != noErr) {
1779 jack_error(
"Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for output");
1786 if (capturing && inchannels > 0) {
1788 size =
sizeof(AudioStreamBasicDescription);
1789 err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size);
1790 if (err1 != noErr) {
1791 jack_error(
"Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
1795 PrintStreamDesc(&srcFormat);
1797 jack_log(
"JackCoreAudioDriver::OpenAUHAL : setup AUHAL input stream converter SR = %ld", sample_rate);
1798 srcFormat.mSampleRate = sample_rate;
1799 srcFormat.mFormatID = kAudioFormatLinearPCM;
1800 srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
1801 srcFormat.mBytesPerPacket =
sizeof(jack_default_audio_sample_t);
1802 srcFormat.mFramesPerPacket = 1;
1803 srcFormat.mBytesPerFrame =
sizeof(jack_default_audio_sample_t);
1804 srcFormat.mChannelsPerFrame = inchannels;
1805 srcFormat.mBitsPerChannel = 32;
1806 PrintStreamDesc(&srcFormat);
1808 err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat,
sizeof(AudioStreamBasicDescription));
1809 if (err1 != noErr) {
1810 jack_error(
"Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
1816 if (playing && outchannels > 0) {
1818 size =
sizeof(AudioStreamBasicDescription);
1819 err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size);
1820 if (err1 != noErr) {
1821 jack_error(
"Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
1825 PrintStreamDesc(&dstFormat);
1827 jack_log(
"JackCoreAudioDriver::OpenAUHAL : setup AUHAL output stream converter SR = %ld", sample_rate);
1828 dstFormat.mSampleRate = sample_rate;
1829 dstFormat.mFormatID = kAudioFormatLinearPCM;
1830 dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
1831 dstFormat.mBytesPerPacket =
sizeof(jack_default_audio_sample_t);
1832 dstFormat.mFramesPerPacket = 1;
1833 dstFormat.mBytesPerFrame =
sizeof(jack_default_audio_sample_t);
1834 dstFormat.mChannelsPerFrame = outchannels;
1835 dstFormat.mBitsPerChannel = 32;
1836 PrintStreamDesc(&dstFormat);
1838 err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat,
sizeof(AudioStreamBasicDescription));
1839 if (err1 != noErr) {
1840 jack_error(
"Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
1847 if (inchannels > 0 && outchannels == 0) {
1848 AURenderCallbackStruct output;
1849 output.inputProc = Render;
1850 output.inputProcRefCon =
this;
1851 err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output,
sizeof(output));
1852 if (err1 != noErr) {
1853 jack_error(
"Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1");
1858 AURenderCallbackStruct output;
1859 output.inputProc = Render;
1860 output.inputProcRefCon =
this;
1861 err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output,
sizeof(output));
1862 if (err1 != noErr) {
1863 jack_error(
"Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0");
1876 int JackCoreAudioDriver::SetupBuffers(
int inchannels)
1879 fJackInputData = (AudioBufferList*)malloc(
sizeof(UInt32) + inchannels *
sizeof(AudioBuffer));
1880 fJackInputData->mNumberBuffers = inchannels;
1881 for (
int i = 0; i < inchannels; i++) {
1882 fJackInputData->mBuffers[i].mNumberChannels = 1;
1883 fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize *
sizeof(jack_default_audio_sample_t);
1888 void JackCoreAudioDriver::DisposeBuffers()
1890 if (fJackInputData) {
1891 free(fJackInputData);
1896 void JackCoreAudioDriver::CloseAUHAL()
1898 AudioOutputUnitStop(fAUHAL);
1899 AudioUnitUninitialize(fAUHAL);
1900 CloseComponent(fAUHAL);
1903 int JackCoreAudioDriver::AddListeners()
1905 OSStatus err = noErr;
1908 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDeviceProcessorOverload, DeviceNotificationCallback,
this);
1910 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload");
1915 err = AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices, AudioHardwareNotificationCallback,
this);
1917 jack_error(
"Error calling AudioHardwareAddPropertyListener with kAudioHardwarePropertyDevices");
1922 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback,
this);
1924 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate");
1929 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback,
this);
1931 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceIsRunning");
1936 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyDeviceIsAlive, DeviceNotificationCallback,
this);
1938 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceIsAlive");
1943 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyDeviceHasChanged, DeviceNotificationCallback,
this);
1945 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceHasChanged");
1950 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback,
this);
1952 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration");
1957 err = AudioDeviceAddPropertyListener(fDeviceID, 0,
false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback,
this);
1959 jack_error(
"Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration");
1964 if (!fEngineControl->fSyncMode && fIOUsage != 1.f) {
1965 UInt32 outSize =
sizeof(float);
1966 err = AudioDeviceSetProperty(fDeviceID, NULL, 0,
false, kAudioDevicePropertyIOCycleUsage, outSize, &fIOUsage);
1968 jack_error(
"Error calling AudioDeviceSetProperty kAudioDevicePropertyIOCycleUsage");
1976 void JackCoreAudioDriver::RemoveListeners()
1978 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDeviceProcessorOverload, DeviceNotificationCallback);
1979 AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDevices, AudioHardwareNotificationCallback);
1980 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback);
1981 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback);
1982 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyDeviceIsAlive, DeviceNotificationCallback);
1983 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyDeviceHasChanged, DeviceNotificationCallback);
1984 AudioDeviceRemovePropertyListener(fDeviceID, 0,
true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback);
1985 AudioDeviceRemovePropertyListener(fDeviceID, 0,
false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback);
1988 int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
1989 jack_nframes_t sample_rate,
1994 const char* chan_in_list,
1995 const char* chan_out_list,
1997 const char* capture_driver_uid,
1998 const char* playback_driver_uid,
1999 jack_nframes_t capture_latency,
2000 jack_nframes_t playback_latency,
2001 int async_output_latency,
2002 int computation_grain,
2009 int in_maxChannels = 0;
2010 int out_maxChannels = 0;
2011 char capture_driver_name[256];
2012 char playback_driver_name[256];
2014 fCaptureLatency = capture_latency;
2015 fPlaybackLatency = playback_latency;
2016 fIOUsage = float(async_output_latency) / 100.f;
2017 fComputationGrain = float(computation_grain) / 100.f;
2019 fClockDriftCompensate = clock_drift;
2023 Gestalt(gestaltSystemVersionMajor, &major);
2024 Gestalt(gestaltSystemVersionMinor, &minor);
2026 vector<int> parsed_chan_in_list;
2027 vector<int> parsed_chan_out_list;
2030 if (major == 10 && minor >= 6) {
2031 CFRunLoopRef theRunLoop = NULL;
2032 AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
2033 OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL,
sizeof(CFRunLoopRef), &theRunLoop);
2034 if (osErr != noErr) {
2035 jack_error(
"Open kAudioHardwarePropertyRunLoop error");
2040 if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate, ac3_encoding) < 0) {
2045 if (JackAudioDriver::Open(buffer_size, sample_rate,
2047 inchannels, outchannels,
2049 capture_driver_name,
2050 playback_driver_name,
2052 playback_latency) != 0) {
2056 if (SetupChannels(capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, !ac3_encoding) < 0) {
2060 ParseChannelList(chan_in_list, parsed_chan_in_list, in_maxChannels);
2061 if (parsed_chan_in_list.size() > 0) {
2062 jack_info(
"Explicit input channel list size = %d", parsed_chan_in_list.size());
2063 inchannels = parsed_chan_in_list.size();
2066 ParseChannelList(chan_out_list, parsed_chan_out_list, out_maxChannels);
2067 if (parsed_chan_out_list.size() > 0) {
2068 jack_info(
"Explicit output channel list size = %d", parsed_chan_out_list.size());
2069 outchannels = parsed_chan_out_list.size();
2072 if (SetupBufferSize(buffer_size) < 0) {
2076 if (SetupSampleRate(sample_rate) < 0) {
2082 if (!fDigitalPlayback) {
2083 jack_error(
"AC3 encoding can only be used with a digital device");
2087 JackAC3EncoderParams params;
2088 memset(¶ms, 0,
sizeof(JackAC3EncoderParams));
2089 params.bitrate = ac3_bitrate;
2090 params.channels = outchannels;
2091 params.sample_rate = sample_rate;
2092 params.lfe = ac3_lfe;
2093 fAC3Encoder =
new JackAC3Encoder(params);
2095 if (!fAC3Encoder || !fAC3Encoder->Init(sample_rate)) {
2096 jack_error(
"Cannot allocate or init AC3 encoder");
2101 fPlaybackChannels = outchannels;
2103 fPlaybackChannels++;
2106 if (fPlaybackChannels < 2 || fPlaybackChannels > 6) {
2107 jack_error(
"AC3 encoder channels must be between 2 and 6");
2112 outchannels = out_maxChannels = 2;
2115 fPlaybackChannels = outchannels;
2119 fCaptureChannels = inchannels;
2121 if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, parsed_chan_in_list, parsed_chan_out_list, buffer_size, sample_rate) < 0) {
2125 if (capturing && inchannels > 0) {
2126 if (SetupBuffers(inchannels) < 0) {
2131 if (AddListeners() < 0) {
2142 int JackCoreAudioDriver::Close()
2144 jack_log(
"JackCoreAudioDriver::Close");
2147 int res = JackAudioDriver::Close();
2152 DestroyAggregateDevice();
2156 void JackCoreAudioDriver::UpdateLatencies()
2165 size =
sizeof(UInt32);
2168 err = AudioDeviceGetProperty(fDeviceID, 0,
true, kAudioDevicePropertyLatency, &size, &value1);
2170 jack_error(
"AudioDeviceGetProperty kAudioDevicePropertyLatency error");
2172 err = AudioDeviceGetProperty(fDeviceID, 0,
true, kAudioDevicePropertySafetyOffset, &size, &value2);
2174 jack_error(
"AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
2177 input_range.
min = input_range.
max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency;
2180 vector<int> input_latencies;
2181 err = GetStreamLatencies(fDeviceID,
true, input_latencies);
2183 for (
int i = 0; i < fCaptureChannels; i++) {
2185 input_range.
min += input_latencies[i];
2186 input_range.
max += input_latencies[i];
2188 fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
2192 size =
sizeof(UInt32);
2195 err = AudioDeviceGetProperty(fDeviceID, 0,
false, kAudioDevicePropertyLatency, &size, &value1);
2197 jack_error(
"AudioDeviceGetProperty kAudioDevicePropertyLatency error");
2199 err = AudioDeviceGetProperty(fDeviceID, 0,
false, kAudioDevicePropertySafetyOffset, &size, &value2);
2201 jack_error(
"AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
2205 vector<int> output_latencies;
2206 err = GetStreamLatencies(fDeviceID,
false, output_latencies);
2209 output_range.
min = output_range.
max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode)
2210 ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency;
2212 for (
int i = 0; i < fPlaybackChannels; i++) {
2214 output_range.
min += output_latencies[i];
2215 output_range.
max += output_latencies[i];
2217 fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
2220 if (fWithMonitorPorts) {
2221 monitor_range.
min = monitor_range.
max = fEngineControl->fBufferSize;
2222 fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
2227 int JackCoreAudioDriver::Attach()
2231 jack_port_id_t port_index;
2234 char channel_name[64];
2235 char name[REAL_JACK_PORT_NAME_SIZE];
2236 char alias[REAL_JACK_PORT_NAME_SIZE];
2238 jack_log(
"JackCoreAudioDriver::Attach : fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
2240 for (
int i = 0; i < fCaptureChannels; i++) {
2242 err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1,
true, kAudioDevicePropertyChannelName, &size, &isWritable);
2244 jack_log(
"JackCoreAudioDriver::Attach : AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
2246 if (err == noErr && size > 0) {
2247 err = AudioDeviceGetProperty(fDeviceID, i + 1,
true, kAudioDevicePropertyChannelName, &size, channel_name);
2249 jack_log(
"JackCoreAudioDriver::Attach : AudioDeviceGetProperty kAudioDevicePropertyChannelName error");
2251 snprintf(alias,
sizeof(alias),
"%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1);
2253 snprintf(alias,
sizeof(alias),
"%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1);
2256 snprintf(name,
sizeof(name),
"%s:capture_%d", fClientControl.fName, i + 1);
2258 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
2259 jack_error(
"Cannot register port for %s", name);
2263 port = fGraphManager->GetPort(port_index);
2264 port->SetAlias(alias);
2265 fCapturePortList[i] = port_index;
2268 for (
int i = 0; i < fPlaybackChannels; i++) {
2270 err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1,
false, kAudioDevicePropertyChannelName, &size, &isWritable);
2272 jack_log(
"JackCoreAudioDriver::Attach : AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
2274 if (err == noErr && size > 0) {
2275 err = AudioDeviceGetProperty(fDeviceID, i + 1,
false, kAudioDevicePropertyChannelName, &size, channel_name);
2277 jack_log(
"JackCoreAudioDriver::Attach : AudioDeviceGetProperty kAudioDevicePropertyChannelName error");
2279 snprintf(alias,
sizeof(alias),
"%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1);
2281 snprintf(alias,
sizeof(alias),
"%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1);
2284 snprintf(name,
sizeof(name),
"%s:playback_%d", fClientControl.fName, i + 1);
2286 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
2287 jack_error(
"Cannot register port for %s", name);
2291 port = fGraphManager->GetPort(port_index);
2292 port->SetAlias(alias);
2293 fPlaybackPortList[i] = port_index;
2296 if (fWithMonitorPorts) {
2297 jack_log(
"JackCoreAudioDriver::Attach : create monitor port");
2298 snprintf(name,
sizeof(name),
"%s:monitor_%u", fClientControl.fName, i + 1);
2299 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
2300 jack_error(
"Cannot register monitor port for %s", name);
2303 fMonitorPortList[i] = port_index;
2310 for (
int i = 0; i < fPlaybackChannels; i++) {
2311 fAC3Encoder->GetChannelName(
"coreaudio",
"", alias, i);
2312 port = fGraphManager->GetPort(fPlaybackPortList[i]);
2313 port->SetAlias(alias);
2320 for (
int i = 0; i < fCaptureChannels; i++) {
2321 fJackInputData->mBuffers[i].mData = GetInputBuffer(i);
2327 int JackCoreAudioDriver::Start()
2329 jack_log(
"JackCoreAudioDriver::Start");
2330 if (JackAudioDriver::Start() == 0) {
2336 OSStatus err = AudioOutputUnitStart(fAUHAL);
2339 while (!fState && count++ < WAIT_COUNTER) {
2341 jack_log(
"JackCoreAudioDriver::Start : wait count = %d", count);
2344 if (count < WAIT_COUNTER) {
2345 jack_info(
"CoreAudio driver is running...");
2349 jack_error(
"CoreAudio driver cannot start...");
2351 JackAudioDriver::Stop();
2356 int JackCoreAudioDriver::Stop()
2358 jack_log(
"JackCoreAudioDriver::Stop");
2359 int res = (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1;
2360 if (JackAudioDriver::Stop() < 0) {
2366 int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
2368 if (SetupBufferSize(buffer_size) < 0) {
2372 JackAudioDriver::SetBufferSize(buffer_size);
2378 for (
int i = 0; i < fCaptureChannels; i++) {
2379 fJackInputData->mBuffers[i].mNumberChannels = 1;
2380 fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize *
sizeof(jack_default_audio_sample_t);
2381 fJackInputData->mBuffers[i].mData = GetInputBuffer(i);
2387 bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID,
bool isInput)
2392 UInt32 propSize =
sizeof(hog_pid);
2393 err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyHogMode, &propSize, &hog_pid);
2399 jack_log(
"JackCoreAudioDriver::TakeHogAux : deviceID = %d", deviceID);
2401 if (hog_pid != getpid()) {
2403 err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid);
2405 jack_error(
"Can't hog device = %d because it's being hogged by another program or cannot be hogged", deviceID);
2413 bool JackCoreAudioDriver::TakeHog()
2415 OSStatus err = noErr;
2416 AudioObjectID sub_device[32];
2417 UInt32 outSize =
sizeof(sub_device);
2418 err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
2421 jack_log(
"JackCoreAudioDriver::TakeHog : device does not have subdevices");
2422 return TakeHogAux(fDeviceID,
true);
2424 int num_devices = outSize /
sizeof(AudioObjectID);
2425 jack_log(
"JackCoreAudioDriver::TakeHog : device does has %d subdevices", num_devices);
2426 for (
int i = 0; i < num_devices; i++) {
2427 if (!TakeHogAux(sub_device[i],
true)) {
2435 bool JackCoreAudioDriver::IsAggregateDevice(AudioDeviceID device)
2437 UInt32 deviceType, outSize =
sizeof(UInt32);
2438 OSStatus err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, &outSize, &deviceType);
2441 jack_log(
"JackCoreAudioDriver::IsAggregateDevice kAudioDevicePropertyTransportType error");
2444 return (deviceType == kAudioDeviceTransportTypeAggregate);
2463 desc = jack_driver_descriptor_construct(
"coreaudio", JackDriverMaster,
"Apple CoreAudio API based audio backend", &filler);
2466 jack_driver_descriptor_add_parameter(desc, &filler,
"channels",
'c', JackDriverParamInt, &value, NULL,
"Maximum number of channels",
"Maximum number of channels. If -1, max possible number of channels will be used");
2467 jack_driver_descriptor_add_parameter(desc, &filler,
"in-channels",
'i', JackDriverParamInt, &value, NULL,
"Maximum number of input channels",
"Maximum number of input channels. If -1, max possible number of input channels will be used");
2468 jack_driver_descriptor_add_parameter(desc, &filler,
"out-channels",
'o', JackDriverParamInt, &value, NULL,
"Maximum number of output channels",
"Maximum number of output channels. If -1, max possible number of output channels will be used");
2471 jack_driver_descriptor_add_parameter(desc, &filler,
"input-list",
'n', JackDriverParamString, &value, NULL,
"Input channel list for channel mapping",
"List of input channel number to be opened (syntax like : \"0 3 2\")");
2472 jack_driver_descriptor_add_parameter(desc, &filler,
"output-list",
'N', JackDriverParamString, &value, NULL,
"Output channel list for channel mapping",
"List of output channel number to be opened (syntax like : \"0 3 2\")");
2475 jack_driver_descriptor_add_parameter(desc, &filler,
"capture",
'C', JackDriverParamString, &value, NULL,
"Input CoreAudio device name", NULL);
2476 jack_driver_descriptor_add_parameter(desc, &filler,
"playback",
'P', JackDriverParamString, &value, NULL,
"Output CoreAudio device name", NULL);
2479 jack_driver_descriptor_add_parameter(desc, &filler,
"monitor",
'm', JackDriverParamBool, &value, NULL,
"Provide monitor ports for the output", NULL);
2483 jack_driver_descriptor_add_parameter(desc, &filler,
"AC3-encoding",
'a', JackDriverParamBool, &value, NULL,
"AC3 multi-channels encoding", NULL);
2486 jack_driver_descriptor_add_parameter(desc, &filler,
"AC3-bitrate",
'b', JackDriverParamUInt, &value, NULL,
"AC3 bitrate", NULL);
2489 jack_driver_descriptor_add_parameter(desc, &filler,
"AC3-LFE",
'f', JackDriverParamBool, &value, NULL,
"AC3 LFE channel", NULL);
2492 jack_driver_descriptor_add_parameter(desc, &filler,
"duplex",
'D', JackDriverParamBool, &value, NULL,
"Provide both capture and playback ports", NULL);
2495 jack_driver_descriptor_add_parameter(desc, &filler,
"rate",
'r', JackDriverParamUInt, &value, NULL,
"Sample rate", NULL);
2498 jack_driver_descriptor_add_parameter(desc, &filler,
"period",
'p', JackDriverParamUInt, &value, NULL,
"Frames per period", NULL);
2501 jack_driver_descriptor_add_parameter(desc, &filler,
"device",
'd', JackDriverParamString, &value, NULL,
"CoreAudio device name", NULL);
2504 jack_driver_descriptor_add_parameter(desc, &filler,
"input-latency",
'I', JackDriverParamUInt, &value, NULL,
"Extra input latency (frames)", NULL);
2505 jack_driver_descriptor_add_parameter(desc, &filler,
"output-latency",
'O', JackDriverParamUInt, &value, NULL,
"Extra output latency (frames)", NULL);
2508 jack_driver_descriptor_add_parameter(desc, &filler,
"list-devices",
'l', JackDriverParamBool, &value, NULL,
"Display available CoreAudio devices", NULL);
2511 jack_driver_descriptor_add_parameter(desc, &filler,
"hog",
'H', JackDriverParamBool, &value, NULL,
"Take exclusive access of the audio device", NULL);
2514 jack_driver_descriptor_add_parameter(desc, &filler,
"async-latency",
'L', JackDriverParamUInt, &value, NULL,
"Extra output latency in asynchronous mode (percent)", NULL);
2517 jack_driver_descriptor_add_parameter(desc, &filler,
"grain",
'G', JackDriverParamUInt, &value, NULL,
"Computation grain in RT thread (percent)", NULL);
2520 jack_driver_descriptor_add_parameter(desc, &filler,
"clock-drift",
's', JackDriverParamBool, &value, NULL,
"Clock drift compensation",
"Whether to compensate clock drift in dynamically created aggregate device");
2527 jack_nframes_t srate = 44100;
2528 jack_nframes_t frames_per_interrupt = 256;
2529 bool capture =
false;
2530 bool playback =
false;
2533 const char* chan_in_list =
"";
2534 const char* chan_out_list =
"";
2535 bool monitor =
false;
2536 const char* capture_driver_uid =
"";
2537 const char* playback_driver_uid =
"";
2540 jack_nframes_t systemic_input_latency = 0;
2541 jack_nframes_t systemic_output_latency = 0;
2542 int async_output_latency = 100;
2543 int computation_grain = -1;
2544 bool hogged =
false;
2545 bool clock_drift =
false;
2546 bool ac3_encoding =
false;
2547 int ac3_bitrate = 448;
2548 bool ac3_lfe =
false;
2550 for (node = params; node; node = jack_slist_next(node)) {
2553 switch (param->character) {
2556 capture_driver_uid = param->value.str;
2557 playback_driver_uid = param->value.str;
2566 chan_in = chan_out = param->value.i;
2570 chan_in = param->value.i;
2574 chan_out = param->value.i;
2578 chan_in_list = param->value.str;
2582 chan_out_list = param->value.str;
2587 if (strcmp(param->value.str,
"none") != 0) {
2588 capture_driver_uid = param->value.str;
2594 if (strcmp(param->value.str,
"none") != 0) {
2595 playback_driver_uid = param->value.str;
2600 monitor = param->value.i;
2605 ac3_encoding = param->value.i;
2609 ac3_bitrate = param->value.i;
2613 ac3_lfe = param->value.i;
2618 srate = param->value.ui;
2622 frames_per_interrupt = (
unsigned int)param->value.ui;
2626 systemic_input_latency = param->value.ui;
2630 systemic_output_latency = param->value.ui;
2634 Jack::DisplayDeviceNames();
2643 async_output_latency = param->value.ui;
2647 computation_grain = param->value.ui;
2657 if (!capture && !playback) {
2662 if (strcmp(chan_in_list,
"") != 0 && chan_in >= 0) {
2663 printf(
"Input channel list and in channels are both specified, input channel list will take over...\n");
2666 if (strcmp(chan_out_list,
"") != 0 && chan_out >= 0) {
2667 printf(
"Output channel list and out channels are both specified, output channel list will take over...\n");
2671 if (driver->Open(frames_per_interrupt,
2674 chan_out, chan_in_list,
2675 chan_out_list, monitor,
2677 playback_driver_uid,
2678 systemic_input_latency,
2679 systemic_output_latency,
2680 async_output_latency,
2682 hogged, clock_drift,
2683 ac3_encoding, ac3_bitrate, ac3_lfe) == 0) {
Inter process synchronization using using Mach semaphore.
Locked Engine, access to methods is serialized using a mutex.
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
The base interface for drivers clients.
SERVER_EXPORT void jack_log(const char *fmt,...)