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:
parent
1963c3ff10
commit
ada32733c5
@ -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" */
|
||||
|
Loading…
Reference in New Issue
Block a user