Index: /pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-audiodev/audiodev.h
===================================================================
--- /pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-audiodev/audiodev.h	(revision 2465)
+++ /pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-audiodev/audiodev.h	(revision 2466)
@@ -578,4 +578,7 @@
 #define PJMEDIA_EAUD_NODEV	-1
 
+/* Device not ready */
+#define PJMEDIA_EAUD_NOTREADY	-1
+
 /* Unknown system error */
 #define PJMEDIA_EAUD_SYSERR	-1
Index: /pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
===================================================================
--- /pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp	(revision 2465)
+++ /pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp	(revision 2466)
@@ -367,4 +367,12 @@
 
     TInt ActivateSpeaker(TBool active);
+    
+    TInt SetVolume(TInt vol) { return iSession.SetVolume(vol); }
+    TInt GetVolume() { return iSession.Volume(); }
+    TInt GetMaxVolume() { return iSession.MaxVolume(); }
+    
+    TInt SetGain(TInt gain) { return iSession.SetGain(gain); }
+    TInt GetGain() { return iSession.Gain(); }
+    TInt GetMaxGain() { return iSession.MaxGain(); }
 
 private:
@@ -1107,6 +1115,6 @@
     af->dev_info.default_samples_per_sec = 8000;
     af->dev_info.caps = PJMEDIA_AUD_DEV_CAP_EXT_FORMAT |
-			//PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING |
-			//PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING |
+			PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING |
+			PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING |
 			PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE |
 			PJMEDIA_AUD_DEV_CAP_VAD |
@@ -1116,14 +1124,12 @@
     af->dev_info.input_count = 1;
     af->dev_info.output_count = 1;
-    
-    af->dev_info.ext_fmt_cnt = 2;
-    
+
+    af->dev_info.ext_fmt_cnt = 6;
     af->dev_info.ext_fmt[0].id = PJMEDIA_FORMAT_AMR;
-    af->dev_info.ext_fmt[0].bitrate = 0;
-    af->dev_info.ext_fmt[0].vad = PJ_TRUE;
-
     af->dev_info.ext_fmt[1].id = PJMEDIA_FORMAT_G729;
-    af->dev_info.ext_fmt[1].bitrate = 0;
-    af->dev_info.ext_fmt[1].vad = PJ_TRUE;
+    af->dev_info.ext_fmt[2].id = PJMEDIA_FORMAT_ILBC;
+    af->dev_info.ext_fmt[3].id = PJMEDIA_FORMAT_PCMU;
+    af->dev_info.ext_fmt[4].id = PJMEDIA_FORMAT_PCMA;
+    af->dev_info.ext_fmt[5].id = PJMEDIA_FORMAT_L16;
     
     PJ_LOG(4, (THIS_FILE, "APS initialized"));
@@ -1141,4 +1147,6 @@
     pj_pool_release(pool);
 
+    PJ_LOG(4, (THIS_FILE, "APS destroyed"));
+    
     return PJ_SUCCESS;
 }
@@ -1183,4 +1191,6 @@
     param->bits_per_sample = BITS_PER_SAMPLE;
     param->flags = af->dev_info.caps;
+    param->ext_fmt.id = PJMEDIA_FORMAT_L16;
+    param->out_route = PJMEDIA_AUD_DEV_ROUTE_EARPIECE;
 
     return PJ_SUCCESS;
@@ -1352,6 +1362,32 @@
 	break;
     case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
+	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
+	    PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
+	    
+	    TInt max_gain = strm->engine->GetMaxGain();
+	    TInt gain = strm->engine->GetGain();
+	    
+	    if (max_gain > 0 && gain >= 0) {
+		*(unsigned*)pval = gain * 100 / max_gain; 
+		status = PJ_SUCCESS;
+	    } else {
+		status = PJMEDIA_EAUD_NOTREADY;
+	    }
+	}
 	break;
     case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
+	if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
+	    PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
+	    
+	    TInt max_vol = strm->engine->GetMaxVolume();
+	    TInt vol = strm->engine->GetVolume();
+	    
+	    if (max_vol > 0 && vol >= 0) {
+		*(unsigned*)pval = vol * 100 / max_vol; 
+		status = PJ_SUCCESS;
+	    } else {
+		status = PJMEDIA_EAUD_NOTREADY;
+	    }
+	}
 	break;
     default:
@@ -1399,6 +1435,34 @@
 	break;
     case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
+	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
+	    PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
+	    
+	    TInt max_gain = strm->engine->GetMaxGain();
+	    if (max_gain > 0) {
+		TInt gain, err;
+		
+		gain = *(unsigned*)pval * max_gain / 100;
+		err = strm->engine->SetGain(gain);
+		status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
+	    } else {
+		status = PJMEDIA_EAUD_NOTREADY;
+	    }
+	}
 	break;
     case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
+	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
+	    PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
+	    
+	    TInt max_vol = strm->engine->GetMaxVolume();
+	    if (max_vol > 0) {
+		TInt vol, err;
+		
+		vol = *(unsigned*)pval * max_vol / 100;
+		err = strm->engine->SetVolume(vol);
+		status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
+	    } else {
+		status = PJMEDIA_EAUD_NOTREADY;
+	    }
+	}
 	break;
     default:
