PJMEDIA/PJMEDIA-AUDIODEV update:
- pjmedia.h: re-added inclusion of <sound.h> since we have compat 
    layer now
- audiodev.h: 
    - added input_vol and output_vol in pjmedia_aud_param, and
       implement it on WMME dev
    - added  pjmedia_aud_dev_cap_name() to see cap name
    - added pjmedia_aud_param_set_cap() and  pjmedia_aud_param_get_cap()
      to set and get specific capability in param
- conference.h: exported PJMEDIA_CONF_BRIDGE_SIGNATURE and 
    PJMEDIA_CONF_SWITCH_SIGNATURE since these are needed by PJSUA-LIB
- WMME: bug due to addition of input_vol and output_vol in param: 
    volumes are set in flags in default_param(), but the
    fields are not set. This would cause audio volume to be set to
    zero for example.
- WMME: some refactoring, removed duplicate settings in param
- WMME: bug: setting set in set_cap() is not saved to param, so
    get_param() will return wrong setting
- APS: update because of s/out_route/output_route/ in param
- APS: same bug as WMME due to addition of input_vol and output_vol in
    param: flags are set in param but the fields are not



git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/aps-direct@2492 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev.h b/pjmedia/include/pjmedia-audiodev/audiodev.h
index 61e14b4..8f2ab78 100644
--- a/pjmedia/include/pjmedia-audiodev/audiodev.h
+++ b/pjmedia/include/pjmedia-audiodev/audiodev.h
@@ -66,13 +66,6 @@
 };
 
 
-/** 
- * Type for device unique identifier. The unique device ID can be used to save
- * a reference to a particular device across software reboots.
- */
-typedef pj_uint32_t pjmedia_aud_dev_uid;
-
-
 /**
  * This enumeration identifies various audio device capabilities. These audio
  * capabilities indicates what features are supported by the underlying
@@ -186,8 +179,13 @@
      * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
      * PJ_FALSE.
      */
-    PJMEDIA_AUD_DEV_CAP_PLC = 8192
+    PJMEDIA_AUD_DEV_CAP_PLC = 8192,
     
+    /**
+     * End of capability
+     */
+    PJMEDIA_AUD_DEV_CAP_MAX = 16384
+
 } pjmedia_aud_dev_cap;
 
 
@@ -369,11 +367,31 @@
      */
     unsigned output_latency_ms;
 
+    /**
+     * Input volume setting, in percent. This setting is optional, and will 
+     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in 
+     * the flags.
+     */
+    unsigned input_vol;
+
+    /**
+     * Output volume setting, in percent. This setting is optional, and will 
+     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in 
+     * the flags.
+     */
+    unsigned output_vol;
+
+    /** 
+     * Set the audio input route. This setting is optional, and will only be
+     * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags.
+     */
+    pjmedia_aud_dev_route input_route;
+
     /** 
      * Set the audio output route. This setting is optional, and will only be
      * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags.
      */
-    pjmedia_aud_dev_route out_route;
+    pjmedia_aud_dev_route output_route;
 
     /**
      * Enable/disable echo canceller, if the device supports it. This setting
@@ -410,6 +428,52 @@
 /** Forward declaration for audio device factory */
 typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory;
 
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap		The capability ID.
+ * @param p_desc	Optional pointer which will be filled with longer 
+ *			description about the capability.
+ *
+ * @return		Capability name.
+ */
+PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+					      const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_aud_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param		The structure.
+ * @param cap		The audio capability which value is to be set.
+ * @param value		Pointer to value. Please see the type of value to
+ *			be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_aud_param structure. This
+ * function will return PJMEDIA_EAUD_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param		The structure.
+ * @param cap		The audio capability which value is to be retrieved.
+ * @param value		Pointer to value. Please see the type of value to
+ *			be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       void *pval);
 
 /**
  * Initialize the audio subsystem. This will register all supported audio 
@@ -446,19 +510,6 @@
 
 
 /**
- * Get string info for the specified capability.
- *
- * @param cap		The capability ID.
- * @param p_desc	Optional pointer which will be filled with longer 
- *			description about the capability.
- *
- * @return		Capability name.
- */
-PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
-					      const char **p_desc);
-
-
-/**
  * Get the number of sound devices installed in the system.
  *
  * @return		The number of sound devices installed in the system.
@@ -548,7 +599,9 @@
  * @param strm		The audio stream.
  * @param cap		The audio capability which value is to be retrieved.
  * @param value		Pointer to value to be filled in by this function 
- *			once it returns successfully.
+ *			once it returns successfully.  Please see the type 
+ *			of value to be supplied in the pjmedia_aud_dev_cap
+ *			documentation.
  *
  * @return		PJ_SUCCESS on successful operation or the appropriate
  *			error code.
@@ -562,7 +615,8 @@
  *
  * @param strm		The audio stream.
  * @param cap		The audio capability which value is to be set.
- * @param value		Pointer to value.
+ * @param value		Pointer to value. Please see the type of value to
+ *			be supplied in the pjmedia_aud_dev_cap documentation.
  *
  * @return		PJ_SUCCESS on successful operation or the appropriate
  *			error code.
diff --git a/pjmedia/include/pjmedia.h b/pjmedia/include/pjmedia.h
index 28db590..55e8977 100644
--- a/pjmedia/include/pjmedia.h
+++ b/pjmedia/include/pjmedia.h
@@ -52,12 +52,7 @@
 #include <pjmedia/sdp_neg.h>
 #include <pjmedia/session.h>
 #include <pjmedia/silencedet.h>
-/* This sound API is deprecated. Please see:
-http://trac.pjsip.org/repos/wiki/Audio_Dev_API
-*/
-#if PJMEDIA_AUDIO_API != PJMEDIA_AUDIO_API_NEW_ONLY
 #include <pjmedia/sound.h>
-#endif
 #include <pjmedia/sound_port.h>
 #include <pjmedia/splitcomb.h>
 #include <pjmedia/stereo.h>
diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h
index 1f4890b..584e56c 100644
--- a/pjmedia/include/pjmedia/conference.h
+++ b/pjmedia/include/pjmedia/conference.h
@@ -43,6 +43,18 @@
 
 PJ_BEGIN_DECL
 
+/**
+ * The conference bridge signature in pjmedia_port_info.
+ */
+#define PJMEDIA_CONF_BRIDGE_SIGNATURE	\
+		    PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'F')
+
+/**
+ * The audio switchboard signature in pjmedia_port_info.
+ */
+#define PJMEDIA_CONF_SWITCH_SIGNATURE	\
+		    PJMEDIA_PORT_SIGNATURE('A', 'S', 'W', 'I')
+
 
 /**
  * Opaque type for conference bridge.
diff --git a/pjmedia/src/pjmedia-audiodev/audiodev.c b/pjmedia/src/pjmedia-audiodev/audiodev.c
index 1603216..956b5a9 100644
--- a/pjmedia/src/pjmedia-audiodev/audiodev.c
+++ b/pjmedia/src/pjmedia-audiodev/audiodev.c
@@ -115,6 +115,123 @@
 
 } aud_subsys;
 
+/* API: get capability name/info */
+PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+					     const char **p_desc)
+{
+    const 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;
+}
+
+static pj_status_t get_cap_pointer(const pjmedia_aud_param *param,
+				   pjmedia_aud_dev_cap cap,
+				   void **ptr,
+				   unsigned *size)
+{
+#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
+			    *size = sizeof(param->name)
+
+    switch (cap) {
+    case PJMEDIA_AUD_DEV_CAP_EXT_FORMAT:
+	FIELD_INFO(ext_fmt);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY:
+	FIELD_INFO(input_latency_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY:
+	FIELD_INFO(output_latency_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
+	FIELD_INFO(input_vol);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
+	FIELD_INFO(output_vol);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE:
+	FIELD_INFO(input_route);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:
+	FIELD_INFO(output_route);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_EC:
+	FIELD_INFO(ec_enabled);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_EC_TAIL:
+	FIELD_INFO(ec_tail_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_VAD:
+	FIELD_INFO(ext_fmt.vad);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_CNG:
+	FIELD_INFO(cng_enabled);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_PLC:
+	FIELD_INFO(plc_enabled);
+	break;
+    default:
+	return PJMEDIA_EAUD_INVCAP;
+    }
+
+#undef FIELD_INFO
+
+    return PJ_SUCCESS;
+}
+
+/* API: set cap value to param */
+PJ_DEF(pj_status_t) pjmedia_aud_param_set_cap( pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       const void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_memcpy(cap_ptr, pval, cap_size);
+    param->flags |= cap;
+
+    return PJ_SUCCESS;
+}
+
+/* API: get cap value from param */
+PJ_DEF(pj_status_t) pjmedia_aud_param_get_cap( const pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if ((param->flags & cap) == 0) {
+	pj_bzero(cap_ptr, cap_size);
+	return PJMEDIA_EAUD_INVCAP;
+    }
+
+    pj_memcpy(pval, cap_ptr, cap_size);
+    return PJ_SUCCESS;
+}
 
 /* Internal: init driver */
 static pj_status_t init_driver(unsigned drv_idx)
@@ -293,29 +410,6 @@
     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)
-{
-    const 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)
 {
diff --git a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
index 5494a4e..7ae1962 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
@@ -1205,9 +1205,9 @@
     param->channel_count = 1;
     param->samples_per_frame = af->dev_info.default_samples_per_sec * 20 / 1000;
     param->bits_per_sample = BITS_PER_SAMPLE;
-    param->flags = af->dev_info.caps;
+    param->flags = PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE;
     param->ext_fmt.id = PJMEDIA_FORMAT_L16;
-    param->out_route = PJMEDIA_AUD_DEV_ROUTE_EARPIECE;
+    param->output_route = PJMEDIA_AUD_DEV_ROUTE_EARPIECE;
 
     return PJ_SUCCESS;
 }
@@ -1300,7 +1300,7 @@
     aps_setting.plc = strm->param.plc_enabled;
     aps_setting.cng = aps_setting.vad;
     aps_setting.loudspk = 
-		strm->param.out_route==PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
+		strm->param.output_route==PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
 
     /* Set audio engine callbacks. */
     if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16) {
@@ -1375,7 +1375,7 @@
     switch (cap) {
     case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE: 
 	if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
-	    *(pjmedia_aud_dev_route*)pval = strm->param.out_route;
+	    *(pjmedia_aud_dev_route*)pval = strm->param.output_route;
 	    status = PJ_SUCCESS;
 	}
 	break;
@@ -1449,7 +1449,7 @@
 		break;
 	    }
 	    if (status == PJ_SUCCESS)
-		strm->param.out_route = r; 
+		strm->param.output_route = r; 
 	}
 	break;
     case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
diff --git a/pjmedia/src/pjmedia-audiodev/wmme_dev.c b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
index 650e0d5..8008520 100644
--- a/pjmedia/src/pjmedia-audiodev/wmme_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
@@ -47,7 +47,6 @@
 
 #define THIS_FILE			"wmme_dev.c"
 
-
 /* WMME device info */
 struct wmme_dev_info
 {
@@ -80,7 +79,6 @@
     HANDLE        hEvent;
     DWORD         dwBufIdx;
     DWORD         dwMaxBufIdx;
-    unsigned	  latency_ms;
     pj_timestamp  timestamp;
 };
 
@@ -88,10 +86,8 @@
 /* Sound stream. */
 struct wmme_stream
 {
-    pjmedia_aud_stream	 base;
-    pjmedia_dir          dir;               /**< Sound direction.      */
-    int                  play_id;           /**< Playback dev id.      */
-    int                  rec_id;            /**< Recording dev id.     */
+    pjmedia_aud_stream	 base;		    /**< Base stream	       */
+    pjmedia_aud_param	 param;		    /**< Settings	       */
     pj_pool_t           *pool;              /**< Memory pool.          */
 
     pjmedia_aud_rec_cb   rec_cb;            /**< Capture callback.     */
@@ -104,11 +100,7 @@
     void    		*buffer;	    /**< Temp. frame buffer.   */
     pjmedia_format_id	 fmt_id;	    /**< Frame format	       */
     pj_uint8_t		 silence_char;	    /**< Silence pattern       */
-    unsigned             clock_rate;        /**< Clock rate.           */
     unsigned		 bytes_per_frame;   /**< Bytes per frame       */
-    unsigned             samples_per_frame; /**< Samples per frame.    */
-    unsigned             bits_per_sample;   /**< Bits per sample.      */
-    unsigned             channel_count;     /**< Channel count.        */
 
     pjmedia_frame_ext	*xfrm;		    /**< Extended frame buffer */
     unsigned		 xfrm_size;	    /**< Total ext frm size    */
@@ -437,7 +429,8 @@
     param->channel_count = 1;
     param->samples_per_frame = di->info.default_samples_per_sec * 20 / 1000;
     param->bits_per_sample = 16;
-    param->flags = di->info.caps;
+    param->flags = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |
+		   PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
     param->input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;
     param->output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
 
@@ -497,7 +490,7 @@
     static char name[8];
 
     if (id == PJMEDIA_FORMAT_L16)
-	return "l16";
+	return "PCM";
     pj_memcpy(name, &id, 4);
     name[4] = '\0';
     return name;
@@ -685,9 +678,9 @@
 
     eventCount = 0;
     events[eventCount++] = strm->thread_quit_event;
-    if (strm->dir & PJMEDIA_DIR_PLAYBACK)
+    if (strm->param.dir & PJMEDIA_DIR_PLAYBACK)
 	events[eventCount++] = strm->play_strm.hEvent;
-    if (strm->dir & PJMEDIA_DIR_CAPTURE)
+    if (strm->param.dir & PJMEDIA_DIR_CAPTURE)
 	events[eventCount++] = strm->rec_strm.hEvent;
 
 
@@ -695,7 +688,7 @@
      * system activity.
      */
 #if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0
-    if (strm->dir & PJMEDIA_DIR_PLAYBACK)
+    if (strm->param.dir & PJMEDIA_DIR_PLAYBACK)
 	CeSetThreadPriority(GetCurrentThread(), 153);
     else
 	CeSetThreadPriority(GetCurrentThread(), 247);
@@ -833,8 +826,8 @@
 		/* Increment position. */
 		if (++wmme_strm->dwBufIdx >= wmme_strm->dwMaxBufIdx)
 		    wmme_strm->dwBufIdx = 0;
-		wmme_strm->timestamp.u64 += strm->samples_per_frame / 
-					    strm->channel_count;
+		wmme_strm->timestamp.u64 += strm->param.samples_per_frame /
+					    strm->param.channel_count;
 	    }
 	}
 	else
@@ -913,9 +906,11 @@
 
 		    strm->xfrm->samples_cnt = 0;
 		    strm->xfrm->subframe_cnt = 0;
-		    pjmedia_frame_ext_append_subframe(strm->xfrm, buffer,
-						      strm->bytes_per_frame *8,
-						      strm->samples_per_frame);
+		    pjmedia_frame_ext_append_subframe(
+			strm->xfrm, buffer,
+			strm->bytes_per_frame *8,
+			strm->param.samples_per_frame
+		    );
 		}
 
 		/* Re-add the buffer to the device. */
@@ -937,8 +932,8 @@
 		/* Increment position. */
 		if (++wmme_strm->dwBufIdx >= wmme_strm->dwMaxBufIdx)
 		    wmme_strm->dwBufIdx = 0;
-		wmme_strm->timestamp.u64 += strm->samples_per_frame / 
-					    strm->channel_count;
+		wmme_strm->timestamp.u64 += strm->param.samples_per_frame /
+					    strm->param.channel_count;
 	    }
 	}
     }
@@ -981,30 +976,24 @@
     PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
 
     strm = PJ_POOL_ZALLOC_T(pool, struct wmme_stream);
-    strm->dir = param->dir;
-    strm->play_id = param->play_id;
-    strm->rec_id = param->rec_id;
+    pj_memcpy(&strm->param, param, sizeof(*param));
     strm->pool = pool;
     strm->rec_cb = rec_cb;
     strm->play_cb = play_cb;
     strm->user_data = user_data;
     strm->fmt_id = param->ext_fmt.id;
     strm->silence_char = silence_char;
-    strm->clock_rate = param->clock_rate;
-    strm->samples_per_frame = param->samples_per_frame;
-    strm->bits_per_sample = param->bits_per_sample;
-    strm->channel_count = param->channel_count;
 
     /* Create player stream */
     if (param->dir & PJMEDIA_DIR_PLAYBACK) {
 	unsigned buf_count;
 
-	if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY)
-	    strm->play_strm.latency_ms = param->output_latency_ms;
-	else
-	    strm->play_strm.latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
+	if ((param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY)==0) {
+	    strm->param.flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
+	    strm->param.output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
+	}
 
-	buf_count = strm->play_strm.latency_ms * param->clock_rate * 
+	buf_count = strm->param.output_latency_ms * param->clock_rate * 
 		    param->channel_count / param->samples_per_frame / 1000;
 
 	status = init_player_stream(wf, strm->pool,
@@ -1023,12 +1012,12 @@
     if (param->dir & PJMEDIA_DIR_CAPTURE) {
 	unsigned buf_count;
 
-	if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY)
-	    strm->rec_strm.latency_ms = param->input_latency_ms;
-	else
-	    strm->rec_strm.latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;
+	if ((param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY)==0) {
+	    strm->param.flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;
+	    strm->param.input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;
+	}
 
-	buf_count = strm->rec_strm.latency_ms * param->clock_rate * 
+	buf_count = strm->param.input_latency_ms * param->clock_rate * 
 		    param->channel_count / param->samples_per_frame / 1000;
 
 	status = init_capture_stream(wf, strm->pool,
@@ -1074,6 +1063,13 @@
 	return status;
     }
 
+    /* Apply the remaining settings */
+    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {
+	stream_set_cap(&strm->base, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+		       &param->output_vol);
+    }
+
+
     /* Done */
     strm->base.op = &stream_op;
     *p_aud_strm = &strm->base;
@@ -1089,26 +1085,8 @@
 
     PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
 
-    pj_bzero(pi, sizeof(*pi));
-    pi->dir = strm->dir;
-    pi->play_id = strm->play_id;
-    pi->rec_id = strm->rec_id;
-    pi->clock_rate = strm->clock_rate;
-    pi->channel_count = strm->channel_count;
-    pi->samples_per_frame = strm->samples_per_frame;
-    pi->bits_per_sample = strm->bits_per_sample;
+    pj_memcpy(pi, &strm->param, sizeof(*pi));
     
-    if (pi->dir & PJMEDIA_DIR_CAPTURE) {
-	pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;
-	pi->input_latency_ms = strm->rec_strm.latency_ms;
-    }
-
-    if (pi->dir & PJMEDIA_DIR_PLAYBACK) {
-	/* TODO: report the actual latency? */
-	pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
-	pi->output_latency_ms = strm->play_strm.latency_ms;
-    }
-
     return PJ_SUCCESS;
 }
 
@@ -1122,31 +1100,31 @@
     PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
     if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY && 
-	(strm->dir & PJMEDIA_DIR_CAPTURE)) 
+	(strm->param.dir & PJMEDIA_DIR_CAPTURE)) 
     {
 	/* Recording latency */
-	*(unsigned*)pval = strm->rec_strm.latency_ms;
+	*(unsigned*)pval = strm->param.input_latency_ms;
 	return PJ_SUCCESS;
     } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY  && 
-	       (strm->dir & PJMEDIA_DIR_PLAYBACK))
+	       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))
     {
 	/* Playback latency */
-	*(unsigned*)pval = strm->play_strm.latency_ms;
+	*(unsigned*)pval = strm->param.output_latency_ms;
 	return PJ_SUCCESS;
     } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING &&
 	       strm->play_strm.hWave.Out)
     {
 	/* Output volume setting */
-	DWORD dwVol;
+	DWORD waveVol;
 	MMRESULT mr;
 
-	mr = waveOutGetVolume(strm->play_strm.hWave.Out, &dwVol);
+	mr = waveOutGetVolume(strm->play_strm.hWave.Out, &waveVol);
 	if (mr != MMSYSERR_NOERROR) {
 	    return PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);
 	}
 
-	dwVol &= 0xFFFF;
-	*(unsigned*)pval = (dwVol * 100) / 0xFFFF;
+	waveVol &= 0xFFFF;
+	*(unsigned*)pval = (waveVol * 100) / 0xFFFF;
 	return PJ_SUCCESS;
     } else {
 	return PJMEDIA_EAUD_INVCAP;
@@ -1166,15 +1144,24 @@
 	strm->play_strm.hWave.Out)
     {
 	/* Output volume setting */
-	DWORD dwVol;
+	unsigned vol = *(unsigned*)pval;
+	DWORD waveVol;
 	MMRESULT mr;
+	pj_status_t status;
 
-	dwVol = ((*(unsigned*)pval) * 0xFFFF) / 100;
-	dwVol |= (dwVol << 16);
+	if (vol > 100)
+	    vol = 100;
 
-	mr = waveOutSetVolume(strm->play_strm.hWave.Out, dwVol);
-	return (mr==MMSYSERR_NOERROR)? PJ_SUCCESS : 
+	waveVol = (vol * 0xFFFF) / 100;
+	waveVol |= (waveVol << 16);
+
+	mr = waveOutSetVolume(strm->play_strm.hWave.Out, waveVol);
+	status = (mr==MMSYSERR_NOERROR)? PJ_SUCCESS : 
 				PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(mr);
+	if (status == PJ_SUCCESS) {
+	    strm->param.output_vol = *(unsigned*)pval;
+	}
+	return status;
     }
 
     return PJMEDIA_EAUD_INVCAP;
diff --git a/pjmedia/src/pjmedia/conf_switch.c b/pjmedia/src/pjmedia/conf_switch.c
index ca8f3cd..bf8ca50 100644
--- a/pjmedia/src/pjmedia/conf_switch.c
+++ b/pjmedia/src/pjmedia/conf_switch.c
@@ -45,7 +45,7 @@
 
 #define THIS_FILE	    "conf_switch.c"
 
-#define SIGNATURE	    PJMEDIA_PORT_SIGNATURE('S', 'W', 'T', 'C')
+#define SIGNATURE	    PJMEDIA_CONF_SWITCH_SIGNATURE
 #define SIGNATURE_PORT	    PJMEDIA_PORT_SIGNATURE('S', 'W', 'T', 'P')
 #define NORMAL_LEVEL	    128
 #define SLOT_TYPE	    unsigned
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index a89aff3..c39ec03 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -64,7 +64,7 @@
 
 #define BYTES_PER_SAMPLE    2
 
-#define SIGNATURE	    PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'F')
+#define SIGNATURE	    PJMEDIA_CONF_BRIDGE_SIGNATURE
 #define SIGNATURE_PORT	    PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'P')
 /* Normal level is hardcodec to 128 in all over places */
 #define NORMAL_LEVEL	    128