TimestretchBufferProvider integration with Sonic Library

Using Sonic as backbone for time stretching algorithm.
Adding libsonic to needed makefiles.

bug: 19196501
Change-Id: I1ea9221d2f56e4e79fba8746ce0ad350b5079e82
diff --git a/services/audioflinger/BufferProviders.cpp b/services/audioflinger/BufferProviders.cpp
index e058e6c..dcae5e7 100644
--- a/services/audioflinger/BufferProviders.cpp
+++ b/services/audioflinger/BufferProviders.cpp
@@ -370,16 +370,22 @@
         mPitch(pitch),
         mLocalBufferFrameCount(0),
         mLocalBufferData(NULL),
-        mRemaining(0)
+        mRemaining(0),
+        mSonicStream(sonicCreateStream(sampleRate, mChannelCount))
 {
     ALOGV("TimestretchBufferProvider(%p)(%u, %#x, %u %f %f)",
             this, channelCount, format, sampleRate, speed, pitch);
     mBuffer.frameCount = 0;
+
+    LOG_ALWAYS_FATAL_IF(mSonicStream == NULL,
+            "TimestretchBufferProvider can't allocate Sonic stream");
+    sonicSetSpeed(mSonicStream, speed);
 }
 
 TimestretchBufferProvider::~TimestretchBufferProvider()
 {
     ALOGV("~TimestretchBufferProvider(%p)", this);
+    sonicDestroyStream(mSonicStream);
     if (mBuffer.frameCount != 0) {
         mTrackBufferProvider->releaseBuffer(&mBuffer);
     }
@@ -489,6 +495,9 @@
 {
     mSpeed = speed;
     mPitch = pitch;
+
+    sonicSetSpeed(mSonicStream, speed);
+    //TODO: pitch is ignored for now
     return OK;
 }
 
@@ -506,17 +515,24 @@
         *srcFrames = targetSrc + 1;
     }
 
-    // Do the time stretch by memory copy without any local buffer.
-    if (*dstFrames <= *srcFrames) {
-        size_t copySize = mFrameSize * *dstFrames;
-        memcpy(dstBuffer, srcBuffer, copySize);
-    } else {
-        // cyclically repeat the source.
-        for (size_t count = 0; count < *dstFrames; count += *srcFrames) {
-            size_t remaining = min(*srcFrames, *dstFrames - count);
-            memcpy((uint8_t*)dstBuffer + mFrameSize * count,
-                    srcBuffer, mFrameSize * *srcFrames);
+    switch (mFormat) {
+    case AUDIO_FORMAT_PCM_FLOAT:
+        if (sonicWriteFloatToStream(mSonicStream, (float*)srcBuffer, *srcFrames) != 1) {
+            ALOGE("sonicWriteFloatToStream cannot realloc");
+            *srcFrames = 0; // cannot consume all of srcBuffer
         }
+        *dstFrames = sonicReadFloatFromStream(mSonicStream, (float*)dstBuffer, *dstFrames);
+        break;
+    case AUDIO_FORMAT_PCM_16_BIT:
+        if (sonicWriteShortToStream(mSonicStream, (short*)srcBuffer, *srcFrames) != 1) {
+            ALOGE("sonicWriteShortToStream cannot realloc");
+            *srcFrames = 0; // cannot consume all of srcBuffer
+        }
+        *dstFrames = sonicReadShortFromStream(mSonicStream, (short*)dstBuffer, *dstFrames);
+        break;
+    default:
+        // could also be caught on construction
+        LOG_ALWAYS_FATAL("invalid format %#x for TimestretchBufferProvider", mFormat);
     }
 }