diff --git a/frameworks/native/offlineaudioeffect/include/offline_audio_effect_chain_impl.h b/frameworks/native/offlineaudioeffect/include/offline_audio_effect_chain_impl.h index 0376cf7b065fae0ef0c38eeabb1f9a72a2d42742..36c5d54af8353a1341453801a666fcfeb4a47682 100644 --- a/frameworks/native/offlineaudioeffect/include/offline_audio_effect_chain_impl.h +++ b/frameworks/native/offlineaudioeffect/include/offline_audio_effect_chain_impl.h @@ -41,15 +41,19 @@ public: ~OfflineAudioEffectChainImpl(); - int32_t InitIpcChain(); + int32_t CreateEffectChain(); private: + void InitDump(); + std::string chainName_; - std::shared_ptr offlineStreamInClient_; - std::shared_ptr clientBufferIn_; - std::shared_ptr clientBufferOut_; - uint8_t *inBufferBase_; - uint8_t *outBufferBase_; - std::shared_mutex bufferMutex_; + std::shared_ptr offlineStreamInClient_ = nullptr; + std::shared_ptr clientBufferIn_ = nullptr; + std::shared_ptr clientBufferOut_ = nullptr; + uint8_t *inBufferBase_ = nullptr; + uint8_t *outBufferBase_ = nullptr; + std::mutex streamClientMutex_; + FILE *dumpFileIn_ = nullptr; + FILE *dumpFileOut_ = nullptr; }; } // namespace AudioStandard } // namespace OHOS 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 42250fb5842fc77adc4f732398e9803ab8807f00..7059a6544a8568d5a4d1b06d49fca215fce10355 100644 --- a/frameworks/native/offlineaudioeffect/include/offline_audio_effect_server_chain.h +++ b/frameworks/native/offlineaudioeffect/include/offline_audio_effect_server_chain.h @@ -35,13 +35,23 @@ namespace OHOS { namespace AudioStandard { using namespace std; + +struct OfflineEffectConfig { + uint32_t samplingRate; + uint32_t channels; + uint32_t format; +}; + +struct OfflineEffectIOConfig { + OfflineEffectConfig inputCfg; + OfflineEffectConfig outputCfg; +}; + class OfflineAudioEffectServerChain { public: OfflineAudioEffectServerChain(const string &chainName); ~OfflineAudioEffectServerChain(); - static int32_t InitEffectModel(); - static int32_t ReleaseEffectModel(); static int32_t GetOfflineAudioEffectChains(vector &chainNamesVector); int32_t Create(); @@ -52,19 +62,19 @@ public: int32_t Release(); private: - int32_t SetDeviceType(const DeviceType deviceType); - int32_t SetRenderStreamUsage(const StreamUsage usage); - int32_t SetCapturerSourceType(const SourceType sourceType); - int32_t Configure(); + void InitDump(); - static struct IEffectModel *model_; - static struct EffectInfo info_; struct IEffectControl *controller_ = nullptr; - struct ControllerId *controllerId_ = nullptr; + struct ControllerId controllerId_ = {}; shared_ptr serverBufferIn_ = nullptr; shared_ptr serverBufferOut_ = nullptr; + uint32_t inBufferSize_ = 0; + uint32_t outBufferSize_ = 0; string chainName_; mutex offlineChainMutex_; + OfflineEffectIOConfig offlineConfig_ = {}; + FILE *dumpFileIn_ = nullptr; + FILE *dumpFileOut_ = nullptr; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_chain_impl.cpp b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_chain_impl.cpp index bf68effe2078d615564537d1b0bc7878a9f5cc3d..6214cf9229469382af66a58c9a1b3994ff7c2440 100644 --- a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_chain_impl.cpp +++ b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_chain_impl.cpp @@ -22,6 +22,7 @@ #include "audio_errors.h" #include "audio_service_log.h" +#include "audio_utils.h" namespace OHOS { namespace AudioStandard { @@ -37,21 +38,37 @@ OfflineAudioEffectChainImpl::~OfflineAudioEffectChainImpl() Release(); } -int32_t OfflineAudioEffectChainImpl::InitIpcChain() +void OfflineAudioEffectChainImpl::InitDump() { + static uint32_t chainId = 0; + std::string dumpFileName = "OfflineEffectClient"; + std::string dumpFileInName = dumpFileName + "_" + std::to_string(chainId) + "_In.pcm"; + std::string dumpFileOutName = dumpFileName + "_" + std::to_string(chainId) + "_Out.pcm"; + DumpFileUtil::OpenDumpFile(DUMP_CLIENT_PARA, dumpFileInName, &dumpFileIn_); + DumpFileUtil::OpenDumpFile(DUMP_CLIENT_PARA, dumpFileOutName, &dumpFileOut_); + chainId++; +} + +int32_t OfflineAudioEffectChainImpl::CreateEffectChain() +{ + std::lock_guard lock(streamClientMutex_); CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!"); - return offlineStreamInClient_->CreateOfflineEffectChain(chainName_); + int32_t ret = offlineStreamInClient_->CreateOfflineEffectChain(chainName_); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitIpcChainFailed!"); + InitDump(); + return SUCCESS; } int32_t OfflineAudioEffectChainImpl::Configure(const AudioStreamInfo &inInfo, const AudioStreamInfo &outInfo) { + std::lock_guard lock(streamClientMutex_); CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!"); return offlineStreamInClient_->ConfigureOfflineEffectChain(inInfo, outInfo); } int32_t OfflineAudioEffectChainImpl::GetEffectBufferSize(uint32_t &inBufferSize, uint32_t &outBufferSize) { - std::shared_lock lock(bufferMutex_); + std::lock_guard lock(streamClientMutex_); CHECK_AND_RETURN_RET_LOG(clientBufferIn_ && clientBufferOut_, ERR_ILLEGAL_STATE, "buffer not prepared"); inBufferSize = clientBufferIn_->GetSize(); outBufferSize = clientBufferOut_->GetSize(); @@ -60,8 +77,8 @@ int32_t OfflineAudioEffectChainImpl::GetEffectBufferSize(uint32_t &inBufferSize, int32_t OfflineAudioEffectChainImpl::Prepare() { + std::lock_guard lock(streamClientMutex_); CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!"); - std::lock_guard lock(bufferMutex_); int32_t ret = offlineStreamInClient_->PrepareOfflineEffectChain(clientBufferIn_, clientBufferOut_); inBufferBase_ = clientBufferIn_->GetBase(); outBufferBase_ = clientBufferOut_->GetBase(); @@ -70,8 +87,8 @@ int32_t OfflineAudioEffectChainImpl::Prepare() int32_t OfflineAudioEffectChainImpl::Process(uint8_t *inBuffer, int32_t inSize, uint8_t *outBuffer, int32_t outSize) { + std::lock_guard lock(streamClientMutex_); CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!"); - std::lock_guard lock(bufferMutex_); CHECK_AND_RETURN_RET_LOG(inBufferBase_ && outBufferBase_ && clientBufferIn_ && clientBufferOut_, ERR_ILLEGAL_STATE, "buffer not prepared"); int32_t inBufferSize = clientBufferIn_->GetSize(); @@ -79,26 +96,33 @@ int32_t OfflineAudioEffectChainImpl::Process(uint8_t *inBuffer, int32_t inSize, CHECK_AND_RETURN_RET_LOG(inSize > 0 && inSize <= inBufferSize && outSize > 0 && outSize <= outBufferSize, ERR_INVALID_PARAM, "buffer size invalid"); CHECK_AND_RETURN_RET_LOG(inBuffer && outBuffer, ERR_INVALID_PARAM, "buffer ptr invalid"); + + DumpFileUtil::WriteDumpFile(dumpFileIn_, inBufferBase_, inSize); + int32_t ret = memcpy_s(inBufferBase_, inBufferSize, inBuffer, inSize); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "memcpy inbuffer failed"); ret = offlineStreamInClient_->ProcessOfflineEffectChain(inSize, outSize); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "process effect failed"); ret = memcpy_s(outBuffer, outSize, outBufferBase_, outSize); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "memcpy outBuffer failed"); + + DumpFileUtil::WriteDumpFile(dumpFileOut_, outBufferBase_, outSize); return SUCCESS; } void OfflineAudioEffectChainImpl::Release() { - std::lock_guard lock(bufferMutex_); - clientBufferIn_ = nullptr; - clientBufferOut_ = nullptr; - inBufferBase_ = nullptr; - outBufferBase_ = nullptr; + std::lock_guard lock(streamClientMutex_); if (offlineStreamInClient_ != nullptr) { offlineStreamInClient_->ReleaseOfflineEffectChain(); offlineStreamInClient_ = nullptr; } + inBufferBase_ = nullptr; + outBufferBase_ = nullptr; + clientBufferIn_ = nullptr; + clientBufferOut_ = nullptr; + DumpFileUtil::CloseDumpFile(&dumpFileIn_); + DumpFileUtil::CloseDumpFile(&dumpFileOut_); } } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_manager.cpp b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_manager.cpp index f34d96ce51d65a7143db3e667be3b57c056e4059..6112401d1b71175ddc562c3f12b60ef106742ea9 100644 --- a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_manager.cpp +++ b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_manager.cpp @@ -38,7 +38,7 @@ std::unique_ptr OfflineAudioEffectManager::CreateOfflin const std::string &chainName) { std::unique_ptr chain = std::make_unique(chainName); - int32_t ret = chain->InitIpcChain(); + int32_t ret = chain->CreateEffectChain(); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, nullptr, "create OfflineEffectChain failed, errcode is %{public}d", ret); return chain; } 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 23ad7e3fa7785f28a87d962a395689d6dc833a40..80359eeb8868e9eb7d73b82623f39dbed0bd4406 100644 --- a/frameworks/native/offlineaudioeffect/src/offline_audio_effect_server_chain.cpp +++ b/frameworks/native/offlineaudioeffect/src/offline_audio_effect_server_chain.cpp @@ -20,101 +20,190 @@ #include #include +#include #include #include -#include +#include +#include #include #include "securec.h" #include "audio_common_log.h" #include "audio_errors.h" +#include "audio_utils.h" using namespace OHOS::AudioStandard; namespace OHOS { namespace AudioStandard { namespace { - constexpr size_t DEFAULT_BUFFER_SIZE = 7680 * 2; - constexpr uint32_t SEND_COMMAND_LEN = 10; - constexpr uint32_t GET_BUFFER_LEN = 10; - static const std::string LIBNAME = "offline_record_algo"; - static const std::string UUID = "a953e8d6-fb7c-4684-9dc2-78be1a995bb2"; +constexpr uint32_t MAX_DESCRIPTOR_NUM = 20; +constexpr uint32_t MAX_CMD_LEN = 10; +constexpr uint32_t MAX_REPLY_LEN = 10; +constexpr uint32_t MAX_TIME_INTERVAL_MS = 160; // ms +// key for effectName, value for (libName, effectId) +static std::map> g_chainName2infoMap; +static std::mutex g_chainMutex; } -struct IEffectModel *OfflineAudioEffectServerChain::model_; -struct EffectInfo OfflineAudioEffectServerChain::info_; +template +static inline void FreeIfNotNull(T*& ptr) +{ + if (ptr != nullptr) { + free(ptr); + ptr = nullptr; + } +} + +static inline int32_t GetByteSize(AudioSampleFormat format) +{ + static const std::unordered_map sizeMap = { + {SAMPLE_U8, 1}, + {SAMPLE_S16LE, 2}, + {SAMPLE_S24LE, 3}, + {SAMPLE_S32LE, 4}, + {SAMPLE_F32LE, 4} + }; + + auto it = sizeMap.find(format); + return (it != sizeMap.end()) ? it->second : 2; // Default size is 2 +} OfflineAudioEffectServerChain::OfflineAudioEffectServerChain(const std::string &chainName) : chainName_(chainName) {} OfflineAudioEffectServerChain::~OfflineAudioEffectServerChain() { - controller_ = nullptr; - controllerId_ = nullptr; + if (controller_) { + Release(); + } + FreeIfNotNull(controllerId_.libName); + FreeIfNotNull(controllerId_.effectId); serverBufferIn_ = nullptr; serverBufferOut_ = nullptr; + DumpFileUtil::CloseDumpFile(&dumpFileIn_); + DumpFileUtil::CloseDumpFile(&dumpFileOut_); } - -int32_t OfflineAudioEffectServerChain::InitEffectModel() + +static struct IEffectModel *InitEffectModel() { - model_ = IEffectModelGet(false); - info_.libName = strdup(LIBNAME.c_str()); - info_.effectId = strdup(UUID.c_str()); - info_.ioDirection = 1; - return SUCCESS; + static struct IEffectModel *effectModel = IEffectModelGet(false); + return effectModel; } -int32_t OfflineAudioEffectServerChain::ReleaseEffectModel() +static void InitControllerDescriptor() { - if (info_.libName != nullptr) { - free(info_.libName); - } - if (info_.effectId != nullptr) { - free(info_.effectId); + std::lock_guard maplock(g_chainMutex); + if (g_chainName2infoMap.size() > 0) { + return; } - if (model_ != nullptr) { - IEffectModelRelease(model_, false); + static uint32_t descsLen = MAX_DESCRIPTOR_NUM; + auto model = InitEffectModel(); + CHECK_AND_RETURN_LOG(model, "get all descriptor failed, effectmodel is nullptr"); + struct EffectControllerDescriptor descs[MAX_DESCRIPTOR_NUM]; + int32_t ret = model->GetAllEffectDescriptors(model, descs, &descsLen); + CHECK_AND_RETURN_LOG(model, "get all descriptor failed, errCode is %{public}d", ret); + for (uint32_t i = 0; i < descsLen; i++) { + g_chainName2infoMap.insert_or_assign(descs[i].effectName, + std::make_pair(std::string(descs[i].libName), std::string(descs[i].effectId))); + FreeIfNotNull(descs[i].effectName); + FreeIfNotNull(descs[i].libName); + FreeIfNotNull(descs[i].effectId); + FreeIfNotNull(descs[i].supplier); } - return SUCCESS; +} + +void OfflineAudioEffectServerChain::InitDump() +{ + static uint32_t chainId = 0; + std::string dumpFileName = "OfflineEffectServer"; + std::string dumpFileInName = dumpFileName + "_" + std::to_string(chainId) + "_In.pcm"; + std::string dumpFileOutName = dumpFileName + "_" + std::to_string(chainId) + "_Out.pcm"; + DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dumpFileInName, &dumpFileIn_); + DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dumpFileOutName, &dumpFileOut_); + chainId++; } int32_t OfflineAudioEffectServerChain::GetOfflineAudioEffectChains(std::vector &chainNamesVector) { + InitControllerDescriptor(); + std::lock_guard maplock(g_chainMutex); + for (auto item : g_chainName2infoMap) { + chainNamesVector.emplace_back(item.first); + } AUDIO_INFO_LOG("GetOfflineAudioEffectChains done"); return SUCCESS; } int32_t OfflineAudioEffectServerChain::Create() { - AUDIO_INFO_LOG("Create %{public}s done", chainName_.c_str()); - return SUCCESS; -} + InitControllerDescriptor(); + std::lock_guard maplock(g_chainMutex); + auto mapIter = g_chainName2infoMap.find(chainName_); + CHECK_AND_RETURN_RET_LOG(mapIter != g_chainName2infoMap.end(), ERROR, + "create failed, no chain named %{public}s", chainName_.c_str()); + auto model = InitEffectModel(); + CHECK_AND_RETURN_RET_LOG(model, ERROR, "create failed, effectmodel is nullptr"); -int32_t OfflineAudioEffectServerChain::Configure() -{ - int8_t input[SEND_COMMAND_LEN] = {0}; - int8_t output[GET_BUFFER_LEN] = {0}; - uint32_t replyLen = GET_BUFFER_LEN; + // second.first for libName, second.second for effectId, 1 for ioDirection + // do not need to release char* in info + struct EffectInfo info = {&mapIter->second.first[0], &mapIter->second.second[0], 1}; - int32_t ret = controller_->SendCommand(controller_, AUDIO_EFFECT_COMMAND_SET_CONFIG, - input, SEND_COMMAND_LEN, output, &replyLen); - CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "send command AUDIO_EFFECT_COMMAND_SET_CONFIG failed"); + int32_t ret = model->CreateEffectController(model, &info, &controller_, &controllerId_); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, + "create %{public}s effect controller failed, errCode is %{public}d", chainName_.c_str(), ret); + + int8_t input[MAX_CMD_LEN] = {0}; + 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); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, + "%{public}s effect COMMAND_ENABLE failed, errCode is %{public}d", chainName_.c_str(), ret); + + InitDump(); + + AUDIO_INFO_LOG("Create %{public}s done", chainName_.c_str()); return SUCCESS; } int32_t OfflineAudioEffectServerChain::SetParam(AudioStreamInfo inInfo, AudioStreamInfo outInfo) { - AUDIO_INFO_LOG("%{public}d %{public}d %{public}hhu %{public}hhu %{public}" PRIu64 "StreamInfo set", + AUDIO_INFO_LOG("%{public}d %{public}d %{public}hhu %{public}hhu %{public}" PRIu64 " InStreamInfo set", inInfo.samplingRate, inInfo.encoding, inInfo.format, inInfo.channels, inInfo.channelLayout); - AUDIO_INFO_LOG("%{public}d %{public}d %{public}hhu %{public}hhu %{public}" PRIu64 "StreamInfo set", + 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); + + offlineConfig_.inputCfg = {inInfo.samplingRate, inInfo.channels, inInfo.format}; + offlineConfig_.outputCfg = {outInfo.samplingRate, outInfo.channels, outInfo.format}; + + 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, "configure failed, controller is nullptr"); + int32_t ret = controller_->SendCommand(controller_, AUDIO_EFFECT_COMMAND_SET_CONFIG, + reinterpret_cast(&offlineConfig_), sizeof(offlineConfig_), output, &replyLen); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, + "%{public}s effect COMMAND_SET_CONFIG failed, errCode is %{public}d", chainName_.c_str(), ret); + + inBufferSize_ = GetByteSize(inInfo.format) * inInfo.samplingRate * inInfo.channels * + MAX_TIME_INTERVAL_MS / AUDIO_MS_PER_SECOND; + outBufferSize_ = GetByteSize(outInfo.format) * outInfo.samplingRate * outInfo.channels * + MAX_TIME_INTERVAL_MS / AUDIO_MS_PER_SECOND; return SUCCESS; } int32_t OfflineAudioEffectServerChain::GetEffectBufferSize(uint32_t &inBufferSize, uint32_t &outBufferSize) { - inBufferSize = DEFAULT_BUFFER_SIZE; - outBufferSize = DEFAULT_BUFFER_SIZE; - AUDIO_INFO_LOG("GetEffectBufferSize in server done"); + 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_; + outBufferSize = outBufferSize_; + AUDIO_INFO_LOG("GetEffectBufferSize in server done, inBufferSize_:%{public}u inBufferSize_:%{public}u", + inBufferSize_, outBufferSize_); return SUCCESS; } @@ -129,35 +218,49 @@ int32_t OfflineAudioEffectServerChain::Prepare(const std::shared_ptrGetSize() && outSize <= serverBufferOut_->GetSize(), - ERR_INVALID_PARAM, "inSize %{public}u or outSize %{public}u out of range", inSize, outSize); - uint8_t *bufIn = serverBufferIn_->GetBase(); - uint8_t *bufOut = serverBufferOut_->GetBase(); - for (uint32_t i = 0; i < outSize; i++) { - bufOut[i] = bufIn[i] << 1; - } - AUDIO_INFO_LOG("Process in server done"); - return SUCCESS; -} + CHECK_AND_RETURN_RET_LOG(serverBufferIn_ && serverBufferIn_->GetBase(), ERROR, "serverBufferIn_ is nullptr"); + CHECK_AND_RETURN_RET_LOG(serverBufferOut_ && serverBufferOut_->GetBase(), ERROR, "serverBufferOut_ is nullptr"); -int32_t OfflineAudioEffectServerChain::Release() -{ - AUDIO_INFO_LOG("Release in server success"); - return SUCCESS; -} + CHECK_AND_RETURN_RET_LOG(inSize <= inBufferSize_, ERROR, + "inSize %{public}u > serverInBufferSize %{public}u", inSize, inBufferSize_); + CHECK_AND_RETURN_RET_LOG(outSize <= outBufferSize_, ERROR, + "outSize %{public}u > serverOutBufferSize %{public}u", outSize, outBufferSize_); -int32_t OfflineAudioEffectServerChain::SetDeviceType(const DeviceType deviceType) -{ - return SUCCESS; -} + DumpFileUtil::WriteDumpFile(dumpFileIn_, serverBufferIn_->GetBase(), inSize); -int32_t OfflineAudioEffectServerChain::SetRenderStreamUsage(const StreamUsage usage) -{ + struct AudioEffectBuffer input; + struct AudioEffectBuffer output; + + input = {inSize / GetFormatByteSize(offlineConfig_.inputCfg.format), + GetFormatByteSize(offlineConfig_.inputCfg.format), + reinterpret_cast(serverBufferIn_->GetBase()), inSize}; + output = {}; + + std::lock_guard lock(offlineChainMutex_); + CHECK_AND_RETURN_RET_LOG(controller_, ERROR, "process failed, controller is nullptr"); + int32_t ret = controller_->EffectProcess(controller_, &input, &output); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "EffectProcess failed ret:%{public}d", ret); + 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); + FreeIfNotNull(output.rawData); + + DumpFileUtil::WriteDumpFile(dumpFileOut_, serverBufferOut_->GetBase(), outSize); return SUCCESS; } -int32_t OfflineAudioEffectServerChain::SetCapturerSourceType(const SourceType sourceType) +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, + "chainId:%{public}s release failed, errCode is %{public}d", controllerId_.effectId, ret); + + AUDIO_INFO_LOG("Release in server success"); return SUCCESS; } } // namespace AudioStandard 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 9d47ad76ca391d588229e60ba9fee1a4b6ffad37..1fab9ec57aa5877141c649a3ce186175c207c0c0 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 @@ -25,7 +25,8 @@ using namespace std; namespace OHOS { namespace AudioStandard { namespace { - const std::string NORMAL_CHAIN_NAME = "abcdefg"; + const std::string INVALID_EFFECT_NAME = "0d000721"; + constexpr AudioStreamInfo NORMAL_STREAM_INFO( AudioSamplingRate::SAMPLE_RATE_48000, AudioEncodingType::ENCODING_PCM, AudioSampleFormat::SAMPLE_S16LE, AudioChannel::STEREO, AudioChannelLayout::CH_LAYOUT_STEREO); @@ -53,21 +54,27 @@ protected: shared_ptr chain_ = nullptr; }; -shared_ptr manager_ = nullptr; +shared_ptr g_manager = nullptr; +string g_normalName = ""; void OfflineAudioEffectChainUnitTest::SetUpTestCase(void) { - manager_ = make_shared(); + g_manager = make_shared(); + vector names; + names = g_manager->GetOfflineAudioEffectChains(); + if (names.size() > 0) { + g_normalName = names[0]; + } } void OfflineAudioEffectChainUnitTest::TearDownTestCase(void) { - manager_ = nullptr; + g_manager = nullptr; } void OfflineAudioEffectChainUnitTest::SetUp(void) { - chain_ = manager_->CreateOfflineAudioEffectChain(NORMAL_CHAIN_NAME); + chain_ = g_manager->CreateOfflineAudioEffectChain(g_normalName); } void OfflineAudioEffectChainUnitTest::TearDown(void) @@ -100,8 +107,25 @@ HWTEST(OfflineAudioEffectManagerUnitTest, OfflineAudioEffectManager_001, TestSiz HWTEST(OfflineAudioEffectManagerUnitTest, OfflineAudioEffectManager_002, TestSize.Level1) { auto manager = make_shared(); - auto chain = manager->CreateOfflineAudioEffectChain(NORMAL_CHAIN_NAME); - EXPECT_NE(nullptr, chain); + auto chain = manager->CreateOfflineAudioEffectChain(g_normalName); + if (g_normalName == "") { + EXPECT_EQ(nullptr, chain); + } else { + EXPECT_NE(nullptr, chain); + } +} + +/** + * @tc.name : Test CreateOfflineAudioEffectChain API + * @tc.type : FUNC + * @tc.number: OfflineAudioEffectManager_003 + * @tc.desc : Test OfflineAudioEffectManager interface. + */ +HWTEST(OfflineAudioEffectManagerUnitTest, OfflineAudioEffectManager_003, TestSize.Level1) +{ + auto manager = make_shared(); + auto chain = manager->CreateOfflineAudioEffectChain(INVALID_EFFECT_NAME); + EXPECT_EQ(nullptr, chain); } /** @@ -112,9 +136,10 @@ HWTEST(OfflineAudioEffectManagerUnitTest, OfflineAudioEffectManager_002, TestSiz */ HWTEST_F(OfflineAudioEffectChainUnitTest, OfflineAudioEffectChain_001, TestSize.Level1) { - EXPECT_NE(nullptr, chain_); - int32_t ret = chain_->Configure(NORMAL_STREAM_INFO, NORMAL_STREAM_INFO); - EXPECT_EQ(SUCCESS, ret); + if (chain_) { + int32_t ret = chain_->Configure(NORMAL_STREAM_INFO, NORMAL_STREAM_INFO); + EXPECT_EQ(SUCCESS, ret); + } } /** @@ -125,9 +150,10 @@ HWTEST_F(OfflineAudioEffectChainUnitTest, OfflineAudioEffectChain_001, TestSize. */ HWTEST_F(OfflineAudioEffectChainUnitTest, OfflineAudioEffectChain_002, TestSize.Level1) { - EXPECT_NE(nullptr, chain_); - EXPECT_EQ(SUCCESS, chain_->Configure(NORMAL_STREAM_INFO, NORMAL_STREAM_INFO)); - EXPECT_EQ(SUCCESS, chain_->Prepare()); + if (chain_) { + EXPECT_EQ(SUCCESS, chain_->Configure(NORMAL_STREAM_INFO, NORMAL_STREAM_INFO)); + EXPECT_EQ(SUCCESS, chain_->Prepare()); + } } /** @@ -140,24 +166,25 @@ HWTEST_F(OfflineAudioEffectChainUnitTest, OfflineAudioEffectChain_003, TestSize. { uint32_t inSize = 0; uint32_t outSize = 0; - EXPECT_NE(nullptr, chain_); - EXPECT_EQ(SUCCESS, chain_->Configure(NORMAL_STREAM_INFO, NORMAL_STREAM_INFO)); - EXPECT_EQ(SUCCESS, chain_->Prepare()); - EXPECT_EQ(SUCCESS, chain_->GetEffectBufferSize(inSize, outSize)); - EXPECT_GT(inSize, 0); - EXPECT_GT(outSize, 0); - uint8_t *inBuffer = new uint8_t[inSize]; - uint8_t *outBuffer = new uint8_t[outSize]; - for (uint32_t i = 0; i < inSize; i++) { - inBuffer[i] = 1; + if (chain_) { + EXPECT_EQ(SUCCESS, chain_->Configure(NORMAL_STREAM_INFO, NORMAL_STREAM_INFO)); + EXPECT_EQ(SUCCESS, chain_->Prepare()); + EXPECT_EQ(SUCCESS, chain_->GetEffectBufferSize(inSize, outSize)); + EXPECT_GT(inSize, 0); + EXPECT_GT(outSize, 0); + uint8_t *inBuffer = new uint8_t[inSize]; + uint8_t *outBuffer = new uint8_t[outSize]; + for (uint32_t i = 0; i < inSize; i++) { + inBuffer[i] = 1; + } + EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(nullptr, inSize, outBuffer, outSize)); + EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(inBuffer, inSize + 1, outBuffer, outSize)); + EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(inBuffer, inSize, nullptr, outSize)); + EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(inBuffer, inSize, outBuffer, outSize + 1)); + EXPECT_EQ(SUCCESS, chain_->Process(inBuffer, inSize, outBuffer, outSize)); + delete []inBuffer; + delete []outBuffer; } - EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(nullptr, inSize, outBuffer, outSize)); - EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(inBuffer, inSize + 1, outBuffer, outSize)); - EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(inBuffer, inSize, nullptr, outSize)); - EXPECT_EQ(ERR_INVALID_PARAM, chain_->Process(inBuffer, inSize, outBuffer, outSize + 1)); - EXPECT_EQ(SUCCESS, chain_->Process(inBuffer, inSize, outBuffer, outSize)); - delete []inBuffer; - delete []outBuffer; } } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/client/src/ipc_offline_stream_proxy.cpp b/services/audio_service/client/src/ipc_offline_stream_proxy.cpp index 74b8f01b736ee54bb2fd764790779505003863dc..dd878a00c687a2871f5cb2d1fe5ddaab4ed1bb49 100644 --- a/services/audio_service/client/src/ipc_offline_stream_proxy.cpp +++ b/services/audio_service/client/src/ipc_offline_stream_proxy.cpp @@ -35,7 +35,7 @@ int32_t IpcOfflineStreamProxy::CreateOfflineEffectChain(const std::string &chain MessageOption option; CHECK_AND_RETURN_RET_LOG(data.WriteInterfaceToken(GetDescriptor()), ERROR, "Write descriptor failed!"); - + data.WriteString(chainName); int ret = Remote()->SendRequest(IpcOfflineStreamMsg::CREATE_OFFLINE_EFFECT_CHAIN, data, reply, option); CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, ERR_OPERATION_FAILED, "Create failed, error: %{public}d", ret);