Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision loss over far smaller durations than 9 years #2

Open
lichendust opened this issue Mar 14, 2024 · 0 comments
Open

Precision loss over far smaller durations than 9 years #2

lichendust opened this issue Mar 14, 2024 · 0 comments

Comments

@lichendust
Copy link

While building a film and scoring tool that depends on this library, I ran into some odd precision issues on values far smaller than expected based on the claims of the library.

Initially I believed it was after repeated conversion back and forth between Timecode and time.Duration, but in fact the behaviour just occurs above certain arbitrary values per edit rate.

For a 24fps edit rate, the timestamp begins to drift by whole frames during the 375th hour — a lot less than 9 years.

This example shows a timecode gaining an extra frame immediately on creation —

package main

import "fmt"
import "time"

import lib "github.com/trimmer-io/go-timecode/timecode"

func main() {
    const DURATION = time.Hour * 375

    tc := lib.New(DURATION, lib.Rate24)

    fmt.Println(tc)
}
375:00:00:01

The problem occurs far earlier at higher edit rates, such as —

  • 60fps — 58th hour
  • 120fps — 28th hour

In theory, this shouldn't come up in most use-cases, but the precision claim is wildly overstated and anyone who might be using the library under the assumption of high-precision without questioning it may be surprised.


I was going to build a better example using a zero tc and adding 32,000,000 frames to it to show it coughing back up 32,000,001 from tc.Frame() but, while doing that I also discovered that AddFrames with a frame number greater than the existing frame count of the Timecode just clamps it to zero.

The negative result gate is implemented backwards; positive values greater than the base tc value are zero'd, and negative values are freely allowed to wrap around.

func main() {
    tc := lib.New(0, lib.Rate24)
    tc = tc.AddFrames(-1)
    fmt.Println(tc)
}
160127:59:21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant