aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-04-23 14:22:19 +0100
committerConor Curran <conor.curran@canonical.com>2010-04-23 14:22:19 +0100
commit7dd979c68888c9ac9c423aadf8a4c16296132551 (patch)
tree7b59c2a0e9661c0f88f5f7232f08d8244d9a4258
parent164f6fe4575215d00a935b20152c222e1d356fda (diff)
parent069f29434cb928f76131c068911ec06e0b946d98 (diff)
downloadayatana-indicator-sound-7dd979c68888c9ac9c423aadf8a4c16296132551.tar.gz
ayatana-indicator-sound-7dd979c68888c9ac9c423aadf8a4c16296132551.tar.bz2
ayatana-indicator-sound-7dd979c68888c9ac9c423aadf8a4c16296132551.zip
all volumes are now treated as if they are mono - most efficient way to deal with multichannel setups, balance and single slider control
-rw-r--r--src/pulse-manager.c123
1 files 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;
}