From: Sangchul Lee Date: Mon, 22 Apr 2019 01:42:49 +0000 (+0900) Subject: Add internal API for setting virtual stream volume X-Git-Tag: submit/tizen/20190423.020435^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F79%2F204179%2F2;p=platform%2Fcore%2Fapi%2Fsound-manager.git Add internal API for setting virtual stream volume [Version] 0.5.23 [Issue Type] New feature Change-Id: Ia803cdb4c09ceed2de53d577420e44fa2f34320c Signed-off-by: Sangchul Lee --- diff --git a/include/sound_manager_internal.h b/include/sound_manager_internal.h index f2847c2..0bc8972 100644 --- a/include/sound_manager_internal.h +++ b/include/sound_manager_internal.h @@ -671,6 +671,24 @@ int sound_manager_start_virtual_stream(virtual_sound_stream_h virtual_stream); */ int sound_manager_stop_virtual_stream(virtual_sound_stream_h virtual_stream); +/** + * @internal + * @brief Sets the virtual stream volume. + * @since_tizen 5.5 + * @param[in] virtual_stream The handle of virtual stream + * @param[in] ratio The volume ratio to be set (Min.:0.0 ~ Max.:1.0, default:1.0) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SOUND_MANAGER_ERROR_INVALID_STATE Invalid state + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @see sound_manager_create_virtual_stream() + * @see sound_manager_destroy_virtual_stream() + * @see sound_manager_start_virtual_stream() + */ +int sound_manager_set_virtual_stream_volume(virtual_sound_stream_h virtual_stream, double ratio); + /** * @internal * @brief Set sound filter and apply to audio streams given selected stream type. diff --git a/include/sound_manager_private.h b/include/sound_manager_private.h index 1c72fc4..127b5c8 100644 --- a/include/sound_manager_private.h +++ b/include/sound_manager_private.h @@ -337,6 +337,10 @@ int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream); int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream); +int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio); + +int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio); + #ifdef __cplusplus } #endif diff --git a/packaging/capi-media-sound-manager.spec b/packaging/capi-media-sound-manager.spec index a6c81c9..b1031bd 100644 --- a/packaging/capi-media-sound-manager.spec +++ b/packaging/capi-media-sound-manager.spec @@ -1,6 +1,6 @@ Name: capi-media-sound-manager Summary: Sound Manager library -Version: 0.5.22 +Version: 0.5.23 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/sound_manager_internal.c b/src/sound_manager_internal.c index a7d1796..2e965c2 100644 --- a/src/sound_manager_internal.c +++ b/src/sound_manager_internal.c @@ -417,6 +417,18 @@ int sound_manager_stop_virtual_stream(virtual_sound_stream_h virtual_stream) return _convert_sound_manager_error_code(__func__, ret); } +int sound_manager_set_virtual_stream_volume(virtual_sound_stream_h virtual_stream, double ratio) +{ + int ret = MM_ERROR_NONE; + virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)virtual_stream; + + LOGI(">> enter"); + + ret = _set_virtual_stream_volume(vstream_h, ratio); + + return _convert_sound_manager_error_code(__func__, ret); +} + static int _convert_filter(sound_filter_e filter, char **filter_str, char **filter_params_str) { if (filter_str == NULL || filter_params_str == NULL) diff --git a/src/sound_manager_private.c b/src/sound_manager_private.c index 0258faf..caec215 100644 --- a/src/sound_manager_private.c +++ b/src/sound_manager_private.c @@ -29,6 +29,7 @@ #define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL "GetVolumeMaxLevel" #define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL "GetVolumeLevel" #define PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL "SetVolumeLevel" +#define PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATIO "SetVolumeRatio" #define PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE "GetCurrentVolumeType" #define PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH "GetCurrentMediaRoutingPath" #define PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS "UpdateFocusStatus" @@ -2437,7 +2438,6 @@ int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream) if (virtual_stream->stream_info->stream_conf_info.avail_out_devices[0] != NULL) io_direction |= SOUND_STREAM_DIRECTION_OUTPUT; - /* LOCK the pa_threaded_mainloop */ pa_threaded_mainloop_lock(virtual_stream->pa_mainloop); for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { @@ -2488,13 +2488,11 @@ int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream) } virtual_stream->state = _VSTREAM_STATE_RUNNING; - /* UNLOCK the pa_threaded_mainloop */ pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); return ret; //LCOV_EXCL_START ERROR_WITH_UNLOCK: - /* UNLOCK the pa_threaded_mainloop */ pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { @@ -2516,7 +2514,6 @@ int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream) SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream); SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_RUNNING); - /* LOCK the pa_threaded_mainloop */ pa_threaded_mainloop_lock(virtual_stream->pa_mainloop); for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { @@ -2537,10 +2534,82 @@ int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream) } } - /* UNLOCK the pa_threaded_mainloop */ pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); virtual_stream->state = _VSTREAM_STATE_READY; return ret; } + +int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio) +{ + int ret = MM_ERROR_NONE; + GDBusConnection *conn = NULL; + GError *err = NULL; + GVariant *result = NULL; + const gchar *dbus_ret = NULL; + + if ((ret = __get_dbus_connection(&conn))) + return ret; + + result = g_dbus_connection_call_sync(conn, + PA_BUS_NAME, + PA_STREAM_MANAGER_OBJECT_PATH, + PA_STREAM_MANAGER_INTERFACE, + PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATIO, + g_variant_new("(sud)", (direction == SOUND_STREAM_DIRECTION_OUTPUT) ? "out" : "in", stream_index, ratio), + G_VARIANT_TYPE("(s)"), + G_DBUS_CALL_FLAGS_NONE, + 2000, + NULL, + &err); + if (!result || err) { + LOGE("g_dbus_connection_call_sync() for SET_VOLUME_RATIO error (%s)", err ? err->message : NULL); + ret = _convert_dbus_error(err ? err->message : NULL); + g_error_free(err); + goto LEAVE; + } + g_variant_get(result, "(&s)", &dbus_ret); + LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret); + if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret))) + ret = MM_ERROR_INVALID_ARGUMENT; + else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret))) + ret = MM_ERROR_SOUND_NO_DATA; + else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) + ret = MM_ERROR_SOUND_INTERNAL; + +LEAVE: + g_variant_unref(result); + g_object_unref(conn); + + return ret; +} + +int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio) +{ + int ret = MM_ERROR_NONE; + int i = 0; + uint32_t index; + + SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream); + SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_RUNNING); + + pa_threaded_mainloop_lock(virtual_stream->pa_mainloop); + + for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { + if (virtual_stream->pa_stream[i]) { + index = pa_stream_get_index(virtual_stream->pa_stream[i]); + if ((ret = _set_volume_ratio(index, i + 1, ratio))) { + if (ret == MM_ERROR_SOUND_NO_DATA) { + LOGE("something wrong, no match index of %u", index); + ret = MM_ERROR_SOUND_INTERNAL; + } + break; + } + } + } + + pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); + + return ret; +} \ No newline at end of file diff --git a/test/sound_manager_test.c b/test/sound_manager_test.c index 0f7eb73..4027100 100644 --- a/test/sound_manager_test.c +++ b/test/sound_manager_test.c @@ -88,6 +88,7 @@ enum { CURRENT_STATUS_START_VIRTUAL_STREAM, CURRENT_STATUS_STOP_VIRTUAL_STREAM, CURRENT_STATUS_DESTROY_VIRTUAL_STREAM, + CURRENT_STATUS_SET_VIRTUAL_STREAM_VOLUME, CURRENT_STATUS_SET_FILTER, CURRENT_STATUS_SET_FILTER_PRESET, CURRENT_STATUS_UNSET_FILTER, @@ -296,6 +297,8 @@ void _interpret_main_menu(char *cmd) g_menu_state = CURRENT_STATUS_STOP_VIRTUAL_STREAM; else if (strncmp(cmd, "vdt", MAX_CMD_LEN) == 0) g_menu_state = CURRENT_STATUS_DESTROY_VIRTUAL_STREAM; + else if (strncmp(cmd, "vsv", MAX_CMD_LEN) == 0) + g_menu_state = CURRENT_STATUS_SET_VIRTUAL_STREAM_VOLUME; else if (strncmp(cmd, "sft", MAX_CMD_LEN) == 0) g_menu_state = CURRENT_STATUS_SET_FILTER; else if (strncmp(cmd, "sfp", MAX_CMD_LEN) == 0) @@ -393,8 +396,9 @@ void display_sub_basic() g_print("sso. *Set option for stream routing\n"); g_print("vcr. *Create VStream\t"); g_print("vsr. *Start VStream\t"); - g_print("vst. *Stop VStream\t"); - g_print("vdt. *Destroy VStream\n"); + g_print("vsv. *Set VStream Volume\n"); + g_print("vdt. *Destroy VStream\t"); + g_print("vst. *Stop VStream\n"); g_print("sft. *Set Filter\t"); g_print("sfp. *Set Filter Preset\t"); g_print("uft. *Unset Filter\n"); @@ -527,6 +531,8 @@ static void displaymenu() g_print("*** press enter to stop virtual stream\n"); else if (g_menu_state == CURRENT_STATUS_DESTROY_VIRTUAL_STREAM) g_print("*** press enter to destroy virtual stream\n"); + else if (g_menu_state == CURRENT_STATUS_SET_VIRTUAL_STREAM_VOLUME) + g_print("*** input volume ratio of virtual stream (Min:0.0 ~ Max:1.0)\n"); else if (g_menu_state == CURRENT_STATUS_SET_FILTER) g_print("*** input filter type of media stream (0:LOW_PASS 1:HIGH_PASS 2:DELAY 3:SOUNDALIVE)\n"); else if (g_menu_state == CURRENT_STATUS_SET_FILTER_PRESET) @@ -665,12 +671,21 @@ void _device_connected_cb(sound_device_h device, bool is_connected, void *user_d char *type, *name; const char *direc, *state; bool is_running = false; + int ret; + sound_device_type_e device_type; _get_device_props_simple(device, &id, &type, &name, &direc, &state, &vendor_id, &product_id, &is_running); g_print("[ Device #%d %s %s ] %s\n", id, type, name, is_connected ? "Connected" : "Disconnected"); g_print(" Direc[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ], ProductID[ %04x ]\n", direc, state, is_running, vendor_id, product_id); + + + ret = sound_manager_get_current_media_playback_device_type(&device_type); + if (ret) + g_print("fail to sound_manager_get_current_media_playback_device_type, ret(0x%x)\n", ret); + else + g_print("current media playback device type is [%d] (0:BuiltinSPK 1:BuiltinRcv 2:BuiltinMic 3:AudioJack 4:BTMedia 5:HDMI 6:Forwarding 7:USBAduio 8:BTVoice)\n", device_type); } void _device_running_changed_cb(sound_device_h device, bool is_running, void *user_data) @@ -1963,6 +1978,22 @@ static void interpret(char *cmd) reset_menu_state(); break; } + case CURRENT_STATUS_SET_VIRTUAL_STREAM_VOLUME: { + int ret = SOUND_MANAGER_ERROR_NONE; + double ratio = 1.0; + + ratio = atof(cmd); + + if (g_vstream_h) { + ret = sound_manager_set_virtual_stream_volume(g_vstream_h, ratio); + if (ret) + g_print("fail to sound_manager_set_virtual_stream_volume(), ret(0x%x)\n", ret); + else + g_print("success to sound_manager_set_virtual_stream_volume(), ratio(%f), ret(0x%x)\n", ratio, ret); + } + reset_menu_state(); + break; + } case CURRENT_STATUS_SET_FILTER: { int ret = SOUND_MANAGER_ERROR_NONE; sound_filter_e filter;