--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1543,6 +1543,8 @@ PJ_DECL(pjmedia_endpt*) pjsua_get_pjmedi
 PJ_DECL(pj_pool_factory*) pjsua_get_pool_factory(void);
 
 
+PJ_DECL(pj_status_t) pjsua_add_snd_port(int id, pjsua_conf_port_id *p_id);
+
 
 /*****************************************************************************
  * Utilities.
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -261,6 +261,8 @@ typedef struct pjsua_stun_resolve
 } pjsua_stun_resolve;
 
 
+#define MAX_PORT	2
+
 /**
  * Global pjsua application data.
  */
@@ -336,7 +338,7 @@ struct pjsua_data
     pj_bool_t		 aud_open_cnt;/**< How many # device is opened	*/
     pj_bool_t		 no_snd;    /**< No sound (app will manage it)	*/
     pj_pool_t		*snd_pool;  /**< Sound's private pool.		*/
-    pjmedia_snd_port	*snd_port;  /**< Sound port.			*/
+    pjmedia_snd_port	*snd_port[MAX_PORT];  /**< Sound port.			*/
     pj_timer_entry	 snd_idle_timer;/**< Sound device idle timer.	*/
     pjmedia_master_port	*null_snd;  /**< Master port for null sound.	*/
     pjmedia_port	*null_port; /**< Null port.			*/
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -588,7 +588,7 @@ static void check_snd_dev_idle()
      * It is idle when there is no port connection in the bridge and
      * there is no active call.
      */
-    if ((pjsua_var.snd_port!=NULL || pjsua_var.null_snd!=NULL) && 
+    if ((pjsua_var.snd_port[0]!=NULL || pjsua_var.null_snd!=NULL) &&
 	pjsua_var.snd_idle_timer.id == PJ_FALSE &&
 	pjmedia_conf_get_connect_count(pjsua_var.mconf) == 0 &&
 	call_cnt == 0 &&
@@ -2008,7 +2008,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect(
 	pj_assert(status == PJ_SUCCESS);
 
 	/* Check if sound device is instantiated. */
-	need_reopen = (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL && 
+	need_reopen = (pjsua_var.snd_port[0]==NULL && pjsua_var.null_snd==NULL &&
 		      !pjsua_var.no_snd);
 
 	/* Check if sound device need to reopen because it needs to modify 
@@ -2072,7 +2072,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect(
 	/* The bridge version */
 
 	/* Create sound port if none is instantiated */
-	if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL && 
+	if (pjsua_var.snd_port[0]==NULL && pjsua_var.null_snd==NULL &&
 	    !pjsua_var.no_snd) 
 	{
 	    pj_status_t status;
@@ -2686,9 +2686,9 @@ static pj_status_t update_initial_aud_pa
     pjmedia_aud_param param;
     pj_status_t status;
 
-    PJ_ASSERT_RETURN(pjsua_var.snd_port != NULL, PJ_EBUG);
+    PJ_ASSERT_RETURN(pjsua_var.snd_port[0] != NULL, PJ_EBUG);
 
-    strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
+    strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]);
 
     status = pjmedia_aud_stream_get_param(strm, &param);
     if (status != PJ_SUCCESS) {
@@ -2754,7 +2754,7 @@ static pj_status_t open_snd_dev(pjmedia_
 	      1000 / param->base.clock_rate));
 
     status = pjmedia_snd_port_create2( pjsua_var.snd_pool, 
-				       param, &pjsua_var.snd_port);
+				       param, &pjsua_var.snd_port[0]);
     if (status != PJ_SUCCESS)
 	return status;
 
@@ -2812,13 +2812,13 @@ static pj_status_t open_snd_dev(pjmedia_
     }
 
     /* Connect sound port to the bridge */
-    status = pjmedia_snd_port_connect(pjsua_var.snd_port, 	 
+    status = pjmedia_snd_port_connect(pjsua_var.snd_port[0],
 				      conf_port ); 	 
     if (status != PJ_SUCCESS) { 	 
 	pjsua_perror(THIS_FILE, "Unable to connect conference port to "
 			        "sound device", status); 	 
-	pjmedia_snd_port_destroy(pjsua_var.snd_port); 	 
-	pjsua_var.snd_port = NULL; 	 
+	pjmedia_snd_port_destroy(pjsua_var.snd_port[0]);
+	pjsua_var.snd_port[0] = NULL;
 	return status; 	 
     }
 
@@ -2833,7 +2833,7 @@ static pj_status_t open_snd_dev(pjmedia_
 	pjmedia_aud_param si;
         pj_str_t tmp;
 
-	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
+	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]);
 	status = pjmedia_aud_stream_get_param(strm, &si);
 	if (status == PJ_SUCCESS)
 	    status = pjmedia_aud_dev_get_info(si.rec_id, &rec_info);
@@ -2876,12 +2876,12 @@ static pj_status_t open_snd_dev(pjmedia_
 static void close_snd_dev(void)
 {
     /* Close sound device */
-    if (pjsua_var.snd_port) {
+    if (pjsua_var.snd_port[0]) {
 	pjmedia_aud_dev_info cap_info, play_info;
 	pjmedia_aud_stream *strm;
 	pjmedia_aud_param param;
 
-	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
+	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]);
 	pjmedia_aud_stream_get_param(strm, &param);
 
 	if (pjmedia_aud_dev_get_info(param.rec_id, &cap_info) != PJ_SUCCESS)
@@ -2893,9 +2893,9 @@ static void close_snd_dev(void)
 			     "%s sound capture device",
 			     play_info.name, cap_info.name));
 
-	pjmedia_snd_port_disconnect(pjsua_var.snd_port);
-	pjmedia_snd_port_destroy(pjsua_var.snd_port);
-	pjsua_var.snd_port = NULL;
+	pjmedia_snd_port_disconnect(pjsua_var.snd_port[0]);
+	pjmedia_snd_port_destroy(pjsua_var.snd_port[0]);
+	pjsua_var.snd_port[0] = NULL;
     }
 
     /* Close null sound device */
@@ -2984,6 +2984,35 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( i
     return PJ_SUCCESS;
 }
 
+PJ_DEF(pj_status_t) pjsua_add_snd_port(int id, pjsua_conf_port_id *p_id)
+{
+	unsigned alt_cr_cnt = 1;
+	unsigned alt_cr = 0;
+	pj_status_t status = -1;
+	pjmedia_snd_port_param param;
+	unsigned samples_per_frame;
+	pjmedia_port *port;
+	const pj_str_t name = pj_str("tapi2");
+	alt_cr = pjsua_var.media_cfg.clock_rate;
+	samples_per_frame = alt_cr *
+			    pjsua_var.media_cfg.audio_frame_ptime *
+			    pjsua_var.media_cfg.channel_count / 1000;
+	status = create_aud_param(&param.base,
+				pjsua_var.play_dev,
+				pjsua_var.cap_dev,
+				alt_cr,
+				pjsua_var.media_cfg.channel_count,
+				samples_per_frame, 16);
+	if (status != PJ_SUCCESS)
+		return status;
+	param.base.rec_id = id;
+	param.base.play_id = id;
+	param.options = 0;
+	status = pjmedia_snd_port_create2(pjsua_var.snd_pool,
+				       &param, &pjsua_var.snd_port[id]);
+	return PJ_SUCCESS;
+}
+
 
 /*
  * Get currently active sound devices. If sound devices has not been created
@@ -3088,7 +3117,7 @@ PJ_DEF(pj_status_t) pjsua_set_ec(unsigne
     pjsua_var.media_cfg.ec_options = options;
 
     if (pjsua_var.snd_port)
-	status = pjmedia_snd_port_set_ec(pjsua_var.snd_port, pjsua_var.pool,
+	status = pjmedia_snd_port_set_ec(pjsua_var.snd_port[0], pjsua_var.pool,
 					 tail_ms, options);
     
     PJSUA_UNLOCK();
@@ -3111,7 +3140,7 @@ PJ_DEF(pj_status_t) pjsua_get_ec_tail(un
  */
 PJ_DEF(pj_bool_t) pjsua_snd_is_active(void)
 {
-    return pjsua_var.snd_port != NULL;
+    return pjsua_var.snd_port[0] != NULL;
 }
 
 
@@ -3135,7 +3164,7 @@ PJ_DEF(pj_status_t) pjsua_snd_set_settin
     if (pjsua_snd_is_active()) {
 	pjmedia_aud_stream *strm;
 	
-	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
+	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]);
 	status = pjmedia_aud_stream_set_cap(strm, cap, pval);
     } else {
 	status = PJ_SUCCESS;
@@ -3181,7 +3210,7 @@ PJ_DEF(pj_status_t) pjsua_snd_get_settin
 	/* Sound is active, retrieve from device directly */
 	pjmedia_aud_stream *strm;
 	
-	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
+	strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]);
 	status = pjmedia_aud_stream_get_cap(strm, cap, pval);
     } else {
 	/* Otherwise retrieve from internal param */
