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/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 0e2e48c..ba47172 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -45,7 +45,8 @@
     frameworks/av/services/mediaresourcemanager \
     $(call include-path-for, audio-utils) \
     frameworks/av/services/soundtrigger \
-    frameworks/av/services/radio
+    frameworks/av/services/radio \
+    external/sonic
 
 LOCAL_MODULE:= mediaserver
 LOCAL_32_BIT_ONLY := true
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index f8446ac..c359be5 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -50,6 +50,7 @@
 
 LOCAL_C_INCLUDES := \
     $(TOPDIR)frameworks/av/services/audiopolicy \
+    $(TOPDIR)external/sonic \
     $(call include-path-for, audio-effects) \
     $(call include-path-for, audio-utils)
 
@@ -68,7 +69,8 @@
     libhardware_legacy \
     libeffects \
     libpowermanager \
-    libserviceutility
+    libserviceutility \
+    libsonic
 
 LOCAL_STATIC_LIBRARIES := \
     libscheduling_policy \
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);
     }
 }
 
diff --git a/services/audioflinger/BufferProviders.h b/services/audioflinger/BufferProviders.h
index 2b6ea47..42030c0 100644
--- a/services/audioflinger/BufferProviders.h
+++ b/services/audioflinger/BufferProviders.h
@@ -23,6 +23,7 @@
 #include <hardware/audio_effect.h>
 #include <media/AudioBufferProvider.h>
 #include <system/audio.h>
+#include <sonic.h>
 
 namespace android {
 
@@ -183,6 +184,7 @@
     size_t               mLocalBufferFrameCount;
     void                *mLocalBufferData;
     size_t               mRemaining;
+    sonicStream          mSonicStream;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/services/audioflinger/tests/Android.mk b/services/audioflinger/tests/Android.mk
index 76997be..536eb93 100644
--- a/services/audioflinger/tests/Android.mk
+++ b/services/audioflinger/tests/Android.mk
@@ -44,7 +44,8 @@
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, audio-effects) \
 	$(call include-path-for, audio-utils) \
-	frameworks/av/services/audioflinger
+	frameworks/av/services/audioflinger \
+	external/sonic
 
 LOCAL_STATIC_LIBRARIES := \
 	libsndfile
@@ -58,7 +59,8 @@
 	libdl \
 	libcutils \
 	libutils \
-	liblog
+	liblog \
+	libsonic
 
 LOCAL_MODULE:= test-mixer