Index: pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp	(revision 3553)
+++ pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp	(revision 3841)
@@ -240,4 +240,5 @@
     TInt		     lastError_;
     pj_uint32_t		     timeStamp_;
+    CActiveSchedulerWait     startAsw_;
 
     // cache variable
@@ -364,4 +365,11 @@
     iInputStream_->Open(&iStreamSettings);
     
+#if defined(PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START) && \
+    PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START != 0
+    
+    startAsw_.Start();
+    
+#endif
+    
     // Success
     PJ_LOG(4,(THIS_FILE, "Sound capture started."));
@@ -387,4 +395,8 @@
     }
     
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+    
     state_ = STATE_INACTIVE;
 }
@@ -400,8 +412,21 @@
 void CPjAudioInputEngine::MaiscOpenComplete(TInt aError)
 {
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+    
     lastError_ = aError;
     if (aError != KErrNone) {
         snd_perror("Error in MaiscOpenComplete()", aError);
     	return;
+    }
+
+    /* Apply input volume setting if specified */
+    if (parentStrm_->param.flags & 
+        PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING) 
+    {
+        stream_set_cap(&parentStrm_->base,
+                       PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING, 
+                       &parentStrm_->param.input_vol);
     }
 
@@ -415,5 +440,10 @@
     if (err2) {
     	PJ_LOG(4,(THIS_FILE, "Exception in iInputStream_->ReadL()"));
-    }
+	lastError_ = err2;
+	return;
+    }
+
+    // input stream opened succesfully, set status to Active
+    state_ = STATE_ACTIVE;
 }
 
@@ -548,4 +578,5 @@
     TInt		     lastError_;
     unsigned		     timestamp_;
+    CActiveSchedulerWait     startAsw_;
 
     CPjAudioOutputEngine(struct mda_stream *parent_strm,
@@ -639,4 +670,11 @@
     lastError_ = KRequestPending;
     iOutputStream_->Open(&iStreamSettings);
+    
+#if defined(PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START) && \
+    PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START != 0
+    
+    startAsw_.Start();
+    
+#endif
 
     // Success
@@ -663,4 +701,8 @@
     }
     
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+    
     state_ = STATE_INACTIVE;
 }
@@ -668,10 +710,11 @@
 void CPjAudioOutputEngine::MaoscOpenComplete(TInt aError)
 {
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+
     lastError_ = aError;
     
     if (aError==KErrNone) {
-	// output stream opened succesfully, set status to Active
-	state_ = STATE_ACTIVE;
-
 	// set stream properties, 16bit 8KHz mono
 	TMdaAudioDataSettings iSettings;
@@ -684,6 +727,15 @@
 					    iSettings.iChannels);
 
-	// set volume to 1/2th of stream max volume
-	iOutputStream_->SetVolume(iOutputStream_->MaxVolume()/2);
+        /* Apply output volume setting if specified */
+        if (parentStrm_->param.flags & 
+            PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) 
+        {
+            stream_set_cap(&parentStrm_->base,
+                           PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 
+                           &parentStrm_->param.output_vol);
+        } else {
+            // set volume to 1/2th of stream max volume
+            iOutputStream_->SetVolume(iOutputStream_->MaxVolume()/2);
+        }
 	
 	// set stream priority to normal and time sensitive
@@ -719,4 +771,7 @@
 	frame_.Set(frameBuf_, frameBufSize_);
 	iOutputStream_->WriteL(frame_);
+
+	// output stream opened succesfully, set status to Active
+	state_ = STATE_ACTIVE;
     } else {
     	snd_perror("Error in MaoscOpenComplete()", aError);
@@ -882,5 +937,6 @@
     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;
+    // Don't set the flags without specifying the flags value.
+    //param->flags = af->dev_info.caps;
 
     return PJ_SUCCESS;
@@ -956,4 +1012,18 @@
 
     pj_memcpy(pi, &strm->param, sizeof(*pi));
+    
+    /* Update the output volume setting */
+    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+		       &pi->output_vol) == PJ_SUCCESS)
+    {
+	pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
+    }
+    
+    /* Update the input volume setting */
+    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING,
+		       &pi->input_vol) == PJ_SUCCESS)
+    {
+	pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING;
+    }
     
     return PJ_SUCCESS;
@@ -1035,5 +1105,5 @@
 	break;
     case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
-	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
+	if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 	    PJ_ASSERT_RETURN(strm->out_engine, PJ_EINVAL);
 	    
