diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index d1a11a8b..65a05fc7 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -50,7 +50,7 @@ static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) { jack_log("- - - - - - - - - - - - - - - - - - - -"); jack_log(" Sample Rate:%f", inDesc->mSampleRate); - jack_log(" Format ID:%.*s", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); + jack_log(" Format ID:%.*s", (int)sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); jack_log(" Format Flags:%lX", inDesc->mFormatFlags); jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); @@ -124,7 +124,7 @@ static void printError(OSStatus err) jack_log("error code : kAudioHardwareUnsupportedOperationError"); break; default: - Print4CharCode("error code : unknown", err); + Print4CharCode("error code : unknown ", err); break; } } @@ -648,12 +648,13 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { int stream_count = outSize / sizeof(AudioBufferList); + jack_log(" JackCoreAudioDriver::GetTotalChannels stream_count = %d", stream_count); AudioBufferList bufferList[stream_count]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { for (uint i = 0; i < bufferList->mNumberBuffers; i++) { channelCount += bufferList->mBuffers[i].mNumberChannels; - //jack_info("GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels); + jack_log(" JackCoreAudioDriver::GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels); } } } @@ -731,12 +732,12 @@ bool JackCoreAudioDriver::IsDigitalDevice(AudioDeviceID device) } AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; - + for (int i = 0; i < stream_count ; i++) { - + /* Find a stream with a cac3 stream */ int format_num = 0; - + /* Retrieve all the stream formats supported by each output stream */ err = AudioObjectGetPropertyDataSize(streamIDs[i], &physicalFormatsAddress, 0, NULL, &outSize1); @@ -754,13 +755,16 @@ bool JackCoreAudioDriver::IsDigitalDevice(AudioDeviceID device) jack_error("IsDigitalDevice could not get the list of streamformats err = %d", err); return false; } - + /* Check if one of the supported formats is a digital format */ for (int j = 0; j < format_num; j++) { + + PrintStreamDesc(&format_list[j].mFormat); + if (format_list[j].mFormat.mFormatID == 'IAC3' || format_list[j].mFormat.mFormatID == 'iac3' || format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || - format_list[j].mFormat.mFormatID == kAudioFormatAC3 ) + format_list[j].mFormat.mFormatID == kAudioFormatAC3) { is_digital = true; break; @@ -781,7 +785,8 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja fHogged(false), fIOUsage(1.f), fComputationGrain(-1.f), - fClockDriftCompensate(false) + fClockDriftCompensate(false), + fDigitalPlayback(false) {} JackCoreAudioDriver::~JackCoreAudioDriver() @@ -1207,7 +1212,8 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name, - jack_nframes_t samplerate) + jack_nframes_t samplerate, + bool ac3_encoding) { capture_driver_name[0] = 0; playback_driver_name[0] = 0; @@ -1230,12 +1236,22 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, jack_error("Cannot get device name from device ID"); return -1; } + + if (fHogged) { + if (!TakeHogAux(fDeviceID, false)) { + jack_error("Cannot take hog mode"); + } + if (ac3_encoding) { + fDigitalPlayback = IsDigitalDevice(fDeviceID); + } + } } else { // Creates aggregate device - AudioDeviceID captureID, playbackID; - + AudioDeviceID captureID = -1; + AudioDeviceID playbackID = -1; + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { @@ -1258,7 +1274,20 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, GetDeviceNameFromID(captureID, fCaptureUID); GetDeviceNameFromID(playbackID, fPlaybackUID); - } + + if (fHogged) { + if (!TakeHogAux(captureID, true)) { + jack_error("Cannot take hog mode for capture device"); + } + if (!TakeHogAux(playbackID, false)) { + jack_error("Cannot take hog mode for playback device"); + } + if (ac3_encoding) { + fDigitalPlayback = IsDigitalDevice(playbackID); + } + } + + } // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { @@ -1274,6 +1303,12 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, jack_error("Cannot get device name from device ID"); return -1; } + + if (fHogged) { + if (!TakeHogAux(fDeviceID, true)) { + jack_error("Cannot take hog mode for capture device"); + } + } // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { @@ -1289,6 +1324,15 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, jack_error("Cannot get device name from device ID"); return -1; } + + if (fHogged) { + if (!TakeHogAux(fDeviceID, false)) { + jack_error("Cannot take hog mode for playback device"); + } + if (ac3_encoding) { + fDigitalPlayback = IsDigitalDevice(fDeviceID); + } + } // Use default driver in duplex mode } else { @@ -1297,8 +1341,9 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); // Creates aggregate device - AudioDeviceID captureID, playbackID; - + AudioDeviceID captureID = -1; + AudioDeviceID playbackID = -1; + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { @@ -1321,15 +1366,29 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, GetDeviceNameFromID(captureID, fCaptureUID); GetDeviceNameFromID(playbackID, fPlaybackUID); + + if (fHogged) { + if (!TakeHogAux(captureID, true)) { + jack_error("Cannot take hog mode for capture device"); + } + if (!TakeHogAux(playbackID, false)) { + jack_error("Cannot take hog mode for playback device"); + } + if (ac3_encoding) { + fDigitalPlayback = IsDigitalDevice(playbackID); + } + } } } - + + /* if (fHogged) { if (TakeHog()) { jack_info("Device = %ld has been hogged", fDeviceID); } } - + */ + return 0; } @@ -1582,7 +1641,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, printError(err1); goto error; } - + // Start I/O if (capturing && inchannels > 0) { enableIO = 1; @@ -1986,7 +2045,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, } } - if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate) < 0) { + if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate, ac3_encoding) < 0) { goto error; } @@ -2016,15 +2075,24 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, if (ac3_encoding) { + /* + // Force hogged mode + fHogged = true; + if (TakeHog()) { + jack_info("Device = %ld has been hogged", fDeviceID); + } + */ + + /* if (!IsDigitalDevice(fDeviceID)) { jack_error("AC3 encoding can only be used with a digital device"); goto error; } + */ - // Force hogged mode - fHogged = true; - if (TakeHog()) { - jack_info("Device = %ld has been hogged", fDeviceID); + if (!fDigitalPlayback) { + jack_error("AC3 encoding can only be used with a digital device"); + goto error; } JackAC3EncoderParams params; @@ -2036,7 +2104,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, fAC3Encoder = new JackAC3Encoder(params); if (!fAC3Encoder || !fAC3Encoder->Init(sample_rate)) { - jack_error("Cannot allocate of init AC3 encoder"); + jack_error("Cannot allocate or init AC3 encoder"); goto error; } @@ -2338,6 +2406,8 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) jack_error("Cannot read hog state..."); printError(err); } + + jack_log("JackCoreAudioDriver::TakeHogAux : deviceID = %d", deviceID); if (hog_pid != getpid()) { hog_pid = getpid(); diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index 0c6e421c..5e70efb8 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -79,8 +79,8 @@ class JackCoreAudioDriver : public JackAudioDriver float fIOUsage; float fComputationGrain; bool fClockDriftCompensate; + bool fDigitalPlayback; - static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, @@ -126,7 +126,8 @@ class JackCoreAudioDriver : public JackAudioDriver const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name, - jack_nframes_t samplerate); + jack_nframes_t samplerate, + bool ac3_encoding); int SetupChannels(bool capturing, bool playing,