From 5fe13017be527a9127ff760b81fdcc8b2b4591c3 Mon Sep 17 00:00:00 2001
From: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
Date: Wed, 5 Mar 2008 17:04:16 -0500
Subject: [PATCH] Associate a sound card id with its string description

---
 sflphone-gtk/src/configurationmanager-glue.h | 18 +++++------
 sflphone-gtk/src/configwindow.c              | 13 +++++---
 sflphone-gtk/src/dbus.c                      | 22 ++++++-------
 sflphone-gtk/src/dbus.h                      |  3 +-
 src/audio/audiolayer.cpp                     | 34 ++++++++++++++++++--
 src/audio/audiolayer.h                       | 10 ++++--
 src/dbus/configurationmanager-glue.h         | 18 +++++------
 src/dbus/configurationmanager-introspec.xml  |  6 ++--
 src/dbus/configurationmanager.cpp            |  8 ++---
 src/dbus/configurationmanager.h              |  2 +-
 src/global.h                                 |  2 ++
 src/managerimpl.cpp                          | 34 +++++++++++---------
 src/managerimpl.h                            |  4 +--
 13 files changed, 108 insertions(+), 66 deletions(-)

diff --git a/sflphone-gtk/src/configurationmanager-glue.h b/sflphone-gtk/src/configurationmanager-glue.h
index 9e395b9f87..097e6921c2 100644
--- a/sflphone-gtk/src/configurationmanager-glue.h
+++ b/sflphone-gtk/src/configurationmanager-glue.h
@@ -955,22 +955,22 @@ static
 inline
 #endif
 gboolean
-org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details (DBusGProxy *proxy, const gint IN_index, char *** OUT_details, GError **error)
+org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index (DBusGProxy *proxy, const char * IN_name, gint* OUT_index, GError **error)
 
 {
-  return dbus_g_proxy_call (proxy, "getAudioDeviceDetails", error, G_TYPE_INT, IN_index, G_TYPE_INVALID, G_TYPE_STRV, OUT_details, G_TYPE_INVALID);
+  return dbus_g_proxy_call (proxy, "getAudioDeviceIndex", error, G_TYPE_STRING, IN_name, G_TYPE_INVALID, G_TYPE_INT, OUT_index, G_TYPE_INVALID);
 }
 
-typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details_reply) (DBusGProxy *proxy, char * *OUT_details, GError *error, gpointer userdata);
+typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index_reply) (DBusGProxy *proxy, gint OUT_index, GError *error, gpointer userdata);
 
 static void
-org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
+org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
 {
   DBusGAsyncData *data = (DBusGAsyncData*) user_data;
   GError *error = NULL;
-  char ** OUT_details;
-  dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_details, G_TYPE_INVALID);
-  (*(org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details_reply)data->cb) (proxy, OUT_details, error, data->userdata);
+  gint OUT_index;
+  dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &OUT_index, G_TYPE_INVALID);
+  (*(org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index_reply)data->cb) (proxy, OUT_index, error, data->userdata);
   return;
 }
 
@@ -979,14 +979,14 @@ static
 inline
 #endif
 DBusGProxyCall*
-org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details_async (DBusGProxy *proxy, const gint IN_index, org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details_reply callback, gpointer userdata)
+org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index_async (DBusGProxy *proxy, const char * IN_name, org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index_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, "getAudioDeviceDetails", org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details_async_callback, stuff, g_free, G_TYPE_INT, IN_index, G_TYPE_INVALID);
+  return dbus_g_proxy_begin_call (proxy, "getAudioDeviceIndex", org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index_async_callback, stuff, g_free, G_TYPE_STRING, IN_name, G_TYPE_INVALID);
 }
 #endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_org_sflphone_SFLphone_ConfigurationManager */
 
diff --git a/sflphone-gtk/src/configwindow.c b/sflphone-gtk/src/configwindow.c
index a8454c9790..dbbc6e277f 100644
--- a/sflphone-gtk/src/configwindow.c
+++ b/sflphone-gtk/src/configwindow.c
@@ -195,6 +195,7 @@ config_window_fill_output_audio_device_list()
 	GtkTreeIter iter;
 	gchar** list;
 	gchar** audioDevice;
+	int index;
 
 	gtk_list_store_clear(outputAudioDeviceManagerStore);
 	
@@ -205,8 +206,9 @@ 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(outputAudioDeviceManagerStore, &iter);
-		gtk_list_store_set(outputAudioDeviceManagerStore, &iter, 0, *list, 1, c, -1);
+		gtk_list_store_set(outputAudioDeviceManagerStore, &iter, 0, *list, 1, index, -1);
 		c++;
 	}
 }
@@ -255,19 +257,20 @@ config_window_fill_input_audio_device_list()
 	GtkTreeIter iter;
 	gchar** list;
 	gchar** audioDevice;
-
+	int index ;
 	gtk_list_store_clear(inputAudioDeviceManagerStore);
 	
 	// Call dbus to retreive list
 	list = dbus_get_audio_input_device_list();
 	
 	// For each device name included in list
-	int c = 0;
+	//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, c, -1);
-		c++;
+		gtk_list_store_set(inputAudioDeviceManagerStore, &iter, 0, *list, 1, index, -1);
+		//c++;
 	}
 }
 
diff --git a/sflphone-gtk/src/dbus.c b/sflphone-gtk/src/dbus.c
index 4400c347c4..73d30739e9 100644
--- a/sflphone-gtk/src/dbus.c
+++ b/sflphone-gtk/src/dbus.c
@@ -979,26 +979,26 @@ dbus_get_current_audio_devices_index()
 }
 
 /**
- * Get name, max input channels, max output channels and sample rate for a device
+ * Get index
  */
-gchar**
-dbus_get_audio_device_details(const int index)
+int
+dbus_get_audio_device_index(const gchar *name)
 {
-	g_print("Before get audio device details");
-	gchar** array;
+	g_print("Before get audio device index");
+	int index;
 	GError* error = NULL;
-	org_sflphone_SFLphone_ConfigurationManager_get_audio_device_details(
+	org_sflphone_SFLphone_ConfigurationManager_get_audio_device_index(
 			configurationManagerProxy,
-			index,
-			&array,
+			name,
+			&index,
 			&error);
 	g_print("After");
 	if(error)
 	{
-		g_printerr("Failed to call get_audio_device_details() on ConfigurationManager: %s\n", error->message);
+		g_printerr("Failed to call get_audio_device_index() on ConfigurationManager: %s\n", error->message);
 		g_error_free(error);
 	}
 	else
-		g_print("DBus called get_audio_device_details() on ConfigurationManager\n");
-	return array;
+		g_print("DBus called get_audio_device_index() on ConfigurationManager\n");
+	return index;
 }
diff --git a/sflphone-gtk/src/dbus.h b/sflphone-gtk/src/dbus.h
index 2282fe38a6..01d3f5d8b7 100644
--- a/sflphone-gtk/src/dbus.h
+++ b/sflphone-gtk/src/dbus.h
@@ -71,8 +71,7 @@ gchar** dbus_get_audio_input_device_list();
 void dbus_set_audio_input_device(const int index);
 // Output and input current devices
 gchar** dbus_get_current_audio_devices_index();
-// Name, Max Input Channels, Max Output Channels, Sample rate
-gchar** dbus_get_audio_device_details(const int index);
+int dbus_get_audio_device_index(const gchar* name);
 
 /* Instance */
 void dbus_register( int pid, gchar * name);
diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp
index 85ed055320..25d58ae160 100644
--- a/src/audio/audiolayer.cpp
+++ b/src/audio/audiolayer.cpp
@@ -503,6 +503,7 @@ AudioLayer::buildDeviceTopo( std::string plugin, int card, int subdevice )
 AudioLayer::getSoundCardsInfo( int flag )
 {
   std::vector<std::string> cards_id;
+  HwIDPair p;
 
   snd_ctl_t* handle;
   snd_ctl_card_info_t *info;
@@ -541,6 +542,9 @@ AudioLayer::getSoundCardsInfo( int flag )
 	  description.append(" - ");
 	  description.append(snd_pcm_info_get_name( pcminfo ));
 	  cards_id.push_back( description );
+	  // The number of the sound card is associated with a string description 
+	  p = HwIDPair( numCard , description );
+	  IDSoundCards.push_back( p );
 	}
       }
       snd_ctl_close( handle );
@@ -548,7 +552,6 @@ AudioLayer::getSoundCardsInfo( int flag )
     if ( snd_card_next( &numCard ) < 0 ) {
       break;
     }
-
   }
   return cards_id;
 }
@@ -564,7 +567,7 @@ AudioLayer::closeCaptureStream( void)
   }
 }
 
-void
+  void
 AudioLayer::closePlaybackStream( void)
 {
   if(_PlaybackHandle){
@@ -576,4 +579,31 @@ AudioLayer::closePlaybackStream( void)
 }
 
 
+  bool
+AudioLayer::soundCardIndexExist( int card )
+{
+  snd_ctl_t* handle;
+  std::string name = "hw:";
+  std::stringstream ss;
+  ss << card ;
+  name.append(ss.str());
+  if(snd_ctl_open( &handle, name.c_str(), 0) == 0 )
+    return true;
+  else
+    return false;
+}  
 
+  int
+AudioLayer::soundCardGetIndex( std::string description )
+{
+  int i;
+  for( i = 0 ; i < IDSoundCards.size() ; i++ )
+  {
+    HwIDPair p = IDSoundCards[i];
+    _debug("%i %s\n", p.first , p.second.c_str());
+    if( p.second == description )
+      return  p.first ;
+  }
+  // else return the default one
+  return 0;
+}
diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h
index 8359176a72..cfe8559d43 100644
--- a/src/audio/audiolayer.h
+++ b/src/audio/audiolayer.h
@@ -38,9 +38,12 @@
 #include <sstream>
 #define FRAME_PER_BUFFER	160
 
+
 class RingBuffer;
 class ManagerImpl;
 
+typedef std::pair<int , std::string> HwIDPair;
+
 class AudioLayer {
   public:
     AudioLayer(ManagerImpl* manager);
@@ -152,6 +155,8 @@ class AudioLayer {
      * @return std::vector<std::string> The vector containing the string description of the card
      */
     std::vector<std::string> getSoundCardsInfo( int flag );
+    bool soundCardIndexExist( int card );
+    int soundCardGetIndex( std::string description );
 
     void setErrorMessage(const std::string& error) { _errorMessage = error; }
     std::string getErrorMessage() { return _errorMessage; }
@@ -351,12 +356,11 @@ class AudioLayer {
      */
     bool _echoTesting;
 
+    std::vector<HwIDPair> IDSoundCards;
+
     std::string _errorMessage;
     ost::Mutex _mutex;
 
-    float *table_;
-    int tableSize_;
-    int leftPhase_;
 };
 
 #endif // _AUDIO_LAYER_H_
diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h
index f11da96a60..f4a08f647f 100644
--- a/src/dbus/configurationmanager-glue.h
+++ b/src/dbus/configurationmanager-glue.h
@@ -45,7 +45,7 @@ public:
         register_method(ConfigurationManager, getAudioInputDeviceList, _getAudioInputDeviceList_stub);
         register_method(ConfigurationManager, setAudioInputDevice, _setAudioInputDevice_stub);
         register_method(ConfigurationManager, getCurrentAudioDevicesIndex, _getCurrentAudioDevicesIndex_stub);
-        register_method(ConfigurationManager, getAudioDeviceDetails, _getAudioDeviceDetails_stub);
+        register_method(ConfigurationManager, getAudioDeviceIndex, _getAudioDeviceIndex_stub);
     }
 
     ::DBus::IntrospectedInterface* const introspect() const 
@@ -178,10 +178,10 @@ public:
             { "list", "as", false },
             { 0, 0, 0 }
         };
-        static ::DBus::IntrospectedArgument getAudioDeviceDetails_args[] = 
+        static ::DBus::IntrospectedArgument getAudioDeviceIndex_args[] = 
         {
-            { "index", "i", true },
-            { "details", "as", false },
+            { "name", "s", true },
+            { "index", "i", false },
             { 0, 0, 0 }
         };
         static ::DBus::IntrospectedArgument parametersChanged_args[] = 
@@ -220,7 +220,7 @@ public:
             { "getAudioInputDeviceList", getAudioInputDeviceList_args },
             { "setAudioInputDevice", setAudioInputDevice_args },
             { "getCurrentAudioDevicesIndex", getCurrentAudioDevicesIndex_args },
-            { "getAudioDeviceDetails", getAudioDeviceDetails_args },
+            { "getAudioDeviceIndex", getAudioDeviceIndex_args },
             { 0, 0 }
         };
         static ::DBus::IntrospectedMethod ConfigurationManager_signals[] = 
@@ -279,7 +279,7 @@ public:
     virtual std::vector< ::DBus::String > getAudioInputDeviceList(  ) = 0;
     virtual void setAudioInputDevice( const ::DBus::Int32& index ) = 0;
     virtual std::vector< ::DBus::String > getCurrentAudioDevicesIndex(  ) = 0;
-    virtual std::vector< ::DBus::String > getAudioDeviceDetails( const ::DBus::Int32& index ) = 0;
+    virtual ::DBus::Int32 getAudioDeviceIndex( const ::DBus::String& name ) = 0;
 
 public:
 
@@ -546,12 +546,12 @@ private:
         wi << argout1;
         return reply;
     }
-    ::DBus::Message _getAudioDeviceDetails_stub( const ::DBus::CallMessage& call )
+    ::DBus::Message _getAudioDeviceIndex_stub( const ::DBus::CallMessage& call )
     {
         ::DBus::MessageIter ri = call.reader();
 
-        ::DBus::Int32 argin1; ri >> argin1;
-        std::vector< ::DBus::String > argout1 = getAudioDeviceDetails(argin1);
+        ::DBus::String argin1; ri >> argin1;
+        ::DBus::Int32 argout1 = getAudioDeviceIndex(argin1);
         ::DBus::ReturnMessage reply(call);
         ::DBus::MessageIter wi = reply.writer();
         wi << argout1;
diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml
index 09a92e921c..5a4db59b1d 100644
--- a/src/dbus/configurationmanager-introspec.xml
+++ b/src/dbus/configurationmanager-introspec.xml
@@ -111,9 +111,9 @@
       <arg type="as" name="list" direction="out"/>
     </method>
 
-    <method name="getAudioDeviceDetails">
-      <arg type="i" name="index" direction="in"/>
-      <arg type="as" name="details" direction="out"/>
+    <method name="getAudioDeviceIndex">
+      <arg type="s" name="name" direction="in"/>
+      <arg type="i" name="index" direction="out"/>
     </method>
 
   <!--        /////////////////////////////       -->
diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp
index 0f80ed1d27..59ca709182 100644
--- a/src/dbus/configurationmanager.cpp
+++ b/src/dbus/configurationmanager.cpp
@@ -184,11 +184,11 @@ ConfigurationManager::getCurrentAudioDevicesIndex()
 	_debug("ConfigurationManager::getCurrentAudioDeviceIndex received\n");
 	return Manager::instance().getCurrentAudioDevicesIndex();
 }
-std::vector< ::DBus::String >
-ConfigurationManager::getAudioDeviceDetails(const ::DBus::Int32& index)
+ ::DBus::Int32
+ConfigurationManager::getAudioDeviceIndex(const ::DBus::String& name)
 {
-	_debug("ConfigurationManager::getAudioDeviceDetails received\n");
-	return Manager::instance().getAudioDeviceDetails(index);
+	_debug("ConfigurationManager::getAudioDeviceIndex received\n");
+	return Manager::instance().getAudioDeviceIndex(name);
 }
 
 
diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h
index 6c13b642ab..f9f43375fd 100644
--- a/src/dbus/configurationmanager.h
+++ b/src/dbus/configurationmanager.h
@@ -61,7 +61,7 @@ public:
     std::vector< ::DBus::String > getAudioInputDeviceList();
     void setAudioInputDevice(const ::DBus::Int32& index);
     std::vector< ::DBus::String > getCurrentAudioDevicesIndex();
-    std::vector< ::DBus::String > getAudioDeviceDetails(const ::DBus::Int32& index);
+    ::DBus::Int32 getAudioDeviceIndex(const ::DBus::String& name);
    
     std::vector< ::DBus::String > getToneLocaleList(  );
     std::vector< ::DBus::String > getPlaybackDeviceList(  );
diff --git a/src/global.h b/src/global.h
index b842274b01..5a0a31e349 100644
--- a/src/global.h
+++ b/src/global.h
@@ -71,6 +71,8 @@ typedef short int16;
 #define CHANNELS				2
 #define SIZEBUF 				1024*1024
 
+#define ALSA_DFT_HW_INDEX     0
+
 #define PCM_HW		"hw"
 #define PCM_PLUGHW	"plughw"
 #define PCM_FRONT	"plug:front"
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 04671e1798..6022946459 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -1351,14 +1351,14 @@ ManagerImpl::getCurrentAudioDevicesIndex()
   return v;
 }
 
-/**
- * Get name, max input channels, max output channels, sample rate of audio device
- */
-  std::vector<std::string>
-ManagerImpl::getAudioDeviceDetails(const int index)
+  int
+ManagerImpl::getAudioDeviceIndex(const std::string name)
 {
-  _debug("Get audio input device list\n");
-
+  _debug("Get audio device index\n");
+  int num = _audiodriver -> soundCardGetIndex( name );
+  _debug(" %s has number %i\n" , name.c_str() , num );
+  return num;
+  //return _audiodriver -> soundCardGetIndex( name );
 }
 
 
@@ -1396,16 +1396,20 @@ ManagerImpl::selectAudioDriver (void)
   }
   int frameSize = getConfigInt(AUDIO, DRIVER_FRAME_SIZE);
 
-  // this is when no audio device in/out are set
-  // or the audio device in/out are set to 0
-  // we take the nodevice instead
-  // remove this hack, how can we change the device to 0, if the noDevice is 1?
-  //if (noDeviceIn == 0 && noDeviceOut == 0) {
-  //  noDeviceIn = noDeviceOut = noDevice;
-  //}
+  if( !_audiodriver -> soundCardIndexExist( noDeviceIn ) )
+  {
+    _debug(" Index %i is not a valid card number. Switch to 0.\n", noDeviceIn);
+    noDeviceIn = ALSA_DFT_HW_INDEX ;
+  }
+  if( !_audiodriver -> soundCardIndexExist( noDeviceOut ) )
+  {  
+    _debug(" Index %i is not a valid card number. Switch to 0.\n", noDeviceIn);
+    noDeviceOut = ALSA_DFT_HW_INDEX ;
+  }
+
   _debugInit(" AudioLayer Opening Device");
   _audiodriver->setErrorMessage("");
-  _audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate, frameSize, SFL_PCM_BOTH, PCM_PLUGHW);
+  _audiodriver->openDevice( noDeviceIn , noDeviceOut, sampleRate, frameSize, SFL_PCM_BOTH, PCM_PLUGHW ); 
 }
 
 /**
diff --git a/src/managerimpl.h b/src/managerimpl.h
index 9f5068b304..b5c167481d 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -325,9 +325,9 @@ public:
   std::vector<std::string> getCurrentAudioDevicesIndex();
   
   /**
-   * Get name, max input channels, max output channels, sample rate of audio device
+   * Get index of an audio device
    */
-  std::vector<std::string> getAudioDeviceDetails(const int index);
+  int getAudioDeviceIndex( const std::string name );
   
   /**
    * Convert a list of payload in a special format, readable by the server.
-- 
GitLab