stream_ducking *sd = NULL;
bool target_matched = false;
hal_ducking_activation_info ducking_activation_info;
+ ret_msg_t ret_msg = RET_MSG_OK;
pa_assert(conn);
pa_assert(msg);
sd = pa_hashmap_get(m->stream_duckings, (const void*)id);
if (!sd) {
pa_log_error("no matched stream ducking for id[%u]", id);
+ ret_msg = RET_MSG_ERROR_INTERNAL;
+ goto _ACTIVATE_DUCKING_DONE;
+ }
- pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INTERNAL], DBUS_TYPE_INVALID));
- pa_assert_se(dbus_connection_send(conn, reply, NULL));
- dbus_message_unref(reply);
-
- return;
+ /* check operating now */
+ if (sd->state == STREAM_DUCKING_STATE_DUCKING ||
+ sd->state == STREAM_DUCKING_STATE_UNDUCKING) {
+ pa_log_error("now ducking or unducking (state:%u)", sd->state);
+ ret_msg = RET_MSG_ERROR_INVALID_STATE;
+ goto _ACTIVATE_DUCKING_DONE;
}
sd->duration = duration;
sd->set_vol = PA_VOLUME_NORM * ratio;
if (enable) {
+ sd->state = STREAM_DUCKING_STATE_DUCKING;
snprintf(sd->vol_key, VOLUME_KEY_LENGTH, "stream_ducking_%u_%s", id, target_stream);
snprintf(sd->target_role, STREAM_ROLE_STR_MAX, "%s", target_stream);
+ } else {
+ sd->state = STREAM_DUCKING_STATE_UNDUCKING;
}
/* set volume ramp factor to target stream */
pa_log_info("ducking stream count(%p,%d)", sd, sd->ducking_stream_count);
- pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_OK], DBUS_TYPE_INVALID));
-
+_ACTIVATE_DUCKING_DONE:
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[ret_msg], DBUS_TYPE_INVALID));
pa_assert_se(dbus_connection_send(conn, reply, NULL));
dbus_message_unref(reply);
+ if (ret_msg != RET_MSG_OK)
+ return;
+
/* notify ducking activation */
ducking_activation_info.target_role = target_stream;
ducking_activation_info.duration = duration;
if (target_matched == false) {
/* change ducking state and send signal here,
because ramp_finish_cb could not be called in this case */
- sd->is_ducked = enable;
+ if (enable)
+ sd->state = STREAM_DUCKING_STATE_DUCKED;
+ else
+ sd->state = STREAM_DUCKING_STATE_UNDUCKED;
- pa_log_info("send signal for ramp finished(but, no stream matched) - is_ducked(%d)", sd->is_ducked);
+ pa_log_info("send signal for ramp finished(but, no stream matched) - state(%u)", sd->state);
- send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, sd->is_ducked);
+ send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, is_stream_ducked(sd));
}
}
pa_stream_manager *m = (pa_stream_manager*)userdata;
stream_ducking *sd = NULL;
dbus_bool_t is_ducked = FALSE;
- ret_msg_t msg_index = RET_MSG_OK;
+ ret_msg_t ret_msg = RET_MSG_OK;
pa_assert(conn);
pa_assert(msg);
/* get stream_ducking */
sd = pa_hashmap_get(m->stream_duckings, (const void *)id);
if (sd) {
- is_ducked = (dbus_bool_t)sd->is_ducked;
- pa_log_info("id[%u], is_ducked[%p,%u]", id, sd, sd->is_ducked);
+ is_ducked = (dbus_bool_t)is_stream_ducked(sd);
+ pa_log_info("id[%u], is_ducked[%p,%d]", id, sd, is_ducked);
} else {
- msg_index = RET_MSG_ERROR_INTERNAL;
+ ret_msg = RET_MSG_ERROR_INTERNAL;
pa_log_error("no matched stream ducking for id[%u]", id);
}
pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_ducked, DBUS_TYPE_INVALID));
- pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[msg_index], DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[ret_msg], DBUS_TYPE_INVALID));
pa_assert_se(dbus_connection_send(conn, reply, NULL));
dbus_message_unref(reply);
RET_MSG_ERROR_INVALID_ARGUMENT,
RET_MSG_ERROR_DEVICE_NOT_FOUND,
RET_MSG_ERROR_POLICY,
+ RET_MSG_ERROR_INVALID_STATE
} ret_msg_t;
typedef enum _focus_acquired_status {
NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED,
} notify_command_type_t;
+typedef enum _stream_ducking_state {
+ STREAM_DUCKING_STATE_UNDUCKED,
+ STREAM_DUCKING_STATE_DUCKING,
+ STREAM_DUCKING_STATE_DUCKED,
+ STREAM_DUCKING_STATE_UNDUCKING
+} stream_ducking_state_t;
+
#define GET_STREAM_NEW_SAMPLE_SPEC_PTR(stream, type) \
(type == STREAM_SINK_INPUT ? &(((pa_sink_input_new_data*)stream)->sample_spec) : &(((pa_source_output_new_data*)stream)->sample_spec))
} stream_parent;
typedef struct _stream_ducking {
- bool is_ducked;
+ stream_ducking_state_t state;
int trigger_index;
int ducking_stream_count;
char vol_key[VOLUME_KEY_LENGTH];
bool stream_is_call_family(pa_object *stream);
bool is_active_device_of_stream(const void *stream, stream_type_t stream_type, const char *device_type);
+bool is_stream_ducked(stream_ducking *sd);
int32_t get_route_type(void *stream, stream_type_t stream_type, bool is_new_data, stream_route_type_t *stream_route_type);
int32_t get_stream_info(pa_stream_manager *m, const char *stream_role, stream_info_per_type *info);
int32_t get_available_streams(pa_stream_manager *m, stream_list *list);
return false;
}
+bool is_stream_ducked(stream_ducking *sd) {
+ pa_assert(sd);
+
+ pa_log_info("state : %u", sd->state);
+
+ switch (sd->state) {
+ case STREAM_DUCKING_STATE_DUCKED:
+ case STREAM_DUCKING_STATE_UNDUCKING:
+ return true;
+ case STREAM_DUCKING_STATE_UNDUCKED:
+ case STREAM_DUCKING_STATE_DUCKING:
+ default:
+ return false;
+ }
+}
+
static void set_media_active_device(pa_stream_manager *m) {
pa_tz_device *playback_device, *capture_device;
stream_info *media_info;
if (stream != i)
continue;
- if ((strlen(sd->target_role) && !sd->is_ducked) ||
- (!strlen(sd->target_role) && sd->is_ducked))
+ if (sd->state == STREAM_DUCKING_STATE_DUCKING ||
+ sd->state == STREAM_DUCKING_STATE_UNDUCKING)
pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_RAMP_FINISH], i);
pa_log_error("remove stream(idx:%u,%p) from idx_ducking_streams, trigger_index(%u)",
}
static pa_hook_result_t sink_input_ramp_finish_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) {
- bool is_ducked = false;
stream_ducking *sd = NULL;
pa_sink_input *stream = NULL;
uint32_t idx;
return PA_HOOK_OK;
}
- is_ducked = i->thread_info.ramp.ramps[0].start > i->thread_info.ramp.ramps[0].end;
-
/* Remove trigger when unducked */
- if (is_ducked == false)
+ if (sd->state == STREAM_DUCKING_STATE_UNDUCKING)
pa_idxset_remove_by_data(sd->idx_ducking_streams, (void *)i, NULL);
/* Send signal when all streams are ducked.
* Note that the condition of increasing count value below is located in
* handle_activate_ducking() of DBus handler. */
if (sd->ducking_stream_count > 0 && --sd->ducking_stream_count == 0) {
- pa_log_info("send signal for ramp finished - is_ducked(%p,%d)", sd, is_ducked);
- sd->is_ducked = is_ducked;
- send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, sd->is_ducked);
+ if (sd->state == STREAM_DUCKING_STATE_DUCKING)
+ sd->state = STREAM_DUCKING_STATE_DUCKED;
+ else
+ sd->state = STREAM_DUCKING_STATE_UNDUCKED;
+
+ pa_log_info("send signal for ramp finished - state(%p,%d)", sd, sd->state);
+
+ send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, is_stream_ducked(sd));
}
return PA_HOOK_OK;