From 8ee69aa072883ab2659e707152c11fc5ddf22777 Mon Sep 17 00:00:00 2001 From: David Flynn Date: Thu, 7 Aug 2008 19:39:02 +0000 Subject: [PATCH] Fix date_Increment when i_divider_den > 1 Previously, calling date_Increment(d,1) with divider_den > 1 would cause: - Uncorrectable rounding error due to ordering of / followed by * - If i_divider_num / i_divider_den is not integral, a remainder is accumulated, but not divided by i_divider_num when added to date. => Both cases are evident with num=30000, den=1001. This fixes both issues. Signed-off-by: David Flynn --- src/misc/mtime.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/misc/mtime.c b/src/misc/mtime.c index 5ab08c5e89..d5a809f5b5 100644 --- a/src/misc/mtime.c +++ b/src/misc/mtime.c @@ -427,6 +427,8 @@ void date_Init( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d ) void date_Change( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d ) { + /* change time scale of remainder */ + p_date->i_remainder = p_date->i_remainder * i_divider_n / p_date->i_divider_num; p_date->i_divider_num = i_divider_n; p_date->i_divider_den = i_divider_d; } @@ -475,14 +477,15 @@ void date_Move( date_t *p_date, mtime_t i_difference ) */ mtime_t date_Increment( date_t *p_date, uint32_t i_nb_samples ) { - mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000; - p_date->date += i_dividend / p_date->i_divider_num * p_date->i_divider_den; + mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000 * p_date->i_divider_den; + p_date->date += i_dividend / p_date->i_divider_num; p_date->i_remainder += (int)(i_dividend % p_date->i_divider_num); if( p_date->i_remainder >= p_date->i_divider_num ) { /* This is Bresenham algorithm. */ - p_date->date += p_date->i_divider_den; + /* It is guaranteed that: assert(i_remainder < 2*i_divider_num) */ + p_date->date += 1; p_date->i_remainder -= p_date->i_divider_num; } -- GitLab