summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-07-30 12:09:43 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-07-31 09:59:54 +1000
commitacd17a9b5300a38c4d61ecc0af32974d3b5113f5 (patch)
tree0bbb27d9e5ac956df11c35c8028d7076c256273e
parente9d00f5cfbc774004d121dc7eae69ff22419cb49 (diff)
Use MMCSS to elevate the thread priorities for audio and MIDI threads
use AVRT_PRIORITY_NORMAL for audio threads and AVRT_PRIORITY_HIGH for MIDI threads
-rw-r--r--libs/backends/portaudio/portaudio_backend.cc38
-rw-r--r--libs/backends/portaudio/winmmemidi_input_device.cc26
-rw-r--r--libs/backends/portaudio/winmmemidi_output_device.cc12
-rw-r--r--libs/backends/portaudio/wscript3
4 files changed, 78 insertions, 1 deletions
diff --git a/libs/backends/portaudio/portaudio_backend.cc b/libs/backends/portaudio/portaudio_backend.cc
index 0555f2596b..cfab0d172c 100644
--- a/libs/backends/portaudio/portaudio_backend.cc
+++ b/libs/backends/portaudio/portaudio_backend.cc
@@ -37,6 +37,8 @@
#include "i18n.h"
#include "win_utils.h"
+#include "mmcss.h"
+
#include "debug.h"
using namespace ARDOUR;
@@ -79,6 +81,8 @@ PortAudioBackend::PortAudioBackend (AudioEngine& e, AudioBackendInfo& info)
_instance_name = s_instance_name;
pthread_mutex_init (&_port_callback_mutex, 0);
+ mmcss::initialize ();
+
_pcmio = new PortAudioIO ();
_midiio = new WinMMEMidiIO ();
}
@@ -87,6 +91,9 @@ PortAudioBackend::~PortAudioBackend ()
{
delete _pcmio; _pcmio = 0;
delete _midiio; _midiio = 0;
+
+ mmcss::deinitialize ();
+
pthread_mutex_destroy (&_port_callback_mutex);
}
@@ -636,7 +643,23 @@ PortAudioBackend::portaudio_process_thread (void *arg)
ThreadData* td = reinterpret_cast<ThreadData*> (arg);
boost::function<void ()> f = td->f;
delete td;
+
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+ HANDLE task_handle;
+
+ mmcss::set_thread_characteristics ("Pro Audio", &task_handle);
+ mmcss::set_thread_priority (task_handle, mmcss::AVRT_PRIORITY_NORMAL);
+#endif
+
+ DWORD tid = GetThreadId (GetCurrentThread ());
+ DEBUG_THREADS (string_compose ("Process Thread Child ID: %1\n", tid));
+
f ();
+
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+ mmcss::revert_thread_characteristics (task_handle);
+#endif
+
return 0;
}
@@ -1308,6 +1331,16 @@ PortAudioBackend::main_process_thread ()
engine.halted_callback("PortAudio I/O error.");
}
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+ HANDLE task_handle;
+
+ mmcss::set_thread_characteristics ("Pro Audio", &task_handle);
+ mmcss::set_thread_priority (task_handle, mmcss::AVRT_PRIORITY_NORMAL);
+#endif
+
+ DWORD tid = GetThreadId (GetCurrentThread ());
+ DEBUG_THREADS (string_compose ("Process Thread Master ID: %1\n", tid));
+
while (_run) {
if (_freewheeling != _freewheel) {
@@ -1511,6 +1544,11 @@ PortAudioBackend::main_process_thread ()
if (_run) {
engine.halted_callback("PortAudio I/O error.");
}
+
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+ mmcss::revert_thread_characteristics (task_handle);
+#endif
+
return 0;
}
diff --git a/libs/backends/portaudio/winmmemidi_input_device.cc b/libs/backends/portaudio/winmmemidi_input_device.cc
index 1067b46743..3b52bcefd2 100644
--- a/libs/backends/portaudio/winmmemidi_input_device.cc
+++ b/libs/backends/portaudio/winmmemidi_input_device.cc
@@ -26,6 +26,8 @@
#include "win_utils.h"
#include "midi_util.h"
+#include "mmcss.h"
+
#include "debug.h"
static const uint32_t MIDI_BUFFER_SIZE = 32768;
@@ -175,6 +177,30 @@ WinMMEMidiInputDevice::winmm_input_callback(HMIDIIN handle,
{
WinMMEMidiInputDevice* midi_input = (WinMMEMidiInputDevice*)instance;
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+
+ static HANDLE input_thread = GetCurrentThread ();
+ static bool priority_boosted = false;
+
+ if (input_thread != GetCurrentThread ()) {
+ DWORD otid = GetThreadId (input_thread);
+ DWORD ntid = GetThreadId (GetCurrentThread ());
+ // There was a reference on the internet somewhere that it is possible
+ // for the callback to come from different threads(thread pool) this
+ // could be problematic but I haven't seen this behaviour yet
+ DEBUG_THREADS (string_compose (
+ "WinMME input Thread ID Changed: was %1, now %2\n", otid, ntid));
+ }
+
+ HANDLE task_handle;
+
+ if (!priority_boosted) {
+ mmcss::set_thread_characteristics ("Pro Audio", &task_handle);
+ mmcss::set_thread_priority (task_handle, mmcss::AVRT_PRIORITY_HIGH);
+ priority_boosted = true;
+ }
+#endif
+
switch (msg) {
case MIM_OPEN:
case MIM_CLOSE:
diff --git a/libs/backends/portaudio/winmmemidi_output_device.cc b/libs/backends/portaudio/winmmemidi_output_device.cc
index bb52b2da4f..7dec08e594 100644
--- a/libs/backends/portaudio/winmmemidi_output_device.cc
+++ b/libs/backends/portaudio/winmmemidi_output_device.cc
@@ -27,6 +27,7 @@
#include "win_utils.h"
#include "midi_util.h"
+#include "mmcss.h"
#include "debug.h"
// remove dup with input_device
@@ -349,6 +350,13 @@ WinMMEMidiOutputDevice::midi_output_thread ()
DEBUG_MIDI ("WinMMEMidiOut: MIDI output thread started\n");
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+ HANDLE task_handle;
+
+ mmcss::set_thread_characteristics ("Pro Audio", &task_handle);
+ mmcss::set_thread_priority (task_handle, mmcss::AVRT_PRIORITY_HIGH);
+#endif
+
while (!m_thread_quit) {
if (!wait (m_queue_semaphore)) {
break;
@@ -471,6 +479,10 @@ WinMMEMidiOutputDevice::midi_output_thread ()
#endif
}
+#ifdef USE_MMCSS_THREAD_PRIORITIES
+ mmcss::revert_thread_characteristics (task_handle);
+#endif
+
m_thread_running = false;
}
diff --git a/libs/backends/portaudio/wscript b/libs/backends/portaudio/wscript
index fcc0041a99..93421a0fe2 100644
--- a/libs/backends/portaudio/wscript
+++ b/libs/backends/portaudio/wscript
@@ -36,5 +36,6 @@ def build(bld):
obj.uselib = ['PORTAUDIO']
obj.install_path = os.path.join(bld.env['LIBDIR'], 'backends')
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"',
- 'ARDOURBACKEND_DLL_EXPORTS'
+ 'ARDOURBACKEND_DLL_EXPORTS',
+ 'USE_MMCSS_THREAD_PRIORITIES'
]