From 9c7857b9771e14ed2ea99b2bd25ce283bfa1face Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 2 Dec 2009 09:56:40 +0000 Subject: [PATCH] Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3836 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 ++ common/JackNetInterface.cpp | 4 ++ macosx/coreaudio/JackCoreAudioDriver.cpp | 86 +++++++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index a34e4cac..c7a4f588 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,10 @@ Devin Anderson Jackdmp changes log --------------------------- +2009-12-02 Stephane Letz + + * Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. + 2009-12-01 Stephane Letz * Fix port_rename callback : now both old name and new name are given as parameters. diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 5131c98c..b794e8bf 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -227,6 +227,7 @@ namespace Jack do { session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, SLAVE_SETUP ); SessionParamsHToN(&fParams, &net_params); @@ -316,6 +317,7 @@ namespace Jack JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() ); session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); if ( mcast_socket.NewSocket() == SOCKET_ERROR ) @@ -706,6 +708,7 @@ namespace Jack { //send 'available' session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) ); @@ -746,6 +749,7 @@ namespace Jack //tell the master to start session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, START_MASTER ); SessionParamsHToN(&fParams, &net_params); if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 28d08786..fc291ebd 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -262,6 +262,16 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, case kAudioDevicePropertyNominalSampleRate: { jack_log("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); driver->fState = true; + // Check new sample rate + Float64 sampleRate; + UInt32 outSize = sizeof(Float64); + OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("SRNotificationCallback : checked sample rate = %f", sampleRate); + } break; } } @@ -279,6 +289,15 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { + + case kAudioDevicePropertyDeviceIsRunning: { + UInt32 isrunning = 0; + UInt32 outsize = sizeof(UInt32); + if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, &outsize, &isrunning) == noErr) { + jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsRunning = %d", isrunning); + } + break; + } case kAudioDeviceProcessorOverload: { jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); @@ -296,17 +315,50 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, } case kAudioDevicePropertyNominalSampleRate: { - Float64 new_sample_rate = 0; + Float64 sampleRate = 0; UInt32 outsize = sizeof(Float64); - OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &new_sample_rate); - if (err != noErr || new_sample_rate != driver->fEngineControl->fSampleRate) { - jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate, new SR = %f : server will quit...", new_sample_rate); - driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE - driver->CloseAUHAL(); - kill(JackTools::GetPID(), SIGINT); + OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); + if (err != noErr) return kAudioHardwareUnsupportedOperationError; - } else { - return noErr; + + char device_name[256]; + const char* digidesign_name = "Digidesign"; + driver->GetDeviceNameFromID(driver->fDeviceID, device_name); + + if (sampleRate != driver->fEngineControl->fSampleRate) { + + // Digidesign hardware, so "special" code : change the SR again here + if (strncmp(device_name, digidesign_name, sizeof(digidesign_name)) == 0) { + + jack_log("Digidesign HW = %s", device_name); + + // Set sample rate again... + sampleRate = driver->fEngineControl->fSampleRate; + err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sampleRate); + if (err != noErr) { + jack_error("Cannot set sample rate = %f", sampleRate); + printError(err); + } else { + jack_log("Set sample rate = %f", sampleRate); + } + + // Check new sample rate again... + outsize = sizeof(Float64); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("Checked sample rate = %f", sampleRate); + } + return noErr; + + } else { + driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE + driver->CloseAUHAL(); + kill(JackTools::GetPID(), SIGINT); + return kAudioHardwareUnsupportedOperationError; + } } } @@ -933,8 +985,6 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (fHogged) { if (TakeHog()) { jack_info("Device = %ld has been hogged", fDeviceID); - } else { - jack_error("Cannot hog device = %ld", fDeviceID); } } @@ -1027,6 +1077,8 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes jack_error("Cannot get current sample rate"); printError(err); return -1; + } else { + jack_log("Current sample rate = %f", sampleRate); } // If needed, set new sample rate @@ -1053,6 +1105,16 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes usleep(100000); jack_log("Wait count = %d", count); } + + // Check new sample rate + outSize = sizeof(Float64); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("Checked sample rate = %f", sampleRate); + } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); @@ -1702,7 +1764,7 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) hog_pid = getpid(); err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid); if (err != noErr) { - jack_error("Can't hog device = %d because it's being hogged by another program", deviceID); + jack_error("Can't hog device = %d because it's being hogged by another program or cannot be hogged", deviceID); return false; } } -- 2.11.4.GIT