summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/backends/portaudio/portaudio_backend.cc8
-rw-r--r--libs/backends/portaudio/win_utils.cc136
-rw-r--r--libs/backends/portaudio/win_utils.h58
-rw-r--r--libs/backends/portaudio/winmmemidi_input_device.cc2
-rw-r--r--libs/backends/portaudio/winmmemidi_io.cc5
-rw-r--r--libs/backends/portaudio/winmmemidi_output_device.cc4
6 files changed, 158 insertions, 55 deletions
diff --git a/libs/backends/portaudio/portaudio_backend.cc b/libs/backends/portaudio/portaudio_backend.cc
index dcdb0d168d..f4ab827556 100644
--- a/libs/backends/portaudio/portaudio_backend.cc
+++ b/libs/backends/portaudio/portaudio_backend.cc
@@ -680,7 +680,7 @@ PortAudioBackend::samples_since_cycle_start ()
return 0;
}
- return m_cycle_timer.samples_since_cycle_start (utils::get_microseconds());
+ return m_cycle_timer.samples_since_cycle_start (PBD::get_microseconds());
}
int
@@ -1525,7 +1525,7 @@ PortAudioBackend::blocking_process_main(const float* interleaved_input_data,
int64_t min_elapsed_us = 1000000;
int64_t max_elapsed_us = 0;
- m_dsp_calc.set_start_timestamp_us (utils::get_microseconds());
+ m_dsp_calc.set_start_timestamp_us (PBD::get_microseconds());
i = 0;
/* Copy input audio data into input port buffers */
@@ -1551,7 +1551,7 @@ PortAudioBackend::blocking_process_main(const float* interleaved_input_data,
}
m_last_cycle_start = m_cycle_timer.get_start();
- m_cycle_timer.reset_start(utils::get_microseconds());
+ m_cycle_timer.reset_start(PBD::get_microseconds());
m_cycle_count++;
uint64_t cycle_diff_us = (m_cycle_timer.get_start() - m_last_cycle_start);
@@ -1599,7 +1599,7 @@ PortAudioBackend::blocking_process_main(const float* interleaved_input_data,
_processed_samples += _samples_per_period;
/* calculate DSP load */
- m_dsp_calc.set_stop_timestamp_us (utils::get_microseconds());
+ m_dsp_calc.set_stop_timestamp_us (PBD::get_microseconds());
_dsp_load = m_dsp_calc.get_dsp_load();
DEBUG_TIMING(string_compose("DSP Load: %1\n", _dsp_load));
diff --git a/libs/backends/portaudio/win_utils.cc b/libs/backends/portaudio/win_utils.cc
index dc0f8d5270..6d0e404749 100644
--- a/libs/backends/portaudio/win_utils.cc
+++ b/libs/backends/portaudio/win_utils.cc
@@ -27,27 +27,6 @@
namespace {
-bool&
-qpc_frequency_success ()
-{
- static bool success = false;
- return success;
-}
-
-LARGE_INTEGER
-qpc_frequency ()
-{
- LARGE_INTEGER freq;
- if (QueryPerformanceFrequency(&freq) == 0) {
- DEBUG_TIMING ("Failed to determine frequency of QPC\n");
- qpc_frequency_success() = false;
- } else {
- qpc_frequency_success() = true;
- }
-
- return freq;
-}
-
UINT&
old_timer_resolution ()
{
@@ -57,33 +36,63 @@ old_timer_resolution ()
} // anon namespace
-namespace utils {
+namespace PBD {
+
+namespace MMTIMERS {
bool
-set_min_timer_resolution ()
+set_min_resolution ()
{
TIMECAPS caps;
if (timeGetDevCaps (&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
DEBUG_TIMING ("Could not get timer device capabilities.\n");
return false;
- } else {
- old_timer_resolution () = caps.wPeriodMin;
- if (timeBeginPeriod (caps.wPeriodMin) != TIMERR_NOERROR) {
- DEBUG_TIMING (string_compose (
- "Could not set minimum timer resolution to %1(ms)\n", caps.wPeriodMin));
- return false;
- }
+ }
+ return set_resolution(caps.wPeriodMin);
+}
+
+bool
+set_resolution (uint32_t timer_resolution_ms)
+{
+ TIMECAPS caps;
+
+ if (timeGetDevCaps (&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
+ DEBUG_TIMING ("Could not get timer device capabilities.\n");
+ return false;
+ }
+
+ UINT old_timer_res = caps.wPeriodMin;
+
+ if (timeBeginPeriod(timer_resolution_ms) != TIMERR_NOERROR) {
+ DEBUG_TIMING(
+ string_compose("Could not set minimum timer resolution to %1(ms)\n",
+ timer_resolution_ms));
+ return false;
}
+ old_timer_resolution () = old_timer_res;
+
DEBUG_TIMING (string_compose ("Multimedia timer resolution set to %1(ms)\n",
caps.wPeriodMin));
+ return true;
+}
+bool
+get_resolution (uint32_t& timer_resolution_ms)
+{
+ TIMECAPS caps;
+
+ if (timeGetDevCaps(&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
+ DEBUG_TIMING ("Could not get timer device capabilities.\n");
+ return false;
+ }
+ timer_resolution_ms = caps.wPeriodMin;
return true;
}
bool
-reset_timer_resolution ()
+reset_resolution ()
{
if (old_timer_resolution ()) {
if (timeEndPeriod (old_timer_resolution ()) != TIMERR_NOERROR) {
@@ -98,26 +107,77 @@ reset_timer_resolution ()
return true;
}
+} // namespace MMTIMERS
+
+namespace {
+
+bool&
+qpc_frequency_success ()
+{
+ static bool success = false;
+ return success;
+}
+
+LARGE_INTEGER
+qpc_frequency ()
+{
+ LARGE_INTEGER freq;
+ if (QueryPerformanceFrequency(&freq) == 0) {
+ DEBUG_TIMING ("Failed to determine frequency of QPC\n");
+ qpc_frequency_success() = false;
+ } else {
+ qpc_frequency_success() = true;
+ }
+
+ return freq;
+}
+
+LARGE_INTEGER
+qpc_frequency_cached ()
+{
+ static LARGE_INTEGER frequency = qpc_frequency ();
+ return frequency;
+}
+
+} // anon namespace
+
+namespace QPC {
+
+bool
+get_timer_valid ()
+{
+ // setup caching the timer frequency
+ qpc_frequency_cached ();
+ return qpc_frequency_success ();
+}
+
int64_t
get_microseconds ()
{
- static LARGE_INTEGER frequency = qpc_frequency ();
LARGE_INTEGER current_val;
if (qpc_frequency_success()) {
-
// MS docs say this will always succeed for systems >= XP but it may
// not return a monotonic value with non-invariant TSC's etc
if (QueryPerformanceCounter(&current_val) != 0) {
return (int64_t)(((double)current_val.QuadPart) /
- ((double)frequency.QuadPart) * 1000000.0);
- } else {
- DEBUG_TIMING ("Could not get QPC timer\n");
+ ((double)qpc_frequency_cached().QuadPart) * 1000000.0);
}
- return -1;
+ }
+ DEBUG_TIMING ("Could not get QPC timer\n");
+ return -1;
+}
+
+} // namespace QPC
+
+int64_t
+get_microseconds ()
+{
+ if (qpc_frequency_success()) {
+ return QPC::get_microseconds ();
}
// For XP systems that don't support a high-res performance counter
return g_get_monotonic_time ();
}
-} // namespace utils
+} // namespace PBD
diff --git a/libs/backends/portaudio/win_utils.h b/libs/backends/portaudio/win_utils.h
index 072ce1f0b0..c0c7bbf491 100644
--- a/libs/backends/portaudio/win_utils.h
+++ b/libs/backends/portaudio/win_utils.h
@@ -21,22 +21,66 @@
#include <stdint.h>
-namespace utils {
+namespace PBD {
-bool set_min_timer_resolution ();
+namespace MMTIMERS {
-bool reset_timer_resolution ();
+/**
+ * Set the minimum Multimedia Timer resolution as supported by the system
+ * @return true if min timer resolution was successfully set
+ *
+ * Call reset_resolution to restore old timer resolution
+ */
+bool set_min_resolution ();
+
+/**
+ * Get current Multimedia Timer resolution
+ * @return true if getting the timer value was successful
+ */
+bool get_resolution(uint32_t& timer_resolution_us);
+
+/**
+ * Set current Multimedia Timer resolution
+ * @return true if setting the timer value was successful
+ */
+bool set_resolution(uint32_t timer_resolution_us);
+
+/**
+ * Reset the Multimedia Timer back to what it was originally before
+ * setting the timer resolution.
+ */
+bool reset_resolution ();
+
+} // namespace MMTIMERS
+
+namespace QPC {
+
+/**
+ * @return true if QueryPerformanceCounter is usable as a timer source
+ */
+bool get_timer_valid ();
+
+/**
+ * @return the value of the performance counter converted to microseconds
+ *
+ * If get_counter_valid returns true then get_microseconds will always
+ * return a positive value. If QPC is not supported(OS < XP) then -1 is
+ * returned but the MS docs say that this won't occur for systems >= XP.
+ */
+int64_t get_microseconds ();
+
+} // namespace QPC
-/** The highest resolution timer source provided by the system. On Vista and
+/**
+ * The highest resolution timer source provided by the system. On Vista and
* above this is the value returned by QueryPerformanceCounter(QPC). On XP,
* this will QPC if supported or otherwise g_get_monotonic_time will be used.
*
* @return A timer value in microseconds or -1 in the event that the reading
- * the timer source fails, but the MS docs say that this won't occur for
- * systems >= XP
+ * the timer source fails.
*/
int64_t get_microseconds ();
-}
+} // namespace PBD
#endif // WIN_UTILS_H
diff --git a/libs/backends/portaudio/winmmemidi_input_device.cc b/libs/backends/portaudio/winmmemidi_input_device.cc
index d7a0a6dbaa..95e7faa476 100644
--- a/libs/backends/portaudio/winmmemidi_input_device.cc
+++ b/libs/backends/portaudio/winmmemidi_input_device.cc
@@ -346,7 +346,7 @@ WinMMEMidiInputDevice::enqueue_midi_msg (const uint8_t* midi_data,
}
// don't use winmme timestamps for now
- uint64_t ts = utils::get_microseconds ();
+ uint64_t ts = PBD::get_microseconds ();
DEBUG_TIMING (string_compose (
"Enqueing MIDI data device: %1 with timestamp: %2 and size %3\n",
diff --git a/libs/backends/portaudio/winmmemidi_io.cc b/libs/backends/portaudio/winmmemidi_io.cc
index 43c5d36469..4c93799637 100644
--- a/libs/backends/portaudio/winmmemidi_io.cc
+++ b/libs/backends/portaudio/winmmemidi_io.cc
@@ -31,7 +31,6 @@
#include "i18n.h"
using namespace ARDOUR;
-using namespace utils;
WinMMEMidiIO::WinMMEMidiIO()
: m_active (false)
@@ -136,7 +135,7 @@ WinMMEMidiIO::start ()
m_run = true;
DEBUG_MIDI ("Starting MIDI driver\n");
- set_min_timer_resolution();
+ PBD::MMTIMERS::set_min_resolution();
discover();
start_devices ();
}
@@ -156,7 +155,7 @@ WinMMEMidiIO::stop ()
cleanup ();
pthread_mutex_unlock (&m_device_lock);
- reset_timer_resolution();
+ PBD::MMTIMERS::reset_resolution();
}
void
diff --git a/libs/backends/portaudio/winmmemidi_output_device.cc b/libs/backends/portaudio/winmmemidi_output_device.cc
index 84a72a2304..a1d76cd236 100644
--- a/libs/backends/portaudio/winmmemidi_output_device.cc
+++ b/libs/backends/portaudio/winmmemidi_output_device.cc
@@ -390,7 +390,7 @@ WinMMEMidiOutputDevice::midi_output_thread ()
DEBUG_MIDI ("WinMMEMidiOut: MIDI buffer underrun, shouldn't occur\n");
continue;
}
- uint64_t current_time = utils::get_microseconds ();
+ uint64_t current_time = PBD::get_microseconds ();
DEBUG_TIMING (string_compose (
"WinMMEMidiOut: h.time = %1, current_time = %2\n", h.time, current_time));
@@ -408,7 +408,7 @@ WinMMEMidiOutputDevice::midi_output_thread ()
break;
}
- uint64_t wakeup_time = utils::get_microseconds ();
+ uint64_t wakeup_time = PBD::get_microseconds ();
DEBUG_TIMING (string_compose ("WinMMEMidiOut: woke up at %1(ms)\n",
((double)wakeup_time) / 1000.0));
if (wakeup_time > h.time) {