blob: 4b900311f9fe42713f60a5a9ff943a69c2c7b612 [file] [log] [blame] [edit]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/lib/clock/clock.h"
#include <lib/zx/time.h>
#include <gtest/gtest.h>
#include "src/media/audio/lib/timeline/timeline_rate.h"
//
// media_audio::Clock is a pure virtual class, but this file tests its static methods.
//
using media::TimelineRate;
namespace media_audio {
namespace {
// Rate _adjustments_ are relative to unity 1/1 and stated in integral parts-per-million.
// Thus, we describe a rate of 1999/2000 (999'500/1'000'000) as a rate adjustment of -500ppm.
TEST(ClockTest, TimelineRateToRateAdjustmentPpm) {
// Unity
EXPECT_EQ(Clock::TimelineRateToRateAdjustmentPpm(TimelineRate(1, 1)), 0);
// Rate adjustment 0.5 ppm (rate 1'000'000.5 / 1'000'000) should be rounded "out" to 1ppm.
EXPECT_EQ(Clock::TimelineRateToRateAdjustmentPpm(TimelineRate(10'000'005, 10'000'000)), 1);
// Rate adjustment -0.5 ppm (rate 999'999.5 / 1'000'000) should be rounded "out" to -1ppm.
EXPECT_EQ(Clock::TimelineRateToRateAdjustmentPpm(TimelineRate(9'999'995, 10'000'000)), -1);
// Rate adjustment 0.499 ppm (rate 1'000'000.499 / 1'000'000) should be rounded "in" to 0ppm.
EXPECT_EQ(Clock::TimelineRateToRateAdjustmentPpm(TimelineRate(1'000'000'499, 1'000'000'000)), 0);
// Rate adjustment -0.499 ppm (rate 999'999.501 / 1'000'000) should be rounded "in" to 0ppm.
EXPECT_EQ(Clock::TimelineRateToRateAdjustmentPpm(TimelineRate(999'999'501, 1'000'000'000)), 0);
}
// This method clamps ints to [ZX_CLOCK_UPDATE_MAX_RATE_ADJUST, ZX_CLOCK_UPDATE_MIN_RATE_ADJUST].
TEST(ClockTest, ClampZxClockPpm) {
EXPECT_EQ(Clock::ClampZxClockPpm(0), 0);
EXPECT_EQ(Clock::ClampZxClockPpm(ZX_CLOCK_UPDATE_MAX_RATE_ADJUST + 1),
ZX_CLOCK_UPDATE_MAX_RATE_ADJUST);
EXPECT_EQ(Clock::ClampZxClockPpm(ZX_CLOCK_UPDATE_MIN_RATE_ADJUST - 1),
ZX_CLOCK_UPDATE_MIN_RATE_ADJUST);
}
// This method accepts a zero-based double and converts it to an integer parts-per-million value,
// first rounding _away from zero_ (i.e. it rounds 0.5 to 1, and -0.5 to -1), then clamping the
// result to the [ZX_CLOCK_UPDATE_MAX_RATE_ADJUST,ZX_CLOCK_UPDATE_MIN_RATE_ADJUST] range.
TEST(ClockTest, ClampDoubleToZxClockPpm) {
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(0.0), 0);
// Exact +/-N.5 values should be rounded "out" to +/-(N+1).
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(0.5 / 1'000'000.0), 1);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(42.5 / 1'000'000.0), 43);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(-0.5 / 1'000'000.0), -1);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(-67.5 / 1'000'000.0), -68);
// Values just shy of +/-N.5 (i.e. toward zero) should be rounded "in" to +/-N.
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(0.499999 / 1'000'000.0), 0);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(42.499999 / 1'000'000.0), 42);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(-0.499999 / 1'000'000.0), 0);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(-67.499999 / 1'000'000.0), -67);
// Out-of-range values must be clamped to [...MAX_RATE_ADJUST, ...MIN_RATE_ADJUST].
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(
static_cast<double>(2 * ZX_CLOCK_UPDATE_MAX_RATE_ADJUST) / 1'000'000.0),
ZX_CLOCK_UPDATE_MAX_RATE_ADJUST);
EXPECT_EQ(Clock::ClampDoubleToZxClockPpm(
static_cast<double>(2 * ZX_CLOCK_UPDATE_MIN_RATE_ADJUST) / 1'000'000.0),
ZX_CLOCK_UPDATE_MIN_RATE_ADJUST);
}
} // namespace
} // namespace media_audio