From 069f29434cb928f76131c068911ec06e0b946d98 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 23 Apr 2010 12:00:02 +0100 Subject: volume comparision now far more efficient due to caching of mono volumes as opposed to stereo --- src/pulse-manager.c | 123 ++++++++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 70 deletions(-) diff --git a/src/pulse-manager.c b/src/pulse-manager.c index c527d6d..c84cfcc 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -41,32 +41,22 @@ static void context_success_callback(pa_context *c, int success, void *userdata) static void pulse_sink_input_info_callback(pa_context *c, const pa_sink_input_info *info, int eol, void *userdata); static void pulse_server_info_callback(pa_context *c, const pa_server_info *info, void *userdata); static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, void *userdata); -static void pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata); static void destroy_sink_info(void *value); static gboolean determine_sink_availability(); static void reconnect_to_pulse(); static gboolean has_volume_changed(const pa_sink_info* new_sink, sink_info* cached_sink); -/*static gdouble construct_volume_with_respect_to_balance(pa_cvolume* new_vol, pa_cvolume* cached_vol, pa_channel_map* cached_map);*/ - - -enum { - VOLUME, - BALANCE, - FADE, - LFE, -}; - -#define NUM_TYPES LFE + 1 +static pa_cvolume construct_mono_volume(const pa_cvolume* vol); /** -Refactoring notes -Push all UI updates out through update PA state in the service. +Future Refactoring notes + - Push all UI updates out through update PA state in the service. + - Collapse 3 update_sink_info into one. The essentially do the same thing from different contexts. **/ -/* +/** Entry point -*/ +**/ void establish_pulse_activities(SoundServiceDbus *service) { dbus_service = service; @@ -83,11 +73,19 @@ void establish_pulse_activities(SoundServiceDbus *service) pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); } +/** +get_context() +Needed for testing - bah! +**/ pa_context* get_context() { return pulse_context; } +/** +close_pulse_activites() +Gracefully close our connection with the Pulse async library. +**/ void close_pulse_activites() { if (pulse_context != NULL){ @@ -130,6 +128,10 @@ static void reconnect_to_pulse() pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); } +/** +destroy_sink_info() +item destructor method for the sink_info hash +**/ static void destroy_sink_info(void *value) { sink_info *sink = (sink_info*)value; @@ -184,12 +186,10 @@ static void check_sink_input_while_muted_event(gint sink_index) { g_debug("SINKINPUTWHILEMUTED SIGNAL EVENT TO BE SENT FROM PA MANAGER - check trace for value"); - if (default_sink_is_muted(sink_index) == TRUE) - { + if (default_sink_is_muted(sink_index) == TRUE){ sound_service_dbus_sink_input_while_muted (dbus_service, TRUE); } - else - { + else{ sound_service_dbus_sink_input_while_muted(dbus_service, FALSE); } } @@ -250,11 +250,19 @@ void set_sink_volume(gdouble percent) pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); pa_cvolume_set(&new_volume, 1, new_volume_value); pa_cvolume_set(&cached_sink->volume, cached_sink->channel_map.channels, new_volume_value); - pa_operation_unref(pa_context_set_sink_volume_by_index(pulse_context, DEFAULT_SINK_INDEX, &new_volume, NULL, NULL)); } +static pa_cvolume construct_mono_volume(const pa_cvolume* vol) +{ + pa_cvolume new_volume; + pa_cvolume_init(&new_volume); + new_volume.channels = 1; + pa_volume_t max_vol = pa_cvolume_max(vol); + pa_cvolume_set(&new_volume, 1, max_vol); + return new_volume; +} /**********************************************************************************************************************/ // Pulse-Audio asychronous call-backs @@ -313,7 +321,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in value->index = sink->index; value->name = g_strdup(sink->name); value->mute = !!sink->mute; - value->volume = sink->volume; + value->volume = construct_mono_volume(&sink->volume); value->base_volume = sink->base_volume; value->channel_map = sink->channel_map; g_hash_table_insert(sink_hash, GINT_TO_POINTER(sink->index), value); @@ -387,16 +395,16 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v s->name = g_strdup(info->name); gboolean mute_changed = s->mute != !!info->mute; s->mute = !!info->mute; - g_debug("new balance : %i", (int)(pa_cvolume_get_balance(&info->volume, &info->channel_map) * 100)); - g_debug("cached balance : %i", (int)(pa_cvolume_get_balance(&s->volume, &s->channel_map) * 100)); - g_debug("update_sink_info: new_volume input : %f", (gdouble)(pa_cvolume_avg(&info->volume))); - g_debug("update sink info: cached volume is at: %f", (gdouble)(pa_cvolume_avg(&s->volume))); gboolean volume_changed = has_volume_changed(info, s); - g_debug("update sink info : volume changed = %i", volume_changed); - g_debug("update sink info : compatibility = %i", pa_cvolume_compatible_with_channel_map(&info->volume, &s->channel_map)); +/* g_debug("new balance : %i", (int)(pa_cvolume_get_balance(&info->volume, &info->channel_map) * 100));*/ +/* g_debug("cached balance : %i", (int)(pa_cvolume_get_balance(&s->volume, &s->channel_map) * 100));*/ +/* g_debug("update_sink_info: new_volume input : %f", (gdouble)(pa_cvolume_max(&info->volume)));*/ +/* g_debug("update sink info: cached volume is at: %f", (gdouble)(pa_cvolume_max(&s->volume)));*/ +/* g_debug("update sink info : volume changed = %i", volume_changed);*/ +/* g_debug("update sink info : compatibility = %i", pa_cvolume_compatible_with_channel_map(&info->volume, &s->channel_map));*/ - s->volume = info->volume; + s->volume = construct_mono_volume(&info->volume); s->channel_map = info->channel_map; if(DEFAULT_SINK_INDEX == s->index) @@ -404,7 +412,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v //update the UI if (volume_changed == TRUE && s->mute == FALSE) { - pa_volume_t vol = pa_cvolume_avg(&s->volume); + pa_volume_t vol = pa_cvolume_max(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; g_debug("Updating volume from PA manager with volume = %f", volume_percent); sound_service_dbus_update_sink_volume(dbus_service, volume_percent); @@ -416,7 +424,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v sound_service_dbus_update_sink_mute(dbus_service, s->mute); dbus_menu_manager_update_mute_ui(s->mute); if(s->mute == FALSE){ - pa_volume_t vol = pa_cvolume_avg(&s->volume); + pa_volume_t vol = pa_cvolume_max(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; g_debug("Updating volume from PA manager with volume = %f", volume_percent); sound_service_dbus_update_sink_volume(dbus_service, volume_percent); @@ -431,7 +439,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v value->index = info->index; value->name = g_strdup(info->name); value->mute = !!info->mute; - value->volume = info->volume; + value->volume = construct_mono_volume(&info->volume); value->channel_map = info->channel_map; value->base_volume = info->base_volume; g_hash_table_insert(sink_hash, GINT_TO_POINTER(value->index), value); @@ -446,12 +454,13 @@ static gboolean has_volume_changed(const pa_sink_info* new_sink, sink_info* cach if(pa_cvolume_compatible_with_channel_map(&new_sink->volume, &cached_sink->channel_map) == FALSE) return FALSE; - if(pa_cvolume_equal(&new_sink->volume, &cached_sink->volume) == TRUE) - return FALSE; + pa_cvolume new_vol = construct_mono_volume(&new_sink->volume); - if((int)(pa_cvolume_get_balance(&new_sink->volume, &new_sink->channel_map) * 100) != (int)(pa_cvolume_get_balance(&cached_sink->volume, &cached_sink->channel_map) * 100)) + if(pa_cvolume_equal(&new_vol, &(cached_sink->volume)) == TRUE){ + g_debug("has_volume_changed: volumes appear to be equal? no change triggered!"); return FALSE; - + } + return TRUE; } @@ -487,11 +496,6 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info pa_operation_unref(operation); } -static void pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata) -{ - g_debug("pulse source info callback"); -} - static void subscribed_events_callback(pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) { @@ -503,24 +507,24 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event if(index == DEFAULT_SINK_INDEX) sound_service_dbus_update_sink_availability(dbus_service, FALSE); - g_debug(" - removing sink of index %i from our sink hash - keep the cache tidy !", index); + g_debug("Subscribed_events_callback - removing sink of index %i from our sink hash - keep the cache tidy !", index); g_hash_table_remove(sink_hash, GINT_TO_POINTER(index)); if(index == DEFAULT_SINK_INDEX){ - g_debug("PA_SUBSCRIPTION_EVENT_SINK REMOVAL: default sink %i has been removed.", DEFAULT_SINK_INDEX); + g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK REMOVAL: default sink %i has been removed.", DEFAULT_SINK_INDEX); DEFAULT_SINK_INDEX = -1; determine_sink_availability(); } - g_debug(" - Now what is our default sink : %i", DEFAULT_SINK_INDEX); + g_debug("subscribed_events_callback - Now what is our default sink : %i", DEFAULT_SINK_INDEX); } else { - g_debug("PA_SUBSCRIPTION_EVENT_SINK: a generic sink event - will trigger an update"); + g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK: a generic sink event - will trigger an update"); pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata)); } break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - g_debug("PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!"); + g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { //handle the sink input remove event - not relevant for current design @@ -530,29 +534,12 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event pa_operation_unref(pa_context_get_sink_input_info(c, index, pulse_sink_input_info_callback, userdata)); } break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - g_debug("PA_SUBSCRIPTION_EVENT_SOURCE of some description ???"); - - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) - { - //TODO handle the remove event - } - else - { - pa_operation *o; - if (!(o = pa_context_get_source_info_by_index(c, index, pulse_source_info_callback, userdata))) { - g_warning("pa_context_get_source_info_by_index() failed"); - return; - } - pa_operation_unref(o); - } - break; case PA_SUBSCRIPTION_EVENT_SERVER: - g_debug("PA_SUBSCRIPTION_EVENT_SERVER change of some description ???"); + g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SERVER change of some description ???"); pa_operation *o; if(!(o = pa_context_get_server_info(c, pulse_server_info_callback, userdata))) { - g_warning("pa_context_get_server_info() failed"); + g_warning("subscribed_events_callback - pa_context_get_server_info() failed"); return; } pa_operation_unref(o); @@ -591,12 +578,8 @@ static void context_state_callback(pa_context *c, void *userdata) { if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) (PA_SUBSCRIPTION_MASK_SINK| - PA_SUBSCRIPTION_MASK_SOURCE| PA_SUBSCRIPTION_MASK_SINK_INPUT| - PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT| - PA_SUBSCRIPTION_MASK_CLIENT| - PA_SUBSCRIPTION_MASK_SERVER| - PA_SUBSCRIPTION_MASK_CARD), NULL, NULL))) { + PA_SUBSCRIPTION_MASK_SERVER), NULL, NULL))) { g_warning("pa_context_subscribe() failed"); return; } -- cgit v1.2.3