Automated import from //branches/master/...@142072,142072
diff --git a/android/author/android_audio_input.cpp b/android/author/android_audio_input.cpp
index 09a1f63..4b2376e 100644
--- a/android/author/android_audio_input.cpp
+++ b/android/author/android_audio_input.cpp
@@ -35,6 +35,13 @@
 // Define entry point for this DLL
 OSCL_DLL_ENTRY_POINT_DEFAULT()
 
+// At the start of a recording we are going to mute the first 300ms in
+// order to eliminate recording of the videorecorder signaltone.
+static const int32 AUTO_RAMP_START_MS = 300;
+
+// After the initial mute we're going to linearly ramp up the volume
+// over the next 300ms.
+static const int32 AUTO_RAMP_DURATION_MS = 300;
 
 ////////////////////////////////////////////////////////////////////////////
 AndroidAudioInput::AndroidAudioInput()
@@ -937,6 +944,59 @@
     return PVMFSuccess;
 }
 
+void AndroidAudioInput::RampVolume(
+    int32 timeInFrames,
+    int32 kAutoRampDurationFrames,
+    void *_data,
+    size_t numBytes) const {
+    int16 *data = (int16 *)_data;
+
+    // Apply the ramp to the entire buffer or to the end of the ramp duration
+    // whichever comes first.
+    int32 kStopFrame = timeInFrames + numBytes / sizeof(int16);
+    if (kStopFrame > kAutoRampDurationFrames) {
+        kStopFrame = kAutoRampDurationFrames;
+    }
+
+    const int32 kShift = 14;
+    int32 fixedMultiplier =
+        (timeInFrames << kShift) / kAutoRampDurationFrames;
+
+    if (iAudioNumChannels == 1) {
+        while (timeInFrames < kStopFrame) {
+            data[0] = (data[0] * fixedMultiplier) >> kShift;
+            ++data;
+            ++timeInFrames;
+
+            if ((timeInFrames & 3) == 0) {
+                // Update the multiplier every 4 frames.
+
+                fixedMultiplier =
+                    (timeInFrames << kShift) / kAutoRampDurationFrames;
+            }
+        }
+    } else {
+        LOG_ALWAYS_FATAL_IF(
+                iAudioNumChannels != 2,
+                "We only support mono or stereo audio data here.");
+
+        // Stereo
+        while (timeInFrames < kStopFrame) {
+            data[0] = (data[0] * fixedMultiplier) >> kShift;
+            data[1] = (data[1] * fixedMultiplier) >> kShift;
+            data += 2;
+            ++timeInFrames;
+
+            if ((timeInFrames & 3) == 0) {
+                // Update the multiplier every 4 frames.
+
+                fixedMultiplier =
+                    (timeInFrames << kShift) / kAutoRampDurationFrames;
+            }
+        }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////
 int AndroidAudioInput::audin_thread_func() {
     // setup audio record session
@@ -965,6 +1025,16 @@
 
     if (res == NO_ERROR) {
 
+        // We are going to ramp up the volume from 0 to full at the
+        // start of recording.
+        int64_t numFramesRecorded = 0;
+
+        const int32 kAutoRampStartFrames =
+            AUTO_RAMP_START_MS * iAudioSamplingRate / 1000;
+
+        const int32 kAutoRampDurationFrames =
+            AUTO_RAMP_DURATION_MS * iAudioSamplingRate / 1000;
+
         while (!iExitAudioThread) {
             iOSSRequestQueueLock.Lock();
             if (iOSSRequestQueue.empty()) {
@@ -981,10 +1051,22 @@
             if (numOfBytes <= 0)
                 break;
 
+            if (numFramesRecorded < kAutoRampStartFrames) {
+                // Start with silence...
+                memset(data, 0, numOfBytes);
+            } else {
+                // Then ramp up the volume...
+                int64_t delta = numFramesRecorded - kAutoRampStartFrames;
+                if (delta < kAutoRampDurationFrames) {
+                    RampVolume(
+                            delta, kAutoRampDurationFrames, data, numOfBytes);
+                }
+            }
+
             if (iTrackMaxAmplitude) {
-                short *p = (short*) data;
+                int16 *p = (int16*) data;
                 for (int i = numOfBytes >> 1; i > 0; --i) {
-                    short v = *p++;
+                    int16 v = *p++;
                     if (v < 0) {
                         v = -v;
                     }
@@ -994,8 +1076,10 @@
                 }
             }
 
-            int dataDuration = numOfBytes/iAudioNumChannels/ sizeof(short) * 1000
-                    / iAudioSamplingRate; //ms
+            int32 dataFrames = numOfBytes / sizeof(int16) / iAudioNumChannels;
+            numFramesRecorded += dataFrames;
+            int dataDuration = dataFrames * 1000 / iAudioSamplingRate; //ms
+
             MicData micdata(data, numOfBytes, iTimeStamp,
                     dataDuration);
             iWriteResponseQueueLock.Lock();
diff --git a/android/author/android_audio_input.h b/android/author/android_audio_input.h
index 8a8c109..90ef037 100644
--- a/android/author/android_audio_input.h
+++ b/android/author/android_audio_input.h
@@ -317,6 +317,12 @@
      */
     PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam=false);
 
+    // Linearly ramp up the volume from 0 to full over a duration given
+    // in "kAutoRampDurationFrames". The time of the first audio frame
+    // passed in is "timeInFrames".
+    void RampVolume(int32 timeInFrames, int32 kAutoRampDurationFrames,
+                    void *_data, size_t numBytes) const;
+
     // Command queue
     uint32 iCmdIdCounter;
     Oscl_Vector<AndroidAudioInputCmd, OsclMemAllocator> iCmdQueue;