13
0

Modify some functions to alleviate overflow / precision errors

'session_frame_to_track_frame()' and its complement, 'track_frame_to_session_frame()' both accept a double and an ARDOUR::framepost_t (int64_t). For convenience these both get converted to long double. However, the functions are often called with very large values (ARDOUR::max_framepos). When this happens, rounding and precision errors can cause overflow issues. This is an attempt to alleviate that problem. Not sure if it's strictly necessary to accommodate negative values - but I'm assuming these could happen if 'speed' was negative (reverse play?)

This is the reason why 'Select All Objects' (and similar functionality) don't work for some users.
This commit is contained in:
John Emmas 2015-08-27 12:24:21 +01:00
parent 1963c3ff10
commit ada32733c5

View File

@ -713,13 +713,30 @@ LIBARDOUR_API std::ostream& operator<<(std::ostream& o, const ARDOUR::MeterLineU
static inline ARDOUR::framepos_t
session_frame_to_track_frame (ARDOUR::framepos_t session_frame, double speed)
{
return (ARDOUR::framepos_t) ((long double) session_frame * (long double) speed);
long double result = (long double) session_frame * (long double) speed;
if (result >= (long double) ARDOUR::max_framepos) {
return ARDOUR::max_framepos;
} else if (result <= (long double) (ARDOUR::max_framepos) * (ARDOUR::framepos_t)(-1)) {
return (ARDOUR::max_framepos * (ARDOUR::framepos_t)(-1));
} else {
return result;
}
}
static inline ARDOUR::framepos_t
track_frame_to_session_frame (ARDOUR::framepos_t track_frame, double speed)
{
return (ARDOUR::framepos_t) ((long double) track_frame / (long double) speed);
/* NB - do we need a check for speed == 0 ??? */
long double result = (long double) track_frame / (long double) speed;
if (result >= (long double) ARDOUR::max_framepos) {
return ARDOUR::max_framepos;
} else if (result <= (long double) (ARDOUR::max_framepos) * (ARDOUR::framepos_t)(-1)) {
return (ARDOUR::max_framepos * (ARDOUR::framepos_t)(-1));
} else {
return result;
}
}
/* for now, break the rules and use "using" to make this "global" */