diff --git a/frameworks/native/offlineaudioeffect/include/offline_audio_effect_server_chain.h b/frameworks/native/offlineaudioeffect/include/offline_audio_effect_server_chain.h index d16010918fcecbe35067e102ff5ffd8f9b180f30..24eb1034b6872f0177abbd3a445ea291aaea3953 100644 --- a/frameworks/native/offlineaudioeffect/include/offline_audio_effect_server_chain.h +++ b/frameworks/native/offlineaudioeffect/include/offline_audio_effect_server_chain.h @@ -72,8 +72,8 @@ private: uint32_t inBufferSize_ = 0; uint32_t outBufferSize_ = 0; string chainName_; - mutex offlineChainMutex_; OfflineEffectIOConfig offlineConfig_ = {}; + bool firstProcess_ = false; FILE *dumpFileIn_ = nullptr; FILE *dumpFileOut_ = nullptr; }; diff --git a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_server_chain.cpp b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_server_chain.cpp index 16f64af0e9437bffba087f7b82fbd2eabab43ff9..e1f37e6c6ccdff3f97d934c0b2ab8387d2facdd9 100644 --- a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_server_chain.cpp +++ b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_server_chain.cpp @@ -162,7 +162,6 @@ int32_t OfflineAudioEffectServerChain::Create() int8_t output[MAX_REPLY_LEN] = {0}; uint32_t replyLen = MAX_REPLY_LEN; - std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(controller_, ERROR, "enable failed, controller is nullptr"); ret = controller_->SendCommand(controller_, AUDIO_EFFECT_COMMAND_ENABLE, static_cast(input), MAX_CMD_LEN, output, &replyLen); @@ -182,7 +181,6 @@ int32_t OfflineAudioEffectServerChain::SetConfig(AudioStreamInfo inInfo, AudioSt AUDIO_INFO_LOG("%{public}d %{public}d %{public}hhu %{public}hhu %{public}" PRIu64 " OutStreamInfo set", outInfo.samplingRate, outInfo.encoding, outInfo.format, outInfo.channels, outInfo.channelLayout); - std::lock_guard lock(offlineChainMutex_); offlineConfig_.inputCfg = {inInfo.samplingRate, inInfo.channels, inInfo.format}; offlineConfig_.outputCfg = {outInfo.samplingRate, outInfo.channels, outInfo.format}; @@ -206,7 +204,6 @@ int32_t OfflineAudioEffectServerChain::SetParam(const std::vector ¶ { CHECK_AND_RETURN_RET_LOG(param.size() < PARAM_MAX_SIZE, ERROR, "set param failed, param size %{public}zu is too large", param.size()); - std::lock_guard lock(offlineChainMutex_); std::vector myParam = param; int8_t output[MAX_REPLY_LEN] = {0}; uint32_t replyLen = MAX_REPLY_LEN; @@ -220,7 +217,6 @@ int32_t OfflineAudioEffectServerChain::SetParam(const std::vector ¶ int32_t OfflineAudioEffectServerChain::GetEffectBufferSize(uint32_t &inBufferSize, uint32_t &outBufferSize) { - std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(inBufferSize_ != 0, ERROR, "inBufferSize_ do not init"); CHECK_AND_RETURN_RET_LOG(outBufferSize_ != 0, ERROR, "inBufferSize_ do not init"); inBufferSize = inBufferSize_; @@ -233,16 +229,29 @@ int32_t OfflineAudioEffectServerChain::GetEffectBufferSize(uint32_t &inBufferSiz int32_t OfflineAudioEffectServerChain::Prepare(const std::shared_ptr &bufferIn, const std::shared_ptr &bufferOut) { - std::lock_guard lock(offlineChainMutex_); serverBufferIn_ = bufferIn; serverBufferOut_ = bufferOut; + int8_t input[MAX_REPLY_LEN] = {0}; + int8_t output[MAX_REPLY_LEN] = {0}; + uint32_t replyLen = MAX_REPLY_LEN; + + if (controller_) { + int32_t ret = controller_->SendCommand(controller_, AUDIO_EFFECT_COMMAND_RESET, + input, MAX_REPLY_LEN, output, &replyLen); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("%{public}s effect COMMAND_RESET failed, errCode is %{public}d", chainName_.c_str(), ret); + } else { + firstProcess_ = 0; + } + } else { + AUDIO_ERR_LOG("reset failed, controller is nullptr"); + } AUDIO_INFO_LOG("Prepare in server done"); return SUCCESS; } int32_t OfflineAudioEffectServerChain::Process(uint32_t inSize, uint32_t outSize) { - std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(serverBufferIn_ && serverBufferIn_->GetBase(), ERROR, "serverBufferIn_ is nullptr"); CHECK_AND_RETURN_RET_LOG(serverBufferOut_ && serverBufferOut_->GetBase(), ERROR, "serverBufferOut_ is nullptr"); @@ -267,6 +276,7 @@ int32_t OfflineAudioEffectServerChain::Process(uint32_t inSize, uint32_t outSize ret = memcpy_s(reinterpret_cast(serverBufferOut_->GetBase()), outSize, output.rawData, output.frameCount * GetFormatByteSize(offlineConfig_.outputCfg.format)); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "memcpy failed, ret:%{public}d", ret); + firstProcess_ = true; FreeIfNotNull(output.rawData); DumpFileUtil::WriteDumpFile(dumpFileOut_, serverBufferOut_->GetBase(), outSize); @@ -278,7 +288,6 @@ int32_t OfflineAudioEffectServerChain::Release() auto model = InitEffectModel(); CHECK_AND_RETURN_RET_LOG(model, ERROR, "model is nullptr"); - std::lock_guard lock(offlineChainMutex_); int32_t ret = model->DestroyEffectController(model, &controllerId_); controller_ = nullptr; CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, diff --git a/frameworks/native/offlineaudioeffect/test/unittest/offline_audio_effect_manager_unit_test.cpp b/frameworks/native/offlineaudioeffect/test/unittest/offline_audio_effect_manager_unit_test.cpp index 3953b3ceba3a3c6c44edabcecd1b2bf9921d3be0..ee95ad92194e8f6eb174aa66209cb9755f5430b2 100644 --- a/frameworks/native/offlineaudioeffect/test/unittest/offline_audio_effect_manager_unit_test.cpp +++ b/frameworks/native/offlineaudioeffect/test/unittest/offline_audio_effect_manager_unit_test.cpp @@ -118,6 +118,12 @@ int32_t SendCommand(struct IEffectControl *self, uint32_t cmdId, const int8_t* c return SUCCESS; } +int32_t SendCommandError(struct IEffectControl *self, uint32_t cmdId, const int8_t* cmdData, uint32_t cmdDataLen, + int8_t* replyData, uint32_t* replyDataLen) +{ + return ERROR; +} + int32_t GetEffectDescriptor(struct IEffectControl *self, struct EffectControllerDescriptor* desc) { return SUCCESS; @@ -189,13 +195,36 @@ class OfflineAudioEffectServerChainUnitTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); - void SetUp(); - void TearDown(); + void SetUp() override; + void TearDown() override; + std::shared_ptr serverChain = nullptr; + IEffectControl *mockControl = nullptr; }; void OfflineAudioEffectServerChainUnitTest::SetUpTestCase(void) {} void OfflineAudioEffectServerChainUnitTest::TearDownTestCase(void) {} -void OfflineAudioEffectServerChainUnitTest::SetUp(void) {} -void OfflineAudioEffectServerChainUnitTest::TearDown(void) {} + +void OfflineAudioEffectServerChainUnitTest::SetUp(void) +{ + serverChain = std::make_shared("test"); + + if (!mockControl) { + mockControl = new IEffectControl(); + } + mockControl->EffectProcess = EffectProcess; + mockControl->SendCommand = SendCommand; + mockControl->GetEffectDescriptor = GetEffectDescriptor; + mockControl->EffectReverse = EffectReverse; + mockControl->GetVersion = GetVersion; +} + +void OfflineAudioEffectServerChainUnitTest::TearDown(void) +{ + if (mockControl) { + delete mockControl; + mockControl = nullptr; + } + serverChain.reset(); +} /** * @tc.name : Test GetOfflineAudioEffectChains API * @tc.type : FUNC @@ -291,24 +320,12 @@ HWTEST_F(OfflineAudioEffectChainUnitTest, OfflineAudioEffectChain_004, TestSize. HWTEST_F(OfflineAudioEffectServerChainUnitTest, Create_001, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); - IEffectControl *mockControl = new IEffectControl(); - mockControl->EffectProcess = EffectProcess; - mockControl->SendCommand = SendCommand; - mockControl->GetEffectDescriptor = GetEffectDescriptor; - mockControl->EffectReverse = EffectReverse; - mockControl->GetVersion = GetVersion; - serverChain->controller_=mockControl; int32_t ret = serverChain->Create(); EXPECT_EQ(ret, ERROR); } HWTEST_F(OfflineAudioEffectServerChainUnitTest, SetConfig_001, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); - AudioStreamInfo inInfo; inInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_44100; inInfo.encoding = AudioEncodingType::ENCODING_PCM; @@ -322,40 +339,24 @@ HWTEST_F(OfflineAudioEffectServerChainUnitTest, SetConfig_001, TestSize.Level1) int32_t ret = serverChain->SetConfig(inInfo, outInfo); EXPECT_EQ(ret, ERROR); - IEffectControl *mockControl = new IEffectControl(); - mockControl->EffectProcess = EffectProcess; - mockControl->SendCommand = SendCommand; - mockControl->GetEffectDescriptor = GetEffectDescriptor; - mockControl->EffectReverse = EffectReverse; - mockControl->GetVersion = GetVersion; - serverChain->controller_=mockControl; + serverChain->controller_ = mockControl; ret = serverChain->SetConfig(inInfo, outInfo); EXPECT_EQ(ret, SUCCESS); } HWTEST_F(OfflineAudioEffectServerChainUnitTest, SetParam_001, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); std::vector param(0); int32_t ret = serverChain->SetParam(param); EXPECT_EQ(ret, ERROR); - IEffectControl *mockControl = new IEffectControl(); - mockControl->EffectProcess = EffectProcess; - mockControl->SendCommand = SendCommand; - mockControl->GetEffectDescriptor = GetEffectDescriptor; - mockControl->EffectReverse = EffectReverse; - mockControl->GetVersion = GetVersion; - serverChain->controller_=mockControl; + serverChain->controller_ = mockControl; ret = serverChain->SetParam(param); EXPECT_EQ(ret, SUCCESS); } HWTEST_F(OfflineAudioEffectServerChainUnitTest, GetEffectBufferSize_001, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); uint32_t inBufferSize; uint32_t outBufferSize; int32_t ret = serverChain->GetEffectBufferSize(inBufferSize, outBufferSize); @@ -364,8 +365,6 @@ HWTEST_F(OfflineAudioEffectServerChainUnitTest, GetEffectBufferSize_001, TestSiz HWTEST_F(OfflineAudioEffectServerChainUnitTest, GetEffectBufferSize_002, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); serverChain->inBufferSize_= 1; uint32_t inBufferSize; uint32_t outBufferSize; @@ -375,8 +374,6 @@ HWTEST_F(OfflineAudioEffectServerChainUnitTest, GetEffectBufferSize_002, TestSiz HWTEST_F(OfflineAudioEffectServerChainUnitTest, GetEffectBufferSize_003, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); serverChain->inBufferSize_ = 1; serverChain->outBufferSize_ = 1; uint32_t inBufferSize; @@ -385,18 +382,23 @@ HWTEST_F(OfflineAudioEffectServerChainUnitTest, GetEffectBufferSize_003, TestSiz EXPECT_EQ(ret, SUCCESS); } -HWTEST_F(OfflineAudioEffectServerChainUnitTest, Release_001, TestSize.Level1) +HWTEST_F(OfflineAudioEffectServerChainUnitTest, Prepare_001, TestSize.Level1) { - std::shared_ptr serverChain = - std::make_shared("test"); - - IEffectControl *mockControl = new IEffectControl(); - mockControl->EffectProcess = EffectProcess; + serverChain->firstProcess_ = true; + serverChain->Prepare(nullptr, nullptr); + EXPECT_EQ(serverChain->firstProcess_, true); + serverChain->controller_ = mockControl; + mockControl->SendCommand = SendCommandError; + serverChain->Prepare(nullptr, nullptr); + EXPECT_EQ(serverChain->firstProcess_, true); mockControl->SendCommand = SendCommand; - mockControl->GetEffectDescriptor = GetEffectDescriptor; - mockControl->EffectReverse = EffectReverse; - mockControl->GetVersion = GetVersion; - serverChain->controller_=mockControl; + int32_t ret = serverChain->Prepare(nullptr, nullptr); + EXPECT_EQ(serverChain->firstProcess_, false); + EXPECT_EQ(ret, SUCCESS); +} + +HWTEST_F(OfflineAudioEffectServerChainUnitTest, Release_001, TestSize.Level1) +{ int32_t ret = serverChain->Release(); EXPECT_EQ(ret, ERROR); } diff --git a/services/audio_engine/node/src/hpae_sink_input_node.cpp b/services/audio_engine/node/src/hpae_sink_input_node.cpp index 67af1fe9712d1eae7c3dd184db94693912d7be4a..d054c804295fa2b8ab43cfa5bc2b8cd6dd562547 100644 --- a/services/audio_engine/node/src/hpae_sink_input_node.cpp +++ b/services/audio_engine/node/src/hpae_sink_input_node.cpp @@ -305,7 +305,8 @@ float HpaeSinkInputNode::GetSpeed() uint64_t HpaeSinkInputNode::GetLatency() { - return historyBuffer_ ? historyBuffer_->GetCurFrames() * GetFrameLen() : 0; + uint64_t samples = historyBuffer_ ? historyBuffer_->GetCurFrames() * GetFrameLen() : 0; + return samples * AUDIO_US_PER_SECOND / GetSampleRate(); } int32_t HpaeSinkInputNode::OnStreamInfoChange(bool isPullData) diff --git a/services/audio_service/server/include/offline_stream_in_server.h b/services/audio_service/server/include/offline_stream_in_server.h index 3cda7fa6a6691af213b8b760e63c7886c7bde79b..7114d1f1a9af20f2253fdfae271f73f88b9976b4 100644 --- a/services/audio_service/server/include/offline_stream_in_server.h +++ b/services/audio_service/server/include/offline_stream_in_server.h @@ -53,6 +53,7 @@ private: std::shared_ptr serverBufferOut_; #ifdef FEATURE_OFFLINE_EFFECT std::shared_ptr effectChain_; + std::mutex offlineChainMutex_; #endif }; } // namespace AudioStandard diff --git a/services/audio_service/server/src/offline_stream_in_server.cpp b/services/audio_service/server/src/offline_stream_in_server.cpp index 1ee9172f3312776a5e3f7db70bf9111bc22f551b..9ef32ce79a4c67d7dc5acc7797792c4810b33182 100644 --- a/services/audio_service/server/src/offline_stream_in_server.cpp +++ b/services/audio_service/server/src/offline_stream_in_server.cpp @@ -45,6 +45,7 @@ int32_t OfflineStreamInServer::GetOfflineAudioEffectChains(std::vector lock(offlineChainMutex_); effectChain_ = std::make_shared(chainName); return effectChain_->Create(); } @@ -54,12 +55,14 @@ int32_t OfflineStreamInServer::ConfigureOfflineEffectChain(const AudioStreamInfo { CHECK_AND_RETURN_RET_LOG(CheckSupportedParams(inInfo) == SUCCESS, ERR_INVALID_PARAM, "inInfo do not support"); CHECK_AND_RETURN_RET_LOG(CheckSupportedParams(outInfo) == SUCCESS, ERR_INVALID_PARAM, "outInfo do not support"); + std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(effectChain_, ERR_ILLEGAL_STATE, "effectChain not init"); return effectChain_->SetConfig(inInfo, outInfo); } int32_t OfflineStreamInServer::SetParamOfflineEffectChain(const std::vector ¶m) { + std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(effectChain_, ERR_ILLEGAL_STATE, "effectChain not init"); return effectChain_->SetParam(param); } @@ -67,6 +70,7 @@ int32_t OfflineStreamInServer::SetParamOfflineEffectChain(const std::vector &inBuffer, std::shared_ptr &outBuffer) { + std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(effectChain_, ERR_ILLEGAL_STATE, "effectChain not init"); if (serverBufferIn_ == nullptr || serverBufferOut_ == nullptr) { uint32_t inSize = 0; @@ -82,12 +86,14 @@ int32_t OfflineStreamInServer::PrepareOfflineEffectChain(std::shared_ptr lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(effectChain_, ERR_ILLEGAL_STATE, "effectChain not init"); return effectChain_->Process(inSize, outSize); } int32_t OfflineStreamInServer::ReleaseOfflineEffectChain() { + std::lock_guard lock(offlineChainMutex_); CHECK_AND_RETURN_RET_LOG(effectChain_, ERR_ILLEGAL_STATE, "effectChain not init"); effectChain_->Release(); return SUCCESS;