Index: pjproject/trunk/pjmedia/src/pjmedia-audiodev/alsa_dev.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-audiodev/alsa_dev.c	(revision 3079)
+++ pjproject/trunk/pjmedia/src/pjmedia-audiodev/alsa_dev.c	(revision 3438)
@@ -58,4 +58,5 @@
 static pj_status_t alsa_factory_init(pjmedia_aud_dev_factory *f);
 static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f);
 static unsigned    alsa_factory_get_dev_count(pjmedia_aud_dev_factory *f);
 static pj_status_t alsa_factory_get_dev_info(pjmedia_aud_dev_factory *f,
@@ -93,4 +94,5 @@
     pj_pool_factory		*pf;
     pj_pool_t			*pool;
+    pj_pool_t			*base_pool;
 
     unsigned			 dev_cnt;
@@ -134,5 +136,6 @@
     &alsa_factory_get_dev_info,
     &alsa_factory_default_param,
-    &alsa_factory_create_stream
+    &alsa_factory_create_stream,
+    &alsa_factory_refresh
 };
 
@@ -146,4 +149,18 @@
     &alsa_stream_destroy
 };
+
+static void null_alsa_error_handler (const char *file,
+				int line,
+				const char *function,
+				int err,
+				const char *fmt,
+				...)
+{
+    PJ_UNUSED_ARG(file);
+    PJ_UNUSED_ARG(line);
+    PJ_UNUSED_ARG(function);
+    PJ_UNUSED_ARG(err);
+    PJ_UNUSED_ARG(fmt);
+}
 
 static void alsa_error_handler (const char *file,
@@ -175,8 +192,7 @@
 
 
-static pj_status_t add_dev (struct alsa_factory *af, int card, int device)
+static pj_status_t add_dev (struct alsa_factory *af, const char *dev_name)
 {
     pjmedia_aud_dev_info *adi;
-    char dev_name[32];
     snd_pcm_t* pcm;
     int pb_result, ca_result;
@@ -187,6 +203,5 @@
     adi = &af->devs[af->dev_cnt];
 
-    TRACE_((THIS_FILE, "add_dev (%d, %d): Enter", card, device));
-    sprintf (dev_name, ALSA_DEVICE_NAME, card, device);
+    TRACE_((THIS_FILE, "add_dev (%s): Enter", dev_name));
 
     /* Try to open the device in playback mode */
@@ -246,8 +261,8 @@
     pj_pool_t *pool;
 
-    pool = pj_pool_create(pf, "alsa_aud", 256, 256, NULL);
+    pool = pj_pool_create(pf, "alsa_aud_base", 256, 256, NULL);
     af = PJ_POOL_ZALLOC_T(pool, struct alsa_factory);
     af->pf = pf;
-    af->pool = pool;
+    af->base_pool = pool;
     af->base.op = &alsa_factory_op;
 
@@ -259,13 +274,67 @@
 static pj_status_t alsa_factory_init(pjmedia_aud_dev_factory *f)
 {
+    pj_status_t status = alsa_factory_refresh(f);
+    if (PJ_SUCCESS != status)
+	return status;
+
+    PJ_LOG(4,(THIS_FILE, "ALSA initialized"));
+    return PJ_SUCCESS;
+}
+
+
+/* API: destroy factory */
+static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f)
+{
     struct alsa_factory *af = (struct alsa_factory*)f;
-    int card, device;
+
+    if (af->pool)
+	pj_pool_release(af->pool);
+
+    if (af->base_pool) {
+	pj_pool_t *pool = af->base_pool;
+	af->base_pool = NULL;
+	pj_pool_release(pool);
+    }
+
+    /* Restore handler */
+    snd_lib_error_set_handler(NULL);
+
+    return PJ_SUCCESS;
+}
+
+
+/* API: refresh the device list */
+static pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f)
+{
+    struct alsa_factory *af = (struct alsa_factory*)f;
+    char **hints, **n;
+    int err;
 
     TRACE_((THIS_FILE, "pjmedia_snd_init: Enumerate sound devices"));
+
+    if (af->pool != NULL) {
+	pj_pool_release(af->pool);
+	af->pool = NULL;
+    }
+
+    af->pool = pj_pool_create(af->pf, "alsa_aud", 256, 256, NULL);
+    af->dev_cnt = 0;
+
     /* Enumerate sound devices */
-    for (card=0; card<MAX_SOUND_CARDS; card++) {
-	for (device=0; device<MAX_SOUND_DEVICES_PER_CARD; device++) {
-	    add_dev(af, card, device);
+    err = snd_device_name_hint(-1, "pcm", (void***)&hints);
+    if (err != 0)
+	return PJMEDIA_EAUD_SYSERR;
+
+    /* Set a null error handler prior to enumeration to suppress errors */
+    snd_lib_error_set_handler(null_alsa_error_handler);
+
+    n = hints;
+    while (*n != NULL) {
+	char *name = snd_device_name_get_hint(*n, "NAME");
+	if (name != NULL && 0 != strcmp("null", name)) {
+	    add_dev(af, name);
+	    free(name);
 	}
+	n++;
     }
 
@@ -273,24 +342,9 @@
      * error messages about invalid card/device ID.
      */
-    snd_lib_error_set_handler (alsa_error_handler);
+    snd_lib_error_set_handler(alsa_error_handler);
+
+    err = snd_device_name_free_hint((void**)hints);
 
     PJ_LOG(4,(THIS_FILE, "ALSA driver found %d devices", af->dev_cnt));
-    return PJ_SUCCESS;
-}
-
-
-/* API: destroy factory */
-static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f)
-{
-    struct alsa_factory *af = (struct alsa_factory*)f;
-
-    if (af->pool) {
-	pj_pool_t *pool = af->pool;
-	af->pool = NULL;
-	pj_pool_release(pool);
-    }
-
-    /* Restore handler */
-    snd_lib_error_set_handler(NULL);
 
     return PJ_SUCCESS;
