Commit 8ee69aa0 authored by David Flynn's avatar David Flynn Committed by Derk-Jan Hartman

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: default avatarDavid Flynn <davidf@rd.bbc.co.uk>
parent 331e10fb
...@@ -427,6 +427,8 @@ void date_Init( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d ) ...@@ -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 ) 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_num = i_divider_n;
p_date->i_divider_den = i_divider_d; p_date->i_divider_den = i_divider_d;
} }
...@@ -475,14 +477,15 @@ void date_Move( date_t *p_date, mtime_t i_difference ) ...@@ -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 date_Increment( date_t *p_date, uint32_t i_nb_samples )
{ {
mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000; 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_divider_den; p_date->date += i_dividend / p_date->i_divider_num;
p_date->i_remainder += (int)(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 ) if( p_date->i_remainder >= p_date->i_divider_num )
{ {
/* This is Bresenham algorithm. */ /* 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; p_date->i_remainder -= p_date->i_divider_num;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment