diff --git a/ds/audioOutputPort.cpp b/ds/audioOutputPort.cpp index 2d5fde04..8b7553d2 100644 --- a/ds/audioOutputPort.cpp +++ b/ds/audioOutputPort.cpp @@ -364,7 +364,6 @@ void AudioOutputPort::setEnablePersist (bool isEnabled) return; } - /** * @fn const int AudioOutputPort::getStereoAuto() * @brief This API is used to get the current auto mode. diff --git a/ds/host.cpp b/ds/host.cpp index fd790ea3..5b1841a4 100644 --- a/ds/host.cpp +++ b/ds/host.cpp @@ -521,6 +521,91 @@ Host::~Host() } } +/** + * @brief Sets the application-specific audio configuration. + * + * Some applications may require custom audio settings, such as enabling + * continuous audio output to prevent audio glitches, muting, or format + * re-lock events on downstream devices when the input stream to MS12 is + * temporarily interrupted. + * + * This interface is designed to be extensible and can accommodate additional + * application-specific audio configuration requirements in the future. + * + * Applications should call getApplicationAudioConfigList() to retrieve the list of supported audio configurations + * and then call setApplicationAudioConfig() with a supported audioConfig name. + * + * @param[in] audioConfig - Configuration name entry. + * @param[in] enable - enable/disable audio configuration ( @a true to enable, @a false to disable) + * + * @return None + * + */ +void Host::setApplicationAudioConfig (const std::string &audioConfig, bool enable) +{ + dsApplicationAudioConfig_t config; + memset(config.configName, 0, DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN); + strncpy(config.configName, audioConfig.c_str(), (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN - 1)); + dsError_t ret = dsSetApplicationAudioConfig (NULL, &config, enable); + if (ret != dsERR_NONE) { + INT_ERROR("Failed to set Host::setApplicationAudioConfig\n"); + throw Exception(ret); + } + return; +} + +/** + * @brief Gets the application-specific audio configuration. + * Returns whether the requested specific audio configuration (see setApplicationAudioConfig()) + * is currently enabled or disabled. + * + * @param[in] audioConfig - Configuration name entry + * @param[out] enable - True if audio configuration is enabled, false otherwise. + * + * @return None + * + */ +void Host::getApplicationAudioConfig (const std::string &audioConfig, bool *enable) +{ + dsError_t ret; + if (enable == NULL) { + INT_ERROR("Invalid parameter\n"); + ret = dsERR_INVALID_PARAM; + throw Exception(ret); + } + dsApplicationAudioConfig_t config; + memset(config.configName, 0, DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN); + strncpy(config.configName, audioConfig.c_str(), (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN -1 )); + ret = dsGetApplicationAudioConfig (NULL, &config, enable); + if (ret != dsERR_NONE) { + INT_ERROR("Failed to get Host::getApplicationAudioConfig\n"); + throw Exception(ret); + } + return; +} + +/** + * @brief Gets the list of supported audio configurations. + * + * @param[out] audioConfigList - pointer to List of supported audio configurations + * + * @return None + * + */ +void Host::getApplicationAudioConfigList (std::vector& configList) +{ + dsApplicationAudioConfigList_t appAudioConfigList; + memset(&appAudioConfigList, 0, sizeof(appAudioConfigList)); + dsError_t ret = dsGetApplicationAudioConfigList(NULL, &appAudioConfigList); + if (ret != dsERR_NONE) { + INT_ERROR("Failed to set Host::getApplicationAudioConfigList\n"); + throw Exception(ret); + } + for (int count =0; count < appAudioConfigList.returnedCount; count++) { + configList.push_back(appAudioConfigList.config[count].configName); + } + return; +} /** * @fn Host::setAssociatedAudioMixing(const bool mixing) diff --git a/ds/include/host.hpp b/ds/include/host.hpp index a6a9ce53..1e8e077b 100644 --- a/ds/include/host.hpp +++ b/ds/include/host.hpp @@ -437,7 +437,9 @@ class Host { void getCurrentAudioFormat(dsAudioFormat_t& audioFormat); void getMS12ConfigDetails(std::string& configType); void setAudioMixerLevels(dsAudioInput_t aInput, int volume); - + void setApplicationAudioConfig (const std::string &audioConfig, bool enable); + void getApplicationAudioConfig (const std::string &audioConfig, bool *enable); + void getApplicationAudioConfigList (std::vector& configList); private: std::unique_ptr m_impl; diff --git a/rpc/cli/dsAudio.c b/rpc/cli/dsAudio.c index 93dc17f4..ae4d45f1 100644 --- a/rpc/cli/dsAudio.c +++ b/rpc/cli/dsAudio.c @@ -396,6 +396,96 @@ dsError_t dsSetEnablePersist(intptr_t handle, const char* portName, bool enabled return dsERR_GENERAL ; } +dsError_t dsSetApplicationAudioConfig(intptr_t handle, const dsApplicationAudioConfig_t* audioConfig, bool enable) +{ + _DEBUG_ENTER(); + if (audioConfig == NULL) { + INT_ERROR("%s:Invalid parameter", __func__); + return dsERR_INVALID_PARAM; + } + dsApplicationAudioConfigParam_t param; + memset(¶m, 0, sizeof(param)); + param.handle = handle; + param.enable = enable; + IARM_Result_t rpcRet = IARM_RESULT_SUCCESS; + memset(¶m.audioConfig, '\0', sizeof(param.audioConfig)); + strncpy(param.audioConfig.configName, audioConfig->configName, (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN -1)); + rpcRet = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, + (char *)IARM_BUS_DSMGR_API_dsSetApplicationAudioConfig, + (void *)¶m, + sizeof(param)); + + if (IARM_RESULT_SUCCESS == rpcRet && param.result == dsERR_NONE) + { + return dsERR_NONE; + } + INT_ERROR("%s: Failed to set application audio config\n", __func__); + return dsERR_GENERAL; +} + +dsError_t dsGetApplicationAudioConfigList(intptr_t handle, dsApplicationAudioConfigList_t* appAudioConfigList) +{ + IARM_Result_t rpcRet = IARM_RESULT_SUCCESS; + if (appAudioConfigList == NULL) { + INT_ERROR("%s:Invalid parameter", __func__); + return dsERR_INVALID_PARAM; + } + dsApplicationAudioConfigListParam_t param; + memset(¶m, 0, sizeof(param)); + param.handle = handle; + param.appAudioConfigList.size = sizeof(param.appAudioConfigList); + + rpcRet = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, + (char *)IARM_BUS_DSMGR_API_dsGetApplicationAudioConfigList, + (void *)¶m, + sizeof(param)); + + if (IARM_RESULT_SUCCESS != rpcRet || param.result != dsERR_NONE) + { + INT_ERROR("%s: (GET) GENERAL ERROR\n", __func__); + return dsERR_GENERAL; + } + + appAudioConfigList->size = param.appAudioConfigList.size; + appAudioConfigList->returnedCount = param.appAudioConfigList.returnedCount; + appAudioConfigList->totalCount = param.appAudioConfigList.totalCount; + for (int count=0; count < param.appAudioConfigList.returnedCount; count++) { + strncpy(appAudioConfigList->config[count].configName, param.appAudioConfigList.config[count].configName, + (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN -1) ); + } + return dsERR_NONE; +} + +dsError_t dsGetApplicationAudioConfig(intptr_t handle, const dsApplicationAudioConfig_t* audioConfig, bool* enable) +{ + _DEBUG_ENTER(); + if (audioConfig == NULL || enable == NULL) { + INT_ERROR("%s:Invalid parameter", __func__); + return dsERR_INVALID_PARAM; + } + dsApplicationAudioConfigParam_t param; + memset(¶m, 0, sizeof(param)); + param.handle = handle; + // By default enable will be false. + param.enable = false; + IARM_Result_t rpcRet = IARM_RESULT_SUCCESS; + memset(¶m.audioConfig, 0, sizeof(param.audioConfig)); + strncpy(param.audioConfig.configName, audioConfig->configName, (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN -1)); + rpcRet = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, + (char *)IARM_BUS_DSMGR_API_dsGetApplicationAudioConfig, + (void *)¶m, + sizeof(param)); + + if (IARM_RESULT_SUCCESS == rpcRet && param.result == dsERR_NONE) + { + *enable = param.enable; + return dsERR_NONE; + } + INT_ERROR("%s: Failed to get application audio config\n", __func__); + return dsERR_GENERAL ; +} + + dsError_t dsSetAudioEncoding(intptr_t handle, dsAudioEncoding_t encoding) { dsError_t ret = dsERR_NONE; diff --git a/rpc/include/dsRpc.h b/rpc/include/dsRpc.h index 96b3a086..35d86d5e 100644 --- a/rpc/include/dsRpc.h +++ b/rpc/include/dsRpc.h @@ -73,6 +73,9 @@ extern "C" { #define IARM_BUS_DSMGR_API_dsGetAudioDelay "dsGetAudioDelay" #define IARM_BUS_DSMGR_API_dsGetSinkDeviceAtmosCapability "dsGetSinkDeviceAtmosCapability" #define IARM_BUS_DSMGR_API_dsSetAudioAtmosOutputMode "dsSetAudioAtmosOutputMode" +#define IARM_BUS_DSMGR_API_dsSetApplicationAudioConfig "dsSetApplicationAudioConfig" +#define IARM_BUS_DSMGR_API_dsGetApplicationAudioConfig "dsGetApplicationAudioConfig" +#define IARM_BUS_DSMGR_API_dsGetApplicationAudioConfigList "dsGetApplicationAudioConfigList" #define IARM_BUS_DSMGR_API_dsSetAudioDucking "dsSetAudioDucking" #define IARM_BUS_DSMGR_API_dsSetAudioLevel "dsSetAudioLevel" #define IARM_BUS_DSMGR_API_dsGetAudioLevel "dsGetAudioLevel" @@ -1082,6 +1085,21 @@ typedef struct _dsHdmiVersionParam_t dsHdmiMaxCapabilityVersion_t iCapVersion; }dsHdmiVersionParam_t; +typedef struct _dsApplicationAudioConfigParam_t +{ + dsError_t result; + intptr_t handle; + dsApplicationAudioConfig_t audioConfig ; + bool enable; +}dsApplicationAudioConfigParam_t; + +typedef struct _dsApplicationAudioConfigListParam_t { + dsError_t result; + intptr_t handle; + dsApplicationAudioConfigList_t appAudioConfigList; +} dsApplicationAudioConfigListParam_t; + + #ifdef __cplusplus } #endif diff --git a/rpc/srv/dsAudio.c b/rpc/srv/dsAudio.c index 3201175c..1383ab53 100755 --- a/rpc/srv/dsAudio.c +++ b/rpc/srv/dsAudio.c @@ -121,6 +121,9 @@ IARM_Result_t _dsIsAudioPortEnabled(void *arg); IARM_Result_t _dsGetEnablePersist(void *arg); IARM_Result_t _dsSetEnablePersist(void *arg); +IARM_Result_t _dsSetApplicationAudioConfig(void *arg); +IARM_Result_t _dsGetApplicationAudioConfig(void *arg); +IARM_Result_t _dsGetApplicationAudioConfigList(void *arg); IARM_Result_t _dsEnableAudioPort(void *arg); IARM_Result_t _dsSetAudioDucking(void *arg); @@ -2412,6 +2415,9 @@ IARM_Result_t _dsAudioPortInit(void *arg) IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsGetEnablePersist, _dsGetEnablePersist); IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsSetEnablePersist, _dsSetEnablePersist); + IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsSetApplicationAudioConfig, _dsSetApplicationAudioConfig); + IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsGetApplicationAudioConfig, _dsGetApplicationAudioConfig); + IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsGetApplicationAudioConfigList, _dsGetApplicationAudioConfigList); IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsAudioPortTerm,_dsAudioPortTerm); IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_dsEnableLEConfig,_dsEnableLEConfig); @@ -3691,6 +3697,176 @@ IARM_Result_t _dsSetEnablePersist(void *arg) return result; } +IARM_Result_t _dsGetApplicationAudioConfigList(void *arg) +{ + _DEBUG_ENTER(); + IARM_BUS_Lock(lock); + + IARM_Result_t result = IARM_RESULT_INVALID_STATE; + dsError_t ret = dsERR_NONE; + typedef dsError_t (*dsGetApplicationAudioConfigList_t)(intptr_t handle, dsApplicationAudioConfigList_t* audioConfigList); + static dsGetApplicationAudioConfigList_t func = 0; + INT_DEBUG("Inside _dsGetApplicationAudioConfigList_t srv\n"); + if (func == 0) { + void *dllib = dlopen(RDK_DSHAL_NAME, RTLD_LAZY); + if (dllib) { + func = (dsGetApplicationAudioConfigList_t) dlsym(dllib, "dsGetApplicationAudioConfigList"); + if (func) { + INT_ERROR("dsGetApplicationAudioConfigList_t is defined and loaded\r\n"); + } + else { + IARM_BUS_Unlock(lock); + dlclose(dllib); + INT_ERROR("dsGetApplicationAudioConfigList is not defined\r\n"); + return IARM_RESULT_INVALID_STATE; + } + dlclose(dllib); + } + else { + INT_ERROR("Opening RDK_DSHAL_NAME [%s] failed\r\n", RDK_DSHAL_NAME); + } + } + dsApplicationAudioConfigListParam_t *param = (dsApplicationAudioConfigListParam_t *)arg; + dsApplicationAudioConfigList_t configList; + memset(&configList, 0, sizeof(configList)); + if (func != 0 && param != NULL) + { + configList.size = param->appAudioConfigList.size; + ret = func(param->handle, &configList); + if (ret != dsERR_NONE) + { + param->result = ret; + INT_ERROR("%s: (SERVER) Unable to fetch the application audio configuration list\n", __FUNCTION__); + } + else + { + INT_INFO("%s: (SERVER) success \n", __FUNCTION__); + param->result = ret; + param->appAudioConfigList.size = configList.size; + param->appAudioConfigList.totalCount = configList.totalCount; + param->appAudioConfigList.returnedCount = configList.returnedCount; + for (int count =0; count < param->appAudioConfigList.returnedCount; count++) { + memset(param->appAudioConfigList.config[count].configName, 0, DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN); + strncpy(param->appAudioConfigList.config[count].configName, configList.config[count].configName, (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN-1)); + } + + result = IARM_RESULT_SUCCESS; + } + } + + IARM_BUS_Unlock(lock); + return result; +} + + +IARM_Result_t _dsSetApplicationAudioConfig(void *arg) +{ + _DEBUG_ENTER(); + IARM_BUS_Lock(lock); + + IARM_Result_t result = IARM_RESULT_INVALID_STATE; + dsError_t ret = dsERR_NONE; + typedef dsError_t (*dsSetApplicationAudioConfig_t)(intptr_t handle, dsApplicationAudioConfig_t* audioConfig, bool enable); + static dsSetApplicationAudioConfig_t func = 0; + INT_DEBUG("Inside _dsSetApplicationAudioConfig srv\n"); + if (func == 0) { + void *dllib = dlopen(RDK_DSHAL_NAME, RTLD_LAZY); + if (dllib) { + func = (dsSetApplicationAudioConfig_t) dlsym(dllib, "dsSetApplicationAudioConfig"); + if (func) { + INT_DEBUG("dsSetApplicationAudioConfig_t(int, bool) is defined and loaded\r\n"); + } + else { + IARM_BUS_Unlock(lock); + dlclose(dllib); + INT_ERROR("dsSetApplicationAudioConfig_t(int, bool) is not defined\r\n"); + return IARM_RESULT_INVALID_STATE; + } + dlclose(dllib); + } + else { + INT_ERROR("Opening RDK_DSHAL_NAME [%s] failed\r\n", RDK_DSHAL_NAME); + } + } + dsApplicationAudioConfigParam_t *param = (dsApplicationAudioConfigParam_t *)arg; + dsApplicationAudioConfig_t config; + memset(&config, 0, sizeof(config)); + if (func != 0 && param != NULL) + { + strncpy(config.configName, param->audioConfig.configName, (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN - 1)); + ret = func(param->handle, &config, param->enable); + if (ret != dsERR_NONE) + { + param->result = ret; + INT_ERROR("%s: (SERVER) Unable to set Application audio configuration\n", __FUNCTION__); + } + else + { + INT_INFO("%s: (SERVER) success \n", __FUNCTION__); + param->result = ret; + result = IARM_RESULT_SUCCESS; + } + } + + IARM_BUS_Unlock(lock); + return result; +} + +IARM_Result_t _dsGetApplicationAudioConfig(void *arg) +{ + _DEBUG_ENTER(); + IARM_BUS_Lock(lock); + + IARM_Result_t result = IARM_RESULT_INVALID_STATE; + dsError_t ret = dsERR_NONE; + typedef dsError_t (*dsGetApplicationAudioConfig_t)(intptr_t handle, dsApplicationAudioConfig_t* audioConfig, bool *enable); + static dsGetApplicationAudioConfig_t func = 0; + bool enable = false; + dsApplicationAudioConfig_t config; + INT_DEBUG("Inside _dsGetApplicationAudioConfig srv\n"); + if (func == 0) { + void *dllib = dlopen(RDK_DSHAL_NAME, RTLD_LAZY); + if (dllib) { + func = (dsGetApplicationAudioConfig_t) dlsym(dllib, "dsGetApplicationAudioConfig"); + if (func) { + INT_DEBUG("dsGetApplicationAudioConfig_t(int, bool) is defined and loaded\r\n"); + } + else { + IARM_BUS_Unlock(lock); + dlclose(dllib); + INT_ERROR("dsGetApplicationAudioConfig_t(int, bool) is not defined\r\n"); + return IARM_RESULT_INVALID_STATE; + } + dlclose(dllib); + } + else { + INT_ERROR("Opening RDK_DSHAL_NAME [%s] failed\r\n", RDK_DSHAL_NAME); + } + } + dsApplicationAudioConfigParam_t *param = (dsApplicationAudioConfigParam_t *)arg; + memset(&config, 0, sizeof(config)); + if (func != 0 && param != NULL) + { + strncpy(config.configName, param->audioConfig.configName, (DS_MAX_APPLICATION_AUDIO_CONFIG_NAME_LEN - 1)); + ret = func(param->handle, &config, &enable); + if (ret != dsERR_NONE) + { + param->result = ret; + INT_ERROR("%s: (SERVER) Unable to get application audio configuration\n", __FUNCTION__); + } + else + { + INT_INFO("%s: (SERVER) success \n", __FUNCTION__); + param->result = ret; + param->enable = enable; + result = IARM_RESULT_SUCCESS; + } + } + + IARM_BUS_Unlock(lock); + return result; +} + IARM_Result_t _dsAudioPortTerm(void *arg) {