diff --git a/Jamulus.pro b/Jamulus.pro index 60da17c2..18867a87 100755 --- a/Jamulus.pro +++ b/Jamulus.pro @@ -91,6 +91,8 @@ win32 { QT += macextras HEADERS += mac/sound.h SOURCES += mac/sound.cpp + HEADERS += mac/activity.h + OBJECTIVE_SOURCES += mac/activity.mm RC_FILE = mac/mainicon.icns CONFIG += x86 QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge.llcon @@ -107,7 +109,8 @@ win32 { -framework CoreAudio \ -framework CoreMIDI \ -framework AudioToolbox \ - -framework AudioUnit + -framework AudioUnit \ + -framework Foundation # replace coreaudio with jack if requested contains(CONFIG, "jackonmac") { diff --git a/mac/activity.h b/mac/activity.h new file mode 100644 index 00000000..8f4fa5cb --- /dev/null +++ b/mac/activity.h @@ -0,0 +1,46 @@ +/******************************************************************************\ + * Copyright (c) 2004-2020 + * + * Author(s): + * Volker Fischer + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +\******************************************************************************/ +#pragma once + +// Forward Delcaration to pointer that holds the activity id +class CActivityId; + +// Reperesents an OSX specific activity. See Managing Activities +// https://developer.apple.com/documentation/foundation/nsprocessinfo?language=objc +// This essentially lets us start and stop an Activity frame where we tell the OS +// that we are Latency Critical and are not performing background tasks. +class CActivity +{ +private: + CActivityId *pActivity; + +public: + CActivity(); + + ~CActivity(); + + void BeginActivity(); + + void EndActivity(); +}; diff --git a/mac/activity.mm b/mac/activity.mm new file mode 100644 index 00000000..9fdd2e9d --- /dev/null +++ b/mac/activity.mm @@ -0,0 +1,53 @@ +/******************************************************************************\ + * Copyright (c) 2004-2020 + * + * Author(s): + * Volker Fischer + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +\******************************************************************************/ + +#include "activity.h" +#include + +class CActivityId +{ +public: + id activityId; +}; + +CActivity::CActivity() : pActivity(new CActivityId()) {} + +CActivity::~CActivity() +{ + delete pActivity; +} + +void CActivity::BeginActivity() +{ + NSActivityOptions options = NSActivityBackground | NSActivityIdleSystemSleepDisabled | NSActivityLatencyCritical; + + pActivity->activityId = [[NSProcessInfo processInfo] beginActivityWithOptions: options reason:@"Jamulus provides low latency audio processing and should not be inturrupted by system throttling."]; +} + +void CActivity::EndActivity() +{ + [[NSProcessInfo processInfo] endActivity: pActivity->activityId]; + + pActivity->activityId = nil; +} diff --git a/src/main.cpp b/src/main.cpp index 6dda5852..42557d28 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,9 @@ #ifdef ANDROID # include #endif +#if defined ( __APPLE__ ) || defined ( __MACOSX ) +# include "mac/activity.h" +#endif // Implementation ************************************************************** @@ -517,8 +520,7 @@ int main ( int argc, char** argv ) { tsConsole << "Qt5 requires a windowing system to paint a JPEG image; image will use SVG" << endl; } - - + // Application/GUI setup --------------------------------------------------- // Application object QCoreApplication* pApp = bUseGUI @@ -550,6 +552,14 @@ int main ( int argc, char** argv ) QDir ApplDir ( QApplication::applicationDirPath() ); pApp->addLibraryPath ( QString ( ApplDir.absolutePath() ) ); #endif + +#if defined ( __APPLE__ ) || defined ( __MACOSX ) + // On OSX we need to declare an activity to ensure the process doesn't get + // throttled by OS level Nap, Sleep, and Thread Priority systems. + CActivity activity; + + activity.BeginActivity(); +#endif // init resources Q_INIT_RESOURCE(resources); @@ -688,6 +698,10 @@ int main ( int argc, char** argv ) tsConsole << generr.GetErrorText() << endl; } } + + #if defined ( __APPLE__ ) || defined ( __MACOSX ) + activity.EndActivity(); + #endif return 0; }