Updated libraries and applications to use the new Audio Device API

git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/aps-direct@2468 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjmedia/src/pjmedia-audiodev/audiodev.c b/pjmedia/src/pjmedia-audiodev/audiodev.c
index e2f209d..33e333c 100644
--- a/pjmedia/src/pjmedia-audiodev/audiodev.c
+++ b/pjmedia/src/pjmedia-audiodev/audiodev.c
@@ -19,15 +19,41 @@
  */
 #include <pjmedia-audiodev/audiodev_imp.h>
 #include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/string.h>
+
+#define THIS_FILE   "audiodev.c"
+
+/* Capability names */
+static struct cap_info
+{
+    const char *name;
+    const char *info;
+} cap_infos[] = 
+{
+    {"ext-fmt",	    "Extended/non-PCM format"},
+    {"latency-in",  "Input latency/buffer size setting"},
+    {"latency-out", "Output latency/buffer size setting"},
+    {"vol-in",	    "Input volume setting"},
+    {"vol-out",	    "Output volume setting"},
+    {"meter-in",    "Input meter"},
+    {"meter-out",   "Output meter"},
+    {"route-in",    "Input routing"},
+    {"route-out",   "Output routing"},
+    {"aec",	    "Accoustic echo cancellation"},
+    {"aec-tail",    "Tail length setting for AEC"},
+    {"vad",	    "Voice activity detection"},
+    {"cng",	    "Comfort noise generation"},
+    {"plg",	    "Packet loss concealment"}
+};
+
 
 /*
- * The Device ID seen by application and driver is different. 
+ * The device index seen by application and driver is different. 
  *
- * At application level, device ID is a 32bit value. The high 16bit contains
- * the factory ID, and the low 16bit contains the device index in the 
- * specified factory. The device ID may also be -1 to denote default device.
- *
- * At driver level, device ID is a 16bit unsigned integer index.
+ * At application level, device index is index to global list of device.
+ * At driver level, device index is index to device list on that particular
+ * factory only.
  */
 #define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
 #define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
@@ -40,20 +66,32 @@
 pjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf);
 
 #define MAX_DRIVERS	16
+#define MAX_DEVS	64
+
+/* typedef for factory creation function */
+typedef pjmedia_aud_dev_factory*  (*create_func_ptr)(pj_pool_factory*);
+
+/* driver structure */
+struct driver
+{
+    create_func_ptr	     create;	/* Creation function.		    */
+    pjmedia_aud_dev_factory *f;		/* Factory instance.		    */
+    char		     name[32];	/* Driver name			    */
+    unsigned		     dev_cnt;	/* Number of devices		    */
+    unsigned		     start_idx;	/* Start index in global list	    */
+};
 
 /* The audio subsystem */
 static struct aud_subsys
 {
-    unsigned	     init_count;
-    pj_pool_factory *pf;
-    unsigned	     factory_cnt;
+    unsigned	     init_count;	/* How many times init() is called  */
+    pj_pool_factory *pf;		/* The pool factory.		    */
 
-    struct factory
-    {
-	pjmedia_aud_dev_factory*   (*create)(pj_pool_factory*);
-	pjmedia_aud_dev_factory	    *f;
+    unsigned	     drv_cnt;		/* Number of drivers.		    */
+    struct driver    drv[MAX_DRIVERS];	/* Array of drivers.		    */
 
-    } factories[MAX_DRIVERS];
+    unsigned	     dev_cnt;		/* Total number of devices.	    */
+    pj_uint32_t	     dev_list[MAX_DEVS];/* Array of device IDs.		    */
 
 } aud_subsys;
 
@@ -73,29 +111,67 @@
     }
 
     aud_subsys.pf = pf;
-    aud_subsys.factory_cnt = 0;
+    aud_subsys.drv_cnt = 0;
+    aud_subsys.dev_cnt = 0;
 
-    aud_subsys.factories[aud_subsys.factory_cnt++].create = &pjmedia_pa_factory;
-    aud_subsys.factories[aud_subsys.factory_cnt++].create = &pjmedia_wmme_factory;
+    /* Register creation functions */
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_pa_factory;
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_wmme_factory;
 
-    for (i=0; i<aud_subsys.factory_cnt; ++i) {
+    /* Initialize each factory and build the device ID list */
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
 	pjmedia_aud_dev_factory *f;
+	pjmedia_aud_dev_info info;
+	unsigned j, dev_cnt;
 
-	f = (*aud_subsys.factories[i].create)(pf);
+	/* Create the factory */
+	f = (*aud_subsys.drv[i].create)(pf);
 	if (!f)
 	    continue;
 
+	/* Call factory->init() */
 	status = f->op->init(f);
 	if (status != PJ_SUCCESS) {
 	    f->op->destroy(f);
 	    continue;
 	}
 
-	aud_subsys.factories[i].f = f;
-	aud_subsys.factories[i].f->internal.id = i;
+	/* Build device list */
+	dev_cnt = f->op->get_dev_count(f);
+	if (dev_cnt == 0) {
+	    f->op->destroy(f);
+	    continue;
+	}
+
+	/* Get one device info */
+	status = f->op->get_dev_info(f, 0, &info);
+	if (status != PJ_SUCCESS) {
+	    f->op->destroy(f);
+	    continue;
+	}
+
+	/* Register the factory */
+	aud_subsys.drv[i].f = f;
+	aud_subsys.drv[i].f->internal.id = i;
+	aud_subsys.drv[i].start_idx = aud_subsys.dev_cnt;
+	pj_ansi_strncpy(aud_subsys.drv[i].name, info.driver,
+			sizeof(aud_subsys.drv[i].name));
+	aud_subsys.drv[i].name[sizeof(aud_subsys.drv[i].name)-1] = '\0';
+
+	/* Register devices */
+	if (aud_subsys.dev_cnt + dev_cnt > MAX_DEVS) {
+	    PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
+				  " there are too many sound devices",
+				  aud_subsys.dev_cnt + dev_cnt - MAX_DEVS));
+	    dev_cnt = MAX_DEVS - aud_subsys.dev_cnt;
+	}
+	for (j=0; j<dev_cnt; ++j) {
+	    aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(i, j);
+	}
+
     }
 
-    return aud_subsys.factory_cnt ? PJ_SUCCESS : status;
+    return aud_subsys.drv_cnt ? PJ_SUCCESS : status;
 }
 
 /* API: get the pool factory registered to the audio subsystem. */
@@ -117,167 +193,239 @@
     }
     --aud_subsys.init_count;
 
-    for (i=0; i<aud_subsys.factory_cnt; ++i) {
-	pjmedia_aud_dev_factory *f = aud_subsys.factories[i].f;
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	pjmedia_aud_dev_factory *f = aud_subsys.drv[i].f;
 
 	if (!f)
 	    continue;
 
 	f->op->destroy(f);
-	aud_subsys.factories[i].f = NULL;
+	aud_subsys.drv[i].f = NULL;
     }
 
     return PJ_SUCCESS;
 }
 
+/* API: get capability name/info */
+PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+					     const char **p_desc)
+{
+    char *desc;
+    unsigned i;
+
+    if (p_desc==NULL) p_desc = &desc;
+
+    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
+	if ((1 << i)==cap)
+	    break;
+    }
+
+    if (i==32) {
+	*p_desc = "??";
+	return "??";
+    }
+
+    *p_desc = cap_infos[i].info;
+    return cap_infos[i].name;
+}
+
 /* API: Get the number of sound devices installed in the system. */
 PJ_DEF(unsigned) pjmedia_aud_dev_count(void)
 {
-    unsigned i, count = 0;
-
-    for (i=0; i<aud_subsys.factory_cnt; ++i) {
-	pjmedia_aud_dev_factory *f = aud_subsys.factories[i].f;
-
-	if (!f)
-	    continue;
-
-	count += f->op->get_dev_count(f);
-    }
-
-    return count;
+    return aud_subsys.dev_cnt;
 }
 
-/* API: Enumerate device ID's. */
-PJ_DEF(unsigned) pjmedia_aud_dev_enum(unsigned max_count,
-				      pjmedia_aud_dev_id ids[])
+/* Internal: lookup device id */
+static pj_status_t lookup_dev(pjmedia_aud_dev_index id,
+			      pjmedia_aud_dev_factory **p_f,
+			      unsigned *p_local_index)
 {
-    unsigned i, count = 0;
+    int f_id, index;
 
-    for (i=0; i<aud_subsys.factory_cnt && count < max_count; ++i) {
-	pjmedia_aud_dev_factory *f = aud_subsys.factories[i].f;
-	unsigned j, fcount;
+    if (id == PJMEDIA_AUD_DEV_DEFAULT)
+	id = DEFAULT_DEV_ID;
 
-	if (!f)
-	    continue;
+    PJ_ASSERT_RETURN(id>=0 && id<(int)aud_subsys.dev_cnt, 
+		     PJMEDIA_EAUD_INVDEV);
 
-	fcount = f->op->get_dev_count(f);
-	for (j=0; j<fcount && count<max_count; ++j) {
-	    ids[count++] = MAKE_DEV_ID(i, j);
-	}
-    }
+    f_id = GET_FID(aud_subsys.dev_list[id]);
+    index = GET_INDEX(aud_subsys.dev_list[id]);
 
-    return count;
+    if (f_id < 0 || f_id >= (int)aud_subsys.drv_cnt)
+	return PJMEDIA_EAUD_INVDEV;
+
+    if (index < 0 || index >= (int)aud_subsys.drv[f_id].dev_cnt)
+	return PJMEDIA_EAUD_INVDEV;
+
+    *p_f = aud_subsys.drv[f_id].f;
+    *p_local_index = (unsigned)index;
+
+    return PJ_SUCCESS;
+
 }
 
+/* Internal: convert local index to global device index */
+static pj_status_t make_global_index(pjmedia_aud_dev_factory *f,
+				     pjmedia_aud_dev_index *id)
+{
+    unsigned f_id = f->internal.id;
+
+    if (*id == PJMEDIA_AUD_DEV_DEFAULT)
+	return PJ_SUCCESS;
+
+    /* Check that factory still exists */
+    PJ_ASSERT_RETURN(f, PJ_EBUG);
+
+    /* Check that device index is valid */
+    PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[f_id].dev_cnt, PJ_EBUG);
+
+    *id += aud_subsys.drv[f_id].start_idx;
+    return PJ_SUCCESS;
+}
 
 /* API: Get device information. */
-PJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_id id,
+PJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
 					     pjmedia_aud_dev_info *info)
 {
     pjmedia_aud_dev_factory *f;
-    int f_id, index;
+    unsigned index;
+    pj_status_t status;
 
-    if (id == PJMEDIA_AUD_DEV_DEFAULT_ID)
-	id = DEFAULT_DEV_ID;
+    PJ_ASSERT_RETURN(info, PJ_EINVAL);
 
-    f_id = GET_FID(id);
-    index = GET_INDEX(id);
-
-    if (f_id < 0 || f_id >= (int)aud_subsys.factory_cnt)
-	return PJMEDIA_EAUD_INVDEV;
-
-    f = aud_subsys.factories[f_id].f;
-    if (f == NULL)
-	return PJMEDIA_EAUD_INVDEV;
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
 
     return f->op->get_dev_info(f, index, info);
 }
 
+/* API: find device */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name,
+					    const char *dev_name,
+					    pjmedia_aud_dev_index *id)
+{
+    pjmedia_aud_dev_factory *f = NULL;
+    unsigned i, j;
+
+    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
+
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[i].name)) {
+	    f = aud_subsys.drv[i].f;
+	    break;
+	}
+    }
+
+    if (!f)
+	return PJ_ENOTFOUND;
+
+    for (j=0; j<aud_subsys.drv[i].dev_cnt; ++j) {
+	pjmedia_aud_dev_info info;
+	pj_status_t status;
+
+	status = f->op->get_dev_info(f, j, &info);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	if (!pj_ansi_stricmp(dev_name, info.name))
+	    break;
+    }
+
+    if (j==aud_subsys.drv[i].dev_cnt)
+	return PJ_ENOTFOUND;
+
+    *id = j;
+    make_global_index(f, id);
+
+    return PJ_SUCCESS;
+}
+
 /* API: Initialize the audio device parameters with default values for the
  * specified device.
  */
-PJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_id id,
-						  pjmedia_aud_dev_param *param)
+PJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
+						  pjmedia_aud_param *param)
 {
     pjmedia_aud_dev_factory *f;
-    int f_id, index;
+    unsigned index;
     pj_status_t status;
 
-    if (id == PJMEDIA_AUD_DEV_DEFAULT_ID)
-	id = DEFAULT_DEV_ID;
+    PJ_ASSERT_RETURN(param, PJ_EINVAL);
 
-    f_id = GET_FID(id);
-    index = GET_INDEX(id);
-
-    if (f_id < 0 || f_id >= (int)aud_subsys.factory_cnt)
-	return PJMEDIA_EAUD_INVDEV;
-
-    f = aud_subsys.factories[f_id].f;
-    if (f == NULL)
-	return PJMEDIA_EAUD_INVDEV;
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
 
     status = f->op->default_param(f, index, param);
     if (status != PJ_SUCCESS)
 	return status;
 
     /* Normalize device IDs */
-    if (param->rec_id != PJMEDIA_AUD_DEV_DEFAULT_ID)
-	param->rec_id = MAKE_DEV_ID(f_id, param->rec_id);
-    if (param->play_id != PJMEDIA_AUD_DEV_DEFAULT_ID)
-	param->play_id = MAKE_DEV_ID(f_id, param->play_id);
+    make_global_index(f, &param->rec_id);
+    make_global_index(f, &param->play_id);
 
     return PJ_SUCCESS;
 }
 
 /* API: Open audio stream object using the specified parameters. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_dev_param *p,
+PJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *prm,
 					      pjmedia_aud_rec_cb rec_cb,
 					      pjmedia_aud_play_cb play_cb,
 					      void *user_data,
 					      pjmedia_aud_stream **p_aud_strm)
 {
-    pjmedia_aud_dev_factory *f;
-    pjmedia_aud_dev_param param;
-    int f_id;
+    pjmedia_aud_dev_factory *rec_f=NULL, *play_f=NULL, *f=NULL;
+    pjmedia_aud_param param;
     pj_status_t status;
 
+    PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL);
+
     /* Must make copy of param because we're changing device ID */
-    pj_memcpy(&param, p, sizeof(param));
+    pj_memcpy(&param, prm, sizeof(param));
 
-    /* Set default device */
-    if (param.rec_id == PJMEDIA_AUD_DEV_DEFAULT_ID) 
-	param.rec_id = DEFAULT_DEV_ID;
-    if (param.play_id == PJMEDIA_AUD_DEV_DEFAULT_ID) 
-	param.play_id = DEFAULT_DEV_ID;
+    /* Normalize rec_id */
+    if (param.dir & PJMEDIA_DIR_CAPTURE) {
+	unsigned index;
+
+	status = lookup_dev(param.rec_id, &rec_f, &index);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	param.rec_id = index;
+	f = rec_f;
+    }
+
+    /* Normalize play_id */
+    if (param.dir & PJMEDIA_DIR_PLAYBACK) {
+	unsigned index;
+
+	status = lookup_dev(param.play_id, &play_f, &index);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	param.play_id = index;
+	f = play_f;
+
+	/* For now, rec_id and play_id must belong to the same factory */
+	PJ_ASSERT_RETURN(rec_f == play_f, PJ_EINVAL);
+    }
+
     
-    if (param.dir & PJMEDIA_DIR_CAPTURE)
-	f_id = GET_FID(param.rec_id);
-    else
-	f_id = GET_FID(param.play_id);
-
-    if (f_id < 0 || f_id >= (int)aud_subsys.factory_cnt)
-	return PJMEDIA_EAUD_INVDEV;
-    
-    /* Normalize device id's */
-    param.rec_id = GET_INDEX(param.rec_id);
-    param.play_id = GET_INDEX(param.play_id);
-
-    f = aud_subsys.factories[f_id].f;
-    if (f == NULL)
-	return PJMEDIA_EAUD_INVDEV;
-
+    /* Create the stream */
     status = f->op->create_stream(f, &param, rec_cb, play_cb,
 				  user_data, p_aud_strm);
     if (status != PJ_SUCCESS)
 	return status;
 
-    (*p_aud_strm)->factory = f;
+    /* Assign factory id to the stream */
+    (*p_aud_strm)->factory_id = f->internal.id;
     return PJ_SUCCESS;
 }
 
 /* API: Get the running parameters for the specified audio stream. */
 PJ_DEF(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
-						 pjmedia_aud_dev_param *param)
+						 pjmedia_aud_param *param)
 {
     pj_status_t status;
 
@@ -286,10 +434,8 @@
 	return status;
 
     /* Normalize device id's */
-    if (param->rec_id != PJMEDIA_AUD_DEV_DEFAULT_ID)
-	param->rec_id = MAKE_DEV_ID(strm->factory->internal.id, param->rec_id);
-    if (param->play_id != PJMEDIA_AUD_DEV_DEFAULT_ID)
-	param->play_id = MAKE_DEV_ID(strm->factory->internal.id, param->play_id);
+    make_global_index(aud_subsys.drv[strm->factory_id].f, &param->rec_id);
+    make_global_index(aud_subsys.drv[strm->factory_id].f, &param->play_id);
 
     return PJ_SUCCESS;
 }
diff --git a/pjmedia/src/pjmedia-audiodev/audiotest.c b/pjmedia/src/pjmedia-audiodev/audiotest.c
index 563e1e8..120f710 100644
--- a/pjmedia/src/pjmedia-audiodev/audiotest.c
+++ b/pjmedia/src/pjmedia-audiodev/audiotest.c
@@ -51,7 +51,7 @@
 struct test_data 
 {
     pj_pool_t			   *pool;
-    const pjmedia_aud_dev_param    *param;
+    const pjmedia_aud_param    *param;
     pjmedia_aud_test_results	   *result;
     pj_bool_t			    running;
     pj_bool_t			    has_error;
@@ -181,7 +181,7 @@
 }
 
 
-PJ_DEF(pj_status_t) pjmedia_aud_test( const pjmedia_aud_dev_param *param,
+PJ_DEF(pj_status_t) pjmedia_aud_test( const pjmedia_aud_param *param,
 				      pjmedia_aud_test_results *result)
 {
     pj_status_t status = PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia-audiodev/pa_dev.c b/pjmedia/src/pjmedia-audiodev/pa_dev.c
index 0a0e7a2..4750877 100644
--- a/pjmedia/src/pjmedia-audiodev/pa_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/pa_dev.c
@@ -105,9 +105,9 @@
 				    pjmedia_aud_dev_info *info);
 static pj_status_t  pa_default_param(pjmedia_aud_dev_factory *f,
 				     unsigned index,
-				     pjmedia_aud_dev_param *param);
+				     pjmedia_aud_param *param);
 static pj_status_t  pa_create_stream(pjmedia_aud_dev_factory *f,
-				     const pjmedia_aud_dev_param *param,
+				     const pjmedia_aud_param *param,
 				     pjmedia_aud_rec_cb rec_cb,
 				     pjmedia_aud_play_cb play_cb,
 				     void *user_data,
@@ -115,7 +115,7 @@
 
 /* Stream prototypes */
 static pj_status_t strm_get_param(pjmedia_aud_stream *strm,
-				  pjmedia_aud_dev_param *param);
+				  pjmedia_aud_param *param);
 static pj_status_t strm_get_cap(pjmedia_aud_stream *strm,
 	 		        pjmedia_aud_dev_cap cap,
 			        void *value);
@@ -514,7 +514,7 @@
 /* API: fill in with default parameter. */
 static pj_status_t  pa_default_param(pjmedia_aud_dev_factory *f,
 				     unsigned index,
-				     pjmedia_aud_dev_param *param)
+				     pjmedia_aud_param *param)
 {
     pjmedia_aud_dev_info adi;
     pj_status_t status;
@@ -533,11 +533,11 @@
     } else if (adi.input_count) {
 	param->dir = PJMEDIA_DIR_CAPTURE;
 	param->rec_id = index;
-	param->play_id = PJMEDIA_AUD_DEV_DEFAULT_ID;
+	param->play_id = PJMEDIA_AUD_DEV_DEFAULT;
     } else if (adi.output_count) {
 	param->dir = PJMEDIA_DIR_PLAYBACK;
 	param->play_id = index;
-	param->rec_id = PJMEDIA_AUD_DEV_DEFAULT_ID;
+	param->rec_id = PJMEDIA_AUD_DEV_DEFAULT;
     } else {
 	return PJMEDIA_EAUD_INVDEV;
     }
@@ -669,13 +669,13 @@
 
 /* Internal: create capture/recorder stream */
 static pj_status_t create_rec_stream( struct pa_aud_factory *pa,
-				      const pjmedia_aud_dev_param *param,
+				      const pjmedia_aud_param *param,
 				      pjmedia_aud_rec_cb rec_cb,
 				      void *user_data,
 				      pjmedia_aud_stream **p_snd_strm)
 {
     pj_pool_t *pool;
-    pjmedia_aud_dev_id rec_id;
+    pjmedia_aud_dev_index rec_id;
     struct pa_aud_stream *stream;
     PaStreamParameters inputParam;
     int sampleFormat;
@@ -774,13 +774,13 @@
 
 /* Internal: create playback stream */
 static pj_status_t create_play_stream(struct pa_aud_factory *pa,
-				      const pjmedia_aud_dev_param *param,
+				      const pjmedia_aud_param *param,
 				      pjmedia_aud_play_cb play_cb,
 				      void *user_data,
 				      pjmedia_aud_stream **p_snd_strm)
 {
     pj_pool_t *pool;
-    pjmedia_aud_dev_id play_id;
+    pjmedia_aud_dev_index play_id;
     struct pa_aud_stream *stream;
     PaStreamParameters outputParam;
     int sampleFormat;
@@ -881,14 +881,14 @@
 
 /* Internal: Create both player and recorder stream */
 static pj_status_t create_bidir_stream(struct pa_aud_factory *pa,
-				       const pjmedia_aud_dev_param *param,
+				       const pjmedia_aud_param *param,
 				       pjmedia_aud_rec_cb rec_cb,
 				       pjmedia_aud_play_cb play_cb,
 				       void *user_data,
 				       pjmedia_aud_stream **p_snd_strm)
 {
     pj_pool_t *pool;
-    pjmedia_aud_dev_id rec_id, play_id;
+    pjmedia_aud_dev_index rec_id, play_id;
     struct pa_aud_stream *stream;
     PaStream *paStream = NULL;
     PaStreamParameters inputParam;
@@ -1060,7 +1060,7 @@
 
 /* API: create stream */
 static pj_status_t  pa_create_stream(pjmedia_aud_dev_factory *f,
-				     const pjmedia_aud_dev_param *param,
+				     const pjmedia_aud_param *param,
 				     pjmedia_aud_rec_cb rec_cb,
 				     pjmedia_aud_play_cb play_cb,
 				     void *user_data,
@@ -1091,7 +1091,7 @@
 
 /* API: Get stream parameters */
 static pj_status_t strm_get_param(pjmedia_aud_stream *s,
-				  pjmedia_aud_dev_param *pi)
+				  pjmedia_aud_param *pi)
 {
     struct pa_aud_stream *strm = (struct pa_aud_stream*)s;
     const PaStreamInfo *paPlaySI = NULL, *paRecSI = NULL;
diff --git a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
index 4c38cc4..d931275 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
@@ -71,7 +71,7 @@
     pj_pool_t		*pool;			/**< Memory pool.       */
 
     // Common settings.
-    pjmedia_aud_dev_param param;		/**< Stream param.	*/
+    pjmedia_aud_param param;		/**< Stream param.	*/
     pjmedia_aud_rec_cb   rec_cb;		/**< Record callback.  	*/
     pjmedia_aud_play_cb	 play_cb;		/**< Playback callback. */
     void                *user_data;		/**< Application data.  */
@@ -100,16 +100,16 @@
 					pjmedia_aud_dev_info *info);
 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
 					 unsigned index,
-					 pjmedia_aud_dev_param *param);
+					 pjmedia_aud_param *param);
 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
-					 const pjmedia_aud_dev_param *param,
+					 const pjmedia_aud_param *param,
 					 pjmedia_aud_rec_cb rec_cb,
 					 pjmedia_aud_play_cb play_cb,
 					 void *user_data,
 					 pjmedia_aud_stream **p_aud_strm);
 
 static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
-				    pjmedia_aud_dev_param *param);
+				    pjmedia_aud_param *param);
 static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
 				  pjmedia_aud_dev_cap cap,
 				  void *value);
@@ -1175,7 +1175,7 @@
 /* API: create default device parameter */
 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
 					 unsigned index,
-					 pjmedia_aud_dev_param *param)
+					 pjmedia_aud_param *param)
 {
     struct aps_factory *af = (struct aps_factory*)f;
 
@@ -1199,7 +1199,7 @@
 
 /* API: create stream */
 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
-					 const pjmedia_aud_dev_param *param,
+					 const pjmedia_aud_param *param,
 					 pjmedia_aud_rec_cb rec_cb,
 					 pjmedia_aud_play_cb play_cb,
 					 void *user_data,
@@ -1332,7 +1332,7 @@
 
 /* API: Get stream info. */
 static pj_status_t stream_get_param(pjmedia_aud_stream *s,
-				    pjmedia_aud_dev_param *pi)
+				    pjmedia_aud_param *pi)
 {
     struct aps_stream *strm = (struct aps_stream*)s;
 
diff --git a/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
index e97807d..02fba93 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
@@ -72,7 +72,7 @@
     pj_pool_t		*pool;			/**< Memory pool.       */
 
     // Common settings.
-    pjmedia_aud_dev_param param;		/**< Stream param.	*/
+    pjmedia_aud_param param;		/**< Stream param.	*/
 
     // Audio engine
     CPjAudioInputEngine	*in_engine;		/**< Record engine.	*/
@@ -89,16 +89,16 @@
 					pjmedia_aud_dev_info *info);
 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
 					 unsigned index,
-					 pjmedia_aud_dev_param *param);
+					 pjmedia_aud_param *param);
 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
-					 const pjmedia_aud_dev_param *param,
+					 const pjmedia_aud_param *param,
 					 pjmedia_aud_rec_cb rec_cb,
 					 pjmedia_aud_play_cb play_cb,
 					 void *user_data,
 					 pjmedia_aud_stream **p_aud_strm);
 
 static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
-				    pjmedia_aud_dev_param *param);
+				    pjmedia_aud_param *param);
 static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
 				  pjmedia_aud_dev_cap cap,
 				  void *value);
@@ -844,7 +844,7 @@
 /* API: create default device parameter */
 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
 					 unsigned index,
-					 pjmedia_aud_dev_param *param)
+					 pjmedia_aud_param *param)
 {
     struct mda_factory *af = (struct mda_factory*)f;
 
@@ -866,7 +866,7 @@
 
 /* API: create stream */
 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
-					 const pjmedia_aud_dev_param *param,
+					 const pjmedia_aud_param *param,
 					 pjmedia_aud_rec_cb rec_cb,
 					 pjmedia_aud_play_cb play_cb,
 					 void *user_data,
@@ -921,7 +921,7 @@
 
 /* API: Get stream info. */
 static pj_status_t stream_get_param(pjmedia_aud_stream *s,
-				    pjmedia_aud_dev_param *pi)
+				    pjmedia_aud_param *pi)
 {
     struct mda_stream *strm = (struct mda_stream*)s;
 
diff --git a/pjmedia/src/pjmedia-audiodev/wmme_dev.c b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
index 5a80101..1458d30 100644
--- a/pjmedia/src/pjmedia-audiodev/wmme_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
@@ -120,16 +120,16 @@
 					pjmedia_aud_dev_info *info);
 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
 					 unsigned index,
-					 pjmedia_aud_dev_param *param);
+					 pjmedia_aud_param *param);
 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
-					 const pjmedia_aud_dev_param *param,
+					 const pjmedia_aud_param *param,
 					 pjmedia_aud_rec_cb rec_cb,
 					 pjmedia_aud_play_cb play_cb,
 					 void *user_data,
 					 pjmedia_aud_stream **p_aud_strm);
 
 static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
-				    pjmedia_aud_dev_param *param);
+				    pjmedia_aud_param *param);
 static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
 				  pjmedia_aud_dev_cap cap,
 				  void *value);
@@ -398,7 +398,7 @@
 /* API: create default device parameter */
 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
 					 unsigned index,
-					 pjmedia_aud_dev_param *param)
+					 pjmedia_aud_param *param)
 {
     struct wmme_factory *wf = (struct wmme_factory*)f;
     struct wmme_dev_info *di = &wf->dev_info[index];
@@ -413,11 +413,11 @@
     } else if (di->info.input_count) {
 	param->dir = PJMEDIA_DIR_CAPTURE;
 	param->rec_id = index;
-	param->play_id = PJMEDIA_AUD_DEV_DEFAULT_ID;
+	param->play_id = PJMEDIA_AUD_DEV_DEFAULT;
     } else if (di->info.output_count) {
 	param->dir = PJMEDIA_DIR_PLAYBACK;
 	param->play_id = index;
-	param->rec_id = PJMEDIA_AUD_DEV_DEFAULT_ID;
+	param->rec_id = PJMEDIA_AUD_DEV_DEFAULT;
     } else {
 	return PJMEDIA_EAUD_INVDEV;
     }
@@ -815,7 +815,7 @@
 
 /* API: create stream */
 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
-					 const pjmedia_aud_dev_param *param,
+					 const pjmedia_aud_param *param,
 					 pjmedia_aud_rec_cb rec_cb,
 					 pjmedia_aud_play_cb play_cb,
 					 void *user_data,
@@ -929,7 +929,7 @@
 
 /* API: Get stream info. */
 static pj_status_t stream_get_param(pjmedia_aud_stream *s,
-				    pjmedia_aud_dev_param *pi)
+				    pjmedia_aud_param *pi)
 {
     struct wmme_stream *strm = (struct wmme_stream*)s;