Biquad filter integration to LVM : Reverb changes

Bug: 120944950
Test: reverb_test with lvm/tests/build_and_run_all_unit_tests_reverb.sh
Change-Id: I9bb7f639629808055a58b47785f58793fa822071
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index dbe0d62..34cad1f 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -204,10 +204,12 @@
         "Reverb/lib",
         "Common/lib",
     ],
-
+    static_libs: [
+        "libaudioutils",
+    ],
     cppflags: [
+        "-DBIQUAD_OPT",
         "-fvisibility=hidden",
-
         "-Wall",
         "-Werror",
     ],
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
index 737ef01..be846eb 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
@@ -20,6 +20,10 @@
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
+
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVREV_Private.h"
 #include "Filter.h"
 
@@ -71,10 +75,17 @@
 
         Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
         LVM_FO_HPF(Omega, &Coeffs);
+#ifdef BIQUAD_OPT
+        const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+        pPrivate->pRevHPFBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->HPCoefs, &pPrivate->pFastData->HPTaps,
                                         &Coeffs);
         LoadConst_Float(0, (LVM_FLOAT*)&pPrivate->pFastData->HPTaps,
                         sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+#endif
     }
 
     /*
@@ -99,10 +110,17 @@
                 LVM_FO_LPF(Omega, &Coeffs);
             }
         }
+#ifdef BIQUAD_OPT
+        const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+        pPrivate->pRevLPFBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->LPCoefs, &pPrivate->pFastData->LPTaps,
                                         &Coeffs);
         LoadConst_Float(0, (LVM_FLOAT*)&pPrivate->pFastData->LPTaps,
                         sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+#endif
     }
 
     /*
@@ -231,8 +249,15 @@
                 Coeffs.A1 = 0;
                 Coeffs.B1 = 0;
             }
+#ifdef BIQUAD_OPT
+            const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                    Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+            pPrivate->revLPFBiquad[i].reset(
+                    new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
             FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i],
                                             &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
+#endif
         }
     }
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
index 5c83ce5..f542a2b 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
@@ -56,13 +56,24 @@
      * Clear all filter tap data, delay-lines and other signal related data
      */
 
+#ifdef BIQUAD_OPT
+    pLVREV_Private->pRevHPFBiquad->clear();
+    pLVREV_Private->pRevLPFBiquad->clear();
+#else
     LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->HPTaps, 2);
     LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->LPTaps, 2);
+#endif
     if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4) {
+#ifdef BIQUAD_OPT
+        for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
+            pLVREV_Private->revLPFBiquad[i]->clear();
+        }
+#else
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+#endif
 
         LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
         LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
@@ -71,15 +82,25 @@
     }
 
     if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_2) {
+#ifdef BIQUAD_OPT
+        for (int i = 0; i < LVREV_DELAYLINES_2; i++) {
+            pLVREV_Private->revLPFBiquad[i]->clear();
+        }
+#else
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+#endif
 
         LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
         LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
     }
 
     if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_1) {
+#ifdef BIQUAD_OPT
+        pLVREV_Private->revLPFBiquad[0]->clear();
+#else
         LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+#endif
         LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
     }
     return LVREV_SUCCESS;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
index b5db23b..6ed0605 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
@@ -134,9 +134,11 @@
     /*
      * Set the data, coefficient and temporary memory pointers
      */
+#ifndef BIQUAD_OPT
     /* Fast data memory base address */
     pLVREV_Private->pFastData =
             (LVREV_FastData_st*)InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
+#endif
     if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
         pLVREV_Private->pDelay_T[3] =
                 (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
@@ -194,9 +196,11 @@
     pLVREV_Private->T[3] = LVREV_MAX_T3_DELAY;
     pLVREV_Private->AB_Selection = 1; /* Select smoothing A to B */
 
+#ifndef BIQUAD_OPT
     /* Fast coefficient memory base address */
     pLVREV_Private->pFastCoef =
             (LVREV_FastCoef_st*)InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
+#endif
     /* General purpose scratch */
     pLVREV_Private->pScratch =
             (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
@@ -308,6 +312,17 @@
     pLVREV_Private->A_DelaySize[3] = LVREV_MAX_AP3_DELAY;
     pLVREV_Private->B_DelaySize[3] = LVREV_MAX_AP3_DELAY;
 
+#ifdef BIQUAD_OPT
+    pLVREV_Private->pRevHPFBiquad.reset(
+            new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    pLVREV_Private->pRevLPFBiquad.reset(
+            new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
+        pLVREV_Private->revLPFBiquad[i].reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    }
+#endif
+
     LVREV_ClearAudioBuffers(*phInstance);
 
     return LVREV_SUCCESS;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
index 2c1e04d..e8b2019 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
@@ -139,7 +139,9 @@
         /*
          * Persistent fast data memory
          */
+#ifndef BIQUAD_OPT
         InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
+#endif
         if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
             InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
             InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
@@ -163,7 +165,9 @@
         /*
          * Persistent fast coefficient memory
          */
+#ifndef BIQUAD_OPT
         InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
+#endif
         pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size = InstAlloc_GetTotal(&FastCoef);
         pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Type = LVM_PERSISTENT_FAST_COEF;
         pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index b6edb03..e52a1ca 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -23,6 +23,10 @@
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
+
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVREV.h"
 #include "LVREV_Tables.h"
 #include "BIQUAD.h"
@@ -101,12 +105,12 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifndef BIQUAD_OPT
 /* Fast data structure */
 typedef struct {
     Biquad_1I_Order1_FLOAT_Taps_t HPTaps;       /* High pass filter taps */
     Biquad_1I_Order1_FLOAT_Taps_t LPTaps;       /* Low pass filter taps */
     Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[4]; /* Reverb low pass filters taps */
-
 } LVREV_FastData_st;
 
 /* Fast coefficient structure */
@@ -114,8 +118,9 @@
     Biquad_FLOAT_Instance_t HPCoefs;       /* High pass filter coefficients */
     Biquad_FLOAT_Instance_t LPCoefs;       /* Low pass filter coefficients */
     Biquad_FLOAT_Instance_t RevLPCoefs[4]; /* Reverb low pass filters coefficients */
-
 } LVREV_FastCoef_st;
+#endif
+
 typedef struct {
     /* General */
     LVREV_InstanceParams_st InstanceParams; /* Initialisation time instance parameters */
@@ -134,8 +139,17 @@
                                                processing */
 
     /* Aligned memory pointers */
-    LVREV_FastData_st* pFastData;    /* Fast data memory base address */
-    LVREV_FastCoef_st* pFastCoef;    /* Fast coefficient memory base address */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pRevHPFBiquad; /* Biquad filter instance for HPF */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pRevLPFBiquad; /* Biquad filter instance for LPF */
+    std::array<std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>, LVREV_DELAYLINES_4>
+            revLPFBiquad; /* Biquad filter instance for Reverb LPF */
+#else
+    LVREV_FastData_st* pFastData; /* Fast data memory base address */
+    LVREV_FastCoef_st* pFastCoef; /* Fast coefficient memory base address */
+#endif
     LVM_FLOAT* pScratchDelayLine[4]; /* Delay line scratch memory */
     LVM_FLOAT* pScratch;             /* Multi ussge scratch */
     LVM_FLOAT* pInputSave;           /* Reverb block input save for dry/wet
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
index ed3b89c..e4f939f 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
@@ -204,11 +204,20 @@
     /*
      *  High pass filter
      */
+#ifdef BIQUAD_OPT
+    pPrivate->pRevHPFBiquad->process(pTemp, pTemp, NumSamples);
+#else
     FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->HPCoefs, pTemp, pTemp, (LVM_INT16)NumSamples);
+#endif
+
     /*
      *  Low pass filter
      */
+#ifdef BIQUAD_OPT
+    pPrivate->pRevLPFBiquad->process(pTemp, pTemp, NumSamples);
+#else
     FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->LPCoefs, pTemp, pTemp, (LVM_INT16)NumSamples);
+#endif
 
     /*
      *  Process all delay lines
@@ -253,8 +262,12 @@
         /*
          *  Low pass filter
          */
+#ifdef BIQUAD_OPT
+        pPrivate->revLPFBiquad[j]->process(pDelayLine, pDelayLine, NumSamples);
+#else
         FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->RevLPCoefs[j], pDelayLine, pDelayLine,
                                    (LVM_INT16)NumSamples);
+#endif
     }
 
     /*