9 : m_sample_rate(sample_rate)
45 : m_target_fps(target_fps)
47 , m_start_time(
std::chrono::steady_clock::now())
48 , m_last_tick_time(
std::chrono::steady_clock::now())
49 , m_next_frame_time(
std::chrono::steady_clock::now())
50 , m_measured_fps(static_cast<double>(target_fps))
57 auto now = std::chrono::steady_clock::now();
61 if (frames_to_advance > 0) {
62 m_current_frame.fetch_add(frames_to_advance, std::memory_order_release);
91 auto now = std::chrono::steady_clock::now();
94 if (until_next.count() < 0) {
95 return std::chrono::nanoseconds(0);
98 return std::chrono::duration_cast<std::chrono::nanoseconds>(until_next);
103 auto now = std::chrono::steady_clock::now();
109 auto now = std::chrono::steady_clock::now();
117 return static_cast<uint64_t
>(frames_behind);
131 if (new_fps == 0 || new_fps > 1000) {
134 std::source_location::current(),
135 "FrameClock",
"set_target_fps",
"Invalid FPS value: {}",
146 auto expected_time =
m_start_time + std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>(frames_elapsed /
m_target_fps));
155 if (dt > 0.0 && dt <= 1.0) {
156 double instantaneous_fps = 1.0 / dt;
158 double current_measured =
m_measured_fps.load(std::memory_order_acquire);
174 m_frame_duration = std::chrono::nanoseconds(
static_cast<uint64_t
>(ns_per_frame));
180 if (sleep_duration > std::chrono::microseconds(100)) {
183 }
else if (sleep_duration > std::chrono::nanoseconds(0)) {
184 auto wake_time = std::chrono::steady_clock::now() + sleep_duration;
186 while (std::chrono::steady_clock::now() < wake_time) {
187 std::this_thread::yield();
197 : m_processing_rate(processing_rate)
198 , m_current_position(0)
199 , m_unit_name(unit_name)
const std::string & unit_name() const
Gets the name of the processing units.
double current_time() const override
Converts current position to seconds using custom rate.
uint64_t m_current_position
Current position in custom units.
void reset() override
Reset clock to initial state (position 0)
void tick(uint64_t units=1) override
Advances the clock by the specified number of custom units.
std::string m_unit_name
Name describing the custom units.
uint64_t m_processing_rate
Custom processing rate in units per second.
uint32_t rate() const override
Get the processing rate for this timing domain.
uint64_t current_position() const override
Get current position in the domain's timeline.
CustomClock(uint64_t processing_rate=1000, const std::string &unit_name="units")
Constructs a CustomClock with configurable parameters.
std::chrono::steady_clock::time_point m_last_tick_time
void recalculate_frame_duration()
Recalculate frame duration when target FPS changes.
bool is_frame_late() const
Check if we're running behind target frame rate.
static constexpr double FPS_SMOOTHING_ALPHA
void reset() override
Reset clock to initial state.
std::atomic< double > m_measured_fps
uint64_t current_position() const override
Get current frame position (thread-safe read)
uint32_t rate() const override
Get target frame rate.
double get_measured_fps() const
Get actual measured FPS (exponentially smoothed)
std::chrono::nanoseconds m_frame_duration
std::chrono::steady_clock::time_point m_next_frame_time
double current_time() const override
Convert current frame to seconds.
FrameClock(uint32_t target_fps=60)
Constructs a FrameClock with target frame rate.
uint64_t calculate_elapsed_frames(std::chrono::steady_clock::time_point now) const
Calculate frames elapsed based on wall-clock time.
std::chrono::steady_clock::time_point m_start_time
uint64_t get_frame_lag() const
Get how many frames behind we are (if any)
std::atomic< uint64_t > m_current_frame
void set_target_fps(uint32_t new_fps)
Set new target frame rate (runtime adjustment)
void wait_for_next_frame()
Wait (sleep) until next frame should occur.
std::chrono::nanoseconds time_until_next_frame() const
Get time until next frame should occur.
void update_fps_measurement(std::chrono::steady_clock::time_point now)
Update measured FPS based on tick interval Called internally during tick()
void tick(uint64_t forced_frames=0) override
Advance clock by computing elapsed frames since last tick.
void tick(uint64_t samples=1) override
Advances the clock by the specified number of samples.
uint32_t sample_rate() const
Gets the audio sample rate.
uint64_t m_current_sample
Current sample position counter.
uint32_t m_sample_rate
Audio sample rate in samples per second.
uint64_t current_position() const override
Get current position in the domain's timeline.
void reset() override
Reset clock to initial state (position 0)
double current_time() const override
Converts current sample position to seconds.
uint32_t rate() const override
Get the processing rate for this timing domain.
SampleClock(uint64_t sample_rate=48000)
Constructs a SampleClock with the specified sample rate.
@ ClockSync
Clock synchronization (SampleClock, FrameClock coordination)
@ Vruta
Coroutines, schedulers, clocks, task management.
double units_to_seconds(uint64_t units, uint32_t rate)
Convert processing units to seconds for any rate.