diff --git a/common/include/daudio_latency_test.h b/common/include/daudio_latency_test.h new file mode 100644 index 0000000000000000000000000000000000000000..42e62167a26761b444eb7ec454dc58dacfc40c4a --- /dev/null +++ b/common/include/daudio_latency_test.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OHOS_DAUDIO_LATENCY_TEST_H +#define OHOS_DAUDIO_LATENCY_TEST_H + +#include + +#include "single_instance.h" +namespace OHOS { +namespace DistributedHardware { +class DAudioLatencyTest { +DECLARE_SINGLE_INSTANCE_BASE(DAudioLatencyTest); +public: + int32_t AddPlayTime(const int64_t playBeepTime); + int32_t AddRecordTime(const int64_t recordBeepTime); + int64_t GetNowTimeUs(); + int64_t RecordBeepTime(const uint8_t *base, const int32_t &sizePerFrame, bool &status); + bool IsFrameHigh(const int16_t *audioData, const int32_t size, int32_t threshhold); + int32_t ComputeLatency(); + +private: + DAudioLatencyTest(); + ~DAudioLatencyTest(); + +private: + constexpr static int32_t TWO_BEEP_TIME_INTERVAL = 900000; // 900ms + constexpr static int32_t BEEP_THRESHHOLD = 8000; + constexpr static int32_t US_PER_MS = 1000; + std::vector playBeepTime_; + std::vector captureBeepTime_; + int64_t lastPlayTime_ = 0; + int64_t lastRecordTime_ = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/common/src/daudio_latency_test.cpp b/common/src/daudio_latency_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a29b7e488aeb73c749dfe353d2aa5db8cfb0791 --- /dev/null +++ b/common/src/daudio_latency_test.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#include "daudio_latency_test.h" +#include "daudio_log.h" + +#include +#include + +#undef DH_LOG_TAG +#define DH_LOG_TAG "DAudioLatencyTest" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DAudioLatencyTest); +DAudioLatencyTest::DAudioLatencyTest() +{ + DHLOGI("DAudioLatencyTest constructed."); +} + +DAudioLatencyTest::~DAudioLatencyTest() +{ + DHLOGI("DAudioLatencyTest deconstructed."); +} + +int32_t DAudioLatencyTest::AddPlayTime(const int64_t playBeepTime) +{ + if (GetNowTimeUs() - lastPlayTime_ <= TWO_BEEP_TIME_INTERVAL) { + DHLOGE("Catch play high frame, but not in 900ms."); + return -1; + } + DHLOGI("Catch play high frame, playTime: %lld.", playBeepTime); + playBeepTime_.push_back(playBeepTime); + lastPlayTime_ = GetNowTimeUs(); + return 0; +} + +int32_t DAudioLatencyTest::AddRecordTime(const int64_t recordBeepTime) +{ + if (captureBeepTime_.size() >= playBeepTime_.size()) { + DHLOGE("Catch record high frame, but capturesize >= playsize."); + return -1; + } + if (GetNowTimeUs() - lastRecordTime_ <= TWO_BEEP_TIME_INTERVAL) { + DHLOGE("Catch record high frame, but not in 900ms."); + return -1; + } + DHLOGI("Catch record high frame, recordTime: %lld.", recordBeepTime); + captureBeepTime_.push_back(recordBeepTime); + lastRecordTime_ = GetNowTimeUs(); + return 0; +} + +int64_t DAudioLatencyTest::GetNowTimeUs() +{ + std::chrono::microseconds nowUs = + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + return nowUs.count(); +} + +bool DAudioLatencyTest::IsFrameHigh(const int16_t *audioData, const int32_t size, int32_t threshhold) +{ + int32_t max = 0; + for (int32_t i = 0; i < size; i++) { + int16_t f = abs(audioData[i]); + if (f > max) { + max = f; + } + } + return (max >= threshhold) ? true : false; +} + +int64_t DAudioLatencyTest::RecordBeepTime(const uint8_t *base, const int32_t &sizePerFrame, bool &status) +{ + int32_t threshhold = BEEP_THRESHHOLD; + if (IsFrameHigh((int16_t *)base, sizePerFrame / sizeof(int16_t), threshhold) == true && + status == true) { + status = false; + return GetNowTimeUs(); + } else if (IsFrameHigh((int16_t *)base, sizePerFrame / sizeof(int16_t), threshhold) == false) { + status = true; + } + return 0; +} + +int32_t DAudioLatencyTest::ComputeLatency() +{ + DHLOGD("Compute latency time."); + int32_t playSize = playBeepTime_.size(); + if (playSize == 0 || playBeepTime_.size() != captureBeepTime_.size()) { + DHLOGE("Record num is not equal <%d, %d>", playSize, captureBeepTime_.size()); + return -1; + } + DHLOGI("Record %d times frame high.", playSize); + int32_t sum = 0; + for (int32_t i = 0; i < playSize; i++) { + DHLOGI("Send: %lld, Received: %lld", playBeepTime_[i], captureBeepTime_[i]); + DHLOGI("Time is: %d ms.", (captureBeepTime_[i] - playBeepTime_[i]) / US_PER_MS); + sum += captureBeepTime_[i] - playBeepTime_[i]; + } + DHLOGI("Audio latency in average is: %d us.", sum / playSize); + playBeepTime_.clear(); + captureBeepTime_.clear(); + return sum / playSize; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/common/BUILD.gn b/services/common/BUILD.gn index 1f76499d311f7d12722884c2f27a15493ca93fc8..942d2054edfce64076ee75bae87df619c6b73048 100644 --- a/services/common/BUILD.gn +++ b/services/common/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. # 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 @@ -43,6 +43,7 @@ ohos_shared_library("distributed_audio_utils") { sources = [ "${common_path}/dfx_utils/src/daudio_hisysevent.cpp", "${common_path}/dfx_utils/src/daudio_hitrace.cpp", + "${common_path}/src/daudio_latency_test.cpp", "${common_path}/src/daudio_log.cpp", "${common_path}/src/daudio_util.cpp", "audiodata/src/audio_data.cpp", diff --git a/services/common/test/unittest/audiodata/include/daudio_latency_unit_test.h b/services/common/test/unittest/audiodata/include/daudio_latency_unit_test.h new file mode 100644 index 0000000000000000000000000000000000000000..5a988c8a746c5d6da70e71140dd94905c8f29b41 --- /dev/null +++ b/services/common/test/unittest/audiodata/include/daudio_latency_unit_test.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OHOS_DAUDIO_LATENCY_UNIT_TEST_H +#define OHOS_DAUDIO_LATENCY_UNIT_TEST_H + +#include +#include + +#include "daudio_latency_test.h" + +namespace OHOS { +namespace DistributedHardware { +class DAudioLatencyUnitTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DAUDIO_LATENCY_UNIT_TEST_H \ No newline at end of file diff --git a/services/common/test/unittest/audiodata/src/daudio_latency_unit_test.cpp b/services/common/test/unittest/audiodata/src/daudio_latency_unit_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..011c22e34fae21b18a531cd7978ccbfe51d0c51c --- /dev/null +++ b/services/common/test/unittest/audiodata/src/daudio_latency_unit_test.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 private public +#include "audio_data_test.h" +#undef private + +#include "daudio_constants.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void DAudioLatencyUnitTest::SetUpTestCase(void) {} + +void DAudioLatencyUnitTest::TearDownTestCase(void) {} + +void DAudioLatencyUnitTest::SetUp(void) {} + +void DAudioLatencyUnitTest::TearDown(void) {} + +/** + * @tc.name: AddPlayRecordTime_001 + * @tc.desc: Verify the AddPlayTime & Add RecordTime function. + * @tc.type: FUNC + * @tc.require: AR000H0E5U + */ +HWTEST_F(DAudioLatencyUnitTest, AddPlayRecordTime_001, TestSize.Level1) +{ + int64_t t = DAudioLatencyTest::GetInstance()->GetNowTimeUs(); + int ret = DAudioLatencyTest::GetInstance()->AddPlayTime(t); + EXPECT_EQ(0, ret); + t = DAudioLatencyTest::GetInstance()->GetNowTimeUs(); + ret = DAudioLatencyTest::GetInstance()->AddRecordTime(t); + EXPECT_EQ(0, ret); + int latency = DAudioLatencyTest::GetInstance()->ComputeLatency(); + EXPECT_LE(0, latency); +} +} // namespace DistributedHardware +} // namespace OHOS