diff --git a/sflphone-gtk/src/audioconf.c b/sflphone-gtk/src/audioconf.c index f54bb5f7b87ffad355af9e8804b14e67bb47d970..b983a328e38c7dcacd21bf24bed45e7608e31b96 100644 --- a/sflphone-gtk/src/audioconf.c +++ b/sflphone-gtk/src/audioconf.c @@ -30,6 +30,9 @@ GtkWidget *plugin; GtkWidget *codecMoveUpButton; GtkWidget *codecMoveDownButton; GtkWidget *codecTreeView; // View used instead of store to get access to selection +GtkWidget *pulse; +GtkWidget *alsabox; +GtkWidget *alsa_conf; // Codec properties ID enum { @@ -105,13 +108,13 @@ config_window_fill_output_audio_plugin_list() void config_window_fill_output_audio_device_list() { - /* - GtkTreeIter iter; - gchar** list; - gchar** audioDevice; - int index; - gtk_list_store_clear(outputlist); + GtkTreeIter iter; + gchar** list; + gchar** audioDevice; + int index; + + gtk_list_store_clear(outputlist); // Call dbus to retreive list list = dbus_get_audio_output_device_list(); @@ -120,12 +123,12 @@ config_window_fill_output_audio_device_list() int c = 0; for(audioDevice = list; *list ; list++) { - index = dbus_get_audio_device_index( *list ); - gtk_list_store_append(outputlist, &iter); - gtk_list_store_set(outputlist, &iter, 0, *list, 1, index, -1); - c++; + index = dbus_get_audio_device_index( *list ); + gtk_list_store_append(outputlist, &iter); + gtk_list_store_set(outputlist, &iter, 0, *list, 1, index, -1); + c++; } - */ + } /** @@ -134,35 +137,35 @@ config_window_fill_output_audio_device_list() void select_active_output_audio_device() { - /* - GtkTreeModel* model; - GtkTreeIter iter; - gchar** devices; - int currentDeviceIndex; - int deviceIndex; + + GtkTreeModel* model; + GtkTreeIter iter; + gchar** devices; + int currentDeviceIndex; + int deviceIndex; // Select active output device on server - devices = dbus_get_current_audio_devices_index(); - currentDeviceIndex = atoi(devices[0]); + //devices = dbus_get_current_audio_devices_index(); + currentDeviceIndex = 0;//atoi(devices[0]); printf(_("audio device index for output = %d\n"), currentDeviceIndex); model = gtk_combo_box_get_model(GTK_COMBO_BOX(output)); // Find the currently set output device gtk_tree_model_get_iter_first(model, &iter); do { - gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1); - if(deviceIndex == currentDeviceIndex) - { - // Set current iteration the active one - gtk_combo_box_set_active_iter(GTK_COMBO_BOX(output), &iter); - return; - } + gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1); + if(deviceIndex == currentDeviceIndex) + { + // Set current iteration the active one + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(output), &iter); + return; + } } while(gtk_tree_model_iter_next(model, &iter)); // No index was found, select first one g_print("Warning : No active output device found"); gtk_combo_box_set_active(GTK_COMBO_BOX(output), 0); - */ + } /** @@ -171,12 +174,12 @@ select_active_output_audio_device() void config_window_fill_input_audio_device_list() { - /* - GtkTreeIter iter; - gchar** list; - gchar** audioDevice; - int index ; - gtk_list_store_clear(inputAudioDeviceManagerStore); + + GtkTreeIter iter; + gchar** list; + gchar** audioDevice; + int index ; + gtk_list_store_clear(inputlist); // Call dbus to retreive list list = dbus_get_audio_input_device_list(); @@ -185,12 +188,13 @@ config_window_fill_input_audio_device_list() //int c = 0; for(audioDevice = list; *list; list++) { - index = dbus_get_audio_device_index( *list ); - gtk_list_store_append(inputAudioDeviceManagerStore, &iter); - gtk_list_store_set(inputAudioDeviceManagerStore, &iter, 0, *list, 1, index, -1); - //c++; + g_print("dbasbasdfbzfb\n"); + index = dbus_get_audio_device_index( *list ); + gtk_list_store_append(inputlist, &iter); + gtk_list_store_set(inputlist, &iter, 0, *list, 1, index, -1); + //c++; } - */ + } /** @@ -199,12 +203,12 @@ config_window_fill_input_audio_device_list() void select_active_input_audio_device() { - /* - GtkTreeModel* model; - GtkTreeIter iter; - gchar** devices; - int currentDeviceIndex; - int deviceIndex; + + GtkTreeModel* model; + GtkTreeIter iter; + gchar** devices; + int currentDeviceIndex; + int deviceIndex; // Select active input device on server devices = dbus_get_current_audio_devices_index(); @@ -214,19 +218,19 @@ select_active_input_audio_device() // Find the currently set input device gtk_tree_model_get_iter_first(model, &iter); do { - gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1); - if(deviceIndex == currentDeviceIndex) - { - // Set current iteration the active one - gtk_combo_box_set_active_iter(GTK_COMBO_BOX(input), &iter); - return; - } + gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1); + if(deviceIndex == currentDeviceIndex) + { + // Set current iteration the active one + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(input), &iter); + return; + } } while(gtk_tree_model_iter_next(model, &iter)); // No index was found, select first one g_print("Warning : No active input device found"); gtk_combo_box_set_active(GTK_COMBO_BOX(input), 0); - */ + } /** @@ -593,21 +597,37 @@ GtkWidget* codecs_box() return ret; } + void +select_audio_manager( void ) +{ + if( !SHOW_ALSA_CONF && !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pulse) ) ) + { + alsabox = alsa_box(); + gtk_container_add( GTK_CONTAINER(alsa_conf ) , alsabox); + gtk_widget_show( alsa_conf ); + } + else if( SHOW_ALSA_CONF && gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pulse) )) + { + gtk_container_remove( GTK_CONTAINER(alsa_conf) , alsabox ); + } + gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pulse) )? dbus_set_audio_manager( PULSEAUDIO ):dbus_set_audio_manager( ALSA ); +} + GtkWidget* api_box() { GtkWidget *ret; GtkWidget *alsa; - GtkWidget *pulse; ret = gtk_hbox_new(FALSE, 10); gtk_widget_show( ret ); pulse = gtk_radio_button_new_with_mnemonic( NULL , _("Pulseaudio")); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pulse), TRUE ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pulse), !SHOW_ALSA_CONF ); gtk_box_pack_start( GTK_BOX(ret) , pulse , TRUE , TRUE , 1); alsa = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(pulse), _("ALSA")); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(alsa), FALSE ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(alsa), SHOW_ALSA_CONF ); gtk_box_pack_end( GTK_BOX(ret) , alsa , TRUE , TRUE , 1); + g_signal_connect(G_OBJECT(alsa), "clicked", G_CALLBACK(select_audio_manager), NULL); gtk_widget_show_all(ret); @@ -639,7 +659,7 @@ GtkWidget* alsa_box() plugin = gtk_combo_box_new_with_model(GTK_TREE_MODEL(pluginlist)); //select_active_output_audio_plugin(); gtk_label_set_mnemonic_widget(GTK_LABEL(item), plugin); - //g_signal_connect(G_OBJECT(plugin), "changed", G_CALLBACK(select_output_audio_plugin), plugin); + g_signal_connect(G_OBJECT(plugin), "changed", G_CALLBACK(select_output_audio_plugin), plugin); // Set rendering renderer = gtk_cell_renderer_text_new(); @@ -660,7 +680,7 @@ GtkWidget* alsa_box() output = gtk_combo_box_new_with_model(GTK_TREE_MODEL(outputlist)); //select_active_output_audio_device(); gtk_label_set_mnemonic_widget(GTK_LABEL(item), output); - //g_signal_connect(G_OBJECT(output), "changed", G_CALLBACK(select_audio_output_device), output); + g_signal_connect(G_OBJECT(output), "changed", G_CALLBACK(select_audio_output_device), output); // Set rendering renderer = gtk_cell_renderer_text_new(); @@ -681,7 +701,7 @@ GtkWidget* alsa_box() input = gtk_combo_box_new_with_model(GTK_TREE_MODEL(inputlist)); //select_active_input_audio_device(); gtk_label_set_mnemonic_widget(GTK_LABEL(item), input); - //g_signal_connect(G_OBJECT(input), "changed", G_CALLBACK(select_audio_input_device), input); + g_signal_connect(G_OBJECT(input), "changed", G_CALLBACK(select_audio_input_device), input); // Set rendering renderer = gtk_cell_renderer_text_new(); @@ -730,7 +750,6 @@ GtkWidget* create_audio_configuration() GtkWidget *ret; // Main frames GtkWidget *sound_conf; - GtkWidget *alsa_conf; GtkWidget *codecs_conf; GtkWidget *ringtones_conf; // Sub boxes @@ -750,8 +769,11 @@ GtkWidget* create_audio_configuration() alsa_conf = gtk_frame_new(_("ALSA configuration")); gtk_box_pack_start(GTK_BOX(ret), alsa_conf, FALSE, FALSE, 0); gtk_widget_show( alsa_conf ); - box = alsa_box(); - gtk_container_add( GTK_CONTAINER(alsa_conf) , box ); + if( SHOW_ALSA_CONF ) + { + alsabox = alsa_box(); + gtk_container_add( GTK_CONTAINER(alsa_conf) , alsabox ); + } // Box for the codecs codecs_conf = gtk_frame_new(_("Codecs")); @@ -771,9 +793,3 @@ GtkWidget* create_audio_configuration() return ret; } - -gboolean get_api() -{ - return gtk_widget_get_active() -} - diff --git a/sflphone-gtk/src/configurationmanager-glue.h b/sflphone-gtk/src/configurationmanager-glue.h index 3cad16502d2542ae60116274d3b1af6c3e56b8f2..54d2b22e17b37b222408efd185a1027144b444c6 100644 --- a/sflphone-gtk/src/configurationmanager-glue.h +++ b/sflphone-gtk/src/configurationmanager-glue.h @@ -578,6 +578,81 @@ static inline #endif gboolean +org_sflphone_SFLphone_ConfigurationManager_get_audio_manager (DBusGProxy *proxy, gint* OUT_api, GError **error) + +{ + return dbus_g_proxy_call (proxy, "getAudioManager", error, G_TYPE_INVALID, G_TYPE_INT, OUT_api, G_TYPE_INVALID); +} + +typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_reply) (DBusGProxy *proxy, gint OUT_api, GError *error, gpointer userdata); + +static void +org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + gint OUT_api; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &OUT_api, G_TYPE_INVALID); + (*(org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_reply)data->cb) (proxy, OUT_api, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_async (DBusGProxy *proxy, org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_new (DBusGAsyncData, 1); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "getAudioManager", org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_async_callback, stuff, g_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +org_sflphone_SFLphone_ConfigurationManager_set_audio_manager (DBusGProxy *proxy, const gint IN_api, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setAudioManager", error, G_TYPE_INT, IN_api, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_async (DBusGProxy *proxy, const gint IN_api, org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_new (DBusGAsyncData, 1); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setAudioManager", org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_async_callback, stuff, g_free, G_TYPE_INT, IN_api, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean org_sflphone_SFLphone_ConfigurationManager_get_codec_list (DBusGProxy *proxy, char *** OUT_list, GError **error) { diff --git a/sflphone-gtk/src/dbus.c b/sflphone-gtk/src/dbus.c index c5f10b1b7d0aa86dea9f834434f189d3fb7c40a5..b1487c896ed92dc60372481d4dfdd7de4871540c 100644 --- a/sflphone-gtk/src/dbus.c +++ b/sflphone-gtk/src/dbus.c @@ -1419,3 +1419,40 @@ dbus_get_mail_notify( void ) return level; } + +void +dbus_set_audio_manager( int api ) +{ + GError* error = NULL; + org_sflphone_SFLphone_ConfigurationManager_set_audio_manager( + configurationManagerProxy, + api, + &error); + if(error) + { + g_error_free(error); + } + else + g_print("Called dbus_set_audio_manager\n"); +} + +int +dbus_get_audio_manager( void ) +{ + g_print("Before dbus_get_mail_notif_level()\n"); + int api; + GError* error = NULL; + org_sflphone_SFLphone_ConfigurationManager_get_audio_manager( + configurationManagerProxy, + &api, + &error); + if(error) + { + g_print("Error calling dbus_get_audio_manager\n"); + g_error_free(error); + } + else + g_print("Called dbus_get_audio_manager\n"); + + return api; +} diff --git a/sflphone-gtk/src/dbus.h b/sflphone-gtk/src/dbus.h index d54165f3f7a472b01cbd96d8ec3be3673fb18d95..af5ebe51e3abde2b5ac6064bb97affe49eaed661 100644 --- a/sflphone-gtk/src/dbus.h +++ b/sflphone-gtk/src/dbus.h @@ -352,6 +352,20 @@ void dbus_switch_popup_mode( void ); */ int dbus_popup_mode( void ); +/** + * ConfigurationManager - Returns the selected audio manager + * @return int 0 ALSA + * 1 PULSEAUDIO + */ +int dbus_get_audio_manager( void ); + +/** + * ConfigurationManager - Set the audio manager + * @param api 0 ALSA + * 1 PULSEAUDIO + */ +void dbus_set_audio_manager( int api ); + /** * ConfigurationManager - Configure the notification level * @return int 0 disable diff --git a/sflphone-gtk/src/sflphone_const.h b/sflphone-gtk/src/sflphone_const.h index ff4c90ba4363aa01d72320776af373e39e96b14d..097a8cbbad33a45e59d10c741cce13271184ad3e 100644 --- a/sflphone-gtk/src/sflphone_const.h +++ b/sflphone-gtk/src/sflphone_const.h @@ -76,6 +76,12 @@ #define SHOW_VOLUME ( dbus_get_volume_controls() ) /** Show/Hide the dialpad */ #define SHOW_SEARCHBAR ( dbus_get_searchbar() ) +/** Show/Hide the alsa configuration panel */ +#define SHOW_ALSA_CONF ( dbus_get_audio_manager() == ALSA ) + +/** Audio Managers */ +#define ALSA 0 +#define PULSEAUDIO 1 /** Notification levels */ #define __NOTIF_LEVEL_MIN 0 diff --git a/src/audio/alsalayer.cpp b/src/audio/alsalayer.cpp index 794328d742f0011fe8138beb6d9ff863acaa0281..2763246187851aa687615d5598a0d100b8d0e7db 100644 --- a/src/audio/alsalayer.cpp +++ b/src/audio/alsalayer.cpp @@ -40,6 +40,14 @@ AlsaLayer::~AlsaLayer (void) deviceClosed = true; } +void +AlsaLayer::closeLayer() +{ + _debugAlsa("Close ALSA streams\n"); + closeCaptureStream(); + closePlaybackStream(); + deviceClosed = true; +} bool AlsaLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize, int stream , std::string plugin) diff --git a/src/audio/alsalayer.h b/src/audio/alsalayer.h index f92bbfc6fc06bcecb6d20e676f52f137bd5f0e3d..858e0bba45241ec7e33c1ec589cb151653acb7b2 100644 --- a/src/audio/alsalayer.h +++ b/src/audio/alsalayer.h @@ -46,6 +46,8 @@ class AlsaLayer : public AudioLayer { */ ~AlsaLayer(void); + void closeLayer( void ); + /** * Check if no devices are opened, otherwise close them. * Then open the specified devices by calling the private functions open_device diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h index 95a43ac8f5f4ce1e185785ec068ee4637c2be688..2f51adcb10f1407795aba83d3c3cd8dc56d8ae74 100644 --- a/src/audio/audiolayer.h +++ b/src/audio/audiolayer.h @@ -68,6 +68,8 @@ class AudioLayer { */ ~AudioLayer(void){} + virtual void closeLayer( void ) = 0; + /** * Check if no devices are opened, otherwise close them. * Then open the specified devices by calling the private functions open_device diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index aa85aebc9cefc5c229f9181f9cac0cc78648fcc7..cb30737f116a1af7dc9242722248b747137f630c 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -376,13 +376,12 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime) toAudioLayer = _dataAudioLayer; #endif - // int layer = audiolayer->getLayerType(); - // _debug(" interface %i\n" , layer); -//#if CHECK_INTERFACE( layer , ALSA ) - // audiolayer->playSamples(toAudioLayer, nbSample * sizeof(SFLDataFormat), true); -//#else - audiolayer->putMain( toAudioLayer, nbSample * sizeof(SFLDataFormat) ); -//#endif + int layer = audiolayer->getLayerType(); + //_debug(" interface %i - ALSA = %i\n" , layer, ALSA); + if( CHECK_INTERFACE( layer, ALSA ) ) + audiolayer->playSamples(toAudioLayer, nbSample * sizeof(SFLDataFormat), true); + else + audiolayer->putMain( toAudioLayer, nbSample * sizeof(SFLDataFormat) ); // Notify (with a beep) an incoming call when there is already a call countTime += time->getSecond(); if (Manager::instance().incomingCallWaiting() > 0) { diff --git a/src/audio/audiostream.cpp b/src/audio/audiostream.cpp index cb67bc11fc386427cfb853bd141d407c824aa062..1f57b2f1740e97a50429b8bed93fd3db5080d879 100644 --- a/src/audio/audiostream.cpp +++ b/src/audio/audiostream.cpp @@ -37,6 +37,15 @@ AudioStream::AudioStream( pa_context* context, int type, std::string desc ) AudioStream::~AudioStream() { + _debug("Destroy audio streams\n"); + pa_stream_disconnect( pulseStream() ); +} + +void +AudioStream::disconnect( void ) +{ + _debug("Destroy audio streams\n"); + pa_stream_disconnect( pulseStream() ); } void diff --git a/src/audio/audiostream.h b/src/audio/audiostream.h index c2411d481237dbfe8c0b6fa95935f74f536fd27d..c420628d9b97178924412e8f2d78cb8ed9e1abb7 100644 --- a/src/audio/audiostream.h +++ b/src/audio/audiostream.h @@ -42,6 +42,7 @@ class AudioStream { int putMain( void* buffer , int toCopy ); int putUrgent( void* buffer , int toCopy ); + void disconnect(); pa_stream* pulseStream(){ return _audiostream; } private: diff --git a/src/audio/pulselayer.cpp b/src/audio/pulselayer.cpp index 1a4a054cabb481150a29d09ef768721a042ff407..e783d91682e8b7a3a4df62e6b21626a88d2ce281 100644 --- a/src/audio/pulselayer.cpp +++ b/src/audio/pulselayer.cpp @@ -38,11 +38,20 @@ int framesPerBuffer = 2048; // Destructor PulseLayer::~PulseLayer (void) { + _debug(" Destroy pulselayer\n"); delete playback; delete record; pa_context_disconnect(context); } +void +PulseLayer::closeLayer( void ) +{ + playback->disconnect(); + record->disconnect(); + pa_context_disconnect( context ); +} + void PulseLayer::connectPulseServer( void ) { diff --git a/src/audio/pulselayer.h b/src/audio/pulselayer.h index 8c1e95506b279170368334d20496ec2c29f922b9..7a6bea35625ba797919f0d20d2a64115dfaf6b3b 100644 --- a/src/audio/pulselayer.h +++ b/src/audio/pulselayer.h @@ -31,6 +31,8 @@ class PulseLayer : public AudioLayer { PulseLayer(ManagerImpl* manager); ~PulseLayer(void); + void closeLayer( void ); + /** * Check if no devices are opened, otherwise close them. * Then open the specified devices by calling the private functions open_device diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h index dfd7f8920481f3600b7983cc7df41f29a2bdc9fc..f2cbbbeb89a3d2ffbec91a30c49f86065a055c9d 100644 --- a/src/dbus/configurationmanager-glue.h +++ b/src/dbus/configurationmanager-glue.h @@ -35,6 +35,8 @@ public: register_method(ConfigurationManager, ringtoneEnabled, _ringtoneEnabled_stub); register_method(ConfigurationManager, getRingtoneChoice, _getRingtoneChoice_stub); register_method(ConfigurationManager, setRingtoneChoice, _setRingtoneChoice_stub); + register_method(ConfigurationManager, getAudioManager, _getAudioManager_stub); + register_method(ConfigurationManager, setAudioManager, _setAudioManager_stub); register_method(ConfigurationManager, getCodecList, _getCodecList_stub); register_method(ConfigurationManager, getCodecDetails, _getCodecDetails_stub); register_method(ConfigurationManager, getActiveCodecList, _getActiveCodecList_stub); @@ -148,6 +150,16 @@ public: { "tone", "s", true }, { 0, 0, 0 } }; + static ::DBus::IntrospectedArgument getAudioManager_args[] = + { + { "api", "i", false }, + { 0, 0, 0 } + }; + static ::DBus::IntrospectedArgument setAudioManager_args[] = + { + { "api", "i", true }, + { 0, 0, 0 } + }; static ::DBus::IntrospectedArgument getCodecList_args[] = { { "list", "as", false }, @@ -334,6 +346,8 @@ public: { "ringtoneEnabled", ringtoneEnabled_args }, { "getRingtoneChoice", getRingtoneChoice_args }, { "setRingtoneChoice", setRingtoneChoice_args }, + { "getAudioManager", getAudioManager_args }, + { "setAudioManager", setAudioManager_args }, { "getCodecList", getCodecList_args }, { "getCodecDetails", getCodecDetails_args }, { "getActiveCodecList", getActiveCodecList_args }, @@ -415,6 +429,8 @@ public: virtual void ringtoneEnabled( ) = 0; virtual ::DBus::String getRingtoneChoice( ) = 0; virtual void setRingtoneChoice( const ::DBus::String& tone ) = 0; + virtual ::DBus::Int32 getAudioManager( ) = 0; + virtual void setAudioManager( const ::DBus::Int32& api ) = 0; virtual std::vector< ::DBus::String > getCodecList( ) = 0; virtual std::vector< ::DBus::String > getCodecDetails( const ::DBus::Int32& payload ) = 0; virtual std::vector< ::DBus::String > getActiveCodecList( ) = 0; @@ -622,6 +638,25 @@ private: ::DBus::ReturnMessage reply(call); return reply; } + ::DBus::Message _getAudioManager_stub( const ::DBus::CallMessage& call ) + { + ::DBus::MessageIter ri = call.reader(); + + ::DBus::Int32 argout1 = getAudioManager(); + ::DBus::ReturnMessage reply(call); + ::DBus::MessageIter wi = reply.writer(); + wi << argout1; + return reply; + } + ::DBus::Message _setAudioManager_stub( const ::DBus::CallMessage& call ) + { + ::DBus::MessageIter ri = call.reader(); + + ::DBus::Int32 argin1; ri >> argin1; + setAudioManager(argin1); + ::DBus::ReturnMessage reply(call); + return reply; + } ::DBus::Message _getCodecList_stub( const ::DBus::CallMessage& call ) { ::DBus::MessageIter ri = call.reader(); diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml index 0b785ff3d80e452f66b7e836d47c64a32d264bb1..9a8c87455e34cbc0e5eaa015fea552eadd87f410 100644 --- a/src/dbus/configurationmanager-introspec.xml +++ b/src/dbus/configurationmanager-introspec.xml @@ -69,6 +69,14 @@ <arg type="s" name="tone" direction="in"/> </method> + <method name="getAudioManager"> + <arg type="i" name="api" direction="out"/> + </method> + + <method name="setAudioManager"> + <arg type="i" name="api" direction="in"/> + </method> + <!-- /////////////////////// --> <!-- Codecs-related methods --> diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp index 77e35d2c2d809d1a9578c94fde47f6b5a8dd8eb5..26ea486daec44f72e5d440589e57f1868d9a4e69 100644 --- a/src/dbus/configurationmanager.cpp +++ b/src/dbus/configurationmanager.cpp @@ -335,6 +335,20 @@ ConfigurationManager::getNotify( void ) return Manager::instance().getNotify( ); } +void +ConfigurationManager::setAudioManager( const DBus::Int32& api ) +{ + _debug("Manager received setAudioManager\n"); + Manager::instance().setAudioManager( api ); +} + +::DBus::Int32 +ConfigurationManager::getAudioManager( void ) +{ + _debug("Manager received getAudioManager\n"); + return Manager::instance().getAudioManager( ); +} + void ConfigurationManager::setMailNotify( void ) { diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h index da0c82efb3c0cf9f9a30faab7538b9708a7c5a6c..8dda655d9573fae46b58d4ffcba4e8803f2e8860 100644 --- a/src/dbus/configurationmanager.h +++ b/src/dbus/configurationmanager.h @@ -69,6 +69,8 @@ public: std::vector< ::DBus::String > getRecordDeviceList( ); ::DBus::String getVersion( ); std::vector< ::DBus::String > getRingtoneList( ); + ::DBus::Int32 getAudioManager( void ); + void setAudioManager( const ::DBus::Int32& api ); ::DBus::Int32 isIax2Enabled( void ); ::DBus::Int32 isRingtoneEnabled( void ); diff --git a/src/global.h b/src/global.h index a89b070f3e31b868b4fb8f48e21787a4b0b84ec0..afdbdaf05d53919b587b39a8569b9a41b8fbdf55 100644 --- a/src/global.h +++ b/src/global.h @@ -124,6 +124,6 @@ typedef short int16; #define ALSA 0 #define PULSEAUDIO 1 -#define CHECK_INTERFACE( layer , api ) (layer != api) +#define CHECK_INTERFACE( layer , api ) (layer == api) #endif // __GLOBAL_H__ diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index a1aa8046f33a9b1783d106a686550071f2970d08..eb92a78c1693859682c23614158926cff1cfe7ff 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -496,19 +496,20 @@ ManagerImpl::playDtmf(char code, bool isTalking) // Put buffer to urgentRingBuffer // put the size in bytes... // so size * 1 channel (mono) * sizeof (bytes for the data) -#if CHECK_INTERFACE( layer , ALSA ) - audiolayer->playSamples(_buf, size * sizeof(SFLDataFormat), isTalking); -#else - _debug("DTMF disabled\n"); + if(CHECK_INTERFACE( layer , ALSA )) + audiolayer->playSamples(_buf, size * sizeof(SFLDataFormat), isTalking); + else + _debug("DTMF disabled\n"); //audiolayer->putUrgent( _buf, size * sizeof(SFLDataFormat) ); -#endif + } returnValue = true; -#if CHECK_INTERFACE( layer , PULSEAUDIO ) + if( CHECK_INTERFACE( layer , PULSEAUDIO )) + { // Cache the samples on the sound server (PulseLayer*)audiolayer->putInCache( code, _buf , size * sizeof(SFLDataFormat) ); -#endif + } delete[] _buf; _buf = 0; return returnValue; @@ -726,12 +727,11 @@ ManagerImpl::playATone(Tone::TONEID toneId) { SFLDataFormat buf[nbSampling]; if ( audiolayer ) { int layer = audiolayer->getLayerType(); -#if CHECK_INTERFACE( layer , ALSA ) + if(CHECK_INTERFACE( layer , ALSA ) ) audiolayer->putUrgent( buf, nbSampling ); -#else + else{} // Pulseaudio code - // startStream()?; -#endif + // startStream()?;} } else return false; @@ -750,10 +750,10 @@ ManagerImpl::stopTone(bool stopAudio=true) { if (stopAudio) { AudioLayer* audiolayer = getAudioDriver(); int layer = audiolayer->getLayerType(); -#if CHECK_INTERFACE( layer , ALSA ) -#else + if(CHECK_INTERFACE( layer , ALSA ) ){} + else{} //if (audiolayer) { audiolayer->stopStream(); } -#endif + } _toneMutex.enterMutex(); @@ -830,15 +830,15 @@ ManagerImpl::ringtone() _toneMutex.enterMutex(); _audiofile.start(); _toneMutex.leaveMutex(); -#if CHECK_INTERFACE( layer, ALSA ) + if(CHECK_INTERFACE( layer, ALSA )){ int size = _audiofile.getSize(); SFLDataFormat output[ size ]; _audiofile.getNext(output, size , 100); - audiolayer->putUrgent( output , size ); -#else + audiolayer->putUrgent( output , size );} + else{ // pulseaudio code //audiolayer->startStream(); -#endif + } } else { ringback(); } @@ -886,11 +886,11 @@ ManagerImpl::notificationIncomingCall(void) { unsigned int nbSampling = tone.getSize(); SFLDataFormat buf[nbSampling]; tone.getNext(buf, tone.getSize()); -#if CHECK_INTERFACE( layer , ALSA ) - audiolayer->playSamples(buf, sizeof(SFLDataFormat)*nbSampling, true); -#else - audiolayer->putUrgent( buf, sizeof(SFLDataFormat)*nbSampling ); -#endif + if(CHECK_INTERFACE( layer , ALSA )) + audiolayer->playSamples(buf, sizeof(SFLDataFormat)*nbSampling, true); + else + audiolayer->putUrgent( buf, sizeof(SFLDataFormat)*nbSampling ); + } } @@ -1015,6 +1015,7 @@ ManagerImpl::initConfigFile (void) fill_config_int(CONFIG_VOLUME , YES_STR); fill_config_int(CONFIG_HISTORY , DFT_MAX_CALLS); fill_config_int(REGISTRATION_EXPIRE , DFT_EXPIRE_VALUE); + fill_config_int(CONFIG_AUDIO , DFT_AUDIO_MANAGER); // Loads config from ~/.sflphone/sflphonedrc or so.. if (createSettingsPath() == 1) { @@ -1160,13 +1161,9 @@ ManagerImpl::getInputAudioPluginList(void) std::vector<std::string> v; _debug("Get input audio plugin list"); - /*v.push_back("default"); + v.push_back("default"); v.push_back("surround40"); v.push_back("plug:hw"); - */ - - v.push_back("alsa"); - v.push_back("pulseaudio"); return v; } @@ -1180,12 +1177,9 @@ ManagerImpl::getOutputAudioPluginList(void) std::vector<std::string> v; _debug("Get output audio plugin list"); - //v.push_back( PCM_DEFAULT ); - //v.push_back( PCM_PLUGHW ); - //v.push_back( PCM_DMIX ); - //v.push_back( PCM_PULSE ); - v.push_back("alsa"); - v.push_back("pulseaudio"); + v.push_back( PCM_DEFAULT ); + v.push_back( PCM_PLUGHW ); + v.push_back( PCM_DMIX ); return v; } @@ -1197,7 +1191,8 @@ ManagerImpl::getOutputAudioPluginList(void) ManagerImpl::setInputAudioPlugin(const std::string& audioPlugin) { int layer = _audiodriver -> getLayerType(); -#if CHECK_INTERFACE( layer , ALSA ) + if(CHECK_INTERFACE( layer , ALSA )) + { _debug("Set input audio plugin\n"); _audiodriver -> setErrorMessage( -1 ); _audiodriver -> openDevice( _audiodriver -> getIndexIn(), @@ -1208,8 +1203,8 @@ ManagerImpl::setInputAudioPlugin(const std::string& audioPlugin) audioPlugin); if( _audiodriver -> getErrorMessage() != -1) notifyErrClient( _audiodriver -> getErrorMessage() ); -#else -#endif +}else{} + } /** @@ -1219,10 +1214,9 @@ ManagerImpl::setInputAudioPlugin(const std::string& audioPlugin) ManagerImpl::setOutputAudioPlugin(const std::string& audioPlugin) { int layer = _audiodriver -> getLayerType(); -#if CHECK_INTERFACE( layer , ALSA ) - _debug("Set output audio plugin\n"); - _audiodriver -> setErrorMessage( -1 ); - _audiodriver -> openDevice( _audiodriver -> getIndexIn(), + _debug("Set output audio plugin\n"); + _audiodriver -> setErrorMessage( -1 ); + _audiodriver -> openDevice( _audiodriver -> getIndexIn(), _audiodriver -> getIndexOut(), _audiodriver -> getSampleRate(), _audiodriver -> getFrameSize(), @@ -1232,8 +1226,6 @@ ManagerImpl::setOutputAudioPlugin(const std::string& audioPlugin) notifyErrClient( _audiodriver -> getErrorMessage() ); // set config setConfig( AUDIO , ALSA_PLUGIN , audioPlugin ); -#else -#endif } /** @@ -1253,7 +1245,6 @@ ManagerImpl::getAudioOutputDeviceList(void) ManagerImpl::setAudioOutputDevice(const int index) { int layer = _audiodriver -> getLayerType(); -#if CHECK_INTERFACE( layer , ALSA ) _debug("Set audio output device: %i\n", index); _audiodriver -> setErrorMessage( -1 ); _audiodriver->openDevice(_audiodriver->getIndexIn(), @@ -1266,8 +1257,6 @@ ManagerImpl::setAudioOutputDevice(const int index) notifyErrClient( _audiodriver -> getErrorMessage() ); // set config setConfig( AUDIO , ALSA_CARD_ID_OUT , index ); -#else -#endif } /** @@ -1287,7 +1276,6 @@ ManagerImpl::getAudioInputDeviceList(void) ManagerImpl::setAudioInputDevice(const int index) { int layer = _audiodriver -> getLayerType(); -#if CHECK_INTERFACE( layer , ALSA ) _debug("Set audio input device %i\n", index); _audiodriver -> setErrorMessage( -1 ); _audiodriver->openDevice(index, @@ -1300,8 +1288,6 @@ ManagerImpl::setAudioInputDevice(const int index) notifyErrClient( _audiodriver -> getErrorMessage() ); // set config setConfig( AUDIO , ALSA_CARD_ID_IN , index ); -#else -#endif } /** @@ -1461,6 +1447,19 @@ ManagerImpl::getMailNotify( void ) return getConfigInt( PREFERENCES , CONFIG_MAIL_NOTIFY ); } +void +ManagerImpl::setAudioManager( const DBus::Int32& api ) +{ + setConfig( PREFERENCES , CONFIG_AUDIO , api) ; + switchAudioManager(); +} + +::DBus::Int32 +ManagerImpl::getAudioManager( void ) +{ + return getConfigInt( PREFERENCES , CONFIG_AUDIO ); +} + int ManagerImpl::getRegistrationExpireValue( void) { @@ -1506,7 +1505,19 @@ ManagerImpl::initAudioDriver(void) { _debugInit("AudioLayer Creation"); //_audiodriver = new AlsaLayer( this ); - _audiodriver = new AlsaLayer( this ); + + /*if( _audiodriver ){ + _debug("delete audiodriver\n"); + delete _audiodriver; _audiodriver = NULL; + } */ + + if( getConfigInt( PREFERENCES , CONFIG_AUDIO ) == ALSA ) + _audiodriver = new AlsaLayer( this ); + else if( getConfigInt( PREFERENCES , CONFIG_AUDIO ) == PULSEAUDIO ) + _audiodriver = new PulseLayer( this ); + else + _debug("Error - Audio API unknown\n"); + if (_audiodriver == 0) { _debug("Init audio driver error\n"); } else { @@ -1548,25 +1559,61 @@ ManagerImpl::selectAudioDriver (void) setConfig( AUDIO , ALSA_CARD_ID_OUT , ALSA_DFT_CARD_ID ); } -#if CHECK_INTERFACE( layer , ALSA ) + if(CHECK_INTERFACE( layer , ALSA )) + { + delete _audiodriver; + _audiodriver = new AlsaLayer( this ); _debugInit(" ALSA audio driver \n"); _audiodriver->setErrorMessage(-1); _audiodriver->openDevice( numCardIn , numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin ); if( _audiodriver -> getErrorMessage() != -1 ) notifyErrClient( _audiodriver -> getErrorMessage()); -#else - delete _audiodriver; - _audiodriver = new PulseLayer( this ); + }else{ + delete _audiodriver; + _audiodriver = new PulseLayer( this ); _debug(" Pulse audio driver \n"); _audiodriver->setErrorMessage(-1); _audiodriver->openDevice( numCardIn , numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin ); if( _audiodriver -> getErrorMessage() != -1 ) notifyErrClient( _audiodriver -> getErrorMessage()); - -#endif + } } +void +ManagerImpl::switchAudioManager( void ) +{ + _debug( "Switching audio manager \n"); + + int type = _audiodriver->getLayerType(); + int samplerate = getConfigInt( AUDIO , ALSA_SAMPLE_RATE ); + int framesize = getConfigInt( AUDIO , ALSA_FRAME_SIZE ); + std::string alsaPlugin = getConfigString( AUDIO , ALSA_PLUGIN ); + int numCardIn = getConfigInt( AUDIO , ALSA_CARD_ID_IN ); + int numCardOut = getConfigInt( AUDIO , ALSA_CARD_ID_OUT ); + + _debug("Deleting current layer...\n"); + _audiodriver->closeLayer(); + delete _audiodriver; _audiodriver = NULL; + + switch( type ){ + case ALSA: + _debug("Creating Pulseaudio layer...\n"); + _audiodriver = new PulseLayer( this ); + break; + case PULSEAUDIO: + _debug("Creating ALSA layer...\n"); + _audiodriver = new AlsaLayer( this ); + break; + default: + _debug("Error: audio layer unknown\n"); + } + _audiodriver->setErrorMessage(-1); + _audiodriver->openDevice( numCardIn , numCardOut, samplerate, framesize, SFL_PCM_BOTH, alsaPlugin ); + if( _audiodriver -> getErrorMessage() != -1 ) + notifyErrClient( _audiodriver -> getErrorMessage()); +} + /** * Initialize the Zeroconf scanning services loop * Informations will be store inside a map DNSService->_services diff --git a/src/managerimpl.h b/src/managerimpl.h index 9b4c4dd54936ebc2aa879ea2bb1f0dbb06b1b455..94212b4009416f7e90298d2ed758cf8b6cece423 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -545,6 +545,20 @@ class ManagerImpl { */ void setMailNotify( void ); + /** + * Get the audio manager + * @return int The audio manager + * 0 ALSA + * 1 PULSEAUDIO + */ + ::DBus::Int32 getAudioManager( void ); + + /** + * Set the audio manager + */ + void setAudioManager( const DBus::Int32& api ); + + void switchAudioManager( void ); /** * Get the desktop mail notification level * @return int The mail notification level diff --git a/src/user_cfg.h b/src/user_cfg.h index c6b10556ade891ea35a8de6a0711fbc2fa0669ec..9597b094eddabf56eef3037e3d3262ab2468ea32 100644 --- a/src/user_cfg.h +++ b/src/user_cfg.h @@ -59,6 +59,7 @@ #define CONFIG_VOLUME "Volume.display" /** Display the mic and speaker volume controls */ #define CONFIG_ZEROCONF "Zeroconf.enable" /** Zero configuration networking module */ #define REGISTRATION_EXPIRE "Registration.expire" /** Registration expire value */ +#define CONFIG_AUDIO "Audio.api" /** Audio manager (ALSA or pulseaudio) */ #define SIGNALISATION "VoIPLink" /** Section Signalisation */ #define PLAY_DTMF "DTMF.playDtmf" /** Whether or not should play dtmf */ @@ -84,6 +85,7 @@ #define DFT_NOTIF_LEVEL "2" /** Default desktop notification level : maximum */ #define DFT_MAX_CALLS "20" /** Default maximum calls in history */ #define DFT_EXPIRE_VALUE "180" /** Default expire value for registration */ +#define DFT_AUDIO_MANAGER "1" /** Default audio manager */ #ifdef USE_ZEROCONF #define CONFIG_ZEROCONF_DEFAULT_STR "1" /** Default Zero configuration networking module value */