summaryrefslogtreecommitdiff
path: root/libs/backends
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-09-12 14:58:35 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-09-16 11:22:16 +1000
commit4ffe8ffc0faef8ea4bb17e27963bf3998a006995 (patch)
tree18632b5e3be850f664334659e721afb84951bb03 /libs/backends
parent4330db1aa77b71f7b3071f6b72f24f4a1e64aef3 (diff)
Put Windows timer functions into PBD namespace in preparation for moving them to libpbd
Add functions for get/set the Multimedia timer resolution, although we are really only interested in the minimum, this will facilitate testing Put timer utility functions inside nested namespaces as they are platform specific
Diffstat (limited to 'libs/backends')
-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) {