From 811a999308587c0c83e32f24b4a6c0a54be07e8d Mon Sep 17 00:00:00 2001 From: Robert Wu <85952307+robertwu1@users.noreply.github.com> Date: Mon, 5 Aug 2024 14:29:34 -0700 Subject: [PATCH] Move AudioClock to Oboe (#2080) --- .../app/src/main/cpp/NativeAudioContext.cpp | 2 +- .../app/src/main/cpp/TestColdStartLatency.cpp | 2 +- .../app/src/main/cpp/TestRapidCycle.cpp | 2 +- .../app/src/main/cpp/TestRoutingCrash.cpp | 2 +- {src/common => include/oboe}/AudioClock.h | 1 - include/oboe/Oboe.h | 1 + src/aaudio/AudioStreamAAudio.cpp | 2 +- src/common/AdpfWrapper.cpp | 2 +- src/common/AudioStream.cpp | 6 +- src/common/StabilizedCallback.cpp | 4 +- src/opensles/AudioOutputStreamOpenSLES.cpp | 3 +- src/opensles/AudioStreamBuffered.cpp | 2 +- src/opensles/AudioStreamOpenSLES.cpp | 5 +- tests/CMakeLists.txt | 1 + tests/testAudioClock.cpp | 92 +++++++++++++++++++ 15 files changed, 109 insertions(+), 18 deletions(-) rename {src/common => include/oboe}/AudioClock.h (95%) create mode 100644 tests/testAudioClock.cpp diff --git a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp index d0ea68eda..b55f607b9 100644 --- a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp +++ b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp @@ -27,7 +27,7 @@ #endif // DEBUG_CLOSE_RACE #include -#include +#include "oboe/AudioClock.h" #include "util/WaveFileWriter.h" #include "NativeAudioContext.h" diff --git a/apps/OboeTester/app/src/main/cpp/TestColdStartLatency.cpp b/apps/OboeTester/app/src/main/cpp/TestColdStartLatency.cpp index 7de1c7ab8..9b4f25ca1 100644 --- a/apps/OboeTester/app/src/main/cpp/TestColdStartLatency.cpp +++ b/apps/OboeTester/app/src/main/cpp/TestColdStartLatency.cpp @@ -18,7 +18,7 @@ #include #include "common/OboeDebug.h" -#include "common/AudioClock.h" +#include "oboe/AudioClock.h" #include "TestColdStartLatency.h" #include "OboeTools.h" diff --git a/apps/OboeTester/app/src/main/cpp/TestRapidCycle.cpp b/apps/OboeTester/app/src/main/cpp/TestRapidCycle.cpp index ff310c1c9..4e6a9cb0c 100644 --- a/apps/OboeTester/app/src/main/cpp/TestRapidCycle.cpp +++ b/apps/OboeTester/app/src/main/cpp/TestRapidCycle.cpp @@ -18,7 +18,7 @@ #include #include "common/OboeDebug.h" -#include "common/AudioClock.h" +#include "oboe/AudioClock.h" #include "TestRapidCycle.h" using namespace oboe; diff --git a/apps/OboeTester/app/src/main/cpp/TestRoutingCrash.cpp b/apps/OboeTester/app/src/main/cpp/TestRoutingCrash.cpp index 633e11866..0a0c30ba3 100644 --- a/apps/OboeTester/app/src/main/cpp/TestRoutingCrash.cpp +++ b/apps/OboeTester/app/src/main/cpp/TestRoutingCrash.cpp @@ -18,7 +18,7 @@ #include #include "common/OboeDebug.h" -#include "common/AudioClock.h" +#include "oboe/AudioClock.h" #include "TestRoutingCrash.h" using namespace oboe; diff --git a/src/common/AudioClock.h b/include/oboe/AudioClock.h similarity index 95% rename from src/common/AudioClock.h rename to include/oboe/AudioClock.h index 3fe20cb0a..efbfbf7fa 100644 --- a/src/common/AudioClock.h +++ b/include/oboe/AudioClock.h @@ -23,7 +23,6 @@ namespace oboe { -// TODO: Move this class into the public headers because it is useful when calculating stream latency class AudioClock { public: static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) { diff --git a/include/oboe/Oboe.h b/include/oboe/Oboe.h index b9c948af8..9cd909687 100644 --- a/include/oboe/Oboe.h +++ b/include/oboe/Oboe.h @@ -36,5 +36,6 @@ #include "oboe/FifoBuffer.h" #include "oboe/OboeExtensions.h" #include "oboe/FullDuplexStream.h" +#include "oboe/AudioClock.h" #endif //OBOE_OBOE_H diff --git a/src/aaudio/AudioStreamAAudio.cpp b/src/aaudio/AudioStreamAAudio.cpp index 7aad6dda3..014dc06e7 100644 --- a/src/aaudio/AudioStreamAAudio.cpp +++ b/src/aaudio/AudioStreamAAudio.cpp @@ -20,8 +20,8 @@ #include "aaudio/AAudioLoader.h" #include "aaudio/AudioStreamAAudio.h" -#include "common/AudioClock.h" #include "common/OboeDebug.h" +#include "oboe/AudioClock.h" #include "oboe/Utilities.h" #include "AAudioExtensions.h" diff --git a/src/common/AdpfWrapper.cpp b/src/common/AdpfWrapper.cpp index 05accdea6..aea4143dc 100644 --- a/src/common/AdpfWrapper.cpp +++ b/src/common/AdpfWrapper.cpp @@ -18,8 +18,8 @@ #include #include +#include "oboe/AudioClock.h" #include "AdpfWrapper.h" -#include "AudioClock.h" #include "OboeDebug.h" typedef APerformanceHintManager* (*APH_getManager)(); diff --git a/src/common/AudioStream.cpp b/src/common/AudioStream.cpp index c27370f11..5eb4e4629 100644 --- a/src/common/AudioStream.cpp +++ b/src/common/AudioStream.cpp @@ -18,10 +18,10 @@ #include #include -#include +#include "oboe/AudioClock.h" +#include "oboe/AudioStream.h" +#include "oboe/Utilities.h" #include "OboeDebug.h" -#include "AudioClock.h" -#include namespace oboe { diff --git a/src/common/StabilizedCallback.cpp b/src/common/StabilizedCallback.cpp index a2ac54959..0c561a53f 100644 --- a/src/common/StabilizedCallback.cpp +++ b/src/common/StabilizedCallback.cpp @@ -14,9 +14,9 @@ * limitations under the License. */ -#include "oboe/StabilizedCallback.h" -#include "common/AudioClock.h" #include "common/Trace.h" +#include "oboe/AudioClock.h" +#include "oboe/StabilizedCallback.h" constexpr int32_t kLoadGenerationStepSizeNanos = 20000; constexpr float kPercentageOfCallbackToUse = 0.8; diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp index 1ef9527c7..288a3dbc8 100644 --- a/src/opensles/AudioOutputStreamOpenSLES.cpp +++ b/src/opensles/AudioOutputStreamOpenSLES.cpp @@ -16,9 +16,8 @@ #include -#include - #include "common/OboeDebug.h" +#include "oboe/AudioClock.h" #include "oboe/AudioStreamBuilder.h" #include "AudioOutputStreamOpenSLES.h" #include "AudioStreamOpenSLES.h" diff --git a/src/opensles/AudioStreamBuffered.cpp b/src/opensles/AudioStreamBuffered.cpp index 9737b72bb..d608f2068 100644 --- a/src/opensles/AudioStreamBuffered.cpp +++ b/src/opensles/AudioStreamBuffered.cpp @@ -19,8 +19,8 @@ #include "oboe/Oboe.h" #include "common/OboeDebug.h" +#include "oboe/AudioClock.h" #include "opensles/AudioStreamBuffered.h" -#include "common/AudioClock.h" namespace oboe { diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp index e1170b220..d96a4616d 100644 --- a/src/opensles/AudioStreamOpenSLES.cpp +++ b/src/opensles/AudioStreamOpenSLES.cpp @@ -16,10 +16,9 @@ #include #include -#include -#include - #include "common/OboeDebug.h" +#include "oboe/AudioClock.h" +#include "oboe/AudioStream.h" #include "oboe/AudioStreamBuilder.h" #include "EngineOpenSLES.h" #include "AudioStreamOpenSLES.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 26074e39c..c2d9cffd8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,6 +27,7 @@ include_directories( add_executable( testOboe testAAudio.cpp + testAudioClock.cpp testFlowgraph.cpp testFullDuplexStream.cpp testResampler.cpp diff --git a/tests/testAudioClock.cpp b/tests/testAudioClock.cpp new file mode 100644 index 000000000..cad8d74c4 --- /dev/null +++ b/tests/testAudioClock.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2022 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. + */ + +/* + * Test FlowGraph + */ + +#include "math.h" +#include "stdio.h" + +#include +#include + +using namespace oboe; + +#define NANOS_PER_MICROSECOND ((int64_t) 1000) + +constexpr int64_t kSleepTimeMicroSec = 50 * 1000; +constexpr double kMaxLatenessMicroSec = 20 * 1000; + +TEST(TestAudioClock, GetNanosecondsMonotonic) { + + int64_t startNanos = AudioClock::getNanoseconds(CLOCK_MONOTONIC); + usleep(kSleepTimeMicroSec); + int64_t endNanos = AudioClock::getNanoseconds(CLOCK_MONOTONIC); + ASSERT_GE(endNanos, startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond); + ASSERT_LT(endNanos, startNanos + ((kSleepTimeMicroSec + kMaxLatenessMicroSec) + * kNanosPerMicrosecond)); +} + +TEST(TestAudioClock, GetNanosecondsRealtime) { + + int64_t startNanos = AudioClock::getNanoseconds(CLOCK_REALTIME); + usleep(kSleepTimeMicroSec); + int64_t endNanos = AudioClock::getNanoseconds(CLOCK_REALTIME); + ASSERT_GE(endNanos, startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond); + ASSERT_LT(endNanos, startNanos + ((kSleepTimeMicroSec + kMaxLatenessMicroSec) + * kNanosPerMicrosecond)); +} + +TEST(TestAudioClock, SleepUntilNanoTimeMonotonic) { + + int64_t startNanos = AudioClock::getNanoseconds(CLOCK_MONOTONIC); + AudioClock::sleepUntilNanoTime(startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond, CLOCK_MONOTONIC); + int64_t endNanos = AudioClock::getNanoseconds(CLOCK_MONOTONIC); + ASSERT_GE(endNanos, startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond); + ASSERT_LT(endNanos, startNanos + ((kSleepTimeMicroSec + kMaxLatenessMicroSec) + * kNanosPerMicrosecond)); +} + +TEST(TestAudioClock, SleepUntilNanoTimeRealtime) { + + int64_t startNanos = AudioClock::getNanoseconds(CLOCK_REALTIME); + AudioClock::sleepUntilNanoTime(startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond, CLOCK_REALTIME); + int64_t endNanos = AudioClock::getNanoseconds(CLOCK_REALTIME); + ASSERT_GE(endNanos, startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond); + ASSERT_LT(endNanos, startNanos + ((kSleepTimeMicroSec + kMaxLatenessMicroSec) + * kNanosPerMicrosecond)); +} + +TEST(TestAudioClock, SleepForNanosMonotonic) { + + int64_t startNanos = AudioClock::getNanoseconds(CLOCK_MONOTONIC); + AudioClock::sleepForNanos(kSleepTimeMicroSec * kNanosPerMicrosecond, CLOCK_MONOTONIC); + int64_t endNanos = AudioClock::getNanoseconds(CLOCK_MONOTONIC); + ASSERT_GE(endNanos, startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond); + ASSERT_LT(endNanos, startNanos + ((kSleepTimeMicroSec + kMaxLatenessMicroSec) + * kNanosPerMicrosecond)); +} + +TEST(TestAudioClock, SleepForNanosRealtime) { + + int64_t startNanos = AudioClock::getNanoseconds(CLOCK_REALTIME); + AudioClock::sleepForNanos(kSleepTimeMicroSec * kNanosPerMicrosecond, CLOCK_REALTIME); + int64_t endNanos = AudioClock::getNanoseconds(CLOCK_REALTIME); + ASSERT_GE(endNanos, startNanos + kSleepTimeMicroSec * kNanosPerMicrosecond); + ASSERT_LT(endNanos, startNanos + ((kSleepTimeMicroSec + kMaxLatenessMicroSec) + * kNanosPerMicrosecond)); +}