blob: 7b8afa0529251fb1ec2a8c5b8a49c1c9da673ed6 [file] [log] [blame]
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "audio_utils_timestampverifier_tests"
#include <stdio.h>
#include <audio_utils/TimestampVerifier.h>
#include <gtest/gtest.h>
// Ensure that all TimestampVerifier mutators are really constexpr and free from
// nasty system calls (in case called from a SCHED_FIFO thread).
static constexpr auto makeVerifier(
size_t N, uint32_t sampleRate, size_t errors, size_t discontinuities) {
android::TimestampVerifier<int64_t, int64_t> tv;
int64_t f = 0;
int64_t t = 0;
for (size_t i = 0; i < N; ++i) {
tv.add(f, t, sampleRate);
f += sampleRate;
t += (int64_t)1e9;
}
for (size_t i = 0; i < discontinuities; ++i) {
tv.discontinuity();
}
for (size_t i = 0; i < errors; ++i) {
tv.error();
}
return tv;
}
TEST(TimestampVerifier, sanity)
{
constexpr android::TimestampVerifier<int64_t, int64_t> tv;
// The timestamp verifier must be embeddable in a memcpy structure just like pod.
// We use is_trivially_copyable and is_trivially_destructible for this test.
static_assert(std::is_trivially_copyable<decltype(tv)>::value,
"TimestampVerifier must be trivially copyable");
static_assert(std::is_trivially_destructible<decltype(tv)>::value,
"TimestampVerifier must be trivially destructible");
constexpr android::audio_utils::Statistics<double> s = tv.getJitterMs();
EXPECT_EQ(std::numeric_limits<double>::infinity(), s.getMin());
EXPECT_EQ(-std::numeric_limits<double>::infinity(), s.getMax());
constexpr int64_t frames[] { 0, 48000 };
constexpr int64_t timeNs[] { 0, 1000000000 };
constexpr android::TimestampVerifier<int64_t, int64_t> tv2(frames, timeNs, 48000);
EXPECT_EQ(0., tv2.getJitterMs().getMax());
EXPECT_EQ(0., tv2.getJitterMs().getMin());
EXPECT_EQ(0., tv2.getJitterMs().getMean());
EXPECT_EQ(1, tv2.getJitterMs().getN());
// We should get a perfect straight line estimate as there is no noise.
double a, b, r2;
tv2.estimateSampleRate(a, b, r2);
EXPECT_EQ(0., a);
EXPECT_EQ(48000., b);
EXPECT_NEAR(1., r2, std::numeric_limits<double>::epsilon());
constexpr android::TimestampVerifier<int64_t, int64_t> tv3 =
makeVerifier(8 /* N */, 48000 /* sampleRate */, 10 /* errors */, 10 /* disc */);
EXPECT_EQ(8, tv3.getN());
EXPECT_EQ(10, tv3.getErrors());
EXPECT_EQ(1, tv3.getDiscontinuities()); // consecutive discontinuities read as 1.
EXPECT_EQ(0., tv3.getJitterMs().getMax());
EXPECT_EQ(0., tv3.getJitterMs().getMin());
EXPECT_EQ(0., tv3.getJitterMs().getMean());
constexpr auto first = tv3.getFirstTimestamp();
constexpr auto last = tv3.getLastTimestamp();
EXPECT_EQ(0, first.mFrames);
EXPECT_EQ(0, first.mTimeNs);
EXPECT_EQ(48000 * (8 - 1), last.mFrames);
EXPECT_EQ((int64_t)1e9 * (8 - 1), last.mTimeNs);
EXPECT_EQ((uint32_t)48000, tv3.getSampleRate());
EXPECT_EQ(0, tv3.getColds());
tv3.estimateSampleRate(a, b, r2);
EXPECT_EQ(0., a);
EXPECT_EQ(48000., b);
EXPECT_NEAR(1., r2, std::numeric_limits<double>::epsilon());
}