echo reference: fix buffer overflow

commit 33e8f78b introduced a regression causing the input buffer
size to be underestimated when downsampling and doing stereo to mono
conversion.

Also a test in create_echo_reference() was not removed and prevented
write sampling rates lower than read sampling rates.

Change-Id: I2ce2e32748eb9d00f4d5b32e5db5149f177c8804
diff --git a/audio_utils/echo_reference.c b/audio_utils/echo_reference.c
index 87ff4ac..a0a0662 100644
--- a/audio_utils/echo_reference.c
+++ b/audio_utils/echo_reference.c
@@ -174,11 +174,24 @@
     // do stereo to mono and down sampling if necessary
     if (er->rd_channel_count != er->wr_channel_count ||
             er->rd_sampling_rate != er->wr_sampling_rate) {
+        size_t wrBufSize = buffer->frame_count;
 
-        inFrames = (buffer->frame_count * er->rd_sampling_rate) / er->wr_sampling_rate +
-                                                RESAMPLER_HEADROOM_SAMPLES;
-        if (er->wr_buf_size < inFrames) {
-            er->wr_buf_size = inFrames;
+        inFrames = buffer->frame_count;
+
+        if (er->rd_sampling_rate != er->wr_sampling_rate) {
+            inFrames = (buffer->frame_count * er->rd_sampling_rate) / er->wr_sampling_rate +
+                                                    RESAMPLER_HEADROOM_SAMPLES;
+            // wr_buf is not only used as resampler output but also for stereo to mono conversion
+            // output so buffer size is driven by both write and read sample rates
+            if (inFrames > wrBufSize) {
+                wrBufSize = inFrames;
+            }
+        }
+
+        if (er->wr_buf_size < wrBufSize) {
+            ALOGV("echo_reference_write() increasing write buffer size from %d to %d",
+                    er->wr_buf_size, wrBufSize);
+            er->wr_buf_size = wrBufSize;
             er->wr_buf = realloc(er->wr_buf, er->wr_buf_size * er->rd_frame_size);
         }
 
@@ -453,11 +466,6 @@
         return -EINVAL;
     }
 
-    if (wrSamplingRate < rdSamplingRate) {
-        ALOGW("create_echo_reference bad smp rate rd %d, wr %d", rdSamplingRate, wrSamplingRate);
-        return -EINVAL;
-    }
-
     er = (struct echo_reference *)calloc(1, sizeof(struct echo_reference));
 
     er->itfe.read = echo_reference_read;