diff --git a/sflphone-gtk/src/configurationmanager-glue.h b/sflphone-gtk/src/configurationmanager-glue.h index b2e3c447dabc912dbfcf8b22dcebeca23cb3626a..9e395b9f8782ba75ba14912c7f5d41a17655144b 100644 --- a/sflphone-gtk/src/configurationmanager-glue.h +++ b/sflphone-gtk/src/configurationmanager-glue.h @@ -617,22 +617,22 @@ static inline #endif gboolean -org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list (DBusGProxy *proxy, char *** OUT_list, GError **error) +org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list (DBusGProxy *proxy, char *** OUT_list, GError **error) { - return dbus_g_proxy_call (proxy, "getAudioManagerList", error, G_TYPE_INVALID, G_TYPE_STRV, OUT_list, G_TYPE_INVALID); + return dbus_g_proxy_call (proxy, "getInputAudioPluginList", error, G_TYPE_INVALID, G_TYPE_STRV, OUT_list, G_TYPE_INVALID); } -typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list_reply) (DBusGProxy *proxy, char * *OUT_list, GError *error, gpointer userdata); +typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list_reply) (DBusGProxy *proxy, char * *OUT_list, GError *error, gpointer userdata); static void -org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_list; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_list, G_TYPE_INVALID); - (*(org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list_reply)data->cb) (proxy, OUT_list, error, data->userdata); + (*(org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list_reply)data->cb) (proxy, OUT_list, error, data->userdata); return; } @@ -641,35 +641,110 @@ static inline #endif DBusGProxyCall* -org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list_async (DBusGProxy *proxy, org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list_reply callback, gpointer userdata) +org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list_async (DBusGProxy *proxy, org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list_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, "getAudioManagerList", org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list_async_callback, stuff, g_free, G_TYPE_INVALID); + return dbus_g_proxy_begin_call (proxy, "getInputAudioPluginList", org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list_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 char * IN_audioManager, GError **error) +org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list (DBusGProxy *proxy, char *** OUT_list, GError **error) { - return dbus_g_proxy_call (proxy, "setAudioManager", error, G_TYPE_STRING, IN_audioManager, G_TYPE_INVALID, G_TYPE_INVALID); + return dbus_g_proxy_call (proxy, "getOutputAudioPluginList", error, G_TYPE_INVALID, G_TYPE_STRV, OUT_list, G_TYPE_INVALID); } -typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); +typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list_reply) (DBusGProxy *proxy, char * *OUT_list, GError *error, gpointer userdata); static void -org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + char ** OUT_list; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_list, G_TYPE_INVALID); + (*(org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list_reply)data->cb) (proxy, OUT_list, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list_async (DBusGProxy *proxy, org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list_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, "getOutputAudioPluginList", org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list_async_callback, stuff, g_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin (DBusGProxy *proxy, const char * IN_audioPlugin, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setInputAudioPlugin", error, G_TYPE_STRING, IN_audioPlugin, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin_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_input_audio_plugin_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin_async (DBusGProxy *proxy, const char * IN_audioPlugin, org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin_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, "setInputAudioPlugin", org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin_async_callback, stuff, g_free, G_TYPE_STRING, IN_audioPlugin, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin (DBusGProxy *proxy, const char * IN_audioPlugin, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setOutputAudioPlugin", error, G_TYPE_STRING, IN_audioPlugin, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin_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); + (*(org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin_reply)data->cb) (proxy, error, data->userdata); return; } @@ -678,14 +753,14 @@ static inline #endif DBusGProxyCall* -org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_async (DBusGProxy *proxy, const char * IN_audioManager, org_sflphone_SFLphone_ConfigurationManager_set_audio_manager_reply callback, gpointer userdata) +org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin_async (DBusGProxy *proxy, const char * IN_audioPlugin, org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin_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_STRING, IN_audioManager, G_TYPE_INVALID); + return dbus_g_proxy_begin_call (proxy, "setOutputAudioPlugin", org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin_async_callback, stuff, g_free, G_TYPE_STRING, IN_audioPlugin, G_TYPE_INVALID); } static #ifdef G_HAVE_INLINE diff --git a/sflphone-gtk/src/configwindow.c b/sflphone-gtk/src/configwindow.c index ebcb0d8dd97ff0bfd8e3971b0777f5f247d3bf82..98ccdfbc1f2f71239bcfc78599ddc2b60dd29758 100644 --- a/sflphone-gtk/src/configwindow.c +++ b/sflphone-gtk/src/configwindow.c @@ -39,7 +39,8 @@ gboolean dialogOpen = FALSE; GtkListStore *accountStore; GtkWidget *codecTreeView; // View used instead of store to get access to selection // instead of keeping selected codec as a variable -GtkListStore *audioManagerStore; +GtkListStore *inputAudioPluginStore; +GtkListStore *outputAudioPluginStore; GtkListStore *outputAudioDeviceManagerStore; GtkListStore *inputAudioDeviceManagerStore; @@ -137,30 +138,54 @@ config_window_fill_codec_list() } /** - * Fill store with audio managers + * Fill store with input audio plugins */ void -config_window_fill_audio_manager_list() +config_window_fill_input_audio_plugin_list() { GtkTreeIter iter; gchar** list; gchar* managerName; - gtk_list_store_clear(audioManagerStore); + gtk_list_store_clear(inputAudioPluginStore); // Call dbus to retreive list - list = dbus_get_audio_manager_list(); + list = dbus_get_input_audio_plugin_list(); // For each API name included in list int c = 0; for(managerName = list[c]; managerName != NULL; managerName = list[c]) { c++; - gtk_list_store_append(audioManagerStore, &iter); - gtk_list_store_set(audioManagerStore, &iter, 0 , managerName, -1); + gtk_list_store_append(inputAudioPluginStore, &iter); + gtk_list_store_set(inputAudioPluginStore, &iter, 0 , managerName, -1); } } +/** + * Fill store with output audio plugins + */ +void +config_window_fill_output_audio_plugin_list() +{ + GtkTreeIter iter; + gchar** list; + gchar* managerName; + + gtk_list_store_clear(outputAudioPluginStore); + + // Call dbus to retreive list + list = dbus_get_output_audio_plugin_list(); + + // For each API name included in list + int c = 0; + for(managerName = list[c]; managerName != NULL; managerName = list[c]) + { + c++; + gtk_list_store_append(outputAudioPluginStore, &iter); + gtk_list_store_set(outputAudioPluginStore, &iter, 0 , managerName, -1); + } +} /** * Fill output audio device store */ @@ -281,15 +306,37 @@ select_active_input_audio_device() } /** - * Select the audio manager by calling the server - * Not yet used because audio manager is by default ALSA + * Select the input audio plugin by calling the server */ static void -select_audio_manager(GtkWidget* widget, gpointer data) +select_input_audio_plugin(GtkWidget* widget, gpointer data) { //dbus_set_audio_manager(""); } +/** + * Select the output audio plugin by calling the server + */ +static void +select_output_audio_plugin(GtkComboBox* widget, gpointer data) +{ + GtkTreeModel* model; + GtkTreeIter iter; + int comboBoxIndex; + gchar* pluginName; + + comboBoxIndex = gtk_combo_box_get_active(widget); + + if(comboBoxIndex >= 0) + { + model = gtk_combo_box_get_model(widget); + gtk_combo_box_get_active_iter(widget, &iter); + gtk_tree_model_get(model, &iter, 0, &pluginName, -1); + + dbus_set_output_audio_plugin(pluginName); + } + //dbus_set_output_audio_manager(""); +} /** * Set the audio output device on the server with its index */ @@ -873,6 +920,7 @@ create_audio_tab () gtk_misc_set_alignment(GTK_MISC(deviceLabel), 0, 0.5); gtk_label_set_justify(GTK_LABEL(deviceLabel), GTK_JUSTIFY_LEFT); gtk_box_pack_start(GTK_BOX(ret), deviceLabel, FALSE, FALSE, 0); + // Main device widget deviceBox = gtk_hbox_new(FALSE, 10); @@ -887,17 +935,38 @@ create_audio_tab () // Device : Audio manager // Create title label - titleLabel = gtk_label_new("Audio manager:"); - gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5); + /* + titleLabel = gtk_label_new("Alsa plug-IN:"); + gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5); + gtk_table_attach(GTK_TABLE(deviceTable), titleLabel, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0); + gtk_widget_show(titleLabel); + // Set choices of audio managers + inputAudioPluginStore = gtk_list_store_new(1, G_TYPE_STRING); + config_window_fill_input_audio_plugin_list(); + comboBox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(inputAudioPluginStore)); + gtk_combo_box_set_active(GTK_COMBO_BOX(comboBox), 0); + gtk_label_set_mnemonic_widget(GTK_LABEL(titleLabel), comboBox); + g_signal_connect(G_OBJECT(comboBox), "changed", G_CALLBACK(select_input_audio_plugin), comboBox); + + // Set rendering + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(comboBox), renderer, TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(comboBox), renderer, "text", 0, NULL); + gtk_table_attach(GTK_TABLE(deviceTable), comboBox, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0); + gtk_widget_show(comboBox); + */ + // Create title label + titleLabel = gtk_label_new("Alsa plug-OUT:"); + gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5); gtk_table_attach(GTK_TABLE(deviceTable), titleLabel, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0); gtk_widget_show(titleLabel); // Set choices of audio managers - audioManagerStore = gtk_list_store_new(1, G_TYPE_STRING); - config_window_fill_audio_manager_list(); - comboBox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(audioManagerStore)); + outputAudioPluginStore = gtk_list_store_new(1, G_TYPE_STRING); + config_window_fill_output_audio_plugin_list(); + comboBox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(outputAudioPluginStore)); gtk_combo_box_set_active(GTK_COMBO_BOX(comboBox), 0); gtk_label_set_mnemonic_widget(GTK_LABEL(titleLabel), comboBox); - g_signal_connect(G_OBJECT(comboBox), "changed", G_CALLBACK(select_audio_manager), comboBox); + g_signal_connect(G_OBJECT(comboBox), "changed", G_CALLBACK(select_output_audio_plugin), comboBox); // Set rendering renderer = gtk_cell_renderer_text_new(); @@ -951,7 +1020,7 @@ create_audio_tab () // Create detect button refreshButton = gtk_button_new_with_label("Detect all"); gtk_button_set_image(GTK_BUTTON(refreshButton), gtk_image_new_from_stock(GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON)); - gtk_table_attach(GTK_TABLE(deviceTable), refreshButton, 3, 4, 0, 3, GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach(GTK_TABLE(deviceTable), refreshButton, 3, 4, 3, 4, GTK_EXPAND, GTK_EXPAND, 0, 0); // Set event on selection g_signal_connect(G_OBJECT(refreshButton), "clicked", G_CALLBACK(detect_all_audio_settings), NULL); diff --git a/sflphone-gtk/src/configwindow.h b/sflphone-gtk/src/configwindow.h index f22909a2fcd64b003e4fe2ae454402746e1fc22c..783dc677a337ce514d37ef03e4e8203fc04a6e3a 100644 --- a/sflphone-gtk/src/configwindow.h +++ b/sflphone-gtk/src/configwindow.h @@ -28,7 +28,8 @@ */ void config_window_fill_account_list(); void config_window_fill_codec_list(); -void config_window_fill_audio_manager_list(); +void config_window_fill_input_audio_plugin_list(); +void config_window_fill_output_audio_plugin_list(); void config_window_fill_output_audio_device_list(); void select_active_output_audio_device(); void config_window_fill_input_audio_device_list(); diff --git a/sflphone-gtk/src/dbus.c b/sflphone-gtk/src/dbus.c index d50823ab61a1d1e0335f4d36aee208456d5d4066..4400c347c40f3efd0663aa4b8f167a921b3e2ed9 100644 --- a/sflphone-gtk/src/dbus.c +++ b/sflphone-gtk/src/dbus.c @@ -772,50 +772,95 @@ dbus_set_active_codec_list(const gchar** list) } /** - * Get a list of all supported audio managers + * Get a list of input supported audio plugins */ gchar** -dbus_get_audio_manager_list() +dbus_get_input_audio_plugin_list() { - g_print("Before get audio manager list"); + g_print("Before get input audio plugin list"); gchar** array; GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_get_audio_manager_list( + org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list( configurationManagerProxy, &array, &error); g_print("After"); if(error) { - g_printerr("Failed to call get_audio_manager_list() on ConfigurationManager: %s\n", error->message); + g_printerr("Failed to call get_input_audio_plugin_list() on ConfigurationManager: %s\n", error->message); g_error_free(error); } else - g_print("DBus called get_audio_manager_list() on ConfigurationManager\n"); + g_print("DBus called get_input_audio_plugin_list() on ConfigurationManager\n"); return array; } /** - * Sets the audio manager from its name - * Still not used because ALSA is used by default + * Get a list of output supported audio plugins + */ +gchar** +dbus_get_output_audio_plugin_list() +{ + g_print("Before get output audio plugin list"); + gchar** array; + GError* error = NULL; + org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list( + configurationManagerProxy, + &array, + &error); + g_print("After"); + if(error) + { + g_printerr("Failed to call get_output_audio_plugin_list() on ConfigurationManager: %s\n", error->message); + g_error_free(error); + } + else + g_print("DBus called get_output_audio_plugin_list() on ConfigurationManager\n"); + return array; +} + +/** + * Sets the input audio plugin from its name + */ +void +dbus_set_input_audio_plugin(gchar* audioPlugin) +{ + g_print("Before set input audio plugin"); + GError* error = NULL; + org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin( + configurationManagerProxy, + audioPlugin, + &error); + g_print("After"); + if(error) + { + g_printerr("Failed to call set_input_audio_plugin() on ConfigurationManager: %s\n", error->message); + g_error_free(error); + } + else + g_print("DBus called set_input_audio_plugin() on ConfigurationManager\n"); +} + +/** + * Sets the output audio plugin from its name */ void -dbus_set_audio_manager(gchar* audioManager) +dbus_set_output_audio_plugin(gchar* audioPlugin) { - g_print("Before set audio manager"); + g_print("Before set output audio plugin"); GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_set_audio_manager( + org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin( configurationManagerProxy, - audioManager, + audioPlugin, &error); g_print("After"); if(error) { - g_printerr("Failed to call set_audio_manager() on ConfigurationManager: %s\n", error->message); + g_printerr("Failed to call set_output_audio_plugin() on ConfigurationManager: %s\n", error->message); g_error_free(error); } else - g_print("DBus called set_audio_manager() on ConfigurationManager\n"); + g_print("DBus called set_output_audio_plugin() on ConfigurationManager\n"); } /** diff --git a/sflphone-gtk/src/dbus.h b/sflphone-gtk/src/dbus.h index c954087674e42b02ae4415fc9e8dcfa913bb0e1d..2282fe38a60f7e77331cda1e8039f7df4532bf50 100644 --- a/sflphone-gtk/src/dbus.h +++ b/sflphone-gtk/src/dbus.h @@ -61,8 +61,10 @@ gchar** dbus_get_active_codec_list( void ); void dbus_set_active_codec_list( const gchar** list ); // Audio devices related methods -gchar** dbus_get_audio_manager_list(); -void dbus_set_audio_manager(gchar* audioManager); +gchar** dbus_get_input_audio_plugin_list(); +gchar** dbus_get_output_audio_plugin_list(); +void dbus_set_input_audio_plugin(gchar* audioPlugin); +void dbus_set_output_audio_plugin(gchar* audioPlugin); gchar** dbus_get_audio_output_device_list(); void dbus_set_audio_output_device(const int index); gchar** dbus_get_audio_input_device_list(); diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp index 91575dd030f049c0b253a557f01105f25ed810c0..937faabdfcad4fa2a97f285e8796cbf8dc54590e 100644 --- a/src/audio/audiolayer.cpp +++ b/src/audio/audiolayer.cpp @@ -41,7 +41,9 @@ , _manager(manager) , _playback_handle( NULL ) , _capture_handle( NULL ) - , device_closed( true ) + , deviceClosed( true ) + , _mainBuffer( SIZEBUF ) + , _urgentBuffer( SIZEBUF ) { _inChannel = 1; // don't put in stereo @@ -53,7 +55,7 @@ // Destructor AudioLayer::~AudioLayer (void) { - device_closed = true; + deviceClosed = true; if(_capture_handle){ snd_pcm_drop( _capture_handle ); snd_pcm_close( _capture_handle ); @@ -68,12 +70,12 @@ AudioLayer::~AudioLayer (void) bool -AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize, int flag) +AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize, int stream , std::string plugin) { - if(device_closed == false) + if(deviceClosed == false) { - if( flag == SFL_PCM_CAPTURE) + if( stream == SFL_PCM_CAPTURE ){ if(_capture_handle) { _debugAlsa(" Close the current capture device\n"); @@ -81,30 +83,35 @@ AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize snd_pcm_close( _capture_handle ); _capture_handle = 0; } - else if( flag == SFL_PCM_PLAYBACK) - if(_playback_handle){ - _debugAlsa(" Close the current playback device\n"); - snd_pcm_drop( _playback_handle ); - snd_pcm_close( _playback_handle ); - _playback_handle = 0; - } + } + else if( stream == SFL_PCM_PLAYBACK){ + if(_playback_handle){ + _debugAlsa(" Close the current playback device\n"); + snd_pcm_drop( _playback_handle ); + snd_pcm_close( _playback_handle ); + _playback_handle = 0; + } + } } _indexIn = indexIn; _indexOut = indexOut; _sampleRate = sampleRate; _frameSize = frameSize; + _audioPlugin = plugin; _debug(" Setting audiolayer: device in=%2d, out=%2d\n", _indexIn, _indexOut); _debug(" : nb channel in=%2d, out=%2d\n", _inChannel, _outChannel); - _debug(" : sample rate=%5d, format=%s\n", _sampleRate, SFLPortaudioFormatString); + _debug(" : sample rate=%5d, format=%s\n", _sampleRate, SFLDataFormatString); _debug(" : frame per buffer=%d\n", FRAME_PER_BUFFER); ost::MutexLock guard( _mutex ); - std::string pcmp = buildDeviceTopo(PCM_DMIX, indexOut , 0); - std::string pcmc = buildDeviceTopo(PCM_SURROUND40, indexIn , 0); - return open_device( pcmp , pcmc , flag); + //std::string plugin = PCM_DEFAULT; + //std::string plugout = PCM_DEFAULT; + std::string pcmp = buildDeviceTopo( plugin , indexOut , 0); + std::string pcmc = buildDeviceTopo(PCM_SURROUND40 , indexIn , 0); + return open_device( pcmp , pcmc , stream); } int @@ -114,14 +121,54 @@ AudioLayer::getDeviceCount() return 1; } +void AudioLayer::AlsaCallBack( snd_async_handler_t* pcm_callback ) +{ + ( ( AudioLayer *)snd_async_handler_get_callback_private( pcm_callback )) -> updateBuffers(); +} + + void +AudioLayer::fillHWBuffer( void) +{ + unsigned char* data; + int pcmreturn, l1, l2; + short s1, s2; + int frames; + int periodSize = 1024 * 2; + + data = (unsigned char*)malloc(periodSize); + frames = periodSize >> 2; + for(l1 = 0; l1 < 100; l1++) { + for(l2 = 0; l2 < frames; l2++) { + s1 = 0; + s2 = 0; + data[4*l2] = (unsigned char)s1; + data[4*l2+1] = s1 >> 8; + data[4*l2+2] = (unsigned char)s2; + data[4*l2+3] = s2 >> 8; + } + /* Write num_frames frames from buffer data to the PCM device pointed to by pcm_handle */ + /* writei for interleaved */ + /* writen for non-interleaved */ + while ((pcmreturn = snd_pcm_writei(_playback_handle, data, frames)) < 0) { + snd_pcm_prepare(_playback_handle); + fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n"); + } + } + +} + void AudioLayer::startStream(void) { _debug(" Start stream\n"); + int err; ost::MutexLock guard( _mutex ); snd_pcm_prepare( _capture_handle ); snd_pcm_start( _capture_handle ) ; - //snd_pcm_start( _playback_handle ) ; + + snd_pcm_prepare( _playback_handle ); + + //if( err = snd_pcm_start( _playback_handle) < 0 ) _debugAlsa(" Cannot start (%s)\n", snd_strerror(err)); } @@ -131,13 +178,15 @@ AudioLayer::stopStream(void) ost::MutexLock guard( _mutex ); snd_pcm_drop( _capture_handle ); snd_pcm_prepare( _capture_handle ); + snd_pcm_drop( _playback_handle ); + snd_pcm_prepare( _playback_handle ); } void AudioLayer::sleep(int msec) { - snd_pcm_wait(_playback_handle, msec); + //snd_pcm_wait(_playback_handle, msec); } bool @@ -151,33 +200,46 @@ AudioLayer::isStreamActive (void) int AudioLayer::playSamples(void* buffer, int toCopy) { + //_debug(" Write %d bytes in the main buffer \n ", toCopy); ost::MutexLock guard( _mutex ); if ( _playback_handle ){ - //_debug("Play samples\n"); write(buffer, toCopy); } + /* int a = _mainBuffer.AvailForPut(); + if( a >= toCopy ){ + return _mainBuffer.Put( buffer , toCopy , _defaultVolume ); + } else { + return _mainBuffer.Put( buffer , a , _defaultVolume ) ; + }*/ return 0; } - int -AudioLayer::playRingTone( void* buffer, int toCopy) +AudioLayer::putUrgent(void* buffer, int toCopy) { - _debug(" %d\n", toCopy); + fillHWBuffer(); ost::MutexLock guard( _mutex ); - if( _playback_handle ) - snd_pcm_start( _playback_handle ); - write(buffer, toCopy); + if ( _playback_handle ) + { + int a = _urgentBuffer.AvailForPut(); + if( a >= toCopy ){ + return _urgentBuffer.Put( buffer , toCopy , _defaultVolume ); + } else { + return _urgentBuffer.Put( buffer , a , _defaultVolume ) ; + } + } return 0; } - int -AudioLayer::putUrgent(void* buffer, int toCopy) + void +AudioLayer::stopPlaybackStream( void ) { ost::MutexLock guard( _mutex ); - if ( _playback_handle ) - write(buffer, toCopy); - return 0; + if( _playback_handle ) + { + snd_pcm_drop( _playback_handle ); + snd_pcm_prepare( _playback_handle ); + } } int @@ -224,6 +286,29 @@ AudioLayer::toggleEchoTesting() { ///////////////// ALSA PRIVATE FUNCTIONS //////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// + + + void +AudioLayer::updateBuffers( void ) +{ + + int toGet; + int urgentAvail; + int bytes = 882 * sizeof(SFLDataFormat); + SFLDataFormat* toWrite[bytes]; + snd_pcm_uframes_t avail = 0; + avail = snd_pcm_avail_update( _playback_handle ); + if( avail ) { + //_debug("%i\n", avail); + urgentAvail = _urgentBuffer.AvailForGet(); + if( urgentAvail > 0 ){ + toGet = ( urgentAvail < bytes ) ? urgentAvail : bytes; + _urgentBuffer.Get( toWrite , toGet , 100 ); + //write( toWrite , toGet ); + } + } +} + bool AudioLayer::isPlaybackActive(void) { ost::MutexLock guard( _mutex ); @@ -254,7 +339,7 @@ AudioLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) snd_pcm_uframes_t period_size_in = getFrameSize() * getSampleRate() / 1000 ; snd_pcm_uframes_t buffer_size_in = 4096; snd_pcm_uframes_t threshold = getFrameSize() * getSampleRate() / 1000 ; - snd_pcm_uframes_t period_size_out = 2048 ; + snd_pcm_uframes_t period_size_out = 1024 ; snd_pcm_uframes_t buffer_size_out = 4096 ; snd_pcm_sw_params_t *swparams = NULL; @@ -280,20 +365,21 @@ AudioLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) if( err = snd_pcm_hw_params( _capture_handle, hwparams ) < 0) _debug(" Cannot set hw parameters (%s)\n", snd_strerror(err)); snd_pcm_hw_params_free( hwparams ); - snd_pcm_sw_params_alloca( &swparams ); - snd_pcm_sw_params_current( _capture_handle, swparams ); + //snd_pcm_sw_params_malloc( &swparams ); + //snd_pcm_sw_params_current( _capture_handle, swparams ); - if( err = snd_pcm_sw_params_set_start_threshold( _capture_handle, swparams, 1 ) < 0 ) _debug(" Cannot set start threshold (%s)\n", snd_strerror(err)); - if( err = snd_pcm_sw_params_set_stop_threshold( _capture_handle, swparams, buffer_size_in ) < 0 ) _debug(" Cannot get stop threshold (%s)\n", snd_strerror(err)); - if( err = snd_pcm_sw_params( _capture_handle, swparams ) < 0 ) _debug(" Cannot set sw parameters (%s)\n", snd_strerror(err)); - device_closed = false; + //if( err = snd_pcm_sw_params_set_start_threshold( _capture_handle, swparams, 1 ) < 0 ) _debug(" Cannot set start threshold (%s)\n", snd_strerror(err)); + //if( err = snd_pcm_sw_params_set_stop_threshold( _capture_handle, swparams, buffer_size_in ) < 0 ) _debug(" Cannot get stop threshold (%s)\n", snd_strerror(err)); + //if( err = snd_pcm_sw_params( _capture_handle, swparams ) < 0 ) _debug(" Cannot set sw parameters (%s)\n", snd_strerror(err)); + deviceClosed = false; + //snd_pcm_sw_params_free( swparams ); } if(flag == SFL_PCM_BOTH || flag == SFL_PCM_PLAYBACK) { _debug(" Opening playback device %s\n", pcm_p.c_str()); - if(err = snd_pcm_open(&_playback_handle, pcm_p.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0){ + if(err = snd_pcm_open(&_playback_handle, pcm_p.c_str(), SND_PCM_STREAM_PLAYBACK, 0 ) < 0){ _debug(" Error while opening playback device %s (%s)\n", pcm_p.c_str(), snd_strerror(err)); return false; } @@ -312,71 +398,91 @@ AudioLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) snd_pcm_hw_params_free( hwparams ); snd_pcm_uframes_t val = 1024 ; - snd_pcm_sw_params_alloca( &swparams ); + snd_pcm_sw_params_malloc( &swparams ); snd_pcm_sw_params_current( _playback_handle, swparams ); - if( err = snd_pcm_sw_params_set_start_threshold( _playback_handle, swparams, val ) < 0 ) _debug(" Cannot set start threshold (%s)\n", snd_strerror(err)); - if( err = snd_pcm_sw_params_set_stop_threshold( _playback_handle, swparams, buffer_size_out ) < 0 ) _debug(" Cannot set stop threshold (%s)\n", snd_strerror(err)); + if( err = snd_pcm_sw_params_set_start_threshold( _playback_handle, swparams, period_size_out ) < 0 ) _debug(" Cannot set start threshold (%s)\n", snd_strerror(err)); + //if( err = snd_pcm_sw_params_set_stop_threshold( _playback_handle, swparams, buffer_size_out ) < 0 ) _debug(" Cannot set stop threshold (%s)\n", snd_strerror(err)); + if( err = snd_pcm_sw_params_set_avail_min( _playback_handle, swparams, period_size_out) < 0) _debug(" Cannot set min avail (%s)\n" , snd_strerror(err)); + if( err = snd_pcm_sw_params_set_xfer_align( _playback_handle , swparams , 1 ) < 0) _debug( "Cannot align transfer (%s)\n", snd_strerror(err)); if( err = snd_pcm_sw_params( _playback_handle, swparams ) < 0 ) _debug(" Cannot set sw parameters (%s)\n", snd_strerror(err)); - device_closed = false; + snd_pcm_sw_params_free( swparams ); + + if ( err = snd_async_add_pcm_handler( &_AsyncHandler, _playback_handle , AlsaCallBack, this ) < 0) _debugAlsa(" Unable to install the async callback handler (%s)\n", snd_strerror(err)); + deviceClosed = false; + + //fillHWBuffer(); + + //if( err = snd_pcm_start(_playback_handle ) < 0 ) _debug(" Cannot start\n"); + } return true; } +//TODO EAGAIN error case +//TODO first frame causes broken pipe (underrun) because not enough data are send --> make the handle wait to be ready int AudioLayer::write(void* buffer, int length) { - - if(device_closed || _playback_handle == NULL) - return 0; - int bytes; - short* buff = (short*) buffer; - int result = 0 ; - - + /* if(deviceClosed || _playback_handle == NULL) + return 0; + int framesPerBuffer = 882; + bool playUrgent = false; + SFLDataFormat ringtone[ framesPerBuffer ]; + AudioLoop* tone = _manager->getTelephoneTone(); + if( tone != 0){ + _debug("Play tone \n"); + tone->getNext(ringtone, framesPerBuffer , _manager->getSpkrVolume()); + playUrgent = true; + } + else if( (tone=_manager->getTelephoneFile()) != 0 ){ + _debug("Play tone also \n"); + tone->getNext(ringtone, framesPerBuffer , _manager->getSpkrVolume()); + playUrgent = true; + } + + int bytes;*/ snd_pcm_uframes_t frames = snd_pcm_bytes_to_frames( _playback_handle, length); - - while( frames > 0 ) - { - bytes = snd_pcm_writei( _playback_handle, buff, frames); - if( bytes == -EAGAIN || (bytes >=0 && bytes < frames)) + bytes = snd_pcm_writei( _playback_handle, buffer, frames); + + if( bytes == -EAGAIN) { - //snd_pcm_wait( _playback_handle, 20 ); - break; + _debugAlsa(" (%s)\n", snd_strerror( bytes )); + snd_pcm_resume( _playback_handle ); } + else if(bytes >=0 && bytes < frames) + { + _debugAlsa("Short write - Frames remaining = %d\n", frames); + } else if( bytes == -EPIPE ) { - _debugAlsa(" %d Alsa error from writei (%s)\n", bytes, snd_strerror(bytes)); - snd_pcm_prepare( _playback_handle ); - snd_pcm_writei( _playback_handle , buff , frames ); - break; + _debugAlsa(" %d Alsa error from writei (%s)\n", bytes, snd_strerror(bytes)); + snd_pcm_prepare( _playback_handle ); + snd_pcm_writei( _playback_handle , buffer , frames ); } else if( bytes == -ESTRPIPE ) { - _debug(" Playback suspend \n"); + _debugAlsa(" Playback suspend (%s)\n", snd_strerror(bytes)); snd_pcm_resume( _playback_handle ); - break; } - if( bytes != frames) - { - _debug(" Short write\n"); - frames -= bytes; - buff += bytes; - } - + else if( bytes == -EBADFD) + { + _debugAlsa(" PCM is not in the right state (%s)\n", snd_strerror( bytes )); } + snd_pcm_sframes_t delay; + //snd_pcm_delay( _playback_handle, &delay); + //snd_pcm_avail_update( _playback_handle ); return 0; - } int AudioLayer::read( void* buffer, int toCopy) { - if(device_closed || _capture_handle == NULL) + if(deviceClosed || _capture_handle == NULL) return 0; int err; if(snd_pcm_state( _capture_handle ) == SND_PCM_STATE_XRUN) diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h index 78f1f9dd4a5a9e1f9e66654c274741c6accec130..d60e4fe95fb2b701bc08c47f79a37a9933224bbd 100644 --- a/src/audio/audiolayer.h +++ b/src/audio/audiolayer.h @@ -28,6 +28,7 @@ #include "../global.h" #include "audiodevice.h" +#include "ringbuffer.h" #include <vector> #include <alsa/asoundlib.h> @@ -37,6 +38,7 @@ #include <sstream> #define FRAME_PER_BUFFER 160 +class RingBuffer; class ManagerImpl; class AudioLayer { @@ -56,7 +58,7 @@ class AudioLayer { * SFL_PCM_PLAYBACK * SFL_PCM_BOTH */ - bool openDevice(int, int, int, int, int); + bool openDevice(int, int, int, int, int, std::string); /* * Start the capture stream. The playback starts according th its threshold @@ -70,6 +72,8 @@ class AudioLayer { * ALSA Library API */ void stopStream(void); + + void fillHWBuffer( void) ; void sleep(int); @@ -108,9 +112,10 @@ class AudioLayer { * @return int The number of bytes played */ int playSamples(void* buffer, int toCopy); - int playRingTone( void* buffer, int toCopy); int putUrgent(void* buffer, int toCopy); + void stopPlaybackStream( void ); + /* * Query the audio devices for number of bytes available in the hardware ring buffer * @return int The number of bytes available @@ -177,6 +182,8 @@ class AudioLayer { */ unsigned int getFrameSize() { return _frameSize; } + std::string getAudioPlugin( void ) { return _audioPlugin; } + int getDeviceCount(); /** @@ -184,8 +191,17 @@ class AudioLayer { */ void toggleEchoTesting(); + private: + static void AlsaCallBack( snd_async_handler_t* ); + snd_async_handler_t *_AsyncHandler; + snd_pcm_t* _playback_handle; + snd_pcm_t* _capture_handle; + RingBuffer _urgentBuffer; + RingBuffer _mainBuffer; + void updateBuffers( void ); + /* * Open the specified device. * ALSA Library API @@ -231,15 +247,14 @@ class AudioLayer { * Handle to manipulate capture and playback streams * ALSA Library API */ - snd_pcm_t* _playback_handle; - snd_pcm_t* _capture_handle; - + + /* * Enable to determine if the devices are opened or not * true if the devices are closed * false otherwise */ - bool device_closed; + bool deviceClosed; /** * Number of audio cards on which stream has been opened @@ -259,6 +274,8 @@ class AudioLayer { */ unsigned int _frameSize; + std::string _audioPlugin; + /** * Input channel (mic) should be 1 mono */ diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h index 196851725b3a852582c6fb29e1cfc10a950e815e..f11da96a601fc933068d7544c795d2421504e9b0 100644 --- a/src/dbus/configurationmanager-glue.h +++ b/src/dbus/configurationmanager-glue.h @@ -36,8 +36,10 @@ public: register_method(ConfigurationManager, getCodecDetails, _getCodecDetails_stub); register_method(ConfigurationManager, getActiveCodecList, _getActiveCodecList_stub); register_method(ConfigurationManager, setActiveCodecList, _setActiveCodecList_stub); - register_method(ConfigurationManager, getAudioManagerList, _getAudioManagerList_stub); - register_method(ConfigurationManager, setAudioManager, _setAudioManager_stub); + register_method(ConfigurationManager, getInputAudioPluginList, _getInputAudioPluginList_stub); + register_method(ConfigurationManager, getOutputAudioPluginList, _getOutputAudioPluginList_stub); + register_method(ConfigurationManager, setInputAudioPlugin, _setInputAudioPlugin_stub); + register_method(ConfigurationManager, setOutputAudioPlugin, _setOutputAudioPlugin_stub); register_method(ConfigurationManager, getAudioOutputDeviceList, _getAudioOutputDeviceList_stub); register_method(ConfigurationManager, setAudioOutputDevice, _setAudioOutputDevice_stub); register_method(ConfigurationManager, getAudioInputDeviceList, _getAudioInputDeviceList_stub); @@ -131,14 +133,24 @@ public: { "list", "as", true }, { 0, 0, 0 } }; - static ::DBus::IntrospectedArgument getAudioManagerList_args[] = + static ::DBus::IntrospectedArgument getInputAudioPluginList_args[] = { { "list", "as", false }, { 0, 0, 0 } }; - static ::DBus::IntrospectedArgument setAudioManager_args[] = + static ::DBus::IntrospectedArgument getOutputAudioPluginList_args[] = { - { "audioManager", "s", true }, + { "list", "as", false }, + { 0, 0, 0 } + }; + static ::DBus::IntrospectedArgument setInputAudioPlugin_args[] = + { + { "audioPlugin", "s", true }, + { 0, 0, 0 } + }; + static ::DBus::IntrospectedArgument setOutputAudioPlugin_args[] = + { + { "audioPlugin", "s", true }, { 0, 0, 0 } }; static ::DBus::IntrospectedArgument getAudioOutputDeviceList_args[] = @@ -199,8 +211,10 @@ public: { "getCodecDetails", getCodecDetails_args }, { "getActiveCodecList", getActiveCodecList_args }, { "setActiveCodecList", setActiveCodecList_args }, - { "getAudioManagerList", getAudioManagerList_args }, - { "setAudioManager", setAudioManager_args }, + { "getInputAudioPluginList", getInputAudioPluginList_args }, + { "getOutputAudioPluginList", getOutputAudioPluginList_args }, + { "setInputAudioPlugin", setInputAudioPlugin_args }, + { "setOutputAudioPlugin", setOutputAudioPlugin_args }, { "getAudioOutputDeviceList", getAudioOutputDeviceList_args }, { "setAudioOutputDevice", setAudioOutputDevice_args }, { "getAudioInputDeviceList", getAudioInputDeviceList_args }, @@ -256,8 +270,10 @@ public: virtual std::vector< ::DBus::String > getCodecDetails( const ::DBus::Int32& payload ) = 0; virtual std::vector< ::DBus::String > getActiveCodecList( ) = 0; virtual void setActiveCodecList( const std::vector< ::DBus::String >& list ) = 0; - virtual std::vector< ::DBus::String > getAudioManagerList( ) = 0; - virtual void setAudioManager( const ::DBus::String& audioManager ) = 0; + virtual std::vector< ::DBus::String > getInputAudioPluginList( ) = 0; + virtual std::vector< ::DBus::String > getOutputAudioPluginList( ) = 0; + virtual void setInputAudioPlugin( const ::DBus::String& audioPlugin ) = 0; + virtual void setOutputAudioPlugin( const ::DBus::String& audioPlugin ) = 0; virtual std::vector< ::DBus::String > getAudioOutputDeviceList( ) = 0; virtual void setAudioOutputDevice( const ::DBus::Int32& index ) = 0; virtual std::vector< ::DBus::String > getAudioInputDeviceList( ) = 0; @@ -444,22 +460,41 @@ private: ::DBus::ReturnMessage reply(call); return reply; } - ::DBus::Message _getAudioManagerList_stub( const ::DBus::CallMessage& call ) + ::DBus::Message _getInputAudioPluginList_stub( const ::DBus::CallMessage& call ) + { + ::DBus::MessageIter ri = call.reader(); + + std::vector< ::DBus::String > argout1 = getInputAudioPluginList(); + ::DBus::ReturnMessage reply(call); + ::DBus::MessageIter wi = reply.writer(); + wi << argout1; + return reply; + } + ::DBus::Message _getOutputAudioPluginList_stub( const ::DBus::CallMessage& call ) { ::DBus::MessageIter ri = call.reader(); - std::vector< ::DBus::String > argout1 = getAudioManagerList(); + std::vector< ::DBus::String > argout1 = getOutputAudioPluginList(); ::DBus::ReturnMessage reply(call); ::DBus::MessageIter wi = reply.writer(); wi << argout1; return reply; } - ::DBus::Message _setAudioManager_stub( const ::DBus::CallMessage& call ) + ::DBus::Message _setInputAudioPlugin_stub( const ::DBus::CallMessage& call ) + { + ::DBus::MessageIter ri = call.reader(); + + ::DBus::String argin1; ri >> argin1; + setInputAudioPlugin(argin1); + ::DBus::ReturnMessage reply(call); + return reply; + } + ::DBus::Message _setOutputAudioPlugin_stub( const ::DBus::CallMessage& call ) { ::DBus::MessageIter ri = call.reader(); ::DBus::String argin1; ri >> argin1; - setAudioManager(argin1); + setOutputAudioPlugin(argin1); ::DBus::ReturnMessage reply(call); return reply; } diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml index b0b82baa010452ab6309bb666234b08ba6c09a89..09a92e921ccc9172168fcf9c43315cc3e38fc5b2 100644 --- a/src/dbus/configurationmanager-introspec.xml +++ b/src/dbus/configurationmanager-introspec.xml @@ -81,11 +81,17 @@ <!-- Audio devices methods --> - <method name="getAudioManagerList"> + <method name="getInputAudioPluginList"> <arg type="as" name="list" direction="out"/> </method> - <method name="setAudioManager"> - <arg type="s" name="audioManager" direction="in"/> + <method name="getOutputAudioPluginList"> + <arg type="as" name="list" direction="out"/> + </method> + <method name="setInputAudioPlugin"> + <arg type="s" name="audioPlugin" direction="in"/> + </method> + <method name="setOutputAudioPlugin"> + <arg type="s" name="audioPlugin" direction="in"/> </method> <method name="getAudioOutputDeviceList"> diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp index 980d1815f577feb40ca03188d0f0a4666f9ef0f6..0f80ed1d27f6d2b13245fce1913f57a5b9f709ea 100644 --- a/src/dbus/configurationmanager.cpp +++ b/src/dbus/configurationmanager.cpp @@ -126,19 +126,35 @@ ConfigurationManager::setActiveCodecList( const std::vector< ::DBus::String >& l } // Audio devices related methods -std::vector< ::DBus::String > -ConfigurationManager::getAudioManagerList() + std::vector< ::DBus::String > +ConfigurationManager::getInputAudioPluginList() { - _debug("ConfigurationManager::getAudioManagerList received\n"); - return Manager::instance().getAudioManagerList(); + _debug("ConfigurationManager::getInputAudioPluginList received\n"); + return Manager::instance().getInputAudioPluginList(); } -void -ConfigurationManager::setAudioManager(const ::DBus::String& audioManager) + + std::vector< ::DBus::String > +ConfigurationManager::getOutputAudioPluginList() { - _debug("ConfigurationManager::setAudioManager received\n"); - return Manager::instance().setAudioManager(audioManager); + _debug("ConfigurationManager::getOutputAudioPluginList received\n"); + return Manager::instance().getOutputAudioPluginList(); } -std::vector< ::DBus::String > + + void +ConfigurationManager::setInputAudioPlugin(const ::DBus::String& audioPlugin) +{ + _debug("ConfigurationManager::setInputAudioPlugin received\n"); + return Manager::instance().setInputAudioPlugin(audioPlugin); +} + + void +ConfigurationManager::setOutputAudioPlugin(const ::DBus::String& audioPlugin) +{ + _debug("ConfigurationManager::setOutputAudioPlugin received\n"); + return Manager::instance().setOutputAudioPlugin(audioPlugin); +} + + std::vector< ::DBus::String > ConfigurationManager::getAudioOutputDeviceList() { _debug("ConfigurationManager::getAudioOutputDeviceList received\n"); diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h index 9e800b04aa1ae24972465b6014efb5019a048cf2..6c13b642ab0b6bdd2757c6a1f5f1dcdfc4e4b9fe 100644 --- a/src/dbus/configurationmanager.h +++ b/src/dbus/configurationmanager.h @@ -52,8 +52,10 @@ public: std::vector< ::DBus::String > getActiveCodecList( ); void setActiveCodecList( const std::vector< ::DBus::String >& list ); - std::vector< ::DBus::String > getAudioManagerList(); - void setAudioManager(const ::DBus::String& audioManager); + std::vector< ::DBus::String > getInputAudioPluginList(); + std::vector< ::DBus::String > getOutputAudioPluginList(); + void setInputAudioPlugin(const ::DBus::String& audioPlugin); + void setOutputAudioPlugin(const ::DBus::String& audioPlugin); std::vector< ::DBus::String > getAudioOutputDeviceList(); void setAudioOutputDevice(const ::DBus::Int32& index); std::vector< ::DBus::String > getAudioInputDeviceList(); diff --git a/src/global.h b/src/global.h index 53735727161d55eba06e0976b73edaa18a1d99ae..f410aa3888ad504e17fe60fa5c1066471ab1ed50 100644 --- a/src/global.h +++ b/src/global.h @@ -27,17 +27,14 @@ typedef float float32; typedef short int16; -//#define DATAFORMAT_IS_FLOAT #ifdef DATAFORMAT_IS_FLOAT #define SFLDataFormat float32 -#define SFLPortaudioFormat portaudio::FLOAT32 -#define SFLPortaudioFormatString "Float32" +#define SFLDataFormatString "Float32" #define SFLDataAmplitude 0.05 #define SFLConvertInt16(s) ((float)(s)-16384.0)/16384.0 #else #define SFLDataFormat int16 -#define SFLPortaudioFormat portaudio::INT16 -#define SFLPortaudioFormatString "Int16" +#define SFLDataFormatString "Int16" #define SFLDataAmplitude (32767 >> 4) #define SFLConvertInt16(s) (s) #endif @@ -74,6 +71,7 @@ typedef short int16; #define CHANNELS 2 #define SIZEBUF 1024*1024 +#define PCM_HW "hw" #define PCM_PLUGHW "plughw" #define PCM_FRONT "plug:front" #define PCM_DEFAULT "default" diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 171586e51a2359cee7cfb9888dc3c67dd72b2640..e98012be65a914ffcc36f9ccc599c104d9950e1b 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -350,7 +350,7 @@ ManagerImpl::offHoldCall(const CallID& id) switchCall(id); if (returnValue) { try { - getAudioDriver()->startStream(); + //getAudioDriver()->startStream(); } catch(...) { _debugException("! Manager Off hold could not start audio stream"); } @@ -550,24 +550,22 @@ ManagerImpl::playDtmf(char code) // Put buffer to urgentRingBuffer // put the size in bytes... // so size * 1 channel (mono) * sizeof (bytes for the data) - audiolayer->putUrgent(_buf, size * sizeof(SFLDataFormat)); + audiolayer->playSamples(_buf, size * sizeof(SFLDataFormat)); + //audiolayer->putUrgent(_buf, size * sizeof(SFLDataFormat)); - try { - // We activate the stream if it's not active yet. - if (!audiolayer->isStreamActive()) { - //audiolayer->startStream(); - } else { - audiolayer->sleep(pulselen); // in milliseconds - } - } catch(...) { - _debugException("Portaudio exception when playing a dtmf"); + // We activate the stream if it's not active yet. + if (!audiolayer->isStreamActive()) { + //audiolayer->startStream(); + } else { + _debugAlsa("send dtmf - sleep\n"); + audiolayer->sleep(pulselen); // in milliseconds } - returnValue = true; } + returnValue = true; - // TODO: add caching - delete[] _buf; _buf = 0; - return returnValue; +// TODO: add caching +delete[] _buf; _buf = 0; +return returnValue; } // Multi-thread @@ -617,8 +615,8 @@ ManagerImpl::incomingCall(Call* call, const AccountID& accountId) associateCallToAccount(call->getCallId(), accountId); if ( !hasCurrentCall() ) { - _debug("INCOMING CALL!!!!!!\n"); call->setConnectionState(Call::Ringing); + _debugAlsa(" call ringtone() method\n "); ringtone(); switchCall(call->getCallId()); } else { @@ -806,7 +804,6 @@ ManagerImpl::registrationFailed(const AccountID& accountid) bool ManagerImpl::playATone(Tone::TONEID toneId) { int hasToPlayTone = getConfigInt(SIGNALISATION, PLAY_TONES); - if (!hasToPlayTone) return false; if (_telephoneTone != 0) { @@ -816,14 +813,11 @@ ManagerImpl::playATone(Tone::TONEID toneId) { AudioLoop* audioloop = getTelephoneTone(); unsigned int nbSampling = audioloop->getSize(); - _debug("Telephone tone size = %d\n", nbSampling); AudioLayer* audiolayer = getAudioDriver(); - //int chunks = 2000; SFLDataFormat buf[nbSampling]; - audioloop->getNext(buf, audioloop->getSize()); - if (audiolayer) { - audiolayer->putUrgent( buf, sizeof(SFLDataFormat)*nbSampling); - ///buf += chunks; + audioloop->getNext(buf, (int) nbSampling); + if ( audiolayer ) { + //audiolayer->putUrgent( buf, sizeof(SFLDataFormat)*nbSampling ); } else return false; @@ -840,12 +834,8 @@ ManagerImpl::stopTone(bool stopAudio=true) { if (!hasToPlayTone) return; if (stopAudio) { - try { - AudioLayer* audiolayer = getAudioDriver(); - if (audiolayer) { audiolayer->stopStream(); } - } catch(...) { - _debugException("Stop tone and stop stream"); - } + AudioLayer* audiolayer = getAudioDriver(); + if (audiolayer) { audiolayer->stopStream(); } } _toneMutex.enterMutex(); @@ -892,8 +882,6 @@ ManagerImpl::ringback () { void ManagerImpl::ringtone() { - - int hasToPlayTone = getConfigInt(SIGNALISATION, PLAY_TONES); if (!hasToPlayTone) { return; } @@ -917,14 +905,9 @@ ManagerImpl::ringtone() _toneMutex.leaveMutex(); int size = _audiofile.getSize(); SFLDataFormat output[ size ]; - //_debugAlsa("Size = %i\n", size); - //_audiofile.getNext(output, size , 100); - try { - //audiolayer->putUrgent( output, size); - _debug(" Ringtone if everything would have worked fine\n"); - } catch(...) { - _debugException("Audio file couldn't start audio stream"); - } + _debugAlsa("Size = %i\n", size); + _audiofile.getNext(output, size , 100); + audiolayer->playSamples( output , size ); } else { ringback(); } @@ -971,7 +954,7 @@ ManagerImpl::notificationIncomingCall(void) { unsigned int nbSampling = tone.getSize(); SFLDataFormat buf[nbSampling]; tone.getNext(buf, tone.getSize()); - audiolayer->putUrgent(buf, sizeof(SFLDataFormat)*nbSampling); + audiolayer->playSamples(buf, sizeof(SFLDataFormat)*nbSampling); } } @@ -1222,27 +1205,66 @@ ManagerImpl::getCodecDetails( const ::DBus::Int32& payload ) } /** - * Get list of supported audio manager + * Get list of supported input audio plugin */ std::vector<std::string> -ManagerImpl::getAudioManagerList(void) +ManagerImpl::getInputAudioPluginList(void) { std::vector<std::string> v; - _debug("Get audio manager list"); + _debug("Get input audio plugin list"); + + v.push_back("default"); + v.push_back("surround40"); + v.push_back("plug:hw"); - // Return only ALSA for now - v.push_back("ALSA"); return v; } /** - * Set audio manager (always put ALSA) + * Get list of supported output audio plugin + */ + std::vector<std::string> +ManagerImpl::getOutputAudioPluginList(void) +{ + std::vector<std::string> v; + _debug("Get output audio plugin list"); + + v.push_back("default"); + v.push_back("plug:hw"); + v.push_back("plug:dmix"); + v.push_back("plug:surround40"); + + return v; +} + +/** + * Set input audio plugin + */ + void +ManagerImpl::setInputAudioPlugin(const std::string& audioPlugin) +{ + _debug("Set input audio plugin\n"); + _audiodriver -> openDevice( _audiodriver -> getIndexIn(), + _audiodriver -> getIndexOut(), + _audiodriver -> getSampleRate(), + _audiodriver -> getFrameSize(), + SFL_PCM_CAPTURE, + audioPlugin); +} + +/** + * Set output audio plugin */ void -ManagerImpl::setAudioManager(const std::string& audioManager) +ManagerImpl::setOutputAudioPlugin(const std::string& audioPlugin) { - _debug("Set audio manager\n"); - // Do nothing for now + _debug("Set output audio plugin\n"); + _audiodriver -> openDevice( _audiodriver -> getIndexIn(), + _audiodriver -> getIndexOut(), + _audiodriver -> getSampleRate(), + _audiodriver -> getFrameSize(), + SFL_PCM_PLAYBACK, + audioPlugin); } /** @@ -1266,7 +1288,8 @@ ManagerImpl::setAudioOutputDevice(const int index) index, _audiodriver->getSampleRate(), _audiodriver->getFrameSize(), - SFL_PCM_PLAYBACK); + SFL_PCM_PLAYBACK, + _audiodriver->getAudioPlugin()); } /** @@ -1290,7 +1313,8 @@ ManagerImpl::setAudioInputDevice(const int index) _audiodriver->getIndexOut(), _audiodriver->getSampleRate(), _audiodriver->getFrameSize(), - SFL_PCM_CAPTURE); + SFL_PCM_CAPTURE, + _audiodriver->getAudioPlugin()); } /** @@ -1363,7 +1387,7 @@ ManagerImpl::selectAudioDriver (void) //} _debugInit(" AudioLayer Opening Device"); _audiodriver->setErrorMessage(""); - _audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate, frameSize, SFL_PCM_BOTH); + _audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate, frameSize, SFL_PCM_BOTH, PCM_PLUGHW); } /** diff --git a/src/managerimpl.h b/src/managerimpl.h index 9aae25f52807e77a85158f3bc5dea7c5703243d7..9f5068b304b9cd48947a6811a321b1c20d9d7063 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -278,15 +278,26 @@ public: std::vector< ::DBus::String > getCodecDetails( const ::DBus::Int32& payload); /** - * Get a list of supported audio managers + * Get a list of supported input audio plugin * @return List of names */ - std::vector< std::string> getAudioManagerList(void); + std::vector< std::string> getInputAudioPluginList(void); /** - * Set audio manager (always put ALSA) + * Get a list of supported output audio plugin + * @return List of names + */ + std::vector< std::string> getOutputAudioPluginList(void); + + /** + * Set input audio plugin + */ + void setInputAudioPlugin(const std::string& audioPlugin); + + /** + * Set output audio plugin */ - void setAudioManager(const std::string& audioManager); + void setOutputAudioPlugin(const std::string& audioPlugin); /** * Get list of supported audio output device