Merge pull request #304 from AronVietti/Bug#23-AppNap

Fixes issue with AppNap causing stuttering/silence in background
This commit is contained in:
Volker Fischer 2020-05-28 18:54:53 +02:00 committed by GitHub
commit e3865dacd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 119 additions and 3 deletions

View file

@ -91,6 +91,8 @@ win32 {
QT += macextras QT += macextras
HEADERS += mac/sound.h HEADERS += mac/sound.h
SOURCES += mac/sound.cpp SOURCES += mac/sound.cpp
HEADERS += mac/activity.h
OBJECTIVE_SOURCES += mac/activity.mm
RC_FILE = mac/mainicon.icns RC_FILE = mac/mainicon.icns
CONFIG += x86 CONFIG += x86
QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge.llcon QMAKE_TARGET_BUNDLE_PREFIX = net.sourceforge.llcon
@ -107,7 +109,8 @@ win32 {
-framework CoreAudio \ -framework CoreAudio \
-framework CoreMIDI \ -framework CoreMIDI \
-framework AudioToolbox \ -framework AudioToolbox \
-framework AudioUnit -framework AudioUnit \
-framework Foundation
# replace coreaudio with jack if requested # replace coreaudio with jack if requested
contains(CONFIG, "jackonmac") { contains(CONFIG, "jackonmac") {

46
mac/activity.h Normal file
View file

@ -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();
};

53
mac/activity.mm Normal file
View file

@ -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 <Foundation/Foundation.h>
class CActivityId
{
public:
id<NSObject> 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;
}

View file

@ -37,6 +37,9 @@
#ifdef ANDROID #ifdef ANDROID
# include <QtAndroidExtras/QtAndroid> # include <QtAndroidExtras/QtAndroid>
#endif #endif
#if defined ( __APPLE__ ) || defined ( __MACOSX )
# include "mac/activity.h"
#endif
// Implementation ************************************************************** // 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; tsConsole << "Qt5 requires a windowing system to paint a JPEG image; image will use SVG" << endl;
} }
// Application/GUI setup --------------------------------------------------- // Application/GUI setup ---------------------------------------------------
// Application object // Application object
QCoreApplication* pApp = bUseGUI QCoreApplication* pApp = bUseGUI
@ -550,6 +552,14 @@ int main ( int argc, char** argv )
QDir ApplDir ( QApplication::applicationDirPath() ); QDir ApplDir ( QApplication::applicationDirPath() );
pApp->addLibraryPath ( QString ( ApplDir.absolutePath() ) ); pApp->addLibraryPath ( QString ( ApplDir.absolutePath() ) );
#endif #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 // init resources
Q_INIT_RESOURCE(resources); Q_INIT_RESOURCE(resources);
@ -688,6 +698,10 @@ int main ( int argc, char** argv )
tsConsole << generr.GetErrorText() << endl; tsConsole << generr.GetErrorText() << endl;
} }
} }
#if defined ( __APPLE__ ) || defined ( __MACOSX )
activity.EndActivity();
#endif
return 0; return 0;
} }