Commit 27327cb2 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

#5607: Implment pulseaudio audio device selection in user interface

parent f97fdca0
......@@ -64,6 +64,10 @@ class AudioLayer {
AudioLayer();
virtual ~AudioLayer();
/**
* Function that returns the list of available audio device provided the stream
* type: AUDIO_STREAM_CAPTURE, AUDIO_STREAM_PLAYBACK.
*/
virtual std::vector<std::string> getAudioDeviceList(AudioStreamDirection dir) const = 0;
/**
......
......@@ -189,12 +189,16 @@ bool PulseLayer::inSourceList(const std::string &deviceName) const
std::vector<std::string> PulseLayer::getAudioDeviceList(AudioStreamDirection dir) const
{
std::vector<std::string> emptyVector;
if(AUDIO_STREAM_CAPTURE == dir) {
return sinkList_;
}
if(AUDIO_STREAM_PLAYBACK) {
else if(AUDIO_STREAM_PLAYBACK == dir) {
return sourceList_;
}
return emptyVector;
}
void PulseLayer::createStreams(pa_context* c)
......
......@@ -1975,10 +1975,8 @@ std::vector<std::string> ManagerImpl::getAudioOutputDeviceList()
audioLayerMutexLock();
AlsaLayer *alsalayer = dynamic_cast<AlsaLayer*>(audiodriver_);
if (alsalayer)
devices = alsalayer->getAudioDeviceList(AUDIO_STREAM_PLAYBACK);
if (audiodriver_)
devices = audiodriver_->getAudioDeviceList(AUDIO_STREAM_PLAYBACK);
audioLayerMutexUnlock();
return devices;
......@@ -1994,10 +1992,8 @@ std::vector<std::string> ManagerImpl::getAudioInputDeviceList()
audioLayerMutexLock();
AlsaLayer *alsalayer = dynamic_cast<AlsaLayer *>(audiodriver_);
if (alsalayer)
devices = alsalayer->getAudioDeviceList(AUDIO_STREAM_CAPTURE);
if (audiodriver_)
devices = audiodriver_->getAudioDeviceList(AUDIO_STREAM_CAPTURE);
audioLayerMutexUnlock();
......
......@@ -1064,7 +1064,7 @@ static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
GtkWidget *box = audiocodecs_box(currentAccount);
GtkWidget *box = create_audiocodecs_box(currentAccount);
// Box for the audiocodecs
GtkWidget *audiocodecs = gnome_main_section_new(_("Audio"));
......
/*
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -28,6 +29,8 @@
* as that of the covered work.
*/
#include <gtk/gtk.h>
#include "audioconf.h"
#include "utils.h"
......@@ -52,8 +55,9 @@ static GtkWidget *codecMoveUpButton;
static GtkWidget *codecMoveDownButton;
static GtkWidget *codecTreeView; // View used instead of store to get access to selection
static GtkWidget *pulse;
static GtkWidget *alsabox;
static GtkWidget *alsa_conf;
static GtkWidget *alsabox; // alsa audio plugin/device selection menu
static GtkWidget *pulseaudiobox; // pulseaudio device selection menu
static GtkWidget *audio_conf;
// Codec properties ID
enum {
......@@ -65,6 +69,7 @@ enum {
};
static void active_is_always_recording(void);
static GtkWidget *device_selection_box_alsa(void);
/**
* Fills the tree list with supported codecs
......@@ -100,7 +105,7 @@ static void preferences_dialog_fill_codec_list(account_t *a)
/**
* Fill store with output audio plugins
*/
void
static void
preferences_dialog_fill_audio_plugin_list()
{
gtk_list_store_clear(pluginlist);
......@@ -121,11 +126,13 @@ preferences_dialog_fill_audio_plugin_list()
}
}
void
static void
preferences_dialog_fill_output_audio_device_list()
{
gtk_list_store_clear(outputlist);
DEBUG("FILL OUTPUT DEVICE LIST");
// Call dbus to retrieve list
for (gchar **list = dbus_get_audio_output_device_list(); *list ; list++) {
int device_index = dbus_get_audio_device_index(*list);
......@@ -135,11 +142,13 @@ preferences_dialog_fill_output_audio_device_list()
}
}
void
static void
preferences_dialog_fill_ringtone_audio_device_list()
{
gtk_list_store_clear(ringtonelist);
DEBUG("FILL RINGTONE DEVICE LIST");
// Call dbus to retreive output device
for (gchar **list = dbus_get_audio_output_device_list(); *list; list++) {
int device_index = dbus_get_audio_device_index(*list);
......@@ -149,12 +158,12 @@ preferences_dialog_fill_ringtone_audio_device_list()
}
}
void
static void
select_active_output_audio_device()
{
gboolean show_alsa = must_show_alsa_conf();
SelectedAudioLayer selected = get_selected_audio_api();
if(!show_alsa)
if(ALSA_LAYER_SELECTED != selected)
return;
// Select active output device on server
......@@ -189,10 +198,12 @@ select_active_output_audio_device()
/**
* Select active output audio device
*/
void
static void
select_active_ringtone_audio_device()
{
if (must_show_alsa_conf()) {
SelectedAudioLayer selected = get_selected_audio_api();
if (ALSA_LAYER_SELECTED == selected) {
// Select active ringtone device on server
gchar **devices = dbus_get_current_audio_devices_index();
int currentDeviceIndex = atoi(devices[2]);
......@@ -220,11 +231,13 @@ select_active_ringtone_audio_device()
}
}
void
static void
preferences_dialog_fill_input_audio_device_list()
{
gtk_list_store_clear(inputlist);
DEBUG("FILL INPUT DEVICE LIST");
// Call dbus to retreive list
gchar **list = dbus_get_audio_input_device_list();
......@@ -238,10 +251,12 @@ preferences_dialog_fill_input_audio_device_list()
}
void
static void
select_active_input_audio_device()
{
if (must_show_alsa_conf()) {
SelectedAudioLayer selected = get_selected_audio_api();
if (ALSA_LAYER_SELECTED == selected) {
// Select active input device on server
gchar **devices = dbus_get_current_audio_devices_index();
int currentDeviceIndex = atoi(devices[1]);
......@@ -298,7 +313,7 @@ select_output_audio_plugin(GtkComboBox* widget, gpointer data UNUSED)
}
}
void
static void
select_active_output_audio_plugin()
{
// Select active output device on server
......@@ -516,7 +531,7 @@ static void codec_move_down(GtkButton *button UNUSED, gpointer data)
codec_move(FALSE, data);
}
GtkWidget* audiocodecs_box(account_t *a)
GtkWidget* create_audiocodecs_box(account_t *a)
{
GtkWidget *audiocodecs_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_container_set_border_width(GTK_CONTAINER(audiocodecs_hbox), 10);
......@@ -588,19 +603,25 @@ GtkWidget* audiocodecs_box(account_t *a)
}
void
select_audio_manager(void)
switch_audio_manager(void)
{
if (!must_show_alsa_conf() && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pulse))) {
dbus_set_audio_manager(ALSA_API_STR);
alsabox = alsa_box();
gtk_container_add(GTK_CONTAINER(alsa_conf), alsabox);
gtk_widget_show(alsa_conf);
gtk_widget_set_sensitive(alsa_conf, TRUE);
SelectedAudioLayer selected = get_selected_audio_api();
if (PULSEAUDIO_LAYER_SELECTED == selected) {
dbus_set_audio_manager(ALSA_API_STR);
gtk_widget_set_sensitive(audio_conf, TRUE);
gtk_widget_hide(pulseaudiobox);
gtk_container_remove(GTK_CONTAINER(audio_conf), pulseaudiobox);
gtk_container_add(GTK_CONTAINER(audio_conf), alsabox);
gtk_widget_show(alsabox);
gtk_action_set_sensitive(volumeToggle_, TRUE);
} else if (must_show_alsa_conf() && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pulse))) {
} else if (ALSA_LAYER_SELECTED == selected) {
dbus_set_audio_manager(PULSEAUDIO_API_STR);
gtk_container_remove(GTK_CONTAINER(alsa_conf) , alsabox);
gtk_widget_hide(alsa_conf);
gtk_widget_set_sensitive(audio_conf, TRUE);
gtk_widget_hide(alsabox);
gtk_container_remove(GTK_CONTAINER(audio_conf), alsabox);
gtk_container_add(GTK_CONTAINER(audio_conf), pulseaudiobox);
gtk_widget_show(pulseaudiobox);
if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(volumeToggle_))) {
main_window_volume_controls(FALSE);
......@@ -656,7 +677,7 @@ active_is_always_recording(void)
dbus_set_is_always_recording(!dbus_get_is_always_recording());
}
GtkWidget* alsa_box()
GtkWidget* device_selection_box_alsa()
{
GtkWidget *alsa_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_widget_show(alsa_hbox);
......@@ -762,6 +783,92 @@ GtkWidget* alsa_box()
return alsa_hbox;
}
GtkWidget *device_selection_box_pulseaudio()
{
GtkWidget *pulseaudio_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_widget_show(pulseaudio_hbox);
GtkWidget *table = gtk_table_new(6, 3, FALSE);
gtk_table_set_col_spacing(GTK_TABLE(table), 0, 40);
gtk_box_pack_start(GTK_BOX(pulseaudio_hbox), table, TRUE, TRUE, 1);
gtk_widget_show(table);
// Device : Output Device
// Create title label
DEBUG("Audio: Configuration output");
GtkWidget *label = gtk_label_new(_("Output"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(label);
// Set choices of output devices
outputlist = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
preferences_dialog_fill_output_audio_device_list();
output = gtk_combo_box_new_with_model(GTK_TREE_MODEL(outputlist));
select_active_output_audio_device();
gtk_label_set_mnemonic_widget(GTK_LABEL(label), output);
g_signal_connect(G_OBJECT(output), "changed", G_CALLBACK(select_audio_output_device), output);
// Set rendering
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(output), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(output), renderer, "text", 0, NULL);
gtk_table_attach(GTK_TABLE(table), output, 2, 3, 3, 4, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(output);
// Device : Input device
// Create title label
DEBUG("Audio: Configuration input");
label = gtk_label_new(_("Input"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(label);
// Set choice of ouput devices
inputlist = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
preferences_dialog_fill_input_audio_device_list();
input = gtk_combo_box_new_with_model(GTK_TREE_MODEL(inputlist));
select_active_input_audio_device();
gtk_label_set_mnemonic_widget(GTK_LABEL(label), input);
g_signal_connect(G_OBJECT(input), "changed", G_CALLBACK(select_audio_input_device), input);
// Set rendering
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(input), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(input), renderer, "text", 0, NULL);
gtk_table_attach(GTK_TABLE(table), input, 2, 3, 4, 5, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(input);
// Device : Ringtone device
// Create title label
DEBUG("Audio: Configuration ringtone");
label = gtk_label_new(_("Ringtone"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(label);
// set choices of ringtone devices
ringtonelist = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
preferences_dialog_fill_ringtone_audio_device_list();
ringtone = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ringtonelist));
select_active_ringtone_audio_device();
gtk_label_set_mnemonic_widget(GTK_LABEL(label), output);
g_signal_connect(G_OBJECT(ringtone), "changed", G_CALLBACK(select_audio_ringtone_device), output);
// Set rendering
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(ringtone), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(ringtone), renderer, "text", 0, NULL);
gtk_table_attach(GTK_TABLE(table), ringtone, 2, 3, 5, 6, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(ringtone);
gtk_widget_show_all(pulseaudio_hbox);
// Update the combo box
update_device_widget(dbus_get_current_audio_output_plugin());
return pulseaudio_hbox;
}
static void record_path_changed(GtkFileChooser *chooser , GtkLabel *label UNUSED)
{
gchar* path;
......@@ -772,42 +879,55 @@ static void record_path_changed(GtkFileChooser *chooser , GtkLabel *label UNUSED
GtkWidget* create_audio_configuration()
{
/* Main widget */
GtkWidget *frame = NULL;
GtkWidget *table = NULL;
GtkWidget *audio_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_container_set_border_width(GTK_CONTAINER(audio_vbox), 10);
GtkWidget *frame;
GtkWidget *table;
gnome_main_section_new_with_table(_("Sound Manager"), &frame, &table, 1, 4);
gtk_box_pack_start(GTK_BOX(audio_vbox), frame, FALSE, FALSE, 0);
gchar *audio_manager = dbus_get_audio_manager();
gboolean pulse_audio = FALSE;
if (g_strcmp0(audio_manager, PULSEAUDIO_API_STR) == 0)
pulse_audio = TRUE;
g_free(audio_manager);
SelectedAudioLayer selected = get_selected_audio_api();
pulse = gtk_radio_button_new_with_mnemonic(NULL , _("_Pulseaudio"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pulse), pulse_audio);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pulse), (selected == PULSEAUDIO_LAYER_SELECTED) ? TRUE : FALSE);
gtk_table_attach(GTK_TABLE(table), pulse, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
GtkWidget *alsa = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(pulse), _("_ALSA"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alsa), !pulse_audio);
g_signal_connect(G_OBJECT(alsa), "clicked", G_CALLBACK(select_audio_manager), NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alsa), (selected == ALSA_LAYER_SELECTED) ? TRUE : FALSE);
g_signal_connect(G_OBJECT(alsa), "clicked", G_CALLBACK(switch_audio_manager), NULL);
gtk_table_attach(GTK_TABLE(table), alsa, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
// Box for the ALSA configuration
alsa_conf = gnome_main_section_new(_("ALSA settings"));
gtk_box_pack_start(GTK_BOX(audio_vbox), alsa_conf, FALSE, FALSE, 0);
gtk_widget_show(alsa_conf);
if (must_show_alsa_conf()) {
// Box for the ALSA configuration
alsabox = alsa_box();
gtk_container_add(GTK_CONTAINER(alsa_conf) , alsabox);
gtk_widget_hide(alsa_conf);
}
// Box for audio device selection
audio_conf = gnome_main_section_new(_("Audio Device Selection"));
gtk_box_pack_start(GTK_BOX(audio_vbox), audio_conf, FALSE, FALSE, 0);
gtk_widget_show(audio_conf);
// Alsa specific device configuration
alsabox = device_selection_box_alsa();
g_object_ref(G_OBJECT(alsabox));
// Pulseaudio specific device configuration
pulseaudiobox = device_selection_box_pulseaudio();
g_object_ref(G_OBJECT(pulseaudiobox));
switch (selected) {
case ALSA_LAYER_SELECTED:
gtk_container_add(GTK_CONTAINER(audio_conf), alsabox);
gtk_widget_hide(pulseaudiobox);
gtk_widget_show(alsabox);
break;
case PULSEAUDIO_LAYER_SELECTED:
gtk_container_add(GTK_CONTAINER(audio_conf), pulseaudiobox);
gtk_widget_hide(alsabox);
gtk_widget_show(pulseaudiobox);
break;
case UNKNOWN_AUDIO_LAYER:
default:
DEBUG("Error: Unknown audio layer");
break;
};
gnome_main_section_new_with_table(_("Recordings"), &frame, &table, 2, 3);
gtk_box_pack_start(GTK_BOX(audio_vbox), frame, FALSE, FALSE, 0);
......@@ -868,19 +988,27 @@ GtkWidget* create_audio_configuration()
gtk_widget_show_all(audio_vbox);
if (!pulse_audio)
gtk_widget_show(alsa_conf);
else
gtk_widget_hide(alsa_conf);
return audio_vbox;
}
/** Show/Hide the alsa configuration panel */
gboolean must_show_alsa_conf()
SelectedAudioLayer get_selected_audio_api()
{
SelectedAudioLayer selected = UNKNOWN_AUDIO_LAYER;
gchar *api = dbus_get_audio_manager();
int ret = g_strcmp0(api, ALSA_API_STR);
if(g_strcmp0(api, ALSA_API_STR) == 0) {
selected = ALSA_LAYER_SELECTED;
}
else if (g_strcmp0(api, PULSEAUDIO_API_STR) == 0) {
selected = PULSEAUDIO_LAYER_SELECTED;
}
else {
DEBUG("ERROR UNKNOWN SELECTION");
}
g_free(api);
return ret == 0;
return selected;
}
......@@ -33,15 +33,28 @@
#include "actions.h"
/**
* Selected audio layer enumeration type
*/
typedef enum SelectedAudioLayer_ {
ALSA_LAYER_SELECTED,
PULSEAUDIO_LAYER_SELECTED,
UNKNOWN_AUDIO_LAYER,
} SelectedAudioLayer;
/**
* Return the full audio configuration panel
*/
GtkWidget* create_audio_configuration (void);
GtkWidget* api_box();
GtkWidget* alsa_box();
GtkWidget* pulse_box();
GtkWidget* audiocodecs_box();
GtkWidget* ringtone_box();
/**
* Returns the audio codec activation/deactivation & preference ordering box
*/
GtkWidget* create_audiocodecs_box(account_t *);
gboolean get_api();
gboolean must_show_alsa_conf ();
/**
* Returns the type of the selected api (i.e. ALSA or PULSEAUDIO)
*/
SelectedAudioLayer get_selected_audio_api(void);
#endif // __AUDIO_CONF_H
......@@ -47,10 +47,10 @@
#include "addressbook-config.h"
#include "shortcuts-config.h"
#include "hooks-config.h"
#include "audioconf.h"
#include "uimanager.h"
#include "unused.h"
#include "mainwindow.h"
#include "audioconf.h"
/**
* Local variables
......
......@@ -38,42 +38,6 @@
* @brief The Preferences window.
*/
/**
* Fill the input audio plugin list widget with the data the server send
* Currently not used
*/
void preferences_dialog_fill_input_audio_plugin_list();
/**
* Fill the output audio plugin list widget with the data the server send
*/
void preferences_dialog_fill_output_audio_plugin_list();
/**
* Fill the output audio device list widget with the data the server send
*/
void preferences_dialog_fill_output_audio_device_list();
/**
* Select an output audio device
*/
void select_active_output_audio_device();
/**
* Fill the input audio device list widget with the data the server send
*/
void preferences_dialog_fill_input_audio_device_list();
/**
* Select an input audio device
*/
void select_active_input_audio_device();
/**
* Select an output audio plugin
*/
void select_active_output_audio_plugin();
/**
* Update the combo box state.
* If the default plugin has been selected, the audio devices have to been unsensitive
......
......@@ -140,7 +140,7 @@
/** Behaviour of the main window on incoming calls */
#define __POPUP_WINDOW (eel_gconf_get_integer (POPUP_ON_CALL))
/** Show/Hide the volume controls */
#define SHOW_VOLUME (eel_gconf_get_integer (SHOW_VOLUME_CONTROLS) && must_show_alsa_conf())
#define SHOW_VOLUME (eel_gconf_get_integer (SHOW_VOLUME_CONTROLS) && (ALSA_LAYER_SELECTED == get_selected_audio_api()))
/** DTMF type */
#define OVERRTP "overrtp"
......
......@@ -1576,9 +1576,10 @@ create_menus(GtkUIManager *ui_manager)
volumeToggle_ = gtk_ui_manager_get_action(ui_manager, "/MenuBar/ViewMenu/VolumeControls");
// Set the toggle buttons
SelectedAudioLayer selected = get_selected_audio_api();
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(ui_manager, "/MenuBar/ViewMenu/Dialpad")), eel_gconf_get_boolean(CONF_SHOW_DIALPAD));
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(volumeToggle_),(gboolean) SHOW_VOLUME);
gtk_action_set_sensitive(volumeToggle_, must_show_alsa_conf());
gtk_action_set_sensitive(volumeToggle_, (ALSA_LAYER_SELECTED == selected) ? TRUE : FALSE);
gtk_action_set_sensitive(gtk_ui_manager_get_action(ui_manager, "/MenuBar/ViewMenu/Toolbar"), FALSE);
/* Add the loading icon at the right of the toolbar. It is used for addressbook searches. */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment