13
0

Fix PBD::MMTIMER::reset_resolution and add some documentation

timeEndPeriod must be called with the same timer resolution value used in
timeBeginPeriod. When the process exits the timer resolution is restored anyway
so this is not very important.
This commit is contained in:
Tim Mayberry 2015-09-14 10:29:00 +10:00
parent 62f75b8b16
commit a88b2da6a9
2 changed files with 50 additions and 50 deletions

View File

@ -25,31 +25,35 @@ namespace PBD {
namespace MMTIMERS { namespace MMTIMERS {
/**
* Get the minimum Multimedia Timer resolution as supported by the system
* @return true if getting min timer resolution was not successful
*/
bool get_min_resolution (uint32_t& timer_resolution_ms);
/** /**
* Set the minimum Multimedia Timer resolution as supported by the system * Set the minimum Multimedia Timer resolution as supported by the system
* @return true if min timer resolution was successfully set * @return true if setting min timer resolution was successful
*
* Call reset_resolution to restore old timer resolution
*/ */
bool set_min_resolution (); bool set_min_resolution ();
/** /**
* Get current Multimedia Timer resolution * Set current Multimedia Timer resolution. If the timer resolution has already
* @return true if getting the timer value was successful * been set then reset_resolution() must be called before set_resolution will
* succeed.
* @return true if setting the timer value was successful, false if setting the
* timer resolution failed or the resolution has already been set.
*/ */
bool get_resolution(uint32_t& timer_resolution_us); bool set_resolution(uint32_t timer_resolution_ms);
/** /**
* Set current Multimedia Timer resolution * Reset Multimedia Timer resolution. In my testing, if the timer resolution is
* set below the default, then resetting the resolution will not reset the
* timer resolution back to 15ms. At least it does not reset immediately
* even after calling Sleep.
* @return true if setting the timer value was successful * @return true if setting the timer value was successful
*/ */
bool set_resolution(uint32_t timer_resolution_us); bool reset_resolution();
/**
* Reset the Multimedia Timer back to what it was originally before
* setting the timer resolution.
*/
bool reset_resolution ();
} // namespace MMTIMERS } // namespace MMTIMERS

View File

@ -29,20 +29,20 @@
namespace { namespace {
UINT& UINT&
old_timer_resolution () timer_resolution ()
{ {
static UINT timer_res_ms = 0; static UINT timer_res_ms = 0;
return timer_res_ms; return timer_res_ms;
} }
} // anon namespace }
namespace PBD { namespace PBD {
namespace MMTIMERS { namespace MMTIMERS {
bool bool
set_min_resolution () get_min_resolution (uint32_t& min_resolution_ms)
{ {
TIMECAPS caps; TIMECAPS caps;
@ -50,61 +50,57 @@ set_min_resolution ()
DEBUG_TIMING ("Could not get timer device capabilities.\n"); DEBUG_TIMING ("Could not get timer device capabilities.\n");
return false; return false;
} }
return set_resolution(caps.wPeriodMin);
min_resolution_ms = caps.wPeriodMin;
return true;
}
bool
set_min_resolution ()
{
uint32_t min_resolution = 0;
if (!get_min_resolution (min_resolution)) {
return false;
}
if (!set_resolution (min_resolution)) {
return false;
}
return true;
} }
bool bool
set_resolution (uint32_t timer_resolution_ms) set_resolution (uint32_t timer_resolution_ms)
{ {
TIMECAPS caps; if (timer_resolution() != 0) {
DEBUG_TIMING(
if (timeGetDevCaps (&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) { "Timer resolution must be reset before setting new resolution.\n");
DEBUG_TIMING ("Could not get timer device capabilities.\n");
return false;
} }
UINT old_timer_res = caps.wPeriodMin;
if (timeBeginPeriod(timer_resolution_ms) != TIMERR_NOERROR) { if (timeBeginPeriod(timer_resolution_ms) != TIMERR_NOERROR) {
DEBUG_TIMING( DEBUG_TIMING(
string_compose("Could not set minimum timer resolution to %1(ms)\n", string_compose("Could not set timer resolution to %1(ms)\n",
timer_resolution_ms)); timer_resolution_ms));
return false; return false;
} }
old_timer_resolution () = old_timer_res; timer_resolution() = timer_resolution_ms;
DEBUG_TIMING (string_compose ("Multimedia timer resolution set to %1(ms)\n", DEBUG_TIMING (string_compose ("Multimedia timer resolution set to %1(ms)\n",
caps.wPeriodMin)); timer_resolution_ms));
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; return true;
} }
bool bool
reset_resolution () reset_resolution ()
{ {
if (old_timer_resolution ()) { // You must match calls to timeBegin/EndPeriod with the same resolution
if (timeEndPeriod (old_timer_resolution ()) != TIMERR_NOERROR) { if (timeEndPeriod(timer_resolution()) != TIMERR_NOERROR) {
DEBUG_TIMING ("Could not reset timer resolution.\n"); DEBUG_TIMING("Could not reset the Timer resolution.\n");
return false; return false;
}
} }
timer_resolution() = 0;
DEBUG_TIMING (string_compose ("Multimedia timer resolution set to %1(ms)\n",
old_timer_resolution ()));
return true; return true;
} }