150a07fd2Sopenharmony_ci/* 250a07fd2Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 350a07fd2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 450a07fd2Sopenharmony_ci * you may not use this file except in compliance with the License. 550a07fd2Sopenharmony_ci * You may obtain a copy of the License at 650a07fd2Sopenharmony_ci * 750a07fd2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 850a07fd2Sopenharmony_ci * 950a07fd2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1050a07fd2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1150a07fd2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1250a07fd2Sopenharmony_ci * See the License for the specific language governing permissions and 1350a07fd2Sopenharmony_ci * limitations under the License. 1450a07fd2Sopenharmony_ci */ 1550a07fd2Sopenharmony_ci 1650a07fd2Sopenharmony_ci#include "daudio_latency_test.h" 1750a07fd2Sopenharmony_ci 1850a07fd2Sopenharmony_ci#include <ctime> 1950a07fd2Sopenharmony_ci#include <string> 2050a07fd2Sopenharmony_ci 2150a07fd2Sopenharmony_ci#include "daudio_errorcode.h" 2250a07fd2Sopenharmony_ci#include "daudio_log.h" 2350a07fd2Sopenharmony_ci#include "daudio_util.h" 2450a07fd2Sopenharmony_ci 2550a07fd2Sopenharmony_ci#undef DH_LOG_TAG 2650a07fd2Sopenharmony_ci#define DH_LOG_TAG "DAudioLatencyTest" 2750a07fd2Sopenharmony_cinamespace OHOS { 2850a07fd2Sopenharmony_cinamespace DistributedHardware { 2950a07fd2Sopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(DAudioLatencyTest); 3050a07fd2Sopenharmony_ciconstexpr int32_t MAXSIZE = 8192; 3150a07fd2Sopenharmony_ci 3250a07fd2Sopenharmony_ciDAudioLatencyTest::DAudioLatencyTest() 3350a07fd2Sopenharmony_ci{ 3450a07fd2Sopenharmony_ci DHLOGI("DAudioLatencyTest constructed."); 3550a07fd2Sopenharmony_ci} 3650a07fd2Sopenharmony_ci 3750a07fd2Sopenharmony_ciDAudioLatencyTest::~DAudioLatencyTest() 3850a07fd2Sopenharmony_ci{ 3950a07fd2Sopenharmony_ci DHLOGI("DAudioLatencyTest deconstructed."); 4050a07fd2Sopenharmony_ci} 4150a07fd2Sopenharmony_ci 4250a07fd2Sopenharmony_ciint32_t DAudioLatencyTest::AddPlayTime(const int64_t playBeepTime) 4350a07fd2Sopenharmony_ci{ 4450a07fd2Sopenharmony_ci if (GetNowTimeUs() - lastPlayTime_ <= TWO_BEEP_TIME_INTERVAL) { 4550a07fd2Sopenharmony_ci DHLOGE("Catch play high frame, but not in %{public}d ms.", TWO_BEEP_TIME_INTERVAL); 4650a07fd2Sopenharmony_ci return ERR_DH_AUDIO_FAILED; 4750a07fd2Sopenharmony_ci } 4850a07fd2Sopenharmony_ci DHLOGI("Catch play high frame, playTime: %{public}" PRId64, playBeepTime); 4950a07fd2Sopenharmony_ci playBeepTime_.push_back(playBeepTime); 5050a07fd2Sopenharmony_ci lastPlayTime_ = GetNowTimeUs(); 5150a07fd2Sopenharmony_ci return DH_SUCCESS; 5250a07fd2Sopenharmony_ci} 5350a07fd2Sopenharmony_ci 5450a07fd2Sopenharmony_ciint32_t DAudioLatencyTest::AddRecordTime(const int64_t recordBeepTime) 5550a07fd2Sopenharmony_ci{ 5650a07fd2Sopenharmony_ci if (captureBeepTime_.size() >= playBeepTime_.size()) { 5750a07fd2Sopenharmony_ci DHLOGE("Catch record high frame size error, capturesize %{public}zu, playsize %{public}zu.", 5850a07fd2Sopenharmony_ci captureBeepTime_.size(), playBeepTime_.size()); 5950a07fd2Sopenharmony_ci return ERR_DH_AUDIO_BAD_VALUE; 6050a07fd2Sopenharmony_ci } 6150a07fd2Sopenharmony_ci if (GetNowTimeUs() - lastRecordTime_ <= TWO_BEEP_TIME_INTERVAL) { 6250a07fd2Sopenharmony_ci DHLOGE("Catch record high frame, but not in %{public}d ms.", TWO_BEEP_TIME_INTERVAL); 6350a07fd2Sopenharmony_ci return ERR_DH_AUDIO_FAILED; 6450a07fd2Sopenharmony_ci } 6550a07fd2Sopenharmony_ci DHLOGI("Catch record high frame, recordTime: %{public}" PRId64, recordBeepTime); 6650a07fd2Sopenharmony_ci captureBeepTime_.push_back(recordBeepTime); 6750a07fd2Sopenharmony_ci lastRecordTime_ = GetNowTimeUs(); 6850a07fd2Sopenharmony_ci return DH_SUCCESS; 6950a07fd2Sopenharmony_ci} 7050a07fd2Sopenharmony_ci 7150a07fd2Sopenharmony_cibool DAudioLatencyTest::IsFrameHigh(const int16_t *audioData, const int32_t size, int32_t threshhold) 7250a07fd2Sopenharmony_ci{ 7350a07fd2Sopenharmony_ci if (size > MAXSIZE) { 7450a07fd2Sopenharmony_ci DHLOGI("size=%{public}d is over range", size); 7550a07fd2Sopenharmony_ci return false; 7650a07fd2Sopenharmony_ci } 7750a07fd2Sopenharmony_ci int32_t max = 0; 7850a07fd2Sopenharmony_ci for (int32_t i = 0; i < size; i++) { 7950a07fd2Sopenharmony_ci int16_t f = abs(audioData[i]); 8050a07fd2Sopenharmony_ci if (f > max) { 8150a07fd2Sopenharmony_ci max = f; 8250a07fd2Sopenharmony_ci } 8350a07fd2Sopenharmony_ci } 8450a07fd2Sopenharmony_ci return (max >= threshhold) ? true : false; 8550a07fd2Sopenharmony_ci} 8650a07fd2Sopenharmony_ci 8750a07fd2Sopenharmony_ciint64_t DAudioLatencyTest::RecordBeepTime(const uint8_t *base, const int32_t &sizePerFrame, bool &status) 8850a07fd2Sopenharmony_ci{ 8950a07fd2Sopenharmony_ci int32_t threshhold = BEEP_THRESHHOLD; 9050a07fd2Sopenharmony_ci bool isHigh = IsFrameHigh(reinterpret_cast<int16_t *>(const_cast<uint8_t *>(base)), 9150a07fd2Sopenharmony_ci sizePerFrame / sizeof(int16_t), threshhold); 9250a07fd2Sopenharmony_ci if (isHigh && status) { 9350a07fd2Sopenharmony_ci status = false; 9450a07fd2Sopenharmony_ci return GetNowTimeUs(); 9550a07fd2Sopenharmony_ci } else if (!isHigh) { 9650a07fd2Sopenharmony_ci status = true; 9750a07fd2Sopenharmony_ci } 9850a07fd2Sopenharmony_ci return 0; 9950a07fd2Sopenharmony_ci} 10050a07fd2Sopenharmony_ci 10150a07fd2Sopenharmony_ciint32_t DAudioLatencyTest::ComputeLatency() 10250a07fd2Sopenharmony_ci{ 10350a07fd2Sopenharmony_ci DHLOGD("Compute latency time."); 10450a07fd2Sopenharmony_ci int32_t playSize = static_cast<int32_t>(playBeepTime_.size()); 10550a07fd2Sopenharmony_ci int32_t captureSize = static_cast<int32_t>(captureBeepTime_.size()); 10650a07fd2Sopenharmony_ci if (playSize == 0 || playBeepTime_.size() != captureBeepTime_.size()) { 10750a07fd2Sopenharmony_ci DHLOGE("Record num is not equal %{public}d: %{public}d", playSize, captureSize); 10850a07fd2Sopenharmony_ci return -1; 10950a07fd2Sopenharmony_ci } 11050a07fd2Sopenharmony_ci DHLOGI("Record %{public}d times frame high.", playSize); 11150a07fd2Sopenharmony_ci int32_t sum = 0; 11250a07fd2Sopenharmony_ci for (int32_t i = 0; i < playSize; i++) { 11350a07fd2Sopenharmony_ci DHLOGI("Send: %{public}" PRId64", Received: %{public}" PRId64, playBeepTime_[i], captureBeepTime_[i]); 11450a07fd2Sopenharmony_ci DHLOGI("Time is: %{public}" PRId64" ms.", (captureBeepTime_[i] - playBeepTime_[i]) / US_PER_MS); 11550a07fd2Sopenharmony_ci sum += captureBeepTime_[i] - playBeepTime_[i]; 11650a07fd2Sopenharmony_ci } 11750a07fd2Sopenharmony_ci DHLOGI("Audio latency in average is: %{public}d us.", sum / playSize); 11850a07fd2Sopenharmony_ci playBeepTime_.clear(); 11950a07fd2Sopenharmony_ci captureBeepTime_.clear(); 12050a07fd2Sopenharmony_ci return sum / playSize; 12150a07fd2Sopenharmony_ci} 12250a07fd2Sopenharmony_ci} // namespace DistributedHardware 12350a07fd2Sopenharmony_ci} // namespace OHOS 124