diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp index c1bbb6085e38e906ae7f26329a5f8a424bdf0c85..479857472eadb342c1adb9ce23a2718150c9af15 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp @@ -111,6 +111,8 @@ napi_status NapiAudioRenderer::InitNapiAudioRenderer(napi_env env, napi_value &c DECLARE_NAPI_FUNCTION("getAudioTimestampInfo", GetAudioTimestampInfo), DECLARE_NAPI_FUNCTION("getAudioTimestampInfoSync", GetAudioTimestampInfoSync), DECLARE_NAPI_FUNCTION("setDefaultOutputDevice", SetDefaultOutputDevice), + DECLARE_NAPI_FUNCTION("setTarget", SetTarget), + DECLARE_NAPI_FUNCTION("getTarget", GetTarget), }; napi_status status = napi_define_class(env, NAPI_AUDIO_RENDERER_CLASS_NAME.c_str(), @@ -541,6 +543,85 @@ napi_value NapiAudioRenderer::GetRendererSamplingRate(napi_env env, napi_callbac return NapiAsyncWork::Enqueue(env, context, "GetRendererSamplingRate", executor, complete); } +napi_value NapiAudioRenderer::SetTarget(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + if (context == nullptr) { + AUDIO_ERR_LOG("SetTarget failed : no memory"); + NapiAudioError::ThrowError(env, "SetTarget failed : no memory", + NAPI_ERR_NO_MEMORY); + return NapiParamUtils::GetUndefinedValue(env); + } + + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", + NAPI_ERR_INVALID_PARAM); + context->status = NapiParamUtils::GetValueUInt32(env, context->target, argv[PARAM0]); + NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get Target failed", + NAPI_ERR_INVALID_PARAM); + }; + + context->GetCbInfo(env, info, inputParser); + + auto executor = [context]() { + CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiAudioRenderer = objectGuard.GetPtr(); + CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context), + "context object state is error."); + if (context->target != 0 or context->target != 1) { + context->SignError(NAPI_ERR_INVALID_PARAM); + return; + } + context->intValue = napiAudioRenderer->audioRenderer_->SetTarget(context->target); + CHECK_AND_RETURN(context->intValue != SUCCESS); + if (context->intValue == ERR_PERMISSION_DENIED) { + context->SignError(NAPI_ERR_NO_PERMISSION); + } else if (context->intValue == ERR_SYSTEM_PERMISSION_DENIED) { + context->SignError(NAPI_ERR_PERMISSION_DENIED); + } else if (context->intValue == ERR_ILLEGAL_STATE) { + context->SignError(NAPI_ERR_ILLEGAL_STATE); + } else { + context->SignError(NAPI_ERR_SYSTEM); + } + //todo NAPI_ERR_UNSUPPORTED + }; + + auto complete = [env](napi_value &output) { + output = NapiParamUtils::GetUndefinedValue(env); + }; + return NapiAsyncWork::Enqueue(env, context, "SetTarget", executor, complete); +} + +napi_value NapiAudioRenderer::GetTarget(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + if (context == nullptr) { + AUDIO_ERR_LOG("GetTarget failed : no memory"); + NapiAudioError::ThrowError(env, "GetTarget failed : no memory", + NAPI_ERR_NO_MEMORY); + return NapiParamUtils::GetUndefinedValue(env); + } + + context->GetCbInfo(env, info); + + auto executor = [context]() { + CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiAudioRenderer = objectGuard.GetPtr(); + CHECK_AND_RETURN_LOG(CheckAudioRendererStatus(napiAudioRenderer, context), + "context object state is error."); + context->rendererSampleRate = napiAudioRenderer->audioRenderer_->GetTarget(); + }; + + auto complete = [env, context](napi_value &output) { + NapiParamUtils::SetValueUInt32(env, context->target, output); + }; + return NapiAsyncWork::Enqueue(env, context, "GetTarget", executor, complete); +} + napi_value NapiAudioRenderer::Start(napi_env env, napi_callback_info info) { auto context = std::make_shared(); diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.h b/frameworks/js/napi/audiorenderer/napi_audio_renderer.h index 178b9755c741c7a42699d54013c3f8b3a580a268..ee89efaa7648f85a8b36258aef7cabe7b656a49a 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.h +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.h @@ -58,6 +58,7 @@ private: int32_t audioRendererRate; int32_t rendererFlags; int32_t interruptMode; + int32_t target; bool isTrue; uint64_t time; size_t bufferLen; @@ -140,6 +141,8 @@ private: static napi_value GetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info); static napi_value SetDefaultOutputDevice(napi_env env, napi_callback_info info); static napi_value GetCallback(size_t argc, napi_value *argv); + static napi_value SetTarget(napi_env env, napi_callback_info info); + static napi_value GetTarget(napi_env env, napi_callback_info info); static napi_status WriteArrayBufferToNative(std::shared_ptr context); diff --git a/frameworks/js/napi/common/napi_audio_enum.h b/frameworks/js/napi/common/napi_audio_enum.h index 49ffd206beb9c66479b51583d5806a3bee6d493c..3c14dedeccfea03733a5b4a1d66c1df096ce1217 100644 --- a/frameworks/js/napi/common/napi_audio_enum.h +++ b/frameworks/js/napi/common/napi_audio_enum.h @@ -123,6 +123,11 @@ public: LOOPBACK_MODE_HARDWARE = 0 }; + enum RenderTarget { + PLAYBACK = 0, + INJECT_TO_VOICE_COMMUNICATION_CAPTURE = 1 + } + static napi_value Init(napi_env env, napi_value exports); static bool IsLegalInputArgumentInterruptMode(int32_t interruptMode); static bool IsLegalInputArgumentAudioEffectMode(int32_t audioEffectMode); diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 74c2a8a9cc1e5b488c551925764486a6e9f01284..68a407bfa18c0fb6dec59202676aeee1ed230b6f 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -74,6 +74,8 @@ public: float GetLoudnessGain() const override; int32_t SetRenderRate(AudioRendererRate renderRate) const override; AudioRendererRate GetRenderRate() const override; + int32_t SetTarget(RenderTarget target) const override; + RenderTarget GetTarget() const override; int32_t SetRendererSamplingRate(uint32_t sampleRate) const override; uint32_t GetRendererSamplingRate() const override; int32_t SetRendererCallback(const std::shared_ptr &callback) override; @@ -272,6 +274,7 @@ private: bool isDirectVoipSupported_ = false; bool isEnableVoiceModemCommunicationStartStream_ = false; RendererState state_ = RENDERER_INVALID; + RenderTarget target_ = PLAYBACK; std::optional speed_ = std::nullopt; std::optional pitch_ = std::nullopt; diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index 14351ec5c7cf46fe56ac439ac926ea74a3e45af5..4433f0c712b99033ff37ebbf84aa28169ce43618 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -1476,6 +1476,44 @@ AudioRendererRate AudioRendererPrivate::GetRenderRate() const return currentStream->GetRenderRate(); } +int32_t AudioRendererPrivate::SetTarget(RenderTarget target) const +{ + std::shared_ptr currentStream = GetInnerStream(); + CHECK_AND_RETURN_RET_LOG(currentStream != nullptr, ERROR_ILLEGAL_STATE, "audioStream_ is nullptr"); + int32_t ret = currentStream->SetRenderRate(renderRate); + CHECK_AND_RETURN_RET(ret == SUCCESS, ret); + float speed = 1.0f; + switch (renderRate) { + case RENDER_RATE_NORMAL: + speed = 1.0f; + break; + case RENDER_RATE_DOUBLE: + speed = 2.0f; + break; + case RENDER_RATE_HALF: + speed = 0.5f; + break; + default: + speed = 1.0f; + } + ret = currentStream->SetSpeed(speed); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("SetSpeed Failed, error: %{public}d", ret); + } + ret = currentStream->SetPitch(speed); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("SetPitch Failed, error: %{public}d", ret); + } + return SUCCESS; +} + +RenderTarget AudioRendererPrivate::GetRenderRate() const +{ + std::shared_ptr currentStream = GetInnerStream(); + CHECK_AND_RETURN_RET_LOG(currentStream != nullptr, RENDER_RATE_NORMAL, "audioStream_ is nullptr"); + return currentStream->GetRenderRate(); +} + int32_t AudioRendererPrivate::SetRendererSamplingRate(uint32_t sampleRate) const { std::shared_ptr currentStream = GetInnerStream(); diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index 806c39e4e9a84ff17e37045c16f4f3fafb50b29e..b1d6e491f4ad5ca5af7384e1b861b1d2aad3977c 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -157,6 +157,8 @@ public: virtual bool GetMute() = 0; virtual int32_t SetRenderRate(AudioRendererRate renderRate) = 0; virtual AudioRendererRate GetRenderRate() = 0; + virtual int32_t SetRenderTarget(RenderTarget target) = 0; + virtual RenderTarget GetRenderTarget() = 0; virtual int32_t SetStreamCallback(const std::shared_ptr &callback) = 0; virtual int32_t SetSpeed(float speed) = 0; virtual int32_t SetPitch(float pitch) = 0; diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index 4c2056f8aeba45773e784121c0c5a8547b70d96a..cb73149e5ea37b4c7a50bf3da539afdf43b8fa65 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -303,6 +303,14 @@ enum AudioRendererRate { RENDER_RATE_HALF = 2, }; +/** + * Enumerates the audio playback target. + */ +enum RenderTarget { + PLAYBACK = 0, + INJECT_TO_VOICE_COMMUNICATION_CAPTURE = 1 +} + /** * media safe volume status */ diff --git a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h index 6a03db4231eb9735735b72f14993814295f3ce18..0d672665ee379f6a09f35df2c33f090363207fcb 100644 --- a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h @@ -586,6 +586,25 @@ public: */ virtual AudioRendererRate GetRenderRate() const = 0; + /** + * @brief Set the render target + * + * @param target The target at which the stream needs to be rendered. + * @return Returns {@link SUCCESS} if render rate is successfully set; returns an error code + * defined in {@link audio_errors.h} otherwise. + * @since 22 + */ + virtual int32_t SetTarget(RenderTarget target) const = 0; + + /** + * @brief Obtains the current render target + * + * @return Returns current render target + * @since 22 + */ + virtual RenderTarget GetTarget() const = 0; + + /** * @brief Set the render sampling rate * diff --git a/services/audio_service/client/include/renderer_in_client_private.h b/services/audio_service/client/include/renderer_in_client_private.h index 4cbb5226ab21f79745832cfdcc4f4eca978a2235..a87033de6e824972c33b11f0a70dde3f38b9f971 100644 --- a/services/audio_service/client/include/renderer_in_client_private.h +++ b/services/audio_service/client/include/renderer_in_client_private.h @@ -85,6 +85,8 @@ public: bool GetMute() override; int32_t SetRenderRate(AudioRendererRate renderRate) override; AudioRendererRate GetRenderRate() override; + int32_t SetRenderTarget(RenderTarget target) override; + RenderTarget GetRenderRate() override; int32_t SetStreamCallback(const std::shared_ptr &callback) override; int32_t SetRendererFirstFrameWritingCallback( const std::shared_ptr &callback) override; diff --git a/services/audio_service/client/src/renderer_in_client_public.cpp b/services/audio_service/client/src/renderer_in_client_public.cpp index 1af44d7f47f88d79fb85c47fc3eb241a5334462e..a300f31db408176b27ac6e0ed6c310a91bc38e11 100644 --- a/services/audio_service/client/src/renderer_in_client_public.cpp +++ b/services/audio_service/client/src/renderer_in_client_public.cpp @@ -567,6 +567,23 @@ AudioRendererRate RendererInClientInner::GetRenderRate() return rendererRate_; } +int32_t RendererInClientInner::SetRenderTarget(RenderTarget target) +{ + if (renderTarget_ == target) { + AUDIO_INFO_LOG("Set same target"); + return SUCCESS; + } + CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!"); + renderTarget_ = target; + return ipcStream_->SetTarget(target); +} + +AudioRendererRate RendererInClientInner::GetRenderTarget() +{ + AUDIO_INFO_LOG("Get RenderTarget %{public}d", renderTarget_); + return renderTarget_; +} + int32_t RendererInClientInner::SetStreamCallback(const std::shared_ptr &callback) { if (callback == nullptr) { diff --git a/services/audio_service/idl/IIpcStream.idl b/services/audio_service/idl/IIpcStream.idl index 5f907e064cbe37db2ca91cb75c77fc7eaed25150..7efd37e43a4c16a5e01983c71500e5ef5b260b79 100644 --- a/services/audio_service/idl/IIpcStream.idl +++ b/services/audio_service/idl/IIpcStream.idl @@ -38,6 +38,7 @@ interface IIpcStream { void GetLatency([out] unsigned long latency); void SetRate([in] int rate); // SetRenderRate void GetRate([out] int rate); // SetRenderRate + void SetTarget([in] int target); // SetRenderTarget void SetLowPowerVolume([in] float volume); // renderer only void GetLowPowerVolume([out] float volume); // renderer only void SetAudioEffectMode([in] int effectMode); // renderer only diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 09475e578543a93a96946b076b8a23864036e94c..b988be914aab9fc49d34912039ba5cc8bf455be6 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -82,6 +82,7 @@ public: int32_t GetAudioPosition(uint64_t &framePos, uint64_t ×tamp, uint64_t &latency, int32_t base); int32_t GetLatency(uint64_t &latency); int32_t SetRate(int32_t rate); + int32_t SetTarget(int32_t target); int32_t SetLowPowerVolume(float volume); int32_t GetLowPowerVolume(float &volume); int32_t SetAudioEffectMode(int32_t effectMode); diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index 887418c13d9a89ad805a3a506d990aaffeb3adf8..fad6532df7204c06435fcc08559e1280f8b981a2 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -1377,6 +1377,11 @@ int32_t RendererInServer::SetRate(int32_t rate) return stream_->SetRate(rate); } +int32_t RendererInServer::SetTarget(int32_t target) +{ + return SUCCESS; +} + int32_t RendererInServer::SetLowPowerVolume(float volume) { if (volume < MIN_FLOAT_VOLUME || volume > MAX_FLOAT_VOLUME) {