Merge "Added WriterFuzzerBase class"
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 677f316..f3341ab 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -1061,11 +1061,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAacDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index 2e85915..ea76cbb 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -692,11 +692,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAacEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
index f7943be..c08e02b 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
@@ -420,11 +420,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAMRDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
index e2d8cb6..bb63e1f 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
@@ -337,11 +337,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAmrNbEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
index 84ae4b7..84728ae 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
@@ -411,11 +411,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAmrWbEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index 9ba3b697..c08cd59 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -800,11 +800,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAomFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
index 6b0e363..9f8bc68 100644
--- a/media/codec2/components/avc/Android.bp
+++ b/media/codec2/components/avc/Android.bp
@@ -3,7 +3,8 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_signed-defaults",
-   ],
+        "libcodec2_soft_sanitize_cfi-defaults",
+    ],
 
     static_libs: ["libavcdec"],
 
@@ -20,7 +21,8 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_signed-defaults",
-   ],
+        "libcodec2_soft_sanitize_cfi-defaults",
+    ],
 
     static_libs: ["libavcenc"],
 
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 3afd670..0207311 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -1049,11 +1049,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAvcDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index ab93ce3..cfaeb66 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -1756,11 +1756,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAvcEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index 3712564..0c8f4a4 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -20,7 +20,7 @@
 
     shared_libs: [
         "libcutils", // for properties
-        "liblog",    // for ALOG
+        "liblog", // for ALOG
         "libsfplugin_ccodec_utils", // for ImageCopy
         "libstagefright_foundation", // for Mutexed
     ],
@@ -38,7 +38,7 @@
 
 filegroup {
     name: "codec2_soft_exports",
-    srcs: [ "exports.lds" ],
+    srcs: ["exports.lds"],
 }
 
 // public dependency for software codec implementation
@@ -91,7 +91,20 @@
         misc_undefined: [
             "signed-integer-overflow",
         ],
+    },
+}
+
+cc_defaults {
+    name: "libcodec2_soft_sanitize_cfi-defaults",
+
+    sanitize: {
         cfi: true,
+        config: {
+            cfi_assembly_support: true,
+        },
+        diag: {
+            cfi: true,
+        },
     },
 }
 
@@ -131,4 +144,3 @@
 
     ldflags: ["-Wl,-Bsymbolic"],
 }
-
diff --git a/media/codec2/components/flac/C2SoftFlacDec.cpp b/media/codec2/components/flac/C2SoftFlacDec.cpp
index 4039b9b..e70c289 100644
--- a/media/codec2/components/flac/C2SoftFlacDec.cpp
+++ b/media/codec2/components/flac/C2SoftFlacDec.cpp
@@ -367,11 +367,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftFlacDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.cpp b/media/codec2/components/flac/C2SoftFlacEnc.cpp
index 408db7e..1c0babd 100644
--- a/media/codec2/components/flac/C2SoftFlacEnc.cpp
+++ b/media/codec2/components/flac/C2SoftFlacEnc.cpp
@@ -481,11 +481,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftFlacEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/g711/C2SoftG711Dec.cpp b/media/codec2/components/g711/C2SoftG711Dec.cpp
index 7f9c34e..f9299af 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.cpp
+++ b/media/codec2/components/g711/C2SoftG711Dec.cpp
@@ -259,11 +259,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftG711DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index a1929e7..76345ae 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -770,11 +770,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory *CreateCodec2Factory() {
   ALOGV("in %s", __func__);
   return new ::android::C2SoftGav1Factory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory *factory) {
   ALOGV("in %s", __func__);
   delete factory;
diff --git a/media/codec2/components/gsm/C2SoftGsmDec.cpp b/media/codec2/components/gsm/C2SoftGsmDec.cpp
index 287cfc6..977677d 100644
--- a/media/codec2/components/gsm/C2SoftGsmDec.cpp
+++ b/media/codec2/components/gsm/C2SoftGsmDec.cpp
@@ -294,11 +294,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftGSMDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 23104dc..56dd26b 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -1048,11 +1048,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftHevcDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index c2d2540..436a2c4 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -1078,11 +1078,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftHevcEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
index 5ba7e3d..7137767 100644
--- a/media/codec2/components/mp3/C2SoftMp3Dec.cpp
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -539,11 +539,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMp3DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 55dd475..82c061a 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -1113,11 +1113,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMpeg2DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index 13cc0ec..a7cc037 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -747,11 +747,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMpeg4DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 54c8c47..e1cc6b3 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -652,11 +652,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMpeg4EncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/opus/C2SoftOpusDec.cpp b/media/codec2/components/opus/C2SoftOpusDec.cpp
index b7c1556..d4987c0 100644
--- a/media/codec2/components/opus/C2SoftOpusDec.cpp
+++ b/media/codec2/components/opus/C2SoftOpusDec.cpp
@@ -473,11 +473,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftOpusDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 70d1965..b47275f 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -626,11 +626,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftOpusEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/raw/C2SoftRawDec.cpp b/media/codec2/components/raw/C2SoftRawDec.cpp
index 7b6f21a..31ca705 100644
--- a/media/codec2/components/raw/C2SoftRawDec.cpp
+++ b/media/codec2/components/raw/C2SoftRawDec.cpp
@@ -215,11 +215,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftRawDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
index a8b5377..899fe9b 100644
--- a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -477,11 +477,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVorbisDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVp8Enc.cpp b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
index f18f5d0..049ec38 100644
--- a/media/codec2/components/vpx/C2SoftVp8Enc.cpp
+++ b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
@@ -101,11 +101,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVp8EncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVp9Enc.cpp b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
index 740dbda..6401521 100644
--- a/media/codec2/components/vpx/C2SoftVp9Enc.cpp
+++ b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
@@ -131,11 +131,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVp9EncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 91238e8..2953d90 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -948,11 +948,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVpxFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/xaac/Android.bp b/media/codec2/components/xaac/Android.bp
index 4889d78..9b7e2de 100644
--- a/media/codec2/components/xaac/Android.bp
+++ b/media/codec2/components/xaac/Android.bp
@@ -3,6 +3,7 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_all-defaults",
+	"libcodec2_soft_sanitize_cfi-defaults",
     ],
 
     srcs: ["C2SoftXaacDec.cpp"],
diff --git a/media/codec2/components/xaac/C2SoftXaacDec.cpp b/media/codec2/components/xaac/C2SoftXaacDec.cpp
index 951d058..6deafda 100644
--- a/media/codec2/components/xaac/C2SoftXaacDec.cpp
+++ b/media/codec2/components/xaac/C2SoftXaacDec.cpp
@@ -1600,11 +1600,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftXaacDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/fuzzer/Android.bp b/media/codec2/fuzzer/Android.bp
new file mode 100644
index 0000000..2de400d
--- /dev/null
+++ b/media/codec2/fuzzer/Android.bp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_defaults {
+    name: "C2Fuzzer-defaults",
+
+    srcs: [
+        "C2Fuzzer.cpp",
+    ],
+
+    static_libs: [
+        "liblog",
+        "libion",
+        "libfmq",
+        "libbase",
+        "libutils",
+        "libcutils",
+        "libcodec2",
+        "libhidlbase",
+        "libdmabufheap",
+        "libcodec2_vndk",
+        "libnativewindow",
+        "libcodec2_soft_common",
+        "libsfplugin_ccodec_utils",
+        "libstagefright_foundation",
+        "libstagefright_bufferpool@2.0.1",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.media.bufferpool@2.0",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.bufferqueue@2.0",
+    ],
+
+    shared_libs: [
+        "libui",
+        "libdl",
+        "libbinder",
+        "libhardware",
+        "libvndksupport",
+        "libprocessgroup",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerAvcDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.avc.decoder\"",
+    ],
+
+    static_libs: [
+        "libavcdec",
+        "libcodec2_soft_avcdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerHevcDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.hevc.decoder\"",
+    ],
+
+    static_libs: [
+        "libhevcdec",
+        "libcodec2_soft_hevcdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerMpeg2Dec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.mpeg2.decoder\"",
+    ],
+
+    static_libs: [
+        "libmpeg2dec",
+        "libcodec2_soft_mpeg2dec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerMpeg4Dec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.mpeg4.decoder\"",
+    ],
+
+    static_libs: [
+        "libstagefright_m4vh263dec",
+        "libcodec2_soft_mpeg4dec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerH263Dec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.h263.decoder\"",
+    ],
+
+    static_libs: [
+        "libstagefright_m4vh263dec",
+        "libcodec2_soft_h263dec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerVp8Dec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.vp8.decoder\"",
+    ],
+
+    static_libs: [
+        "libvpx",
+        "libcodec2_soft_vp8dec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerVp9Dec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.vp9.decoder\"",
+    ],
+
+    static_libs: [
+        "libvpx",
+        "libcodec2_soft_vp9dec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerAacDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.aac.decoder\"",
+    ],
+
+    static_libs: [
+        "libFraunhoferAAC",
+        "libcodec2_soft_aacdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerAmrnbDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.amrnb.decoder\"",
+    ],
+
+    static_libs: [
+        "libstagefright_amrnbdec",
+        "libstagefright_amrwbdec",
+        "libstagefright_amrnb_common",
+        "libcodec2_soft_amrnbdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerAmrwbDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.amrwb.decoder\"",
+    ],
+
+    static_libs: [
+        "libstagefright_amrnbdec",
+        "libstagefright_amrwbdec",
+        "libstagefright_amrnb_common",
+        "libcodec2_soft_amrwbdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerFlacDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.flac.decoder\"",
+    ],
+
+    static_libs: [
+        "libFLAC",
+        "libstagefright_flacdec",
+        "libcodec2_soft_flacdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerG711AlawDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.g711.alaw.decoder\"",
+    ],
+
+    static_libs: [
+        "codecs_g711dec",
+        "libcodec2_soft_g711alawdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerG711MlawDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.g711.mlaw.decoder\"",
+    ],
+
+    static_libs: [
+        "codecs_g711dec",
+        "libcodec2_soft_g711mlawdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerGsmDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.gsm.decoder\"",
+    ],
+
+    static_libs: [
+        "libgsm",
+        "libcodec2_soft_gsmdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerMp3Dec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.mp3.decoder\"",
+    ],
+
+    static_libs: [
+        "libstagefright_mp3dec",
+        "libcodec2_soft_mp3dec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerOpusDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.opus.decoder\"",
+    ],
+
+    static_libs: [
+        "libopus",
+        "libcodec2_soft_opusdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerRawDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.raw.decoder\"",
+    ],
+
+    static_libs: [
+        "libcodec2_soft_rawdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerVorbisDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.vorbis.decoder\"",
+    ],
+
+    static_libs: [
+        "libvorbisidec",
+        "libcodec2_soft_vorbisdec",
+    ],
+}
+
+cc_fuzz {
+    name: "C2FuzzerXaacDec",
+    defaults: ["C2Fuzzer-defaults"],
+
+    cflags: [
+        "-DC2COMPONENTNAME=\"c2.android.xaac.decoder\"",
+    ],
+
+    static_libs: [
+        "libxaacdec",
+        "libcodec2_soft_xaacdec",
+    ],
+}
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
new file mode 100644
index 0000000..71956a2
--- /dev/null
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -0,0 +1,318 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <stdio.h>
+
+#include <C2Fuzzer.h>
+
+using namespace android;
+
+class LinearBuffer : public C2Buffer {
+ public:
+  explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+      : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
+
+  explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block, size_t size)
+      : C2Buffer({block->share(block->offset(), size, ::C2Fence())}) {}
+};
+
+/**
+ * Handle Callback functions onWorkDone_nb(), onTripped_nb(), onError_nb() for C2 Components
+ */
+struct CodecListener : public C2Component::Listener {
+ public:
+  CodecListener(const std::function<void(std::weak_ptr<C2Component> comp,
+                                         std::list<std::unique_ptr<C2Work>>& workItems)>
+                    fn = nullptr)
+      : callBack(fn) {}
+  virtual void onWorkDone_nb(const std::weak_ptr<C2Component> comp,
+                             std::list<std::unique_ptr<C2Work>> workItems) {
+    if (callBack) {
+      callBack(comp, workItems);
+    }
+  }
+
+  virtual void onTripped_nb(const std::weak_ptr<C2Component> comp,
+                            const std::vector<std::shared_ptr<C2SettingResult>> settingResults) {
+    (void)comp;
+    (void)settingResults;
+  }
+
+  virtual void onError_nb(const std::weak_ptr<C2Component> comp, uint32_t errorCode) {
+    (void)comp;
+    (void)errorCode;
+  }
+
+  std::function<void(std::weak_ptr<C2Component> comp,
+                     std::list<std::unique_ptr<C2Work>>& workItems)> callBack;
+};
+
+/**
+ * Buffer source implementations to identify a frame and its size
+ */
+bool Codec2Fuzzer::BufferSource::searchForMarker() {
+  while (true) {
+    if (isMarker()) {
+      return true;
+    }
+    --mReadIndex;
+    if (mReadIndex > mSize) {
+      break;
+    }
+  }
+  return false;
+}
+
+void Codec2Fuzzer::BufferSource::parse() {
+  bool isFrameAvailable = true;
+  size_t bytesRemaining = mSize;
+  while (isFrameAvailable) {
+    isFrameAvailable = searchForMarker();
+    if (isFrameAvailable) {
+      size_t location = mReadIndex + kMarkerSize;
+      bool isCSD = isCSDMarker(location);
+      location += kMarkerSuffixSize;
+      uint8_t* framePtr = const_cast<uint8_t*>(&mData[location]);
+      size_t frameSize = bytesRemaining - location;
+      uint32_t flags = 0;
+      if (mFrameList.empty()) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+      } else if (isCSD) {
+        flags |= C2FrameData::FLAG_CODEC_CONFIG;
+      }
+      mFrameList.emplace_back(std::make_tuple(framePtr, frameSize, flags));
+      bytesRemaining -= (frameSize + kMarkerSize + kMarkerSuffixSize);
+      --mReadIndex;
+    }
+  }
+  if (mFrameList.empty()) {
+    /**
+     * Scenario where input data does not contain the custom frame markers.
+     * Hence feed the entire data as single frame.
+     */
+    mFrameList.emplace_back(
+        std::make_tuple(const_cast<uint8_t*>(mData), 0, C2FrameData::FLAG_END_OF_STREAM));
+    mFrameList.emplace_back(
+        std::make_tuple(const_cast<uint8_t*>(mData), mSize, C2FrameData::FLAG_CODEC_CONFIG));
+  }
+}
+
+FrameData Codec2Fuzzer::BufferSource::getFrame() {
+  FrameData frame = mFrameList.back();
+  mFrameList.pop_back();
+  return frame;
+}
+
+void Codec2Fuzzer::handleWorkDone(std::weak_ptr<C2Component> comp,
+                                  std::list<std::unique_ptr<C2Work>>& workItems) {
+  (void)comp;
+  for (std::unique_ptr<C2Work>& work : workItems) {
+    if (!work->worklets.empty()) {
+      if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
+        mEos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+        work->input.buffers.clear();
+        work->worklets.clear();
+        {
+          std::unique_lock<std::mutex> lock(mQueueLock);
+          mWorkQueue.push_back(std::move(work));
+          mQueueCondition.notify_all();
+        }
+        if (mEos) {
+          {
+            std::lock_guard<std::mutex> waitForDecodeComplete(mDecodeCompleteMutex);
+          }
+          mConditionalVariable.notify_one();
+        }
+      }
+    }
+  }
+}
+
+bool Codec2Fuzzer::initDecoder() {
+  std::vector<std::tuple<C2String, C2ComponentFactory::CreateCodec2FactoryFunc,
+        C2ComponentFactory::DestroyCodec2FactoryFunc>> codec2FactoryFunc;
+
+  codec2FactoryFunc.emplace_back(std::make_tuple(C2COMPONENTNAME,
+                                                &CreateCodec2Factory,
+                                                &DestroyCodec2Factory));
+
+  std::shared_ptr<C2ComponentStore> componentStore = GetTestComponentStore(codec2FactoryFunc);
+  if (!componentStore) {
+    return false;
+  }
+
+  std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+  if (!allocatorStore) {
+    return false;
+  }
+
+  c2_status_t status =
+      allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator);
+  if (status != C2_OK) {
+    return false;
+  }
+
+  mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, ++mBlockPoolId);
+  if (!mLinearPool) {
+    return false;
+  }
+
+  for (int32_t i = 0; i < kNumberOfC2WorkItems; ++i) {
+    mWorkQueue.emplace_back(new C2Work);
+  }
+
+  status = componentStore->createComponent(C2COMPONENTNAME, &mComponent);
+  if (status != C2_OK) {
+    return false;
+  }
+
+  status = componentStore->createInterface(C2COMPONENTNAME, &mInterface);
+  if (status != C2_OK) {
+    return false;
+  }
+
+  C2ComponentKindSetting kind;
+  C2ComponentDomainSetting domain;
+  status = mInterface->query_vb({&kind, &domain}, {}, C2_MAY_BLOCK, nullptr);
+  if (status != C2_OK) {
+    return false;
+  }
+
+  std::vector<C2Param*> configParams;
+  if (domain.value == DOMAIN_VIDEO) {
+    C2StreamPictureSizeInfo::input inputSize(0u, kWidthOfVideo, kHeightOfVideo);
+    configParams.push_back(&inputSize);
+  } else if (domain.value == DOMAIN_AUDIO) {
+    C2StreamSampleRateInfo::output sampleRateInfo(0u, kSamplingRateOfAudio);
+    C2StreamChannelCountInfo::output channelCountInfo(0u, kChannelsOfAudio);
+    configParams.push_back(&sampleRateInfo);
+    configParams.push_back(&channelCountInfo);
+  }
+
+  mListener.reset(new CodecListener(
+      [this](std::weak_ptr<C2Component> comp, std::list<std::unique_ptr<C2Work>>& workItems) {
+        handleWorkDone(comp, workItems);
+      }));
+  if (!mListener) {
+    return false;
+  }
+
+  status = mComponent->setListener_vb(mListener, C2_DONT_BLOCK);
+  if (status != C2_OK) {
+    return false;
+  }
+
+  std::vector<std::unique_ptr<C2SettingResult>> failures;
+  componentStore->config_sm(configParams, &failures);
+  if (failures.size() != 0) {
+    return false;
+  }
+
+  status = mComponent->start();
+  if (status != C2_OK) {
+    return false;
+  }
+
+  return true;
+}
+
+void Codec2Fuzzer::deInitDecoder() {
+  mComponent->stop();
+  mComponent->reset();
+  mComponent->release();
+  mComponent = nullptr;
+}
+
+void Codec2Fuzzer::decodeFrames(const uint8_t* data, size_t size) {
+  mBufferSource = new BufferSource(data, size);
+  if (!mBufferSource) {
+    return;
+  }
+  mBufferSource->parse();
+  c2_status_t status = C2_OK;
+  size_t numFrames = 0;
+  while (!mBufferSource->isEos()) {
+    uint8_t* frame = nullptr;
+    size_t frameSize = 0;
+    FrameData frameData = mBufferSource->getFrame();
+    frame = std::get<0>(frameData);
+    frameSize = std::get<1>(frameData);
+
+    std::unique_ptr<C2Work> work;
+    {
+      std::unique_lock<std::mutex> lock(mQueueLock);
+      if (mWorkQueue.empty()) mQueueCondition.wait_for(lock, kC2FuzzerTimeOut);
+      if (!mWorkQueue.empty()) {
+        work.swap(mWorkQueue.front());
+        mWorkQueue.pop_front();
+      } else {
+        return;
+      }
+    }
+
+    work->input.flags = (C2FrameData::flags_t)std::get<2>(frameData);
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = ++numFrames;
+    work->input.buffers.clear();
+    int32_t alignedSize = C2FUZZER_ALIGN(frameSize, PAGE_SIZE);
+
+    std::shared_ptr<C2LinearBlock> block;
+    status = mLinearPool->fetchLinearBlock(
+        alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
+    if (status != C2_OK || block == nullptr) {
+      return;
+    }
+
+    C2WriteView view = block->map().get();
+    if (view.error() != C2_OK) {
+      return;
+    }
+    memcpy(view.base(), frame, frameSize);
+    work->input.buffers.emplace_back(new LinearBuffer(block, frameSize));
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    status = mComponent->queue_nb(&items);
+    if (status != C2_OK) {
+      return;
+    }
+  }
+  std::unique_lock<std::mutex> waitForDecodeComplete(mDecodeCompleteMutex);
+  mConditionalVariable.wait_for(waitForDecodeComplete, kC2FuzzerTimeOut, [this] { return mEos; });
+  std::list<std::unique_ptr<C2Work>> c2flushedWorks;
+  mComponent->flush_sm(C2Component::FLUSH_COMPONENT, &c2flushedWorks);
+  delete mBufferSource;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if (size < 1) {
+    return 0;
+  }
+  Codec2Fuzzer* codec = new Codec2Fuzzer();
+  if (!codec) {
+    return 0;
+  }
+  if (codec->initDecoder()) {
+    codec->decodeFrames(data, size);
+  }
+  delete codec;
+  return 0;
+}
diff --git a/media/codec2/fuzzer/C2Fuzzer.h b/media/codec2/fuzzer/C2Fuzzer.h
new file mode 100644
index 0000000..2efad50
--- /dev/null
+++ b/media/codec2/fuzzer/C2Fuzzer.h
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#ifndef __C2FUZZER_H__
+#define __C2FUZZER_H__
+
+#include <C2AllocatorIon.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2PlatformSupport.h>
+
+using namespace std::chrono_literals;
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory();
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory);
+
+namespace android {
+
+#define C2FUZZER_ALIGN(_sz, _align) (((_sz) + ((_align)-1)) & ~((_align)-1))
+
+constexpr std::chrono::milliseconds kC2FuzzerTimeOut = 5000ms;
+constexpr int32_t kNumberOfC2WorkItems = 8;
+constexpr uint32_t kWidthOfVideo = 3840;
+constexpr uint32_t kHeightOfVideo = 2160;
+constexpr uint32_t kSamplingRateOfAudio = 48000;
+constexpr uint32_t kChannelsOfAudio = 8;
+
+typedef std::tuple<uint8_t*, size_t, uint32_t> FrameData;
+
+class Codec2Fuzzer {
+ public:
+  Codec2Fuzzer() = default;
+  ~Codec2Fuzzer() { deInitDecoder(); }
+  bool initDecoder();
+  void deInitDecoder();
+  void decodeFrames(const uint8_t* data, size_t size);
+
+  void handleWorkDone(std::weak_ptr<C2Component> comp,
+                      std::list<std::unique_ptr<C2Work>>& workItems);
+
+ private:
+  class BufferSource {
+   public:
+    BufferSource(const uint8_t* data, size_t size)
+        : mData(data), mSize(size), mReadIndex(size - kMarkerSize) {}
+    ~BufferSource() {
+      mData = nullptr;
+      mSize = 0;
+      mReadIndex = 0;
+      mFrameList.clear();
+    }
+    bool isEos() { return mFrameList.empty(); }
+    void parse();
+    FrameData getFrame();
+
+   private:
+    bool isMarker() { return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0); }
+
+    bool isCSDMarker(size_t position) {
+      return (memcmp(&mData[position], kCsdMarkerSuffix, kMarkerSuffixSize) == 0);
+    }
+
+    bool searchForMarker();
+
+    const uint8_t* mData = nullptr;
+    size_t mSize = 0;
+    size_t mReadIndex = 0;
+    std::vector<FrameData> mFrameList;
+    static constexpr uint8_t kMarker[] = "_MARK";
+    static constexpr uint8_t kCsdMarkerSuffix[] = "_H_";
+    static constexpr uint8_t kFrameMarkerSuffix[] = "_F_";
+    // All markers should be 5 bytes long ( sizeof '_MARK' which is 5)
+    static constexpr size_t kMarkerSize = (sizeof(kMarker) - 1);
+    // All marker types should be 3 bytes long ('_H_', '_F_')
+    static constexpr size_t kMarkerSuffixSize = 3;
+  };
+
+  BufferSource* mBufferSource;
+  bool mEos = false;
+  C2BlockPool::local_id_t mBlockPoolId;
+
+  std::shared_ptr<C2BlockPool> mLinearPool;
+  std::shared_ptr<C2Allocator> mLinearAllocator;
+  std::shared_ptr<C2Component::Listener> mListener;
+  std::shared_ptr<C2Component> mComponent;
+  std::shared_ptr<C2ComponentInterface> mInterface;
+  std::mutex mQueueLock;
+  std::condition_variable mQueueCondition;
+  std::list<std::unique_ptr<C2Work>> mWorkQueue;
+  std::mutex mDecodeCompleteMutex;
+  std::condition_variable mConditionalVariable;
+};
+
+}  // namespace android
+
+#endif  // __C2FUZZER_H__
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 57252b2..ab7c9af 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -247,15 +247,20 @@
             return NO_INIT;
         }
 
-        size_t numSlots = 4;
-        constexpr OMX_U32 kPortIndexInput = 0;
+        size_t numSlots = 16;
+        // WORKAROUND: having more slots improve performance while consuming
+        // more memory. This is a temporary workaround to reduce memory for
+        // larger-than-4K scenario.
+        if (mWidth * mHeight > 4096 * 2340) {
+            constexpr OMX_U32 kPortIndexInput = 0;
 
-        OMX_PARAM_PORTDEFINITIONTYPE param;
-        param.nPortIndex = kPortIndexInput;
-        status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
-                                           &param, sizeof(param));
-        if (err == OK) {
-            numSlots = param.nBufferCountActual;
+            OMX_PARAM_PORTDEFINITIONTYPE param;
+            param.nPortIndex = kPortIndexInput;
+            status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
+                                               &param, sizeof(param));
+            if (err == OK) {
+                numSlots = param.nBufferCountActual;
+            }
         }
 
         for (size_t i = 0; i < numSlots; ++i) {
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 1e907c1..499ab72 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -622,6 +622,12 @@
             std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
     C2PlatformComponentStore();
 
+    // For testing only
+    C2PlatformComponentStore(
+            std::vector<std::tuple<C2String,
+                                   C2ComponentFactory::CreateCodec2FactoryFunc,
+                                   C2ComponentFactory::DestroyCodec2FactoryFunc>>);
+
     virtual ~C2PlatformComponentStore() override = default;
 
 private:
@@ -662,6 +668,24 @@
         }
 
         /**
+         * Creates an uninitialized component module.
+         * NOTE: For testing only
+         *
+         * \param name[in]  component name.
+         *
+         * \note Only used by ComponentLoader.
+         */
+        ComponentModule(
+                C2ComponentFactory::CreateCodec2FactoryFunc createFactory,
+                C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory)
+            : mInit(C2_NO_INIT),
+              mLibHandle(nullptr),
+              createFactory(createFactory),
+              destroyFactory(destroyFactory),
+              mComponentFactory(nullptr) {
+        }
+
+        /**
          * Initializes a component module with a given library path. Must be called exactly once.
          *
          * \note Only used by ComponentLoader.
@@ -717,7 +741,13 @@
             std::lock_guard<std::mutex> lock(mMutex);
             std::shared_ptr<ComponentModule> localModule = mModule.lock();
             if (localModule == nullptr) {
-                localModule = std::make_shared<ComponentModule>();
+                if(mCreateFactory) {
+                    // For testing only
+                    localModule = std::make_shared<ComponentModule>(mCreateFactory,
+                                                                    mDestroyFactory);
+                } else {
+                    localModule = std::make_shared<ComponentModule>();
+                }
                 res = localModule->init(mLibPath);
                 if (res == C2_OK) {
                     mModule = localModule;
@@ -733,10 +763,22 @@
         ComponentLoader(std::string libPath)
             : mLibPath(libPath) {}
 
+        // For testing only
+        ComponentLoader(std::tuple<C2String,
+                          C2ComponentFactory::CreateCodec2FactoryFunc,
+                          C2ComponentFactory::DestroyCodec2FactoryFunc> func)
+            : mLibPath(std::get<0>(func)),
+              mCreateFactory(std::get<1>(func)),
+              mDestroyFactory(std::get<2>(func)) {}
+
     private:
         std::mutex mMutex; ///< mutex guarding the module
         std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
         std::string mLibPath; ///< library path
+
+        // For testing only
+        C2ComponentFactory::CreateCodec2FactoryFunc mCreateFactory = nullptr;
+        C2ComponentFactory::DestroyCodec2FactoryFunc mDestroyFactory = nullptr;
     };
 
     struct Interface : public C2InterfaceHelper {
@@ -846,25 +888,33 @@
 
     std::shared_ptr<C2ReflectorHelper> mReflector;
     Interface mInterface;
+
+    // For testing only
+    std::vector<std::tuple<C2String,
+                          C2ComponentFactory::CreateCodec2FactoryFunc,
+                          C2ComponentFactory::DestroyCodec2FactoryFunc>> mCodec2FactoryFuncs;
 };
 
 c2_status_t C2PlatformComponentStore::ComponentModule::init(
         std::string libPath) {
     ALOGV("in %s", __func__);
     ALOGV("loading dll");
-    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
-    LOG_ALWAYS_FATAL_IF(mLibHandle == nullptr,
-            "could not dlopen %s: %s", libPath.c_str(), dlerror());
 
-    createFactory =
-        (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
-    LOG_ALWAYS_FATAL_IF(createFactory == nullptr,
-            "createFactory is null in %s", libPath.c_str());
+    if(!createFactory) {
+        mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
+        LOG_ALWAYS_FATAL_IF(mLibHandle == nullptr,
+                "could not dlopen %s: %s", libPath.c_str(), dlerror());
 
-    destroyFactory =
-        (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
-    LOG_ALWAYS_FATAL_IF(destroyFactory == nullptr,
-            "destroyFactory is null in %s", libPath.c_str());
+        createFactory =
+            (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
+        LOG_ALWAYS_FATAL_IF(createFactory == nullptr,
+                "createFactory is null in %s", libPath.c_str());
+
+        destroyFactory =
+            (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
+        LOG_ALWAYS_FATAL_IF(destroyFactory == nullptr,
+                "destroyFactory is null in %s", libPath.c_str());
+    }
 
     mComponentFactory = createFactory();
     if (mComponentFactory == nullptr) {
@@ -1065,6 +1115,22 @@
     emplace("libcodec2_soft_vp8enc.so");
     emplace("libcodec2_soft_vp9dec.so");
     emplace("libcodec2_soft_vp9enc.so");
+
+}
+
+// For testing only
+C2PlatformComponentStore::C2PlatformComponentStore(
+    std::vector<std::tuple<C2String,
+                C2ComponentFactory::CreateCodec2FactoryFunc,
+                C2ComponentFactory::DestroyCodec2FactoryFunc>> funcs)
+    : mVisited(false),
+      mReflector(std::make_shared<C2ReflectorHelper>()),
+      mInterface(mReflector),
+      mCodec2FactoryFuncs(funcs) {
+
+    for(auto const& func: mCodec2FactoryFuncs) {
+        mComponents.emplace(std::get<0>(func), func);
+    }
 }
 
 c2_status_t C2PlatformComponentStore::copyBuffer(
@@ -1184,4 +1250,11 @@
     return store;
 }
 
+// For testing only
+std::shared_ptr<C2ComponentStore> GetTestComponentStore(
+        std::vector<std::tuple<C2String,
+        C2ComponentFactory::CreateCodec2FactoryFunc,
+        C2ComponentFactory::DestroyCodec2FactoryFunc>> funcs) {
+    return std::shared_ptr<C2ComponentStore>(new C2PlatformComponentStore(funcs));
+}
 } // namespace android
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
index 4814494..6d351c2 100644
--- a/media/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -144,6 +144,15 @@
 std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore();
 
 /**
+ * Returns the platform component store.
+ * NOTE: For testing only
+ * \retval nullptr if the platform component store could not be obtained
+ */
+std::shared_ptr<C2ComponentStore> GetTestComponentStore(
+        std::vector<std::tuple<C2String, C2ComponentFactory::CreateCodec2FactoryFunc,
+        C2ComponentFactory::DestroyCodec2FactoryFunc>>);
+
+/**
  * Sets the preferred component store in this process for the sole purpose of accessing its
  * interface. If this is not called, the default IComponentStore HAL (if exists) is the preferred
  * store for this purpose. If the default IComponentStore HAL is not present, the platform
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index d19447a..901b29d 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -95,9 +95,9 @@
     AMediaFormat *mMeta;
     uint16_t mWaveFormat;
     const bool mOutputFloat;
-    int32_t mSampleRate;
-    int32_t mNumChannels;
-    int32_t mBitsPerSample;
+    uint32_t mSampleRate;
+    uint32_t mNumChannels;
+    uint32_t mBitsPerSample;
     off64_t mOffset;
     size_t mSize;
     bool mStarted;
@@ -379,9 +379,9 @@
       mOffset(offset),
       mSize(size),
       mStarted(false) {
-    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &mSampleRate));
-    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &mNumChannels));
-    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &mBitsPerSample));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) &mSampleRate));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, (int32_t*) &mNumChannels));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, (int32_t*) &mBitsPerSample));
 }
 
 WAVSource::~WAVSource() {
@@ -472,7 +472,7 @@
     }
 
     const size_t maxBytesAvailable =
-        (mCurrentPos - mOffset >= (off64_t)mSize)
+        (mCurrentPos < mOffset || mCurrentPos - mOffset >= (off64_t)mSize)
             ? 0 : mSize - (mCurrentPos - mOffset);
 
     if (maxBytesToRead > maxBytesAvailable) {
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
index d85e2a7..b4eeba5 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.h
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -114,6 +114,8 @@
     void closeOutputStream(struct audio_stream_out *stream_out);
     void closeInputStream(struct audio_stream_in *stream_in);
 
+    uint32_t version() const { return mDev->common.version; }
+
   private:
     audio_hw_device_t *mDev;
 
@@ -124,8 +126,6 @@
 
     // The destructor automatically closes the device.
     virtual ~DeviceHalLocal();
-
-    uint32_t version() const { return mDev->common.version; }
 };
 
 } // namespace CPP_VERSION
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 2726e36..09a7c1c 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -25,6 +25,7 @@
 
 #include "DeviceHalHidl.h"
 #include "EffectHalHidl.h"
+#include "HidlUtils.h"
 #include "StreamHalHidl.h"
 #include "VersionUtils.h"
 
@@ -610,12 +611,25 @@
         const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
     CPP_VERSION::SourceMetadata halMetadata = {
         .tracks = transformToHidlVec(sourceMetadata.tracks,
-              [](const playback_track_metadata& metadata) -> PlaybackTrackMetadata {
-                  return {
-                    .usage=static_cast<AudioUsage>(metadata.usage),
-                    .contentType=static_cast<AudioContentType>(metadata.content_type),
-                    .gain=metadata.gain,
+              [](const playback_track_metadata_v7& metadata) -> PlaybackTrackMetadata {
+                  PlaybackTrackMetadata halTrackMetadata = {
+                      .usage=static_cast<AudioUsage>(metadata.base.usage),
+                      .contentType=static_cast<AudioContentType>(metadata.base.content_type),
+                      .gain=metadata.base.gain,
                   };
+#if MAJOR_VERSION >= 7
+                  HidlUtils::audioChannelMaskFromHal(metadata.channel_mask, false /*isInput*/,
+                                                    &halTrackMetadata.channelMask);
+
+                  std::istringstream tags{metadata.tags};
+                  std::string tag;
+                  while (std::getline(tags, tag, HidlUtils::sAudioTagSeparator)) {
+                      if (!tag.empty()) {
+                          halTrackMetadata.tags.push_back(tag);
+                      }
+                  }
+#endif
+                  return halTrackMetadata;
               })};
     return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
 }
@@ -902,11 +916,23 @@
         StreamInHalInterface::SinkMetadata& sinkMetadata) {
     CPP_VERSION::SinkMetadata halMetadata = {
         .tracks = transformToHidlVec(sinkMetadata.tracks,
-              [](const record_track_metadata& metadata) -> RecordTrackMetadata {
-                  return {
-                    .source=static_cast<AudioSource>(metadata.source),
-                    .gain=metadata.gain,
+              [](const record_track_metadata_v7& metadata) -> RecordTrackMetadata {
+                  RecordTrackMetadata halTrackMetadata = {
+                      .source=static_cast<AudioSource>(metadata.base.source),
+                      .gain=metadata.base.gain,
                   };
+#if MAJOR_VERSION >= 7
+                  HidlUtils::audioChannelMaskFromHal(metadata.channel_mask, true /*isInput*/,
+                                                    &halTrackMetadata.channelMask);
+                  std::istringstream tags{metadata.tags};
+                  std::string tag;
+                  while (std::getline(tags, tag, HidlUtils::sAudioTagSeparator)) {
+                      if (!tag.empty()) {
+                          halTrackMetadata.tags.push_back(tag);
+                      }
+                  }
+#endif
+                  return halTrackMetadata;
               })};
     return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
 }
diff --git a/media/libaudiohal/impl/StreamHalLocal.cpp b/media/libaudiohal/impl/StreamHalLocal.cpp
index 69be303..f544e06 100644
--- a/media/libaudiohal/impl/StreamHalLocal.cpp
+++ b/media/libaudiohal/impl/StreamHalLocal.cpp
@@ -241,19 +241,55 @@
     return mStream->get_presentation_position(mStream, frames, timestamp);
 }
 
-status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
-    if (mStream->update_source_metadata == nullptr) {
-        return INVALID_OPERATION;
+void StreamOutHalLocal::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    std::vector<playback_track_metadata> halTracks;
+    halTracks.reserve(sourceMetadata.tracks.size());
+    for (auto& metadata : sourceMetadata.tracks) {
+        playback_track_metadata halTrackMetadata;
+        playback_track_metadata_from_v7(&halTrackMetadata, &metadata);
+        halTracks.push_back(halTrackMetadata);
     }
+    const source_metadata_t halMetadata = {
+        .track_count = halTracks.size(),
+        .tracks = halTracks.data(),
+    };
+    mStream->update_source_metadata(mStream, &halMetadata);
+}
+
+#if MAJOR_VERSION >= 7
+void StreamOutHalLocal::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) {
     const source_metadata_t metadata {
         .track_count = sourceMetadata.tracks.size(),
         // const cast is fine as it is in a const structure
-        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
+        .tracks = const_cast<playback_track_metadata_v7*>(sourceMetadata.tracks.data()),
     };
-    mStream->update_source_metadata(mStream, &metadata);
+    mStream->update_source_metadata_v7(mStream, &metadata);
+}
+#endif
+
+status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+#if MAJOR_VERSION < 7
+    if (mStream->update_source_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    doUpdateSourceMetadata(sourceMetadata);
+#else
+    if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2)
+        if (mStream->update_source_metadata == nullptr) {
+            return INVALID_OPERATION;
+        }
+        doUpdateSourceMetadata(sourceMetadata);
+    } else {
+        if (mStream->update_source_metadata_v7 == nullptr) {
+            return INVALID_OPERATION;
+        }
+        doUpdateSourceMetadataV7(sourceMetadata);
+    }
+#endif
     return OK;
 }
 
+
 status_t StreamOutHalLocal::start() {
     if (mStream->start == NULL) return INVALID_OPERATION;
     return mStream->start(mStream);
@@ -352,16 +388,52 @@
     return mStream->get_capture_position(mStream, frames, time);
 }
 
-status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
-    if (mStream->update_sink_metadata == nullptr) {
-        return INVALID_OPERATION;
+void StreamInHalLocal::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    std::vector<record_track_metadata> halTracks;
+    halTracks.reserve(sinkMetadata.tracks.size());
+    for (auto& metadata : sinkMetadata.tracks) {
+        record_track_metadata halTrackMetadata;
+        record_track_metadata_from_v7(&halTrackMetadata, &metadata);
+        halTracks.push_back(halTrackMetadata);
     }
-    const sink_metadata_t metadata {
+    const sink_metadata_t halMetadata = {
+        .track_count = halTracks.size(),
+        .tracks = halTracks.data(),
+    };
+    mStream->update_sink_metadata(mStream, &halMetadata);
+}
+
+#if MAJOR_VERSION >= 7
+void StreamInHalLocal::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) {
+    const sink_metadata_v7_t halMetadata {
         .track_count = sinkMetadata.tracks.size(),
         // const cast is fine as it is in a const structure
-        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
+        .tracks = const_cast<record_track_metadata_v7*>(sinkMetadata.tracks.data()),
     };
-    mStream->update_sink_metadata(mStream, &metadata);
+    mStream->update_sink_metadata_v7(mStream, &halMetadata);
+}
+#endif
+
+status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+#if MAJOR_VERSION < 7
+
+    if (mStream->update_sink_metadata == nullptr) {
+        return INVALID_OPERATION;  // not supported by the HAL
+    }
+    doUpdateSinkMetadata(sinkMetadata);
+#else
+    if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2)
+        if (mStream->update_sink_metadata == nullptr) {
+            return INVALID_OPERATION;  // not supported by the HAL
+        }
+        doUpdateSinkMetadata(sinkMetadata);
+    } else {
+        if (mStream->update_sink_metadata_v7 == nullptr) {
+            return INVALID_OPERATION;  // not supported by the HAL
+        }
+        doUpdateSinkMetadataV7(sinkMetadata);
+    }
+#endif
     return OK;
 }
 
diff --git a/media/libaudiohal/impl/StreamHalLocal.h b/media/libaudiohal/impl/StreamHalLocal.h
index d17f9f3..8e5180f 100644
--- a/media/libaudiohal/impl/StreamHalLocal.h
+++ b/media/libaudiohal/impl/StreamHalLocal.h
@@ -173,6 +173,9 @@
     static int asyncCallback(stream_callback_event_t event, void *param, void *cookie);
 
     static int asyncEventCallback(stream_event_callback_type_t event, void *param, void *cookie);
+
+    void doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata);
+    void doUpdateSourceMetadata(const SourceMetadata& sourceMetadata);
 };
 
 class StreamInHalLocal : public StreamInHalInterface, public StreamHalLocal {
@@ -227,6 +230,9 @@
     StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device);
 
     virtual ~StreamInHalLocal();
+
+    void doUpdateSinkMetadata(const SinkMetadata& sinkMetadata);
+    void doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata);
 };
 
 } // namespace CPP_VERSION
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index e30cb72..523705e 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -158,7 +158,7 @@
     virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) = 0;
 
     struct SourceMetadata {
-        std::vector<playback_track_metadata_t> tracks;
+        std::vector<playback_track_metadata_v7_t> tracks;
     };
     /**
      * Called when the metadata of the stream's source has been changed.
@@ -197,7 +197,7 @@
     virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
 
     struct SinkMetadata {
-        std::vector<record_track_metadata_t> tracks;
+        std::vector<record_track_metadata_v7_t> tracks;
     };
     /**
      * Called when the metadata of the stream's sink has been changed.
diff --git a/media/libeffects/lvm/benchmarks/Android.bp b/media/libeffects/lvm/benchmarks/Android.bp
index 420e172..930292f 100644
--- a/media/libeffects/lvm/benchmarks/Android.bp
+++ b/media/libeffects/lvm/benchmarks/Android.bp
@@ -14,3 +14,24 @@
         "libhardware_headers",
     ],
 }
+
+cc_benchmark {
+    name: "reverb_benchmark",
+    vendor: true,
+    include_dirs: [
+        "frameworks/av/media/libeffects/lvm/wrapper/Reverb",
+    ],
+    srcs: ["reverb_benchmark.cpp"],
+    static_libs: [
+        "libreverb",
+        "libreverbwrapper",
+    ],
+    shared_libs: [
+        "libaudioutils",
+        "liblog",
+    ],
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+    ],
+}
diff --git a/media/libeffects/lvm/benchmarks/reverb_benchmark.cpp b/media/libeffects/lvm/benchmarks/reverb_benchmark.cpp
new file mode 100644
index 0000000..00a7ff2
--- /dev/null
+++ b/media/libeffects/lvm/benchmarks/reverb_benchmark.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <array>
+#include <climits>
+#include <cstdlib>
+#include <random>
+#include <vector>
+#include <log/log.h>
+#include <benchmark/benchmark.h>
+#include <hardware/audio_effect.h>
+#include <system/audio.h>
+#include "EffectReverb.h"
+
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
+constexpr effect_uuid_t kEffectUuids[] = {
+        {0x172cdf00,
+         0xa3bc,
+         0x11df,
+         0xa72f,
+         {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // preset-insert mode
+        {0xf29a1400,
+         0xa3bb,
+         0x11df,
+         0x8ddc,
+         {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // preset-aux mode
+};
+
+constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
+
+constexpr size_t kFrameCount = 2048;
+
+constexpr int kPresets[] = {
+        REVERB_PRESET_NONE,      REVERB_PRESET_SMALLROOM,  REVERB_PRESET_MEDIUMROOM,
+        REVERB_PRESET_LARGEROOM, REVERB_PRESET_MEDIUMHALL, REVERB_PRESET_LARGEHALL,
+        REVERB_PRESET_PLATE,
+};
+
+constexpr size_t kNumPresets = std::size(kPresets);
+
+constexpr int kSampleRate = 44100;
+
+int reverbSetConfigParam(uint32_t paramType, uint32_t paramValue, effect_handle_t effectHandle) {
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    uint32_t paramData[2] = {paramType, paramValue};
+    auto effectParam = (effect_param_t*)malloc(sizeof(effect_param_t) + sizeof(paramData));
+    memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
+    effectParam->psize = sizeof(paramData[0]);
+    effectParam->vsize = sizeof(paramData[1]);
+    int status = (*effectHandle)
+                         ->command(effectHandle, EFFECT_CMD_SET_PARAM,
+                                   sizeof(effect_param_t) + sizeof(paramData), effectParam,
+                                   &replySize, &reply);
+    free(effectParam);
+    if (status != 0) {
+        ALOGE("Reverb set config returned an error = %d\n", status);
+        return status;
+    }
+    return reply;
+}
+
+/*******************************************************************
+ * A test result running on Pixel 3 with for comparison.
+ * The first parameter indicates the preset level id.
+ * The second parameter indicates the effect.
+ * 0: preset-insert mode, 1: preset-aux mode
+ * --------------------------------------------------------
+ * Benchmark              Time             CPU   Iterations
+ * --------------------------------------------------------
+ * BM_REVERB/0/0      19312 ns        19249 ns        36282
+ * BM_REVERB/0/1       5613 ns         5596 ns       125032
+ * BM_REVERB/1/0     605453 ns       603714 ns         1131
+ * BM_REVERB/1/1     589421 ns       587758 ns         1161
+ * BM_REVERB/2/0     605760 ns       604006 ns         1131
+ * BM_REVERB/2/1     589434 ns       587777 ns         1161
+ * BM_REVERB/3/0     605574 ns       603828 ns         1131
+ * BM_REVERB/3/1     589566 ns       587862 ns         1162
+ * BM_REVERB/4/0     605634 ns       603894 ns         1131
+ * BM_REVERB/4/1     589506 ns       587856 ns         1161
+ * BM_REVERB/5/0     605644 ns       603929 ns         1131
+ * BM_REVERB/5/1     589592 ns       587863 ns         1161
+ * BM_REVERB/6/0     610544 ns       608561 ns         1131
+ * BM_REVERB/6/1     589686 ns       587871 ns         1161
+ *******************************************************************/
+
+static void BM_REVERB(benchmark::State& state) {
+    const size_t chMask = AUDIO_CHANNEL_OUT_STEREO;
+    const size_t preset = kPresets[state.range(0)];
+    const effect_uuid_t uuid = kEffectUuids[state.range(1)];
+    const size_t channelCount = audio_channel_count_from_out_mask(chMask);
+
+    // Initialize input buffer with deterministic pseudo-random values
+    std::minstd_rand gen(chMask);
+    std::uniform_real_distribution<> dis(-1.0f, 1.0f);
+    std::vector<float> input(kFrameCount * channelCount);
+    std::vector<float> output(kFrameCount * channelCount);
+    for (auto& in : input) {
+        in = dis(gen);
+    }
+
+    effect_handle_t effectHandle = nullptr;
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&uuid, 1, 1, &effectHandle);
+        status != 0) {
+        ALOGE("create_effect returned an error = %d\n", status);
+        return;
+    }
+
+    effect_config_t config{};
+    config.inputCfg.samplingRate = config.outputCfg.samplingRate = kSampleRate;
+    config.inputCfg.channels = config.outputCfg.channels = chMask;
+    config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    if (int status = (*effectHandle)
+                             ->command(effectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t),
+                                       &config, &replySize, &reply);
+        status != 0) {
+        ALOGE("command returned an error = %d\n", status);
+        return;
+    }
+
+    if (int status =
+                (*effectHandle)
+                        ->command(effectHandle, EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
+        status != 0) {
+        ALOGE("Command enable call returned error %d\n", reply);
+        return;
+    }
+
+    if (int status = reverbSetConfigParam(REVERB_PARAM_PRESET, preset, effectHandle); status != 0) {
+        ALOGE("Invalid reverb preset. Error %d\n", status);
+        return;
+    }
+
+    // Run the test
+    for (auto _ : state) {
+        benchmark::DoNotOptimize(input.data());
+        benchmark::DoNotOptimize(output.data());
+
+        audio_buffer_t inBuffer = {.frameCount = kFrameCount, .f32 = input.data()};
+        audio_buffer_t outBuffer = {.frameCount = kFrameCount, .f32 = output.data()};
+        (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
+
+        benchmark::ClobberMemory();
+    }
+
+    state.SetComplexityN(state.range(0));
+
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) {
+        ALOGE("release_effect returned an error = %d\n", status);
+        return;
+    }
+}
+
+static void REVERBArgs(benchmark::internal::Benchmark* b) {
+    for (int i = 0; i < kNumPresets; i++) {
+        for (int j = 0; j < kNumEffectUuids; ++j) {
+            b->Args({i, j});
+        }
+    }
+}
+
+BENCHMARK(BM_REVERB)->Apply(REVERBArgs);
+
+BENCHMARK_MAIN();
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index dbe0d62..8d248a3 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -69,28 +69,19 @@
         "Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp",
         "Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp",
         "Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.cpp",
-        "Common/src/Int16LShiftToInt32_16x32.cpp",
-        "Common/src/From2iToMono_16.cpp",
         "Common/src/Copy_16.cpp",
-        "Common/src/MonoTo2I_16.cpp",
         "Common/src/MonoTo2I_32.cpp",
-        "Common/src/LoadConst_16.cpp",
         "Common/src/LoadConst_32.cpp",
         "Common/src/dB_to_Lin32.cpp",
         "Common/src/Shift_Sat_v16xv16.cpp",
         "Common/src/Shift_Sat_v32xv32.cpp",
-        "Common/src/Abs_32.cpp",
-        "Common/src/Int32RShiftToInt16_Sat_32x16.cpp",
         "Common/src/From2iToMono_32.cpp",
-        "Common/src/mult3s_16x16.cpp",
         "Common/src/Mult3s_32x16.cpp",
         "Common/src/NonLinComp_D16.cpp",
         "Common/src/DelayMix_16x16.cpp",
         "Common/src/MSTo2i_Sat_16x16.cpp",
         "Common/src/From2iToMS_16x16.cpp",
-        "Common/src/Mac3s_Sat_16x16.cpp",
         "Common/src/Mac3s_Sat_32x16.cpp",
-        "Common/src/Add2_Sat_16x16.cpp",
         "Common/src/Add2_Sat_32x32.cpp",
         "Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp",
         "Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp",
@@ -166,18 +157,14 @@
         "Reverb/src/LVREV_Process.cpp",
         "Reverb/src/LVREV_SetControlParameters.cpp",
         "Reverb/src/LVREV_Tables.cpp",
-        "Common/src/Abs_32.cpp",
         "Common/src/InstAlloc.cpp",
-        "Common/src/LoadConst_16.cpp",
         "Common/src/LoadConst_32.cpp",
         "Common/src/From2iToMono_32.cpp",
         "Common/src/Mult3s_32x16.cpp",
         "Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp",
         "Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp",
-        "Common/src/DelayAllPass_Sat_32x16To32.cpp",
         "Common/src/Copy_16.cpp",
         "Common/src/Mac3s_Sat_32x16.cpp",
-        "Common/src/DelayWrite_32.cpp",
         "Common/src/Shift_Sat_v32xv32.cpp",
         "Common/src/Add2_Sat_32x32.cpp",
         "Common/src/JoinTo2i_32x32.cpp",
@@ -204,10 +191,12 @@
         "Reverb/lib",
         "Common/lib",
     ],
-
+    static_libs: [
+        "libaudioutils",
+    ],
     cppflags: [
+        "-DBIQUAD_OPT",
         "-fvisibility=hidden",
-
         "-Wall",
         "-Werror",
     ],
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
index 1f0b459..814280f 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
@@ -23,6 +23,7 @@
 
 #ifdef BIQUAD_OPT
 #include <audio_utils/BiquadFilter.h>
+#include <system/audio.h>
 #endif
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
@@ -114,7 +115,7 @@
     std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
             LVDBE_HPF_Table[Offset].A0, LVDBE_HPF_Table[Offset].A1, LVDBE_HPF_Table[Offset].A2,
             -(LVDBE_HPF_Table[Offset].B1), -(LVDBE_HPF_Table[Offset].B2)};
-    pInstance->pBqInstance
+    pInstance->pHPFBiquad
             ->setCoefficients<std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(coefs);
 #else
     LoadConst_Float(0,                                      /* Clear the history, value 0 */
@@ -128,12 +129,19 @@
     /*
      * Setup the band pass filter
      */
+#ifdef BIQUAD_OPT
+    coefs = {LVDBE_BPF_Table[Offset].A0, 0.0, -(LVDBE_BPF_Table[Offset].A0),
+             -(LVDBE_BPF_Table[Offset].B1), -(LVDBE_BPF_Table[Offset].B2)};
+    pInstance->pBPFBiquad
+            ->setCoefficients<std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(coefs);
+#else
     LoadConst_Float(0,                                      /* Clear the history, value 0 */
                     (LVM_FLOAT*)&pInstance->pData->BPFTaps, /* Destination */
                     sizeof(pInstance->pData->BPFTaps) / sizeof(LVM_FLOAT)); /* Number of words */
     BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance, /* Initialise the filter */
                                     &pInstance->pData->BPFTaps,
                                     (BP_FLOAT_Coefs_t*)&LVDBE_BPF_Table[Offset]);
+#endif
 }
 
 /************************************************************************************/
@@ -290,9 +298,8 @@
     /*
      * Create biquad instance
      */
-    pInstance->pBqInstance.reset(
-            new android::audio_utils::BiquadFilter<LVM_FLOAT>(pParams->NrChannels));
-    pInstance->pBqInstance->clear();
+    pInstance->pHPFBiquad.reset(new android::audio_utils::BiquadFilter<LVM_FLOAT>(
+            (FCC_1 == pParams->NrChannels) ? FCC_2 : pParams->NrChannels));
 #endif
 
     /*
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
index 611b762..6bdb7fe 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
@@ -20,8 +20,11 @@
 /*    Includes                                                                          */
 /*                                                                                      */
 /****************************************************************************************/
-#include <stdlib.h>
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
+#include <stdlib.h>
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
 
@@ -89,17 +92,18 @@
     if (pInstance->pData == NULL) {
         return LVDBE_NULLADDRESS;
     }
-    pInstance->pCoef = (LVDBE_Coef_FLOAT_t*)calloc(1, sizeof(*(pInstance->pCoef)));
-    if (pInstance->pCoef == NULL) {
-        return LVDBE_NULLADDRESS;
-    }
-
 #ifdef BIQUAD_OPT
     /*
      * Create biquad instance
      */
-    pInstance->pBqInstance.reset(
+    pInstance->pHPFBiquad.reset(
             new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    pInstance->pBPFBiquad.reset(new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1));
+#else
+    pInstance->pCoef = (LVDBE_Coef_FLOAT_t*)calloc(1, sizeof(*(pInstance->pCoef)));
+    if (pInstance->pCoef == NULL) {
+        return LVDBE_NULLADDRESS;
+    }
 #endif
 
     /*
@@ -190,10 +194,12 @@
         free(pInstance->pData);
         pInstance->pData = LVM_NULL;
     }
+#ifndef BIQUAD_OPT
     if (pInstance->pCoef != LVM_NULL) {
         free(pInstance->pCoef);
         pInstance->pCoef = LVM_NULL;
     }
+#endif
     free(pInstance);
     *phInstance = LVM_NULL;
 }
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index fa85638..23be2aa 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -68,21 +68,22 @@
     /* Process variables */
 #ifndef BIQUAD_OPT
     Biquad_2I_Order2_FLOAT_Taps_t HPFTaps; /* High pass filter taps */
-#endif
     Biquad_1I_Order2_FLOAT_Taps_t BPFTaps; /* Band pass filter taps */
+#endif
     LVMixer3_1St_FLOAT_st BypassVolume;    /* Bypass volume scaler */
     LVMixer3_2St_FLOAT_st BypassMixer;     /* Bypass Mixer for Click Removal */
 
 } LVDBE_Data_FLOAT_t;
 
+#ifndef BIQUAD_OPT
 /* Coefs structure */
 typedef struct {
     /* Process variables */
-#ifndef BIQUAD_OPT
     Biquad_FLOAT_Instance_t HPFInstance; /* High pass filter instance */
-#endif
     Biquad_FLOAT_Instance_t BPFInstance; /* Band pass filter instance */
 } LVDBE_Coef_FLOAT_t;
+#endif
+
 /* Instance structure */
 typedef struct {
     /* Public parameters */
@@ -91,11 +92,15 @@
 
     /* Data and coefficient pointers */
     LVDBE_Data_FLOAT_t* pData; /* Instance data */
+#ifndef BIQUAD_OPT
     LVDBE_Coef_FLOAT_t* pCoef; /* Instance coefficients */
+#endif
     void* pScratch;            /* scratch pointer */
 #ifdef BIQUAD_OPT
     std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
-            pBqInstance; /* Biquad filter instance */
+            pHPFBiquad; /* Biquad filter instance for HPF */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pBPFBiquad; /* Biquad filter instance for BPF */
 #endif
 } LVDBE_Instance_t;
 
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
index bd04a02..e8541fd 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
@@ -129,7 +129,7 @@
          */
         if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
 #ifdef BIQUAD_OPT
-            pInstance->pBqInstance->process(pScratch, pScratch, NrFrames);
+            pInstance->pHPFBiquad->process(pScratch, pScratch, NrFrames);
 #else
             BQ_MC_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance, /* Filter instance      */
                                        pScratch,                       /* Source               */
@@ -149,10 +149,14 @@
         /*
          * Apply the band pass filter
          */
+#ifdef BIQUAD_OPT
+        pInstance->pBPFBiquad->process(pMono, pMono, NrFrames);
+#else
         BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
                                    pMono,                          /* Source                */
                                    pMono,                          /* Destination           */
                                    (LVM_INT16)NrFrames);
+#endif
 
         /*
          * Apply the AGC and mix
@@ -163,15 +167,6 @@
                                    pScratch,                       /* Destination    */
                                    NrFrames,                       /* Number of frames     */
                                    NrChannels);                    /* Number of channels     */
-
-        for (LVM_INT32 ii = 0; ii < NrSamples; ++ii) {
-            // TODO: replace with existing clamping function
-            if (pScratch[ii] < -1.0) {
-                pScratch[ii] = -1.0;
-            } else if (pScratch[ii] > 1.0) {
-                pScratch[ii] = 1.0;
-            }
-        }
     } else {
         // clear DBE processed path
         memset(pScratch, 0, sizeof(*pScratch) * NrSamples);
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
index 3118e77..7e8664a 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
@@ -276,6 +276,16 @@
              */
             Offset = (LVM_INT16)(EffectLevel - 1 +
                                  TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate));
+#ifdef BIQUAD_OPT
+            /*
+             * Create biquad instance
+             */
+            std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                    LVM_TrebleBoostCoefs[Offset].A0, LVM_TrebleBoostCoefs[Offset].A1, 0.0,
+                    -(LVM_TrebleBoostCoefs[Offset].B1), 0.0};
+            pInstance->pTEBiquad.reset(
+                    new android::audio_utils::BiquadFilter<LVM_FLOAT>(pParams->NrChannels, coefs));
+#else
             FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
                                                  &pInstance->pTE_Taps->TrebleBoost_Taps,
                                                  &LVM_TrebleBoostCoefs[Offset]);
@@ -288,6 +298,7 @@
                                                    Cast to void: no dereferencing in function */
                             (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps) /
                                          sizeof(LVM_FLOAT))); /* Number of words */
+#endif
         }
     } else {
         /*
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
index bb962df..bbfa0dc 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
@@ -174,6 +174,7 @@
     /*
      * Treble Enhancement
      */
+#ifndef BIQUAD_OPT
     pInstance->pTE_Taps = (LVM_TE_Data_t*)calloc(1, sizeof(*(pInstance->pTE_Taps)));
     if (pInstance->pTE_Taps == LVM_NULL) {
         return LVM_NULLADDRESS;
@@ -182,6 +183,7 @@
     if (pInstance->pTE_State == LVM_NULL) {
         return LVM_NULLADDRESS;
     }
+#endif
     pInstance->Params.TE_OperatingMode = LVM_TE_OFF;
     pInstance->Params.TE_EffectLevel = 0;
     pInstance->TE_Active = LVM_FALSE;
@@ -494,6 +496,7 @@
     /*
      * Treble Enhancement
      */
+#ifndef BIQUAD_OPT
     if (pInstance->pTE_Taps != LVM_NULL) {
         free(pInstance->pTE_Taps);
         pInstance->pTE_Taps = LVM_NULL;
@@ -502,6 +505,7 @@
         free(pInstance->pTE_State);
         pInstance->pTE_State = LVM_NULL;
     }
+#endif
 
     /*
      * Free the default EQNB pre-gain and pointer to the band definitions
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
index 90a1f19..56bbfd1 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -33,6 +33,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVM.h"            /* LifeVibes */
 #include "LVM_Common.h"     /* LifeVibes common */
 #include "BIQUAD.h"         /* Biquad library */
@@ -127,6 +130,7 @@
     LVM_INT16 SamplesToOutput; /* Samples to write to the output */
 } LVM_Buffer_t;
 
+#ifndef BIQUAD_OPT
 /* Filter taps */
 typedef struct {
     Biquad_2I_Order1_FLOAT_Taps_t TrebleBoost_Taps; /* Treble boost Taps */
@@ -136,6 +140,7 @@
 typedef struct {
     Biquad_FLOAT_Instance_t TrebleBoost_State; /* State for the treble boost filter */
 } LVM_TE_Coefs_t;
+#endif
 
 typedef struct {
     /* Public parameters */
@@ -185,8 +190,13 @@
     LVM_INT16 VC_AVLFixedVolume;         /* AVL fixed volume */
 
     /* Treble Enhancement */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pTEBiquad; /* Biquad filter instance */
+#else
     LVM_TE_Data_t* pTE_Taps;   /* Treble boost Taps */
     LVM_TE_Coefs_t* pTE_State; /* State for the treble boost filter */
+#endif
     LVM_INT16 TE_Active;       /* Control flag */
 
     /* Headroom */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
index c94c469..acd594f 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
@@ -190,9 +190,13 @@
                 /*
                  * Apply the filter
                  */
+#ifdef BIQUAD_OPT
+                pInstance->pTEBiquad->process(pProcessed, pProcessed, NrFrames);
+#else
                 FO_Mc_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
                                                 pProcessed, pProcessed, (LVM_INT16)NrFrames,
                                                 (LVM_INT16)NrChannels);
+#endif
             }
             /*
              * Volume balance
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index c20b49a..31c8200 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -48,11 +48,6 @@
 /*    Function Prototypes                                                              */
 /*                                                                                */
 /**********************************************************************************/
-void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
-                                 const LVM_FLOAT* pStSrc,                /* Stereo source */
-                                 const LVM_FLOAT* pMonoSrc,              /* Mono source */
-                                 LVM_FLOAT* pDst,                        /* Stereo destination */
-                                 LVM_UINT16 n);                          /* Number of samples */
 void AGC_MIX_VOL_Mc1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance,  /* Instance pointer */
                                 const LVM_FLOAT* pStSrc,                 /* Source */
                                 const LVM_FLOAT* pMonoSrc,               /* Mono source */
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index b38e9fb..08772e1 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -72,6 +72,7 @@
     LVM_FLOAT G;  /* Gain */
 } PK_FLOAT_Coefs_t;
 
+#ifndef BIQUAD_OPT
 /**********************************************************************************
    TAPS TYPE DEFINITIONS
 ***********************************************************************************/
@@ -100,6 +101,7 @@
 #define BQ_2I_D32F32Cll_TRC_WRA_01_Init Init_BQ_2I_D32F32Cll_TRC_WRA_01
 #define BP_1I_D32F32C30_TRC_WRA_02 TWO_BP_1I_D32F32C30_TRC_WRA_02
 
+
 /**********************************************************************************
    FUNCTION PROTOTYPES: BIQUAD FILTERS
 ***********************************************************************************/
@@ -161,8 +163,6 @@
                                           Biquad_2I_Order1_FLOAT_Taps_t* pTaps,
                                           FO_FLOAT_LShx_Coefs_t* pCoef);
 
-void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                     LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
 /*** 32 bit data path *************************************************************/
 void FO_1I_D32F32Cll_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
                                      Biquad_1I_Order1_FLOAT_Taps_t* pTaps, FO_FLOAT_Coefs_t* pCoef);
@@ -170,6 +170,7 @@
                                 LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
 void FO_Mc_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
                                      LVM_FLOAT* pDataOut, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
+
 /**********************************************************************************
    FUNCTION PROTOTYPES: BAND PASS FILTERS
 ***********************************************************************************/
@@ -183,6 +184,7 @@
                                      Biquad_1I_Order2_FLOAT_Taps_t* pTaps, BP_FLOAT_Coefs_t* pCoef);
 void BP_1I_D16F32C30_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
                                 LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
+
 /*** 32 bit data path *************************************************************/
 void BP_1I_D32F32Cll_TRC_WRA_02_Init(Biquad_FLOAT_Instance_t* pInstance,
                                      Biquad_1I_Order2_FLOAT_Taps_t* pTaps, BP_FLOAT_Coefs_t* pCoef);
@@ -193,10 +195,9 @@
 void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
                                         Biquad_2I_Order2_FLOAT_Taps_t* pTaps,
                                         PK_FLOAT_Coefs_t* pCoef);
-void PK_2I_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                   LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
 void PK_Mc_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
                                    LVM_FLOAT* pDataOut, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
+#endif
 
 /**********************************************************************************
    FUNCTION PROTOTYPES: DC REMOVAL FILTERS
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index fb797be..b95d076 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -26,7 +26,7 @@
 #define LVM_TYPES_H
 
 #include <stdint.h>
-
+#include <system/audio.h>
 /****************************************************************************************/
 /*                                                                                      */
 /*  definitions                                                                         */
@@ -82,7 +82,7 @@
 #define EFFECT_BUFFER_FORMAT AUDIO_FORMAT_PCM_FLOAT
 typedef float effect_buffer_t;
 
-#define LVM_MAX_CHANNELS 8  // FCC_8
+#define LVM_MAX_CHANNELS FCC_24
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
index 04b180c..36c4cd2 100644
--- a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
@@ -21,7 +21,7 @@
 /*######################################################################################*/
 /*  Include files                                                                       */
 /*######################################################################################*/
-
+#include <math.h>
 #include "LVM_Types.h"
 
 /*######################################################################################*/
@@ -30,7 +30,13 @@
 
 /* Absolute value including the corner case for the extreme negative value */
 
-LVM_FLOAT Abs_Float(LVM_FLOAT input);
+static inline LVM_FLOAT Abs_Float(LVM_FLOAT input) {
+    return fabs(input);
+}
+
+static inline LVM_FLOAT LVM_Clamp(LVM_FLOAT val) {
+    return fmin(fmax(val, -1.0f), 1.0f);
+}
 
 /****************************************************************************************
  *  Name        : dB_to_Lin32()
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 66e3e79..281d941 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -32,45 +32,16 @@
 void Copy_Float_Stereo_Mc(const LVM_FLOAT* src, LVM_FLOAT* StereoOut, LVM_FLOAT* dst,
                           LVM_INT16 NrFrames, LVM_INT32 NrChannels);
 
-/*********************************************************************************
- * note: In Mult3s_16x16() saturation of result is not taken care when           *
- *       overflow occurs.                                                        *
- *       For example when *src = 0x8000, val = *0x8000                           *
- *       The function gives the output as 0x8000 instead of 0x7fff               *
- *       This is the only case which will give wrong result.                     *
- *       For more information refer to Vector_Arithmetic.doc in /doc folder      *
- *********************************************************************************/
 void Mult3s_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n);
 
-/*********************************************************************************
- * note: In Mult3s_32x16() saturation of result is not taken care when           *
- *       overflow occurs.                                                        *
- *       For example when *src = 0x8000000, val = *0x8000                        *
- *       The function gives the output as 0x8000000 instead of 0x7fffffff        *
- *       This is the only extreme condition which is giving unexpected result    *
- *       For more information refer to Vector_Arithmetic.doc in /doc folder      *
- *********************************************************************************/
-void Mult3s_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n);
 void DelayMix_Float(const LVM_FLOAT* src, /* Source 1, to be delayed */
                     LVM_FLOAT* delay,     /* Delay buffer */
                     LVM_INT16 size,       /* Delay size */
                     LVM_FLOAT* dst,       /* Source/destination */
                     LVM_INT16* pOffset,   /* Delay offset */
                     LVM_INT16 n);         /* Number of stereo samples */
-void DelayWrite_32(const LVM_INT32* src,  /* Source 1, to be delayed */
-                   LVM_INT32* delay,      /* Delay buffer */
-                   LVM_UINT16 size,       /* Delay size */
-                   LVM_UINT16* pOffset,   /* Delay offset */
-                   LVM_INT16 n);
 void Add2_Sat_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n);
 void Mac3s_Sat_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n);
-void DelayAllPass_Sat_32x16To32(LVM_INT32* delay,           /* Delay buffer */
-                                LVM_UINT16 size,            /* Delay size */
-                                LVM_INT16 coeff,            /* All pass filter coefficient */
-                                LVM_UINT16 DelayOffset,     /* Simple delay offset */
-                                LVM_UINT16* pAllPassOffset, /* All pass filter delay offset */
-                                LVM_INT32* dst,             /* Source/destination */
-                                LVM_INT16 n);
 
 /**********************************************************************************
     SHIFT FUNCTIONS
@@ -87,15 +58,6 @@
 void From2iToMS_Float(const LVM_FLOAT* src, LVM_FLOAT* dstM, LVM_FLOAT* dstS, LVM_INT16 n);
 void JoinTo2i_Float(const LVM_FLOAT* srcL, const LVM_FLOAT* srcR, LVM_FLOAT* dst, LVM_INT16 n);
 
-/**********************************************************************************
-    DATA TYPE CONVERSION FUNCTIONS
-***********************************************************************************/
-
-void Int16LShiftToInt32_16x32(const LVM_INT16* src, LVM_INT32* dst, LVM_INT16 n, LVM_INT16 shift);
-
-void Int32RShiftToInt16_Sat_32x16(const LVM_INT32* src, LVM_INT16* dst, LVM_INT16 n,
-                                  LVM_INT16 shift);
-
 /**********************************************************************************/
 
 #endif /* _VECTOR_ARITHMETIC_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
index ae8cdad..78f329e 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
@@ -20,7 +20,6 @@
 /*    Includes                                                                          */
 /*                                                                                      */
 /****************************************************************************************/
-
 #include "AGC.h"
 #include "ScalarArithmetic.h"
 
@@ -37,135 +36,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                  AGC_MIX_VOL_2St1Mon_D32_WRA                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*    Apply AGC and mix signals                                                         */
-/*                                                                                      */
-/*                                                                                      */
-/*  StSrc   ------------------|                                                         */
-/*                            |                                                         */
-/*              ______       _|_        ________                                        */
-/*             |      |     |   |      |        |                                       */
-/*  MonoSrc -->| AGC  |---->| + |----->| Volume |------------------------------+--->    */
-/*             | Gain |     |___|      | Gain   |                              |        */
-/*             |______|                |________|                              |        */
-/*                /|\                               __________     ________    |        */
-/*                 |                               |          |   |        |   |        */
-/*                 |-------------------------------| AGC Gain |<--| Peak   |<--|        */
-/*                                                 | Update   |   | Detect |            */
-/*                                                 |__________|   |________|            */
-/*                                                                                      */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  pInstance               Instance pointer                                            */
-/*  pStereoIn               Stereo source                                               */
-/*  pMonoIn                 Mono band pass source                                       */
-/*  pStereoOut              Stereo destination                                          */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  Void                                                                                */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*                                                                                      */
-/****************************************************************************************/
-void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
-                                 const LVM_FLOAT* pStSrc,                /* Stereo source */
-                                 const LVM_FLOAT* pMonoSrc,              /* Mono source */
-                                 LVM_FLOAT* pDst,                        /* Stereo destination */
-                                 LVM_UINT16 NumSamples)                  /* Number of samples */
-{
-    /*
-     * General variables
-     */
-    LVM_UINT16 i;       /* Sample index */
-    LVM_FLOAT Left;     /* Left sample */
-    LVM_FLOAT Right;    /* Right sample */
-    LVM_FLOAT Mono;     /* Mono sample */
-    LVM_FLOAT AbsPeak;  /* Absolute peak signal */
-    LVM_FLOAT AGC_Mult; /* Short AGC gain */
-    LVM_FLOAT Vol_Mult; /* Short volume */
-
-    /*
-     * Instance control variables
-     */
-    LVM_FLOAT AGC_Gain = pInstance->AGC_Gain;       /* Get the current AGC gain */
-    LVM_FLOAT AGC_MaxGain = pInstance->AGC_MaxGain; /* Get maximum AGC gain */
-    LVM_FLOAT AGC_Attack = pInstance->AGC_Attack;   /* Attack scaler */
-    LVM_FLOAT AGC_Decay = (pInstance->AGC_Decay * (1 << (DECAY_SHIFT))); /* Decay scaler */
-    LVM_FLOAT AGC_Target = pInstance->AGC_Target;                        /* Get the target level */
-    LVM_FLOAT Vol_Current = pInstance->Volume;                           /* Actual volume setting */
-    LVM_FLOAT Vol_Target = pInstance->Target;                            /* Target volume setting */
-    LVM_FLOAT Vol_TC = pInstance->VolumeTC;                              /* Time constant */
-
-    /*
-     * Process on a sample by sample basis
-     */
-    for (i = 0; i < NumSamples; i++) /* For each sample */
-    {
-        /*
-         * Get the short scalers
-         */
-        AGC_Mult = (LVM_FLOAT)(AGC_Gain);    /* Get the short AGC gain */
-        Vol_Mult = (LVM_FLOAT)(Vol_Current); /* Get the short volume gain */
-
-        /*
-         * Get the input samples
-         */
-        Left = *pStSrc++;   /* Get the left sample */
-        Right = *pStSrc++;  /* Get the right sample */
-        Mono = *pMonoSrc++; /* Get the mono sample */
-
-        /*
-         * Apply the AGC gain to the mono input and mix with the stereo signal
-         */
-        Left += (Mono * AGC_Mult); /* Mix in the mono signal */
-        Right += (Mono * AGC_Mult);
-
-        /*
-         * Apply the volume and write to the output stream
-         */
-        Left = Left * Vol_Mult;
-        Right = Right * Vol_Mult;
-        *pDst++ = Left; /* Save the results */
-        *pDst++ = Right;
-
-        /*
-         * Update the AGC gain
-         */
-        AbsPeak = Abs_Float(Left) > Abs_Float(Right) ? Abs_Float(Left) : Abs_Float(Right);
-        if (AbsPeak > AGC_Target) {
-            /*
-             * The signal is too large so decrease the gain
-             */
-            AGC_Gain = AGC_Gain * AGC_Attack;
-        } else {
-            /*
-             * The signal is too small so increase the gain
-             */
-            if (AGC_Gain > AGC_MaxGain) {
-                AGC_Gain -= (AGC_Decay);
-            } else {
-                AGC_Gain += (AGC_Decay);
-            }
-        }
-
-        /*
-         * Update the gain
-         */
-        Vol_Current += (Vol_Target - Vol_Current) * ((LVM_FLOAT)Vol_TC / VOL_TC_FLOAT);
-    }
-
-    /*
-     * Update the parameters
-     */
-    pInstance->Volume = Vol_Current; /* Actual volume setting */
-    pInstance->AGC_Gain = AGC_Gain;
-
-    return;
-}
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                  AGC_MIX_VOL_Mc1Mon_D32_WRA                                */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
@@ -255,7 +125,7 @@
              */
             SampleVal = SampleVal * Vol_Mult;
 
-            *pDst++ = SampleVal; /* Save the results */
+            *pDst++ = LVM_Clamp(SampleVal); /* Save the results */
 
             /*
              * Update the AGC gain
diff --git a/media/libeffects/lvm/lib/Common/src/Abs_32.cpp b/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
deleted file mode 100644
index 3e37d89..0000000
--- a/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*######################################################################################*/
-/*  Include files                                                                       */
-/*######################################################################################*/
-
-#include "ScalarArithmetic.h"
-
-/****************************************************************************************
- *  Name        : Abs_32()
- *  Input       : Signed 32-bit integer
- *  Output      :
- *  Returns     : Absolute value
- *  Description : Absolute value with maximum negative value corner case
- *  Remarks     :
- ****************************************************************************************/
-
-LVM_INT32 Abs_32(LVM_INT32 input) {
-    if (input < 0) {
-        if (input == (LVM_INT32)(0x80000000U)) {
-            /* The corner case, so set to the maximum positive value */
-            input = (LVM_INT32)0x7fffffff;
-        } else {
-            /* Negative input, so invert */
-            input = (LVM_INT32)(-input);
-        }
-    }
-    return input;
-}
-LVM_FLOAT Abs_Float(LVM_FLOAT input) {
-    if (input < 0) {
-        /* Negative input, so invert */
-        input = (LVM_FLOAT)(-input);
-    }
-    return input;
-}
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp
deleted file mode 100644
index be20521..0000000
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION ADD2_SAT_16X16
-***********************************************************************************/
-
-void Add2_Sat_16x16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT32 Temp;
-    LVM_INT16 ii;
-    for (ii = n; ii != 0; ii--) {
-        Temp = ((LVM_INT32)*src) + ((LVM_INT32)*dst);
-        src++;
-
-        if (Temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (Temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)Temp;
-        }
-        dst++;
-    }
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
index 420f93e..1981edd 100644
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
@@ -18,53 +18,15 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
+#include "ScalarArithmetic.h"
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION ADD2_SAT_32X32
-***********************************************************************************/
-
-void Add2_Sat_32x32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT32 a, b, c;
-    LVM_INT16 ii;
-    for (ii = n; ii != 0; ii--) {
-        a = *src;
-        src++;
-
-        b = *dst;
-        c = a + b;
-        if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (a < 0) {
-                c = 0x80000000L;
-            } else {
-                c = 0x7FFFFFFFL;
-            }
-        }
-
-        *dst = c;
-        dst++;
-    }
-    return;
-}
-
 void Add2_Sat_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_FLOAT Temp;
     LVM_INT16 ii;
     for (ii = n; ii != 0; ii--) {
-        Temp = ((LVM_FLOAT)*src) + ((LVM_FLOAT)*dst);
-        src++;
-
-        if (Temp > 1.000000f) {
-            *dst = 1.000000f;
-        } else if (Temp < -1.000000f) {
-            *dst = -1.000000f;
-        } else {
-            *dst = Temp;
-        }
-        dst++;
+        Temp = *src++ + *dst;
+        *dst++ = LVM_Clamp(Temp);
     }
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp
index 198a6a1..bc9a2c5 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BP_1I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -67,3 +67,4 @@
         *pDataOut++ = ynL;  // Write Left output
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp
index 6d36302..571676b 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BP_1I_D16F16Css_TRC_WRA_01_Private.h"
 
@@ -47,5 +48,6 @@
     pBiquadState->coefs[1] = pCoef->B2;
     pBiquadState->coefs[2] = pCoef->B1;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BP_1I_D16F16Css_TRC_WRA_01_Init.c                              */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
index a41c855..c19e2f4 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef BIQUAD_OPT
 #ifndef _BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 
@@ -32,3 +33,4 @@
 } Filter_State_FLOAT;
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 #endif /*_BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp
index d4d4eb1..ff3221a 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BP_1I_D16F32Cll_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -68,3 +68,4 @@
         *pDataOut++ = (ynL);  // Write Left output
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp
index d322a8e..26a4793 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BP_1I_D16F32Cll_TRC_WRA_01_Private.h"
 
@@ -57,5 +58,6 @@
     pBiquadState->coefs[1] = pCoef->B2;
     pBiquadState->coefs[2] = pCoef->B1;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BP_1I_D16F32Cll_TRC_WRA_01_Init.c                              */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
index 0603256..ae52cf2 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef BIQUAD_OPT
 #ifndef _BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_
 #define _BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_
 
@@ -31,3 +32,4 @@
 } Filter_State_Float;
 typedef Filter_State_Float* PFilter_State_FLOAT;
 #endif /*_BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp
index 0670334..6462092 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BP_1I_D32F32Cll_TRC_WRA_02_Private.h"
 #include "LVM_Macros.h"
@@ -68,3 +69,4 @@
         *pDataOut++ = ynL;  // Write Left output in Q0
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp
index 146cc63..9b4cccc 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BP_1I_D32F32Cll_TRC_WRA_02_Private.h"
 
@@ -49,5 +50,6 @@
 
     pBiquadState->coefs[2] = pCoef->B1;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BP_1I_D32F32Cll_TRC_WRA_02_Init.c                              */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
index ea83c0b..93a7bfd 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef BIQUAD_OPT
 #ifndef _BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_
 #define _BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_
 
@@ -32,3 +33,4 @@
 typedef Filter_State_Float* PFilter_State_FLOAT;
 
 #endif /*_BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp
index a46b1ef..85a7453 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_1I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -71,3 +72,4 @@
         *pDataOut++ = (LVM_FLOAT)ynL;  // Write Left output in Q0
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp
index e8bfcd8..7ad0793 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_1I_D16F16Css_TRC_WRA_01_Private.h"
 
@@ -54,5 +55,6 @@
     temp = pCoef->B1;
     pBiquadState->coefs[4] = temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_1I_D16F16Css_TRC_WRA_01_Init.c                              */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
index ac2819e..9d1a3b6 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef BIQUAD_OPT
 #ifndef _BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 
@@ -33,3 +34,4 @@
 } Filter_State_FLOAT;
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 #endif /*_BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp
index c60dcf8..58320f7 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_1I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -71,3 +72,4 @@
         *pDataOut++ = (LVM_FLOAT)(ynL);  // Write Left output
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
index af0efc8..3293b2e 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef BIQUAD_OPT
 #ifndef _BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 
@@ -33,3 +34,4 @@
 } Filter_State_FLOAT;
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 #endif /*_BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp
index ecf44ca..0d36e67 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_1I_D16F32Css_TRC_WRA_01_Private.h"
 
@@ -55,5 +56,6 @@
     temp = pCoef->B1;
     pBiquadState->coefs[4] = temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_1I_D16F32Css_TRC_WRA_01_Init                              */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp
index d047e91..9ec9046 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -98,3 +99,4 @@
         *pDataOut++ = (LVM_FLOAT)ynR;  // Write Right output
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp
index 399b5ec..2478016 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -98,3 +99,4 @@
         *pDataOut++ = (LVM_FLOAT)ynR;  // Write Right output
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp
index e0cd934..8b2de31 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
 
@@ -57,3 +58,4 @@
 }
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_2I_D16F16Css_TRC_WRA_01_Init.c                              */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
index 94cc794..f9a31a6 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 
@@ -35,3 +36,4 @@
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 
 #endif /* _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp
index 3b7eb5e..7a66bf9 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -102,3 +103,4 @@
         pDataOut++;
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp
index 8c43430..db57150 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -102,3 +103,4 @@
         pDataOut++;
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp
index 84fbadf..bc9e2df 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -102,3 +103,4 @@
         pDataOut++;
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
index 1cc7618..de06cb1 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 
@@ -35,3 +36,4 @@
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 
 #endif /* _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp
index 6817d9f..0b9fb5a 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 
@@ -55,3 +56,4 @@
 }
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_2I_D16F32Css_TRC_WRA_01_Init                              */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
index 4eeaaa8..2097c4f 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D32F32Cll_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -184,3 +185,4 @@
         }
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp
index 1e27391..2d2a61f 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "BQ_2I_D32F32Cll_TRC_WRA_01_Private.h"
 
@@ -54,5 +55,6 @@
     temp = pCoef->B1;
     pBiquadState->coefs[4] = temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_2I_D32F32C32_TRC_WRA_01_Init.c                              */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
index 4a2149d..029c89d 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 #define _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 
@@ -35,3 +36,4 @@
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 
 #endif /* _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
index 8887890..7046a94 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
@@ -18,53 +18,11 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
+#include <string.h>
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION COPY_16
-***********************************************************************************/
-
-void Copy_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    if (src > dst) {
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst++;
-            src++;
-        }
-    } else {
-        src += n - 1;
-        dst += n - 1;
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst--;
-            src--;
-        }
-    }
-
-    return;
-}
 void Copy_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    if (src > dst) {
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst++;
-            src++;
-        }
-    } else {
-        src += n - 1;
-        dst += n - 1;
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst--;
-            src--;
-        }
-    }
-
+    memmove(dst, src, n * sizeof(LVM_FLOAT));
     return;
 }
 // Extract out the stereo channel pair from multichannel source.
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp
index be9e49b..b7f4b55 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp
@@ -18,9 +18,9 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
 #include "Mixer_private.h"
 #include "LVM_Macros.h"
+#include "ScalarArithmetic.h"
 
 /**********************************************************************************
    FUNCTION CORE_MIXSOFT_1ST_D32C31_WRA
@@ -52,14 +52,7 @@
             Temp2 = *dst;
 
             Temp3 = Temp1 * (pInstance->Current);
-            Temp1 = Temp2 + Temp3;
-
-            if (Temp1 > 1.0f)
-                Temp1 = 1.0f;
-            else if (Temp1 < -1.0f)
-                Temp1 = -1.0f;
-
-            *dst++ = Temp1;
+            *dst++ = LVM_Clamp(Temp2 + Temp3);
         }
     }
 
@@ -72,13 +65,7 @@
             Temp2 = *dst;
 
             Temp3 = Temp1 * (pInstance->Current);
-            Temp1 = Temp2 + Temp3;
-
-            if (Temp1 > 1.0f)
-                Temp1 = 1.0f;
-            else if (Temp1 < -1.0f)
-                Temp1 = -1.0f;
-            *dst++ = Temp1;
+            *dst++ = LVM_Clamp(Temp2 + Temp3);
         }
     }
 }
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
index 2861be6..6e859f4 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
@@ -14,51 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
-void DC_2I_D16_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                          LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
-    LVM_FLOAT LeftDC, RightDC;
-    LVM_FLOAT Diff;
-    LVM_INT32 j;
-    PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State)pInstance;
-
-    LeftDC = pBiquadState->LeftDC;
-    RightDC = pBiquadState->RightDC;
-    for (j = NrSamples - 1; j >= 0; j--) {
-        /* Subtract DC and saturate */
-        Diff = *(pDataIn++) - (LeftDC);
-        if (Diff > 1.0f) {
-            Diff = 1.0f;
-        } else if (Diff < -1.0f) {
-            Diff = -1.0f;
-        }
-        *(pDataOut++) = (LVM_FLOAT)Diff;
-        if (Diff < 0) {
-            LeftDC -= DC_FLOAT_STEP;
-        } else {
-            LeftDC += DC_FLOAT_STEP;
-        }
-
-        /* Subtract DC an saturate */
-        Diff = *(pDataIn++) - (RightDC);
-        if (Diff > 1.0f) {
-            Diff = 1.0f;
-        } else if (Diff < -1.0f) {
-            Diff = -1.0f;
-        }
-        *(pDataOut++) = (LVM_FLOAT)Diff;
-        if (Diff < 0) {
-            RightDC -= DC_FLOAT_STEP;
-        } else {
-            RightDC += DC_FLOAT_STEP;
-        }
-    }
-    pBiquadState->LeftDC = LeftDC;
-    pBiquadState->RightDC = RightDC;
-}
+#include "ScalarArithmetic.h"
 /*
  * FUNCTION:       DC_Mc_D16_TRC_WRA_01
  *
@@ -89,12 +48,7 @@
         /* Subtract DC and saturate */
         for (i = NrChannels - 1; i >= 0; i--) {
             Diff = *(pDataIn++) - (ChDC[i]);
-            if (Diff > 1.0f) {
-                Diff = 1.0f;
-            } else if (Diff < -1.0f) {
-                Diff = -1.0f;
-            }
-            *(pDataOut++) = (LVM_FLOAT)Diff;
+            *(pDataOut++) = LVM_Clamp(Diff);
             if (Diff < 0) {
                 ChDC[i] -= DC_FLOAT_STEP;
             } else {
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
index 2828cb3..c16718c 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
@@ -17,11 +17,6 @@
 
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
-void DC_2I_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance) {
-    PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State)pInstance;
-    pBiquadState->LeftDC = 0.0f;
-    pBiquadState->RightDC = 0.0f;
-}
 void DC_Mc_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance) {
     PFilter_FLOAT_State_Mc pBiquadState = (PFilter_FLOAT_State_Mc)pInstance;
     LVM_INT32 i;
diff --git a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp
deleted file mode 100644
index 5daef59..0000000
--- a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "LVM_Types.h"
-#include "LVM_Macros.h"
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION DelayAllPass_32x32
-***********************************************************************************/
-
-void DelayAllPass_Sat_32x16To32(LVM_INT32* delay,           /* Delay buffer */
-                                LVM_UINT16 size,            /* Delay size */
-                                LVM_INT16 coeff,            /* All pass filter coefficient */
-                                LVM_UINT16 DelayOffset,     /* Simple delay offset */
-                                LVM_UINT16* pAllPassOffset, /* All pass filter delay offset */
-                                LVM_INT32* dst,             /* Source/destination */
-                                LVM_INT16 n)                /* Number of  samples */
-{
-    LVM_INT16 i;
-    LVM_UINT16 AllPassOffset = *pAllPassOffset;
-    LVM_INT32 temp;
-    LVM_INT32 a, b, c;
-
-    for (i = 0; i < n; i++) {
-        MUL32x16INTO32(delay[AllPassOffset], coeff, temp, 15) a = temp;
-        b = delay[DelayOffset];
-        DelayOffset++;
-
-        c = a + b;
-        if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (a < 0) {
-                c = 0x80000000L;
-            } else {
-                c = 0x7FFFFFFFL;
-            }
-        }
-        *dst = c;
-        dst++;
-
-        MUL32x16INTO32(c, -coeff, temp, 15) a = temp;
-        b = delay[AllPassOffset];
-        c = a + b;
-        if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (a < 0) {
-                c = 0x80000000L;
-            } else {
-                c = 0x7FFFFFFFL;
-            }
-        }
-        delay[AllPassOffset] = c;
-        AllPassOffset++;
-
-        /* Make the delay buffer a circular buffer */
-        if (DelayOffset >= size) {
-            DelayOffset = 0;
-        }
-
-        if (AllPassOffset >= size) {
-            AllPassOffset = 0;
-        }
-    }
-
-    /* Update the offset */
-    *pAllPassOffset = AllPassOffset;
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
index da75982..d2537eb 100644
--- a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
@@ -21,51 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION DelayMix_16x16
-***********************************************************************************/
-
-void DelayMix_16x16(const LVM_INT16* src, /* Source 1, to be delayed */
-                    LVM_INT16* delay,     /* Delay buffer */
-                    LVM_INT16 size,       /* Delay size */
-                    LVM_INT16* dst,       /* Source/destination */
-                    LVM_INT16* pOffset,   /* Delay offset */
-                    LVM_INT16 n)          /* Number of stereo samples */
-{
-    LVM_INT16 i;
-    LVM_INT16 Offset = *pOffset;
-    LVM_INT16 temp;
-
-    for (i = 0; i < n; i++) {
-        /* Left channel */
-        temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
-        *dst = temp;
-        dst++;
-
-        delay[Offset] = *src;
-        Offset++;
-        src++;
-
-        /* Right channel */
-        temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
-        *dst = temp;
-        dst++;
-
-        delay[Offset] = *src;
-        Offset++;
-        src++;
-
-        /* Make the reverb delay buffer a circular buffer */
-        if (Offset >= size) {
-            Offset = 0;
-        }
-    }
-
-    /* Update the offset */
-    *pOffset = Offset;
-
-    return;
-}
 void DelayMix_Float(const LVM_FLOAT* src, /* Source 1, to be delayed */
                     LVM_FLOAT* delay,     /* Delay buffer */
                     LVM_INT16 size,       /* Delay size */
@@ -107,4 +62,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp b/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp
deleted file mode 100644
index 47cffbf..0000000
--- a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION DelayMix_16x16
-***********************************************************************************/
-
-void DelayWrite_32(const LVM_INT32* src, /* Source 1, to be delayed */
-                   LVM_INT32* delay,     /* Delay buffer */
-                   LVM_UINT16 size,      /* Delay size */
-                   LVM_UINT16* pOffset,  /* Delay offset */
-                   LVM_INT16 n)          /* Number of samples */
-{
-    LVM_INT16 i;
-    LVM_INT16 Offset = (LVM_INT16)*pOffset;
-
-    for (i = 0; i < n; i++) {
-        delay[Offset] = *src;
-        Offset++;
-        src++;
-
-        /* Make the delay buffer a circular buffer */
-        if (Offset >= size) {
-            Offset = 0;
-        }
-    }
-
-    /* Update the offset */
-    *pOffset = (LVM_UINT16)Offset;
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp
index df8fadc..c85dfb6 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "FO_1I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -62,3 +63,4 @@
         *pDataOut++ = (LVM_FLOAT)ynL;  // Write Left output
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp
index 10604bf..0cff849 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "FO_1I_D16F16Css_TRC_WRA_01_Private.h"
 
@@ -52,3 +53,4 @@
 }
 /*------------------------------------------------*/
 /* End Of File: FO_1I_D16F16Css_TRC_WRA_01_Init.c */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
index d1819fc..50b09b6 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 
@@ -35,3 +36,4 @@
 
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 #endif /* _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp
index 4c75e04..dac090f 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "FO_1I_D32F32Cll_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -63,3 +64,4 @@
         *pDataOut++ = (LVM_FLOAT)ynL;  // Write Left output in Q0
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp
index bf2e5e1..efd6bc0 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "FO_1I_D32F32Cll_TRC_WRA_01_Private.h"
 
@@ -50,5 +51,6 @@
     temp = pCoef->B1;
     pBiquadState->coefs[2] = temp;
 }
+#endif
 /*------------------------------------------------*/
 /* End Of File: FO_1I_D32F32Cll_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
index 8645593..95705be 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 #define _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 
@@ -34,3 +35,4 @@
 
 typedef Filter_State_FLOAT* PFilter_State_FLOAT;
 #endif /* _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
index dad070b..1e3f1e8 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
@@ -24,86 +25,6 @@
 COEFS-
 pBiquadState->coefs[0] is A1,
 pBiquadState->coefs[1] is A0,
-pBiquadState->coefs[2] is -B1, these are in Q15 format
-pBiquadState->Shift    is Shift value
-DELAYS-
-pBiquadState->pDelays[0] is x(n-1)L in Q15 format
-pBiquadState->pDelays[1] is y(n-1)L in Q30 format
-pBiquadState->pDelays[2] is x(n-1)R in Q15 format
-pBiquadState->pDelays[3] is y(n-1)R in Q30 format
-***************************************************************************/
-void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                     LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
-    LVM_FLOAT ynL, ynR;
-    LVM_FLOAT Temp;
-    LVM_FLOAT NegSatValue;
-    LVM_INT16 ii;
-
-    PFilter_Float_State pBiquadState = (PFilter_Float_State)pInstance;
-
-    NegSatValue = -1.0f;
-
-    for (ii = NrSamples; ii != 0; ii--) {
-        /**************************************************************************
-                        PROCESSING OF THE LEFT CHANNEL
-        ***************************************************************************/
-
-        // ynL =A1  * x(n-1)L
-        ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
-        // ynR =A1  * x(n-1)R
-        ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
-
-        // ynL+=A0  * x(n)L
-        ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
-        // ynR+=A0  * x(n)L
-        ynR += (LVM_FLOAT)pBiquadState->coefs[1] * (*(pDataIn + 1));
-
-        // ynL +=  (-B1  * y(n-1)L  )
-        Temp = pBiquadState->pDelays[1] * pBiquadState->coefs[2];
-        ynL += Temp;
-        // ynR +=  (-B1  * y(n-1)R ) )
-        Temp = pBiquadState->pDelays[3] * pBiquadState->coefs[2];
-        ynR += Temp;
-
-        /**************************************************************************
-                        UPDATING THE DELAYS
-        ***************************************************************************/
-        pBiquadState->pDelays[1] = ynL;           // Update y(n-1)L
-        pBiquadState->pDelays[0] = (*pDataIn++);  // Update x(n-1)L
-
-        pBiquadState->pDelays[3] = ynR;           // Update y(n-1)R
-        pBiquadState->pDelays[2] = (*pDataIn++);  // Update x(n-1)R
-
-        /**************************************************************************
-                        WRITING THE OUTPUT
-        ***************************************************************************/
-
-        /*Saturate results*/
-        if (ynL > 1.0f) {
-            ynL = 1.0f;
-        } else {
-            if (ynL < NegSatValue) {
-                ynL = NegSatValue;
-            }
-        }
-
-        if (ynR > 1.0f) {
-            ynR = 1.0f;
-        } else {
-            if (ynR < NegSatValue) {
-                ynR = NegSatValue;
-            }
-        }
-
-        *pDataOut++ = (LVM_FLOAT)ynL;
-        *pDataOut++ = (LVM_FLOAT)ynR;
-    }
-}
-/**************************************************************************
-ASSUMPTIONS:
-COEFS-
-pBiquadState->coefs[0] is A1,
-pBiquadState->coefs[1] is A0,
 pBiquadState->coefs[2] is -B1,
 DELAYS-
 pBiquadState->pDelays[2*ch + 0] is x(n-1) of the 'ch' - channel
@@ -173,3 +94,4 @@
         pDelays -= NrChannels * 2;
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp
index 552aeda..54fbe4a 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
  */
 
 /*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
 
@@ -51,5 +52,6 @@
     temp = pCoef->B1;
     pBiquadState->coefs[2] = temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c                     */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
index 0103328..a71fa32 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_
 #define _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_
 
@@ -27,3 +28,4 @@
 
 typedef Filter_Float_State* PFilter_Float_State;
 #endif /* _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
index b050267..e2f8c67 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
@@ -21,33 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION  From2iToMS_16x16
-***********************************************************************************/
-
-void From2iToMS_16x16(const LVM_INT16* src, LVM_INT16* dstM, LVM_INT16* dstS, LVM_INT16 n) {
-    LVM_INT32 temp1, left, right;
-    LVM_INT16 ii;
-    for (ii = n; ii != 0; ii--) {
-        left = (LVM_INT32)*src;
-        src++;
-
-        right = (LVM_INT32)*src;
-        src++;
-
-        /* Compute M signal*/
-        temp1 = (left + right) >> 1;
-        *dstM = (LVM_INT16)temp1;
-        dstM++;
-
-        /* Compute S signal*/
-        temp1 = (left - right) >> 1;
-        *dstS = (LVM_INT16)temp1;
-        dstS++;
-    }
-
-    return;
-}
 void From2iToMS_Float(const LVM_FLOAT* src, LVM_FLOAT* dstM, LVM_FLOAT* dstS, LVM_INT16 n) {
     LVM_FLOAT temp1, left, right;
     LVM_INT16 ii;
@@ -71,4 +44,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp
deleted file mode 100644
index 9a54ee4..0000000
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION From2iToMono_16
-***********************************************************************************/
-
-void From2iToMono_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 Temp;
-    for (ii = n; ii != 0; ii--) {
-        Temp = (LVM_INT32)*src;
-        src++;
-
-        Temp += (LVM_INT32)*src;
-        src++;
-
-        *dst = (LVM_INT16)(Temp >> 1);
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
index 6ede958..039ee14 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
@@ -21,27 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION From2iToMono_32
-***********************************************************************************/
-
-void From2iToMono_32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 Temp;
-
-    for (ii = n; ii != 0; ii--) {
-        Temp = (*src >> 1);
-        src++;
-
-        Temp += (*src >> 1);
-        src++;
-
-        *dst = Temp;
-        dst++;
-    }
-
-    return;
-}
 void From2iToMono_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     LVM_FLOAT Temp;
@@ -93,5 +72,3 @@
 
     return;
 }
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp b/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp
deleted file mode 100644
index 9ddcbe4..0000000
--- a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION INT16LSHIFTTOINT32_16X32
-***********************************************************************************/
-
-void Int16LShiftToInt32_16x32(const LVM_INT16* src, LVM_INT32* dst, LVM_INT16 n, LVM_INT16 shift) {
-    LVM_INT16 ii;
-
-    src += n - 1;
-    dst += n - 1;
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = (((LVM_INT32)*src) << shift);
-        src--;
-        dst--;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp
deleted file mode 100644
index 2584117..0000000
--- a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION INT32RSHIFTTOINT16_SAT_32X16
-***********************************************************************************/
-
-void Int32RShiftToInt16_Sat_32x16(const LVM_INT32* src, LVM_INT16* dst, LVM_INT16 n,
-                                  LVM_INT16 shift) {
-    LVM_INT32 temp;
-    LVM_INT16 ii;
-
-    for (ii = n; ii != 0; ii--) {
-        temp = *src >> shift;
-        src++;
-
-        if (temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)temp;
-        }
-
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
index 0721b76..6c7c8ae 100644
--- a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
@@ -21,29 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION JoinTo2i_32x32
-***********************************************************************************/
-
-void JoinTo2i_32x32(const LVM_INT32* srcL, const LVM_INT32* srcR, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    srcL += n - 1;
-    srcR += n - 1;
-    dst += ((2 * n) - 1);
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = *srcR;
-        dst--;
-        srcR--;
-
-        *dst = *srcL;
-        dst--;
-        srcL--;
-    }
-
-    return;
-}
 void JoinTo2i_Float(const LVM_FLOAT* srcL, const LVM_FLOAT* srcR, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
index 8b00925..d670b3d 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
@@ -18,39 +18,10 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
 #include "LVC_Mixer_Private.h"
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION LVC_Core_MixHard_1St_2i_D16C31_SAT
-***********************************************************************************/
-void LVC_Core_MixHard_1St_2i_D16C31_SAT(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n) {
-    LVM_FLOAT Temp;
-    LVM_INT16 ii;
-    Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
-    Mix_Private_FLOAT_st* pInstance2 = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
-    for (ii = n; ii != 0; ii--) {
-        Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance1->Current);
-        if (Temp > 1.0f)
-            *dst++ = 1.0f;
-        else if (Temp < -1.0f)
-            *dst++ = -1.0f;
-        else
-            *dst++ = (LVM_FLOAT)Temp;
-
-        Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance2->Current);
-        if (Temp > 1.0f)
-            *dst++ = 1.0f;
-        else if (Temp < -1.0f)
-            *dst++ = -1.0f;
-        else
-            *dst++ = (LVM_FLOAT)Temp;
-    }
-}
 void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
     LVM_FLOAT Temp;
@@ -58,14 +29,8 @@
     for (ii = NrFrames; ii != 0; ii--) {
         for (jj = 0; jj < NrChannels; jj++) {
             Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance[jj]);
-            Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance1->Current);
-            if (Temp > 1.0f)
-                *dst++ = 1.0f;
-            else if (Temp < -1.0f)
-                *dst++ = -1.0f;
-            else
-                *dst++ = (LVM_FLOAT)Temp;
+            Temp =  *src++ * pInstance1->Current;
+            *dst++ = LVM_Clamp(Temp);
         }
     }
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp
index 31cd805..417c1f0 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp
@@ -18,8 +18,8 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
 #include "LVC_Mixer_Private.h"
+#include "ScalarArithmetic.h"
 
 /**********************************************************************************
    FUNCTION LVCore_MIXHARD_2ST_D16C31_SAT
@@ -34,18 +34,12 @@
     Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
     Mix_Private_FLOAT_st* pInstance2 = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
 
-    Current1 = (pInstance1->Current);
-    Current2 = (pInstance2->Current);
+    Current1 = pInstance1->Current;
+    Current2 = pInstance2->Current;
 
     for (ii = n; ii != 0; ii--) {
-        Temp = (((LVM_FLOAT) * (src1++) * (LVM_FLOAT)Current1)) +
-               (((LVM_FLOAT) * (src2++) * (LVM_FLOAT)Current2));
-        if (Temp > 1.0f)
-            *dst++ = 1.0f;
-        else if (Temp < -1.0f)
-            *dst++ = -1.0f;
-        else
-            *dst++ = Temp;
+        Temp =  *src1++ * Current1 + *src2++ * Current2;
+        *dst++ = LVM_Clamp(Temp);
     }
 }
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
index b7865d9..d8c25c9 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
@@ -18,9 +18,9 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
 #include "LVC_Mixer_Private.h"
 #include "LVM_Macros.h"
+#include "ScalarArithmetic.h"
 
 /**********************************************************************************
    FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
@@ -46,13 +46,8 @@
             if (Current > Target) Current = Target;
 
             for (ii = OutLoop; ii != 0; ii--) {
-                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = (LVM_FLOAT)Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
 
@@ -62,13 +57,8 @@
             if (Current > Target) Current = Target;
 
             for (jj = 4; jj != 0; jj--) {
-                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = (LVM_FLOAT)Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
     } else {
@@ -77,13 +67,8 @@
             if (Current < Target) Current = Target;
 
             for (ii = OutLoop; ii != 0; ii--) {
-                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = (LVM_FLOAT)Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
 
@@ -92,13 +77,8 @@
             if (Current < Target) Current = Target;
 
             for (jj = 4; jj != 0; jj--) {
-                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = (LVM_FLOAT)Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
     }
@@ -148,13 +128,8 @@
             if (Current > Target) Current = Target;
 
             for (ii = OutLoop * NrChannels; ii != 0; ii--) {
-                Temp = (*dst) + (*(src++) * Current);
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
 
@@ -164,21 +139,11 @@
             if (Current > Target) Current = Target;
 
             for (jj = NrChannels; jj != 0; jj--) {
-                Temp = (*dst) + (*(src++) * Current);
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
 
-                Temp = (*dst) + (*(src++) * Current);
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
     } else {
@@ -187,13 +152,8 @@
             if (Current < Target) Current = Target;
 
             for (ii = OutLoop * NrChannels; ii != 0; ii--) {
-                Temp = (*dst) + (*(src++) * Current);
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
 
@@ -202,21 +162,11 @@
             if (Current < Target) Current = Target;
 
             for (jj = NrChannels; jj != 0; jj--) {
-                Temp = (*dst) + (*(src++) * Current);
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
 
-                Temp = (*dst) + (*(src++) * Current);
-                if (Temp > 1.0f)
-                    *dst++ = 1.0f;
-                else if (Temp < -1.0f)
-                    *dst++ = -1.0f;
-                else
-                    *dst++ = Temp;
+                Temp = *dst + *src++ * Current;
+                *dst++ = LVM_Clamp(Temp);
             }
         }
     }
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
index d45845a..0968cf8 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
@@ -18,107 +18,16 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
 #include "LVC_Mixer_Private.h"
-#include "ScalarArithmetic.h"
 #include "LVM_Macros.h"
+#include "ScalarArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA
-***********************************************************************************/
-static LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, LVM_FLOAT b, LVM_FLOAT c) {
-    LVM_FLOAT temp;
-    temp = a + b;
-    if (temp < -1.0f)
-        c = -1.0f;
-    else if (temp > 1.0f)
-        c = 1.0f;
-    else
-        c = temp;
-    return c;
-}
-void LVC_Core_MixSoft_1St_2i_D16C31_WRA(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n) {
-    LVM_INT16 OutLoop;
-    LVM_INT16 InLoop;
-    LVM_INT32 ii;
-    Mix_Private_FLOAT_st* pInstanceL = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
-    Mix_Private_FLOAT_st* pInstanceR = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
-
-    LVM_FLOAT DeltaL = pInstanceL->Delta;
-    LVM_FLOAT CurrentL = pInstanceL->Current;
-    LVM_FLOAT TargetL = pInstanceL->Target;
-
-    LVM_FLOAT DeltaR = pInstanceR->Delta;
-    LVM_FLOAT CurrentR = pInstanceR->Current;
-    LVM_FLOAT TargetR = pInstanceR->Target;
-
-    LVM_FLOAT Temp = 0;
-
-    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
-    OutLoop = (LVM_INT16)(n - (InLoop << 2));
-
-    if (OutLoop) {
-        if (CurrentL < TargetL) {
-            ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
-            CurrentL = Temp;
-            if (CurrentL > TargetL) CurrentL = TargetL;
-        } else {
-            CurrentL -= DeltaL;
-            if (CurrentL < TargetL) CurrentL = TargetL;
-        }
-
-        if (CurrentR < TargetR) {
-            ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
-            CurrentR = Temp;
-            if (CurrentR > TargetR) CurrentR = TargetR;
-        } else {
-            CurrentR -= DeltaR;
-            if (CurrentR < TargetR) CurrentR = TargetR;
-        }
-
-        for (ii = OutLoop * 2; ii != 0; ii -= 2) {
-            *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-            *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        }
-    }
-
-    for (ii = InLoop * 2; ii != 0; ii -= 2) {
-        if (CurrentL < TargetL) {
-            ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
-            CurrentL = Temp;
-            if (CurrentL > TargetL) CurrentL = TargetL;
-        } else {
-            CurrentL -= DeltaL;
-            if (CurrentL < TargetL) CurrentL = TargetL;
-        }
-
-        if (CurrentR < TargetR) {
-            ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
-            CurrentR = Temp;
-            if (CurrentR > TargetR) CurrentR = TargetR;
-        } else {
-            CurrentR -= DeltaR;
-            if (CurrentR < TargetR) CurrentR = TargetR;
-        }
-
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-    }
-    pInstanceL->Current = CurrentL;
-    pInstanceR->Current = CurrentR;
+static inline LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, LVM_FLOAT b) {
+    return LVM_Clamp(a + b);
 }
 void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
     LVM_INT32 ii, ch;
-    LVM_FLOAT Temp = 0.0f;
     LVM_FLOAT tempCurrent[NrChannels];
     for (ch = 0; ch < NrChannels; ch++) {
         tempCurrent[ch] = ptrInstance[ch]->Current;
@@ -130,8 +39,7 @@
             LVM_FLOAT Current = tempCurrent[ch];
             const LVM_FLOAT Target = pInstance->Target;
             if (Current < Target) {
-                ADD2_SAT_FLOAT(Current, Delta, Temp);
-                Current = Temp;
+                Current = ADD2_SAT_FLOAT(Current, Delta);
                 if (Current > Target) Current = Target;
             } else {
                 Current -= Delta;
@@ -145,4 +53,3 @@
         ptrInstance[ch]->Current = tempCurrent[ch];
     }
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
index f8c0a9d..fc464e6 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
@@ -18,7 +18,6 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
 #include "LVC_Mixer_Private.h"
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
@@ -35,20 +34,13 @@
     LVM_FLOAT Delta = (LVM_FLOAT)pInstance->Delta;
     LVM_FLOAT Current = (LVM_FLOAT)pInstance->Current;
     LVM_FLOAT Target = (LVM_FLOAT)pInstance->Target;
-    LVM_FLOAT Temp;
 
     InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
     OutLoop = (LVM_INT16)(n - (InLoop << 2));
 
     if (Current < Target) {
         if (OutLoop) {
-            Temp = Current + Delta;
-            if (Temp > 1.0f)
-                Temp = 1.0f;
-            else if (Temp < -1.0f)
-                Temp = -1.0f;
-
-            Current = Temp;
+            Current = LVM_Clamp(Current + Delta);
             if (Current > Target) Current = Target;
 
             for (ii = OutLoop; ii != 0; ii--) {
@@ -57,14 +49,8 @@
         }
 
         for (ii = InLoop; ii != 0; ii--) {
-            Temp = Current + Delta;
+            Current = LVM_Clamp(Current + Delta);
 
-            if (Temp > 1.0f)
-                Temp = 1.0f;
-            else if (Temp < -1.0f)
-                Temp = -1.0f;
-
-            Current = Temp;
             if (Current > Target) Current = Target;
 
             *(dst++) = (((LVM_FLOAT) * (src++) * Current));
@@ -121,7 +107,6 @@
     LVM_FLOAT Delta = (LVM_FLOAT)pInstance->Delta;
     LVM_FLOAT Current = (LVM_FLOAT)pInstance->Current;
     LVM_FLOAT Target = (LVM_FLOAT)pInstance->Target;
-    LVM_FLOAT Temp;
 
     /*
      * Same operation is performed on consecutive frames.
@@ -134,13 +119,7 @@
 
     if (Current < Target) {
         if (OutLoop) {
-            Temp = Current + Delta;
-            if (Temp > 1.0f)
-                Temp = 1.0f;
-            else if (Temp < -1.0f)
-                Temp = -1.0f;
-
-            Current = Temp;
+            Current = LVM_Clamp(Current + Delta);
             if (Current > Target) Current = Target;
 
             for (ii = OutLoop; ii != 0; ii--) {
@@ -151,14 +130,7 @@
         }
 
         for (ii = InLoop; ii != 0; ii--) {
-            Temp = Current + Delta;
-
-            if (Temp > 1.0f)
-                Temp = 1.0f;
-            else if (Temp < -1.0f)
-                Temp = -1.0f;
-
-            Current = Temp;
+            Current = LVM_Clamp(Current + Delta);
             if (Current > Target) Current = Target;
 
             for (jj = NrChannels; jj != 0; jj--) {
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
index c74c8c6..58bc06e 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
@@ -35,7 +35,7 @@
 #define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(*(a))))
 
 /**********************************************************************************
-   FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
+   FUNCTION LVC_MixSoft_1St_MC_float_SAT
 ***********************************************************************************/
 /* This threshold is used to decide on the processing to be applied on
  * front center and back center channels
@@ -192,106 +192,3 @@
         }
     }
 }
-void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st* ptrInstance, const LVM_FLOAT* src,
-                                   LVM_FLOAT* dst, LVM_INT16 n) {
-    char HardMixing = TRUE;
-    LVM_FLOAT TargetGain;
-    Mix_Private_FLOAT_st* pInstance1 =
-            (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[0].PrivateParams);
-    Mix_Private_FLOAT_st* pInstance2 =
-            (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[1].PrivateParams);
-
-    if (n <= 0) return;
-
-    /******************************************************************************
-       SOFT MIXING
-    *******************************************************************************/
-    if ((pInstance1->Current != pInstance1->Target) ||
-        (pInstance2->Current != pInstance2->Target)) {
-        if (pInstance1->Delta == 1.0f) {
-            pInstance1->Current = pInstance1->Target;
-            TargetGain = pInstance1->Target;
-            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
-        } else if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta) {
-            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
-                                                         Make them equal. */
-            TargetGain = pInstance1->Target;
-            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
-        } else {
-            /* Soft mixing has to be applied */
-            HardMixing = FALSE;
-        }
-
-        if (HardMixing == TRUE) {
-            if (pInstance2->Delta == 1.0f) {
-                pInstance2->Current = pInstance2->Target;
-                TargetGain = pInstance2->Target;
-                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
-            } else if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta) {
-                pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
-                                                             \ Make them equal. */
-                TargetGain = pInstance2->Target;
-                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
-            } else {
-                /* Soft mixing has to be applied */
-                HardMixing = FALSE;
-            }
-        }
-
-        if (HardMixing == FALSE) {
-            LVC_Core_MixSoft_1St_2i_D16C31_WRA(&(ptrInstance->MixerStream[0]),
-                                               &(ptrInstance->MixerStream[1]), src, dst, n);
-        }
-    }
-
-    /******************************************************************************
-       HARD MIXING
-    *******************************************************************************/
-
-    if (HardMixing) {
-        if ((pInstance1->Target == 1.0f) && (pInstance2->Target == 1.0f)) {
-            if (src != dst) {
-                Copy_Float(src, dst, n);
-            }
-        } else {
-            LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),
-                                               &(ptrInstance->MixerStream[1]), src, dst, n);
-        }
-    }
-
-    /******************************************************************************
-       CALL BACK
-    *******************************************************************************/
-
-    if (ptrInstance->MixerStream[0].CallbackSet) {
-        if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta) {
-            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
-                                                         Make them equal. */
-            TargetGain = pInstance1->Target;
-            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
-            ptrInstance->MixerStream[0].CallbackSet = FALSE;
-            if (ptrInstance->MixerStream[0].pCallBack != 0) {
-                (*ptrInstance->MixerStream[0].pCallBack)(
-                        ptrInstance->MixerStream[0].pCallbackHandle,
-                        ptrInstance->MixerStream[0].pGeneralPurpose,
-                        ptrInstance->MixerStream[0].CallbackParam);
-            }
-        }
-    }
-    if (ptrInstance->MixerStream[1].CallbackSet) {
-        if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta) {
-            pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
-                                                         Make them equal. */
-            TargetGain = pInstance2->Target;
-            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
-            ptrInstance->MixerStream[1].CallbackSet = FALSE;
-            if (ptrInstance->MixerStream[1].pCallBack != 0) {
-                (*ptrInstance->MixerStream[1].pCallBack)(
-                        ptrInstance->MixerStream[1].pCallbackHandle,
-                        ptrInstance->MixerStream[1].pGeneralPurpose,
-                        ptrInstance->MixerStream[1].CallbackParam);
-            }
-        }
-    }
-}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index 55255a6..1eb2dea 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -101,9 +101,6 @@
 void LVC_MixSoft_1St_MC_float_SAT(LVMixer3_2St_FLOAT_st* pInstance, const LVM_FLOAT* src,
                                   LVM_FLOAT* dst, /* dst can be equal to src */
                                   LVM_INT16 NrFrames, LVM_INT32 NrChannels, LVM_INT32 ChMask);
-void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st* pInstance, const LVM_FLOAT* src,
-                                   LVM_FLOAT* dst, /* dst can be equal to src */
-                                   LVM_INT16 n);   /* Number of stereo samples */
 
 /**********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
index 5f22d77..9206fae 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -65,9 +65,6 @@
 /**********************************************************************************/
 void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
-void LVC_Core_MixSoft_1St_2i_D16C31_WRA(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n);
 
 /**********************************************************************************/
 /* For applying different gains to Left and right chennals                        */
@@ -77,11 +74,5 @@
 /**********************************************************************************/
 void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
-void LVC_Core_MixHard_1St_2i_D16C31_SAT(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n);
-
-/*** 32 bit functions *************************************************************/
-/**********************************************************************************/
 
 #endif  //#ifndef __LVC_MIXER_PRIVATE_H__
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp b/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp
deleted file mode 100644
index a39fa2f..0000000
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION LoadConst_16
-***********************************************************************************/
-
-void LoadConst_16(const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = val;
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
index a19e66f..e5c6f15 100644
--- a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
@@ -18,49 +18,9 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
+#include "ScalarArithmetic.h"
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION  MSTO2I_SAT_16X16
-***********************************************************************************/
-
-void MSTo2i_Sat_16x16(const LVM_INT16* srcM, const LVM_INT16* srcS, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT32 temp, mVal, sVal;
-    LVM_INT16 ii;
-
-    for (ii = n; ii != 0; ii--) {
-        mVal = (LVM_INT32)*srcM;
-        srcM++;
-
-        sVal = (LVM_INT32)*srcS;
-        srcS++;
-
-        temp = mVal + sVal;
-
-        if (temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)temp;
-        }
-        dst++;
-
-        temp = mVal - sVal;
-
-        if (temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)temp;
-        }
-        dst++;
-    }
-
-    return;
-}
 void MSTo2i_Sat_Float(const LVM_FLOAT* srcM, const LVM_FLOAT* srcS, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_FLOAT temp, mVal, sVal;
     LVM_INT16 ii;
@@ -73,28 +33,11 @@
         srcS++;
 
         temp = mVal + sVal;
-
-        if (temp > 1.0f) {
-            *dst = 1.0f;
-        } else if (temp < -1.0f) {
-            *dst = -1.0f;
-        } else {
-            *dst = (LVM_FLOAT)temp;
-        }
-        dst++;
+        *dst++ = LVM_Clamp(temp);
 
         temp = mVal - sVal;
-
-        if (temp > 1.0f) {
-            *dst = 1.0f;
-        } else if (temp < -1.0f) {
-            *dst = -1.0f;
-        } else {
-            *dst = (LVM_FLOAT)temp;
-        }
-        dst++;
+        *dst++ = LVM_Clamp(temp);
     }
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp
deleted file mode 100644
index 1d450b0..0000000
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-
-     %created_by:    sra % (CM/S)
-     %name:          Mac3s_Sat_16x16.c % (CM/S)
-     %version:       1 % (CM/S)
-     %date_created:  Fri Nov 13 12:07:13 2009 % (CM/S)
-
-***********************************************************************************/
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-#include "LVM_Macros.h"
-
-/**********************************************************************************
-   FUNCTION Mac3S_16X16
-***********************************************************************************/
-
-void Mac3s_Sat_16x16(const LVM_INT16* src, const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT16 srcval;
-    LVM_INT32 Temp, dInVal;
-
-    for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
-
-        Temp = (srcval * val) >> 15;
-
-        dInVal = (LVM_INT32)*dst;
-
-        Temp = Temp + dInVal;
-
-        if (Temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (Temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)Temp;
-        }
-
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
index 0fe9fef..24bdf3e 100644
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
@@ -18,66 +18,19 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
+#include "ScalarArithmetic.h"
 #include "VectorArithmetic.h"
 #include "LVM_Macros.h"
 
-/**********************************************************************************
-   FUNCTION MAC3S_16X16
-***********************************************************************************/
-
-void Mac3s_Sat_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 srcval, temp, dInVal, dOutVal;
-
-    for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
-
-        MUL32x16INTO32(srcval, val, temp, 15)
-
-                dInVal = *dst;
-        dOutVal = temp + dInVal;
-
-        if ((((dOutVal ^ temp) & (dOutVal ^ dInVal)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (temp < 0) {
-                dOutVal = 0x80000000L;
-            } else {
-                dOutVal = 0x7FFFFFFFL;
-            }
-        }
-
-        *dst = dOutVal;
-        dst++;
-    }
-
-    return;
-}
 void Mac3s_Sat_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
-    LVM_FLOAT srcval;
-    LVM_FLOAT Temp, dInVal;
 
     for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
+        LVM_FLOAT Temp = *src++ * val;
+        Temp += *dst;
 
-        Temp = srcval * val;
-
-        dInVal = (LVM_FLOAT)*dst;
-        Temp = Temp + dInVal;
-
-        if (Temp > 1.000000f) {
-            *dst = 1.000000f;
-        } else if (Temp < -1.000000f) {
-            *dst = -1.000000f;
-        } else {
-            *dst = Temp;
-        }
-        dst++;
+        *dst++ = LVM_Clamp(Temp);
     }
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp b/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp
deleted file mode 100644
index 7ab5d49..0000000
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION MonoTo2I_16
-***********************************************************************************/
-
-void MonoTo2I_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    src += (n - 1);
-    dst += ((n * 2) - 1);
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = *src;
-        dst--;
-
-        *dst = *src;
-        dst--;
-        src--;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
index 1ba669f..ef3e633 100644
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
@@ -21,26 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION MonoTo2I_32
-***********************************************************************************/
-
-void MonoTo2I_32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    src += (n - 1);
-    dst += ((n * 2) - 1);
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = *src;
-        dst--;
-
-        *dst = *src;
-        dst--;
-        src--;
-    }
-
-    return;
-}
 void MonoTo2I_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     src += (n - 1);
@@ -57,4 +37,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
index 4589703..babfef3 100644
--- a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
@@ -22,26 +22,6 @@
 #include "VectorArithmetic.h"
 #include "LVM_Macros.h"
 
-/**********************************************************************************
-FUNCTION MULT3S_16X16
-***********************************************************************************/
-
-void Mult3s_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 srcval, temp;
-
-    for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
-
-        MUL32x16INTO32(srcval, val, temp, 15)
-
-                * dst = temp;
-        dst++;
-    }
-
-    return;
-}
 void Mult3s_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     LVM_FLOAT temp;
@@ -54,4 +34,3 @@
     }
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
index fba0666..f3a1a67 100644
--- a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
@@ -61,43 +61,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-void NonLinComp_D16(LVM_INT16 Gain, LVM_INT16* pDataIn, LVM_INT16* pDataOut,
-                    LVM_INT32 BlockLength) {
-    LVM_INT16 Sample;   /* Input samples */
-    LVM_INT32 SampleNo; /* Sample index */
-    LVM_INT16 Temp;
-
-    /*
-     * Process a block of samples
-     */
-    for (SampleNo = 0; SampleNo < BlockLength; SampleNo++) {
-        /*
-         * Read the input
-         */
-        Sample = *pDataIn;
-        pDataIn++;
-
-        /*
-         * Apply the compander, this compresses the signal at the expense of
-         * harmonic distortion. The amount of compression is control by the
-         * gain factor
-         */
-        if ((LVM_INT32)Sample != -32768) {
-            Temp = (LVM_INT16)((Sample * Sample) >> 15);
-            if (Sample > 0) {
-                Sample = (LVM_INT16)(Sample + ((Gain * (Sample - Temp)) >> 15));
-            } else {
-                Sample = (LVM_INT16)(Sample + ((Gain * (Sample + Temp)) >> 15));
-            }
-        }
-
-        /*
-         * Save the output
-         */
-        *pDataOut = Sample;
-        pDataOut++;
-    }
-}
 void NonLinComp_Float(LVM_FLOAT Gain, LVM_FLOAT* pDataIn, LVM_FLOAT* pDataOut,
                       LVM_INT32 BlockLength) {
     LVM_FLOAT Sample;   /* Input samples */
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
index 0afaad2..2a5540e 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
@@ -15,102 +15,12 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
 
 /**************************************************************************
- ASSUMPTIONS:
- COEFS-
- pBiquadState->coefs[0] is A0,
- pBiquadState->coefs[1] is -B2,
- pBiquadState->coefs[2] is -B1, these are in Q14 format
- pBiquadState->coefs[3] is Gain, in Q11 format
-
- DELAYS-
- pBiquadState->pDelays[0] is x(n-1)L in Q0 format
- pBiquadState->pDelays[1] is x(n-1)R in Q0 format
- pBiquadState->pDelays[2] is x(n-2)L in Q0 format
- pBiquadState->pDelays[3] is x(n-2)R in Q0 format
- pBiquadState->pDelays[4] is y(n-1)L in Q0 format
- pBiquadState->pDelays[5] is y(n-1)R in Q0 format
- pBiquadState->pDelays[6] is y(n-2)L in Q0 format
- pBiquadState->pDelays[7] is y(n-2)R in Q0 format
-***************************************************************************/
-void PK_2I_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                   LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
-    LVM_FLOAT ynL, ynR, ynLO, ynRO, templ;
-    LVM_INT16 ii;
-    PFilter_State_Float pBiquadState = (PFilter_State_Float)pInstance;
-
-    for (ii = NrSamples; ii != 0; ii--) {
-        /**************************************************************************
-                        PROCESSING OF THE LEFT CHANNEL
-        ***************************************************************************/
-        /* ynL= (A0  * (x(n)L - x(n-2)L  ) )*/
-        templ = (*pDataIn) - pBiquadState->pDelays[2];
-        ynL = templ * pBiquadState->coefs[0];
-
-        /* ynL+= ((-B2  * y(n-2)L  )) */
-        templ = pBiquadState->pDelays[6] * pBiquadState->coefs[1];
-        ynL += templ;
-
-        /* ynL+= ((-B1 * y(n-1)L  ) ) */
-        templ = pBiquadState->pDelays[4] * pBiquadState->coefs[2];
-        ynL += templ;
-
-        /* ynLO= ((Gain * ynL )) */
-        ynLO = ynL * pBiquadState->coefs[3];
-
-        /* ynLO=( ynLO + x(n)L  )*/
-        ynLO += (*pDataIn);
-
-        /**************************************************************************
-                        PROCESSING OF THE RIGHT CHANNEL
-        ***************************************************************************/
-        /* ynR= (A0  * (x(n)R  - x(n-2)R  ) ) */
-        templ = (*(pDataIn + 1)) - pBiquadState->pDelays[3];
-        ynR = templ * pBiquadState->coefs[0];
-
-        /* ynR+= ((-B2  * y(n-2)R  ) )  */
-        templ = pBiquadState->pDelays[7] * pBiquadState->coefs[1];
-        ynR += templ;
-
-        /* ynR+= ((-B1  * y(n-1)R  ) )   */
-        templ = pBiquadState->pDelays[5] * pBiquadState->coefs[2];
-        ynR += templ;
-
-        /* ynRO= ((Gain  * ynR )) */
-        ynRO = ynR * pBiquadState->coefs[3];
-
-        /* ynRO=( ynRO + x(n)R  )*/
-        ynRO += (*(pDataIn + 1));
-
-        /**************************************************************************
-                        UPDATING THE DELAYS
-        ***************************************************************************/
-        pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
-        pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
-        pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
-        pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
-        pBiquadState->pDelays[5] = ynR;                      /* Update y(n-1)R */
-        pBiquadState->pDelays[4] = ynL;                      /* Update y(n-1)L */
-        pBiquadState->pDelays[0] = (*pDataIn);               /* Update x(n-1)L */
-        pDataIn++;
-        pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
-        pDataIn++;
-
-        /**************************************************************************
-                        WRITING THE OUTPUT
-        ***************************************************************************/
-        *pDataOut = ynLO; /* Write Left output*/
-        pDataOut++;
-        *pDataOut = ynRO; /* Write Right output*/
-        pDataOut++;
-    }
-}
-
-/**************************************************************************
 DELAYS-
 pBiquadState->pDelays[0] to
 pBiquadState->pDelays[NrChannels - 1] is x(n-1) for all NrChannels
@@ -173,3 +83,4 @@
         }
     }
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
index 3f5d332..7fcd33c 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_
 #define _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_
 
@@ -28,3 +29,4 @@
 typedef Filter_State* PFilter_State;
 
 #endif /* _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp
index 178d766..d782631 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
 void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
@@ -31,3 +32,4 @@
 
     pBiquadState->coefs[3] = pCoef->G;
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
index 57a1c16..4c9f069 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#ifndef BIQUAD_OPT
 #ifndef _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_
 #define _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_
 
@@ -35,3 +36,4 @@
 typedef Filter_State* PFilter_State;
 
 #endif /* _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp b/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp
deleted file mode 100644
index 66f9132..0000000
--- a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION MULT3S_16X16
-***********************************************************************************/
-
-void Mult3s_16x16(const LVM_INT16* src, const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 temp;
-
-    for (ii = n; ii != 0; ii--) {
-        temp = (LVM_INT32)(*src) * (LVM_INT32)val;
-        src++;
-
-        *dst = (LVM_INT16)(temp >> 15);
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
index bccbe86..f4e625f 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
@@ -21,6 +21,9 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVEQNB.h"
 #include "LVEQNB_Private.h"
 #include "VectorArithmetic.h"
@@ -179,6 +182,9 @@
     LVM_UINT16 i;                    /* Filter band index */
     LVEQNB_BiquadType_en BiquadType; /* Filter biquad type */
 
+#ifdef BIQUAD_OPT
+    pInstance->gain.resize(pInstance->Params.NBands);
+#endif
     /*
      * Set the coefficients for each band by the init function
      */
@@ -198,8 +204,19 @@
                 /*
                  * Set the coefficients
                  */
+#ifdef BIQUAD_OPT
+                pInstance->gain[i] = Coefficients.G;
+                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                        Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+                        -(Coefficients.B2)};
+                pInstance->eqBiquad[i]
+                        .setCoefficients<
+                                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+                                coefs);
+#else
                 PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState_Float[i],
                                                    &pInstance->pEQNB_Taps_Float[i], &Coefficients);
+#endif
                 break;
             }
             default:
@@ -220,6 +237,11 @@
 /*                                                                                  */
 /************************************************************************************/
 void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t* pInstance) {
+#ifdef BIQUAD_OPT
+    for (size_t i = 0; i < pInstance->eqBiquad.size(); i++) {
+        pInstance->eqBiquad[i].clear();
+    }
+#else
     LVM_FLOAT* pTapAddress;
     LVM_INT16 NumTaps;
 
@@ -233,6 +255,7 @@
                         pTapAddress, /* Destination */
                         NumTaps);    /* Number of words */
     }
+#endif
 }
 /****************************************************************************************/
 /*                                                                                      */
@@ -310,6 +333,16 @@
             (OperatingModeSave == LVEQNB_ON && pInstance->bInOperatingModeTransition &&
              LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0);
 
+#ifdef BIQUAD_OPT
+    /*
+     * Create biquad instance
+     */
+    pInstance->eqBiquad.resize(
+            pParams->NBands, android::audio_utils::BiquadFilter<LVM_FLOAT>(
+                                     (FCC_1 == pParams->NrChannels) ? FCC_2 : pParams->NrChannels));
+    LVEQNB_ClearFilterHistory(pInstance);
+#endif
+
     if (bChange || modeChange) {
         /*
          * If the sample rate has changed clear the history
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
index 1d2a5f5..57df4db 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
@@ -62,6 +62,9 @@
     pInstance->pScratch = pScratch;
 
     /* Equaliser Biquad Instance */
+#ifdef BIQUAD_OPT
+    LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions));
+#else
     LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pEQNB_FilterState_Float));
     pInstance->pEQNB_FilterState_Float = (Biquad_FLOAT_Instance_t*)calloc(1, MemSize);
     if (pInstance->pEQNB_FilterState_Float == LVM_NULL) {
@@ -75,6 +78,7 @@
     }
 
     MemSize = (pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions)));
+#endif
     pInstance->pBandDefinitions = (LVEQNB_BandDef_t*)calloc(1, MemSize);
     if (pInstance->pBandDefinitions == LVM_NULL) {
         return LVEQNB_NULLADDRESS;
@@ -105,10 +109,11 @@
      */
     LVEQNB_SetFilters(pInstance, /* Set the filter types */
                       &pInstance->Params);
-
+#ifndef BIQUAD_OPT
     LVEQNB_SetCoefficients(pInstance); /* Set the filter coefficients */
 
     LVEQNB_ClearFilterHistory(pInstance); /* Clear the filter history */
+#endif
 
     /*
      * Initialise the bypass variables
@@ -154,6 +159,7 @@
     }
     pInstance = (LVEQNB_Instance_t*)*phInstance;
 
+#ifndef BIQUAD_OPT
     /* Equaliser Biquad Instance */
     if (pInstance->pEQNB_FilterState_Float != LVM_NULL) {
         free(pInstance->pEQNB_FilterState_Float);
@@ -163,6 +169,7 @@
         free(pInstance->pEQNB_Taps_Float);
         pInstance->pEQNB_Taps_Float = LVM_NULL;
     }
+#endif
     if (pInstance->pBandDefinitions != LVM_NULL) {
         free(pInstance->pBandDefinitions);
         pInstance->pBandDefinitions = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 83a3449..32bad29 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -24,6 +24,9 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVEQNB.h" /* Calling or Application layer definitions */
 #include "BIQUAD.h"
 #include "LVC_Mixer.h"
@@ -69,8 +72,14 @@
     /* Aligned memory pointers */
     LVM_FLOAT* pFastTemporary; /* Fast temporary data base address */
 
+#ifdef BIQUAD_OPT
+    std::vector<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            eqBiquad;            /* Biquad filter instances */
+    std::vector<LVM_FLOAT> gain; /* Gain values for all bands*/
+#else
     Biquad_2I_Order2_FLOAT_Taps_t* pEQNB_Taps_Float;  /* Equaliser Taps */
     Biquad_FLOAT_Instance_t* pEQNB_FilterState_Float; /* State for each filter band */
+#endif
 
     /* Filter definitions and call back */
     LVM_UINT16 NBands;                  /* Number of bands */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
index d2a26db..3f0be7c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
@@ -104,19 +104,30 @@
                  * Check if band is non-zero dB gain
                  */
                 if (pInstance->pBandDefinitions[i].Gain != 0) {
+#ifndef BIQUAD_OPT
                     /*
                      * Get the address of the biquad instance
                      */
                     Biquad_FLOAT_Instance_t* pBiquad = &pInstance->pEQNB_FilterState_Float[i];
+#endif
 
                     /*
                      * Select single or double precision as required
                      */
                     switch (pInstance->pBiquadType[i]) {
                         case LVEQNB_SinglePrecision_Float: {
+#ifdef BIQUAD_OPT
+                            LVM_FLOAT* pTemp = pScratch + NrSamples;
+                            pInstance->eqBiquad[i].process(pTemp, pScratch, NrFrames);
+                            const auto gain = pInstance->gain[i];
+                            for (unsigned j = 0; j < NrSamples; ++j) {
+                                pScratch[j] += pTemp[j] * gain;
+                            }
+#else
                             PK_Mc_D32F32C14G11_TRC_WRA_01(pBiquad, pScratch, pScratch,
                                                           (LVM_INT16)NrFrames,
                                                           (LVM_INT16)NrChannels);
+#endif
                             break;
                         }
                         default:
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
index 737ef01..a744339 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
     }
 
     /*
@@ -130,10 +148,6 @@
         LVM_INT16 i;
         LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4,
                                   LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
-        LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY,
-                                  LVREV_MAX_T3_DELAY};
-        LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, LVREV_MAX_AP2_DELAY,
-                                   LVREV_MAX_AP3_DELAY};
 
         /*
          * For each delay line
@@ -153,7 +167,7 @@
              * Set the fixed delay
              */
 
-            Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000;
+            Temp = (LVREV_MAX_T_DELAY[i] - LVREV_MAX_AP_DELAY[i]) * Fs / 192000;
             pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
 
             /*
@@ -231,8 +245,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..61b3732 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
@@ -56,31 +56,20 @@
      * 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);
-    if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4) {
-        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);
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
-        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_2) {
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-
-        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) {
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
+    for (size_t i = 0; i < pLVREV_Private->InstanceParams.NumDelays; i++) {
+#ifdef BIQUAD_OPT
+        pLVREV_Private->revLPFBiquad[i]->clear();
+#else
+        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[i], 2);
+#endif
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[i], LVREV_MAX_T_DELAY[i]);
     }
     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..fa96e52 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
@@ -120,11 +120,11 @@
     pLVREV_Private->MemoryTable = *pMemoryTable;
 
     if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-        MaxBlockSize = LVREV_MAX_AP3_DELAY;
+        MaxBlockSize = LVREV_MAX_AP_DELAY[3];
     } else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-        MaxBlockSize = LVREV_MAX_AP1_DELAY;
+        MaxBlockSize = LVREV_MAX_AP_DELAY[1];
     } else {
-        MaxBlockSize = LVREV_MAX_AP0_DELAY;
+        MaxBlockSize = LVREV_MAX_AP_DELAY[0];
     }
 
     if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
@@ -134,69 +134,30 @@
     /*
      * 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));
-    if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-        pLVREV_Private->pDelay_T[3] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[2] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[1] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[0] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
-        for (i = 0; i < 4; i++) {
-            /* Scratch for each delay line output */
-            pLVREV_Private->pScratchDelayLine[i] =
-                    (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-        }
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
-        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 (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-        pLVREV_Private->pDelay_T[1] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[0] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
-        for (i = 0; i < 2; i++) {
-            /* Scratch for each delay line output */
-            pLVREV_Private->pScratchDelayLine[i] =
-                    (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-        }
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
-    }
-
-    if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
-        pLVREV_Private->pDelay_T[0] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
-        for (i = 0; i < 1; i++) {
-            /* Scratch for each delay line output */
-            pLVREV_Private->pScratchDelayLine[i] =
-                    (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-        }
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#endif
+    for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+        pLVREV_Private->pDelay_T[i] = (LVM_FLOAT*)InstAlloc_AddMember(
+                &FastData, LVREV_MAX_T_DELAY[i] * sizeof(LVM_FLOAT));
+        /* Scratch for each delay line output */
+        pLVREV_Private->pScratchDelayLine[i] =
+                (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[i], LVREV_MAX_T_DELAY[i]);
     }
     /* All-pass delay buffer addresses and sizes */
-    pLVREV_Private->T[0] = LVREV_MAX_T0_DELAY;
-    pLVREV_Private->T[1] = LVREV_MAX_T1_DELAY;
-    pLVREV_Private->T[2] = LVREV_MAX_T2_DELAY;
-    pLVREV_Private->T[3] = LVREV_MAX_T3_DELAY;
+    for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
+        pLVREV_Private->T[i] = LVREV_MAX_T_DELAY[i];
+    }
     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);
@@ -299,14 +260,21 @@
         pLVREV_Private->FeedbackMixer[i].Target = 0;
     }
     /* Delay tap index */
-    pLVREV_Private->A_DelaySize[0] = LVREV_MAX_AP0_DELAY;
-    pLVREV_Private->B_DelaySize[0] = LVREV_MAX_AP0_DELAY;
-    pLVREV_Private->A_DelaySize[1] = LVREV_MAX_AP1_DELAY;
-    pLVREV_Private->B_DelaySize[1] = LVREV_MAX_AP1_DELAY;
-    pLVREV_Private->A_DelaySize[2] = LVREV_MAX_AP2_DELAY;
-    pLVREV_Private->B_DelaySize[2] = LVREV_MAX_AP2_DELAY;
-    pLVREV_Private->A_DelaySize[3] = LVREV_MAX_AP3_DELAY;
-    pLVREV_Private->B_DelaySize[3] = LVREV_MAX_AP3_DELAY;
+    for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
+        pLVREV_Private->A_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
+        pLVREV_Private->B_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
+    }
+
+#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);
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
index 2c1e04d..b344b20 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
@@ -63,7 +63,6 @@
     INST_ALLOC FastData;
     INST_ALLOC FastCoef;
     INST_ALLOC Temporary;
-    LVM_INT16 i;
     LVM_UINT16 MaxBlockSize;
 
     /*
@@ -117,11 +116,11 @@
          * Select the maximum internal block size
          */
         if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-            MaxBlockSize = LVREV_MAX_AP3_DELAY;
+            MaxBlockSize = LVREV_MAX_AP_DELAY[3];
         } else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-            MaxBlockSize = LVREV_MAX_AP1_DELAY;
+            MaxBlockSize = LVREV_MAX_AP_DELAY[1];
         } else {
-            MaxBlockSize = LVREV_MAX_AP0_DELAY;
+            MaxBlockSize = LVREV_MAX_AP_DELAY[0];
         }
 
         if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
@@ -139,21 +138,11 @@
         /*
          * Persistent fast data memory
          */
+#ifndef BIQUAD_OPT
         InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
-        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));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
+        for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T_DELAY[i] * sizeof(LVM_FLOAT));
         }
 
         pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size = InstAlloc_GetTotal(&FastData);
@@ -163,7 +152,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;
@@ -175,25 +166,9 @@
         InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
         /* Mono->stereo input saved for end mix */
         InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * MaxBlockSize);
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-            for (i = 0; i < 4; i++) {
-                /* A Scratch buffer for each delay line */
-                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-            }
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-            for (i = 0; i < 2; i++) {
-                /* A Scratch buffer for each delay line */
-                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-            }
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
-            for (i = 0; i < 1; i++) {
-                /* A Scratch buffer for each delay line */
-                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-            }
+        for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+            /* A Scratch buffer for each delay line */
+            InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
         }
 
         pMemoryTable->Region[LVM_TEMPORARY_FAST].Size = InstAlloc_GetTotal(&Temporary);
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index b6edb03..c62ad1e 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,21 +105,23 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#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 */
-
+    Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[LVREV_DELAYLINES_4]; /* Reverb low pass filters taps */
 } LVREV_FastData_st;
 
 /* Fast coefficient structure */
 typedef struct {
     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 */
-
+    Biquad_FLOAT_Instance_t
+            RevLPCoefs[LVREV_DELAYLINES_4]; /* Reverb low pass filters coefficients */
 } LVREV_FastCoef_st;
+#endif
+
 typedef struct {
     /* General */
     LVREV_InstanceParams_st InstanceParams; /* Initialisation time instance parameters */
@@ -134,30 +140,39 @@
                                                processing */
 
     /* Aligned memory pointers */
-    LVREV_FastData_st* pFastData;    /* Fast data memory base address */
-    LVREV_FastCoef_st* pFastCoef;    /* Fast coefficient memory base address */
-    LVM_FLOAT* pScratchDelayLine[4]; /* Delay line scratch memory */
+#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[LVREV_DELAYLINES_4]; /* Delay line scratch memory */
     LVM_FLOAT* pScratch;             /* Multi ussge scratch */
     LVM_FLOAT* pInputSave;           /* Reverb block input save for dry/wet
                                         mixing*/
 
     /* Feedback matrix */
-    Mix_1St_Cll_FLOAT_t FeedbackMixer[4]; /* Mixer for Pop and Click Suppression \
+    Mix_1St_Cll_FLOAT_t FeedbackMixer[LVREV_DELAYLINES_4]; /* Mixer for Pop and Click Suppression \
                                              caused by feedback Gain */
 
     /* All-Pass Filter */
-    LVM_INT32 T[4];                             /* Maximum delay size of buffer */
-    LVM_FLOAT* pDelay_T[4];                     /* Pointer to delay buffers */
-    LVM_INT32 Delay_AP[4];                      /* Offset to AP delay buffer start */
+    LVM_INT32 T[LVREV_DELAYLINES_4];                          /* Maximum delay size of buffer */
+    LVM_FLOAT* pDelay_T[LVREV_DELAYLINES_4];                  /* Pointer to delay buffers */
+    LVM_INT32 Delay_AP[LVREV_DELAYLINES_4];                   /* Offset to AP delay buffer start */
     LVM_INT16 AB_Selection;                     /* Smooth from tap A to B when 1 \
                                                    otherwise B to A */
-    LVM_INT32 A_DelaySize[4];                   /* A delay length in samples */
-    LVM_INT32 B_DelaySize[4];                   /* B delay length in samples */
-    LVM_FLOAT* pOffsetA[4];                     /* Offset for the A delay tap */
-    LVM_FLOAT* pOffsetB[4];                     /* Offset for the B delay tap */
-    Mix_2St_Cll_FLOAT_t Mixer_APTaps[4];        /* Smoothed AP delay mixer */
-    Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[4];    /* Smoothed SAfeedback gain */
-    Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[4]; /* Smoothed AP feedforward gain */
+    LVM_INT32 A_DelaySize[LVREV_DELAYLINES_4];                /* A delay length in samples */
+    LVM_INT32 B_DelaySize[LVREV_DELAYLINES_4];                /* B delay length in samples */
+    LVM_FLOAT* pOffsetA[LVREV_DELAYLINES_4];                  /* Offset for the A delay tap */
+    LVM_FLOAT* pOffsetB[LVREV_DELAYLINES_4];                  /* Offset for the B delay tap */
+    Mix_2St_Cll_FLOAT_t Mixer_APTaps[LVREV_DELAYLINES_4];     /* Smoothed AP delay mixer */
+    Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[LVREV_DELAYLINES_4]; /* Smoothed SAfeedback gain */
+    Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[LVREV_DELAYLINES_4]; /* Smoothed AP feedforward gain */
 
     /* Output gain */
     Mix_2St_Cll_FLOAT_t BypassMixer; /* Dry/wet mixer */
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
     }
 
     /*
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
index 35a6522..bb6cf12 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
@@ -29,6 +29,11 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+const LVM_INT16 LVREV_MAX_T_DELAY[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY,
+                                       LVREV_MAX_T3_DELAY};
+const LVM_INT16 LVREV_MAX_AP_DELAY[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY,
+                                        LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
+
 /* Table with supported sampling rates.  The table can be indexed using LVM_Fs_en       */
 const LVM_UINT32 LVM_FsTable[] = {8000,  11025, 12000, 16000, 22050,  24000, 32000,
                                   44100, 48000, 88200, 96000, 176400, 192000};
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
index 4b0dcca..723d1ff 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
@@ -35,6 +35,8 @@
 extern LVM_UINT32 LVM_GetFsFromTable(LVM_Fs_en FsIndex);
 
 extern const LVM_FLOAT LVREV_GainPolyTable[24][5];
+extern const LVM_INT16 LVREV_MAX_T_DELAY[];
+extern const LVM_INT16 LVREV_MAX_AP_DELAY[];
 
 #endif /** _LVREV_TABLES_H_ **/
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
index 4e90a42..436e7cb 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
@@ -15,6 +15,9 @@
  * limitations under the License.
  */
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVPSA.h"
 #include "LVPSA_Private.h"
 #include "VectorArithmetic.h"
@@ -182,6 +185,13 @@
                 break;
             }
         }
+#ifdef BIQUAD_OPT
+        /*
+         * Create biquad instance
+         */
+        pInst->specBiquad.resize(pInst->nRelevantFilters,
+                                 android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1));
+#endif
         LVPSA_SetBPFiltersType(pInst, &Params);
         LVPSA_SetBPFCoefficients(pInst, &Params);
         LVPSA_SetQPFCoefficients(pInst, &Params);
@@ -302,8 +312,18 @@
                 /*
                  * Set the coefficients
                  */
+#ifdef BIQUAD_OPT
+                const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                        Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+                        -(Coefficients.B2)};
+                pInst->specBiquad[ii]
+                        .setCoefficients<
+                                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+                                coefs);
+#else
                 BP_1I_D16F32Cll_TRC_WRA_01_Init(&pInst->pBP_Instances[ii], &pInst->pBP_Taps[ii],
                                                 &Coefficients);
+#endif
                 break;
             }
 
@@ -319,8 +339,18 @@
                 /*
                  * Set the coefficients
                  */
+#ifdef BIQUAD_OPT
+                const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                        Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+                        -(Coefficients.B2)};
+                pInst->specBiquad[ii]
+                        .setCoefficients<
+                                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+                                coefs);
+#else
                 BP_1I_D16F16Css_TRC_WRA_01_Init(&pInst->pBP_Instances[ii], &pInst->pBP_Taps[ii],
                                                 &Coefficients);
+#endif
                 break;
             }
         }
@@ -604,6 +634,11 @@
 /*                                                                                  */
 /************************************************************************************/
 LVPSA_RETURN LVPSA_ClearFilterHistory(LVPSA_InstancePr_t* pInst) {
+#ifdef BIQUAD_OPT
+    for (size_t i = 0; i < pInst->specBiquad.size(); i++) {
+        pInst->specBiquad[i].clear();
+    }
+#else
     LVM_INT8* pTapAddress;
     LVM_UINT32 i;
 
@@ -617,6 +652,7 @@
     for (i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++) {
         pTapAddress[i] = 0;
     }
+#endif
 
     return (LVPSA_OK);
 }
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
index 9a2b29f..f77460b 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
@@ -108,21 +108,25 @@
     if (pLVPSA_Inst->pBPFiltersPrecision == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#ifndef BIQUAD_OPT
     pLVPSA_Inst->pBP_Instances = (Biquad_FLOAT_Instance_t*)calloc(
             pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Instances)));
     if (pLVPSA_Inst->pBP_Instances == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#endif
     pLVPSA_Inst->pQPD_States =
             (QPD_FLOAT_State_t*)calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_States)));
     if (pLVPSA_Inst->pQPD_States == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#ifndef BIQUAD_OPT
     pLVPSA_Inst->pBP_Taps = (Biquad_1I_Order2_FLOAT_Taps_t*)calloc(
             pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Taps)));
     if (pLVPSA_Inst->pBP_Taps == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#endif
     pLVPSA_Inst->pQPD_Taps =
             (QPD_FLOAT_Taps_t*)calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_Taps)));
     if (pLVPSA_Inst->pQPD_Taps == LVM_NULL) {
@@ -193,18 +197,22 @@
         free(pLVPSA_Inst->pBPFiltersPrecision);
         pLVPSA_Inst->pBPFiltersPrecision = LVM_NULL;
     }
+#ifndef BIQUAD_OPT
     if (pLVPSA_Inst->pBP_Instances != LVM_NULL) {
         free(pLVPSA_Inst->pBP_Instances);
         pLVPSA_Inst->pBP_Instances = LVM_NULL;
     }
+#endif
     if (pLVPSA_Inst->pQPD_States != LVM_NULL) {
         free(pLVPSA_Inst->pQPD_States);
         pLVPSA_Inst->pQPD_States = LVM_NULL;
     }
+#ifndef BIQUAD_OPT
     if (pLVPSA_Inst->pBP_Taps != LVM_NULL) {
         free(pLVPSA_Inst->pBP_Taps);
         pLVPSA_Inst->pBP_Taps = LVM_NULL;
     }
+#endif
     if (pLVPSA_Inst->pQPD_Taps != LVM_NULL) {
         free(pLVPSA_Inst->pQPD_Taps);
         pLVPSA_Inst->pQPD_Taps = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index e00c11c..553156f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -18,6 +18,9 @@
 #ifndef _LVPSA_PRIVATE_H_
 #define _LVPSA_PRIVATE_H_
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVPSA.h"
 #include "BIQUAD.h"
 #include "LVPSA_QPD.h"
@@ -82,9 +85,14 @@
 
     LVPSA_BPFilterPrecision_en* pBPFiltersPrecision; /* Points a nBands elements array that contains
                                                         the filter precision for each band */
+#ifdef BIQUAD_OPT
+    std::vector<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            specBiquad; /* Biquad filter instances */
+#else
     Biquad_FLOAT_Instance_t* pBP_Instances;
     /* Points a nBands elements array that contains the band pass filter taps for each band */
     Biquad_1I_Order2_FLOAT_Taps_t* pBP_Taps;
+#endif
     /* Points a nBands elements array that contains the QPD filter instance for each band */
     QPD_FLOAT_State_t* pQPD_States;
     /* Points a nBands elements array that contains the QPD filter taps for each band */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
index 299dfd2..148b21f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
@@ -96,13 +96,23 @@
     for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++) {
         switch (pLVPSA_Inst->pBPFiltersPrecision[ii]) {
             case LVPSA_SimplePrecisionFilter:
+#ifdef BIQUAD_OPT
+                pLVPSA_Inst->specBiquad[ii].process(pScratch + InputBlockSize, pScratch,
+                                                    (LVM_INT16)InputBlockSize);
+#else
                 BP_1I_D16F16C14_TRC_WRA_01(&pLVPSA_Inst->pBP_Instances[ii], pScratch,
                                            pScratch + InputBlockSize, (LVM_INT16)InputBlockSize);
+#endif
                 break;
 
             case LVPSA_DoublePrecisionFilter:
+#ifdef BIQUAD_OPT
+                pLVPSA_Inst->specBiquad[ii].process(pScratch + InputBlockSize, pScratch,
+                                                    (LVM_INT16)InputBlockSize);
+#else
                 BP_1I_D16F32C30_TRC_WRA_01(&pLVPSA_Inst->pBP_Instances[ii], pScratch,
                                            pScratch + InputBlockSize, (LVM_INT16)InputBlockSize);
+#endif
                 break;
             default:
                 break;
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
index bad9aef..a5952fb 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
@@ -21,6 +21,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVCS.h"
 #include "LVCS_Private.h"
 #include "LVCS_Equaliser.h"
@@ -56,14 +59,18 @@
 LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t hInstance, LVCS_Params_t* pParams) {
     LVM_UINT16 Offset;
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
+#ifndef BIQUAD_OPT
     LVCS_Equaliser_t* pConfig = (LVCS_Equaliser_t*)&pInstance->Equaliser;
     LVCS_Data_t* pData;
     LVCS_Coefficient_t* pCoefficients;
     BQ_FLOAT_Coefs_t Coeffs;
+#endif
     const BiquadA012B12CoefsSP_t* pEqualiserCoefTable;
 
+#ifndef BIQUAD_OPT
     pData = (LVCS_Data_t*)pInstance->pData;
     pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
     /*
      * If the sample rate changes re-initialise the filters
      */
@@ -75,6 +82,13 @@
         Offset = (LVM_UINT16)(pParams->SampleRate + (pParams->SpeakerType * (1 + LVM_FS_48000)));
         pEqualiserCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_EqualiserCoefTable[0];
 
+#ifdef BIQUAD_OPT
+        std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                pEqualiserCoefTable[Offset].A0, pEqualiserCoefTable[Offset].A1,
+                pEqualiserCoefTable[Offset].A2, -(pEqualiserCoefTable[Offset].B1),
+                -(pEqualiserCoefTable[Offset].B2)};
+        pInstance->pEqBiquad.reset(new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_2, coefs));
+#else
         /* Left and right filters */
         /* Convert incoming coefficients to the required format/ordering */
         Coeffs.A0 = (LVM_FLOAT)pEqualiserCoefTable[Offset].A0;
@@ -103,6 +117,7 @@
                 pConfig->pBiquadCallBack = BQ_2I_D16F32C15_TRC_WRA_01;
                 break;
         }
+#endif
     }
 
     return (LVCS_SUCCESS);
@@ -129,19 +144,25 @@
 LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t hInstance, LVM_FLOAT* pInputOutput,
                                     LVM_UINT16 NumSamples) {
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
+#ifndef BIQUAD_OPT
     LVCS_Equaliser_t* pConfig = (LVCS_Equaliser_t*)&pInstance->Equaliser;
     LVCS_Coefficient_t* pCoefficients;
 
     pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
 
     /*
      * Check if the equaliser is required
      */
     if ((pInstance->Params.OperatingMode & LVCS_EQUALISERSWITCH) != 0) {
         /* Apply filter to the left and right channels */
+#ifdef BIQUAD_OPT
+        pInstance->pEqBiquad->process(pInputOutput, pInputOutput, NumSamples);
+#else
         (pConfig->pBiquadCallBack)(
                 (Biquad_FLOAT_Instance_t*)&pCoefficients->EqualiserBiquadInstance,
                 (LVM_FLOAT*)pInputOutput, (LVM_FLOAT*)pInputOutput, (LVM_INT16)NumSamples);
+#endif
     }
 
     return (LVCS_SUCCESS);
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
index c0d0950..18b350d 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
@@ -23,12 +23,12 @@
 /*    Structures                                                                    */
 /*                                                                                  */
 /************************************************************************************/
-
+#ifndef BIQUAD_OPT
 /* Equaliser structure */
 typedef struct {
     void (*pBiquadCallBack)(Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
 } LVCS_Equaliser_t;
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /*    Function prototypes                                                           */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
index 5c8f1ae..f23261f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
@@ -123,6 +123,7 @@
     if (pInstance == LVM_NULL) {
         return;
     }
+#ifndef BIQUAD_OPT
     if (pInstance->pCoeff != LVM_NULL) {
         free(pInstance->pCoeff);
         pInstance->pCoeff = LVM_NULL;
@@ -131,6 +132,7 @@
         free(pInstance->pData);
         pInstance->pData = LVM_NULL;
     }
+#endif
     free(pInstance);
     *phInstance = LVM_NULL;
     return;
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index f9c23b3..605a204 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -33,6 +33,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVCS.h"                 /* Calling or Application layer definitions */
 #include "LVCS_StereoEnhancer.h"  /* Stereo enhancer module definitions */
 #include "LVCS_ReverbGenerator.h" /* Reverberation module definitions */
@@ -110,7 +113,9 @@
     /* Sub-block configurations */
     LVCS_StereoEnhancer_t StereoEnhancer; /* Stereo enhancer configuration */
     LVCS_ReverbGenerator_t Reverberation; /* Reverberation configuration */
+#ifndef BIQUAD_OPT
     LVCS_Equaliser_t Equaliser;           /* Equaliser configuration */
+#endif
     LVCS_BypassMix_t BypassMix;           /* Bypass mixer configuration */
 
     /* Bypass variable */
@@ -120,12 +125,24 @@
     LVM_INT16 bTimerDone;                 /* Timer completion flag */
     LVM_Timer_Params_t TimerParams;       /* Timer parameters */
     LVM_Timer_Instance_t TimerInstance;   /* Timer instance */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pEqBiquad; /* Biquad filter instance for Equaliser */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pRevBiquad; /* Biquad filter instance for Reverberation */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pSEMidBiquad; /* Biquad filter instance for Stereo enhancement mid */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pSESideBiquad; /* Biquad filter instance for Stereo enhancement side */
+#else
     void* pCoeff;                         /* pointer to buffer for equaliser filter coeffs */
     void* pData;                          /* pointer to buffer for equaliser filter states */
+#endif
     void* pScratch;                       /* Pointer to bundle scratch buffer */
 
 } LVCS_Instance_t;
 
+#ifndef BIQUAD_OPT
 /* Coefficient Structure */
 typedef struct {
     Biquad_FLOAT_Instance_t EqualiserBiquadInstance;
@@ -141,6 +158,7 @@
     Biquad_1I_Order1_FLOAT_Taps_t SEBiquadTapsMid;
     Biquad_1I_Order2_FLOAT_Taps_t SEBiquadTapsSide;
 } LVCS_Data_t;
+#endif
 
 void LVCS_TimerCallBack(void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam);
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
index f6d2453..82a3a43 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
@@ -20,6 +20,9 @@
 /*  Includes                                                                        */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include <stdlib.h>
 #include "LVCS.h"
 #include "LVCS_Private.h"
@@ -62,11 +65,14 @@
     LVM_UINT16 Offset;
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
     LVCS_ReverbGenerator_t* pConfig = (LVCS_ReverbGenerator_t*)&pInstance->Reverberation;
+#ifndef BIQUAD_OPT
     LVCS_Data_t* pData;
     LVCS_Coefficient_t* pCoefficients;
     BQ_FLOAT_Coefs_t Coeffs;
+#endif
     const BiquadA012B12CoefsSP_t* pReverbCoefTable;
 
+#ifndef BIQUAD_OPT
     if (pInstance->pData == LVM_NULL) {
         pInstance->pData = pData = (LVCS_Data_t*)calloc(1, sizeof(*pData));
         if (pData == LVM_NULL) {
@@ -83,6 +89,7 @@
     } else {
         pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
     }
+#endif
 
     /*
      * Initialise the delay and filters if:
@@ -109,6 +116,14 @@
         Offset = (LVM_UINT16)pParams->SampleRate;
         pReverbCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_ReverbCoefTable[0];
 
+#ifdef BIQUAD_OPT
+        std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                pReverbCoefTable[Offset].A0, pReverbCoefTable[Offset].A1,
+                pReverbCoefTable[Offset].A2, -(pReverbCoefTable[Offset].B1),
+                -(pReverbCoefTable[Offset].B2)};
+        pInstance->pRevBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_2, coefs));
+#else
         /* Convert incoming coefficients to the required format/ordering */
         Coeffs.A0 = (LVM_FLOAT)pReverbCoefTable[Offset].A0;
         Coeffs.A1 = (LVM_FLOAT)pReverbCoefTable[Offset].A1;
@@ -133,6 +148,7 @@
                 pConfig->pBiquadCallBack = BQ_2I_D16F16C15_TRC_WRA_01;
                 break;
         }
+#endif
 
         /*
          * Setup the mixer
@@ -190,10 +206,14 @@
                                           LVM_FLOAT* pOutData, LVM_UINT16 NumSamples) {
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
     LVCS_ReverbGenerator_t* pConfig = (LVCS_ReverbGenerator_t*)&pInstance->Reverberation;
+#ifndef BIQUAD_OPT
     LVCS_Coefficient_t* pCoefficients;
+#endif
     LVM_FLOAT* pScratch;
 
+#ifndef BIQUAD_OPT
     pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
     pScratch = (LVM_FLOAT*)pInstance->pScratch;
 
     /*
@@ -233,9 +253,13 @@
         /*
          * Filter the data
          */
+#ifdef BIQUAD_OPT
+        pInstance->pRevBiquad->process(pScratch, pScratch, NumSamples);
+#else
         (pConfig->pBiquadCallBack)((Biquad_FLOAT_Instance_t*)&pCoefficients->ReverbBiquadInstance,
                                    (LVM_FLOAT*)pScratch, (LVM_FLOAT*)pScratch,
                                    (LVM_INT16)NumSamples);
+#endif
 
         Mult3s_Float((LVM_FLOAT*)pScratch, pConfig->ReverbLevel, (LVM_FLOAT*)pScratch,
                      (LVM_INT16)(2 * NumSamples));
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
index b666da3..a200267 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
@@ -51,8 +51,10 @@
     LVM_FLOAT StereoSamples[2 * LVCS_STEREODELAY_CS_MAX_VAL];
     /* Reverb Level */
     LVM_FLOAT ReverbLevel;
+#ifndef BIQUAD_OPT
     /* Filter */
     void (*pBiquadCallBack)(Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
 } LVCS_ReverbGenerator_t;
 
 /************************************************************************************/
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
index ffa9c9b..0e488f5 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
@@ -21,6 +21,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVCS.h"
 #include "LVCS_Private.h"
 #include "LVCS_StereoEnhancer.h"
@@ -52,15 +55,19 @@
 LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t hInstance, LVCS_Params_t* pParams) {
     LVM_UINT16 Offset;
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
+#ifndef BIQUAD_OPT
     LVCS_StereoEnhancer_t* pConfig = (LVCS_StereoEnhancer_t*)&pInstance->StereoEnhancer;
     LVCS_Data_t* pData;
     LVCS_Coefficient_t* pCoefficient;
     FO_FLOAT_Coefs_t CoeffsMid;
     BQ_FLOAT_Coefs_t CoeffsSide;
+#endif
     const BiquadA012B12CoefsSP_t* pSESideCoefs;
 
+#ifndef BIQUAD_OPT
     pData = (LVCS_Data_t*)pInstance->pData;
     pCoefficient = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
 
     /*
      * If the sample rate or speaker type has changed update the filters
@@ -73,6 +80,13 @@
         /* Mid filter */
         Offset = (LVM_UINT16)pParams->SampleRate;
 
+#ifdef BIQUAD_OPT
+        std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                LVCS_SEMidCoefTable[Offset].A0, LVCS_SEMidCoefTable[Offset].A1, 0.0,
+                -(LVCS_SEMidCoefTable[Offset].B1), 0.0};
+        pInstance->pSEMidBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         /* Convert incoming coefficients to the required format/ordering */
         CoeffsMid.A0 = (LVM_FLOAT)LVCS_SEMidCoefTable[Offset].A0;
         CoeffsMid.A1 = (LVM_FLOAT)LVCS_SEMidCoefTable[Offset].A1;
@@ -91,11 +105,18 @@
         if (LVCS_SEMidCoefTable[Offset].Scale == 15) {
             pConfig->pBiquadCallBack_Mid = FO_1I_D16F16C15_TRC_WRA_01;
         }
+#endif
 
         Offset = (LVM_UINT16)(pParams->SampleRate);
         pSESideCoefs = (BiquadA012B12CoefsSP_t*)&LVCS_SESideCoefTable[0];
 
         /* Side filter */
+#ifdef BIQUAD_OPT
+        coefs = {pSESideCoefs[Offset].A0, pSESideCoefs[Offset].A1, pSESideCoefs[Offset].A2,
+                 -(pSESideCoefs[Offset].B1), -(pSESideCoefs[Offset].B2)};
+        pInstance->pSESideBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         /* Convert incoming coefficients to the required format/ordering */
         CoeffsSide.A0 = (LVM_FLOAT)pSESideCoefs[Offset].A0;
         CoeffsSide.A1 = (LVM_FLOAT)pSESideCoefs[Offset].A1;
@@ -123,6 +144,7 @@
                 pConfig->pBiquadCallBack_Side = BQ_1I_D16F16C15_TRC_WRA_01;
                 break;
         }
+#endif
     }
 
     return (LVCS_SUCCESS);
@@ -169,9 +191,13 @@
                                          LVM_FLOAT* pOutData, LVM_UINT16 NumSamples) {
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
     LVCS_StereoEnhancer_t* pConfig = (LVCS_StereoEnhancer_t*)&pInstance->StereoEnhancer;
+#ifndef BIQUAD_OPT
     LVCS_Coefficient_t* pCoefficient;
+#endif
     LVM_FLOAT* pScratch;
+#ifndef BIQUAD_OPT
     pCoefficient = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
     pScratch = (LVM_FLOAT*)pInstance->pScratch;
     /*
      * Check if the Stereo Enhancer is enabled
@@ -186,9 +212,13 @@
          * Apply filter to the middle signal
          */
         if (pInstance->OutputDevice == LVCS_HEADPHONE) {
+#ifdef BIQUAD_OPT
+            pInstance->pSEMidBiquad->process(pScratch, pScratch, NumSamples);
+#else
             (pConfig->pBiquadCallBack_Mid)(
                     (Biquad_FLOAT_Instance_t*)&pCoefficient->SEBiquadInstanceMid,
                     (LVM_FLOAT*)pScratch, (LVM_FLOAT*)pScratch, (LVM_INT16)NumSamples);
+#endif
         } else {
             Mult3s_Float(pScratch,                    /* Source */
                          (LVM_FLOAT)pConfig->MidGain, /* Gain */
@@ -201,10 +231,15 @@
          * and in all modes for mobile speakers
          */
         if (pInstance->Params.SourceFormat == LVCS_STEREO) {
+#ifdef BIQUAD_OPT
+            pInstance->pSESideBiquad->process(pScratch + NumSamples, pScratch + NumSamples,
+                                              NumSamples);
+#else
             (pConfig->pBiquadCallBack_Side)(
                     (Biquad_FLOAT_Instance_t*)&pCoefficient->SEBiquadInstanceSide,
                     (LVM_FLOAT*)(pScratch + NumSamples), (LVM_FLOAT*)(pScratch + NumSamples),
                     (LVM_INT16)NumSamples);
+#endif
         }
 
         /*
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
index c92f8a5..a083c47 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
@@ -36,6 +36,7 @@
 
 /* Stereo enhancer structure */
 typedef struct {
+#ifndef BIQUAD_OPT
     /*
      * Middle filter
      */
@@ -45,6 +46,7 @@
      * Side filter
      */
     void (*pBiquadCallBack_Side)(Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
     LVM_FLOAT MidGain; /* Middle gain in mobile speaker mode */
 } LVCS_StereoEnhancer_t;
 
diff --git a/media/libeffects/lvm/tests/Android.bp b/media/libeffects/lvm/tests/Android.bp
index d026ab6..abacc94 100644
--- a/media/libeffects/lvm/tests/Android.bp
+++ b/media/libeffects/lvm/tests/Android.bp
@@ -59,9 +59,12 @@
     shared_libs: [
         "libaudioutils",
         "liblog",
-        "libreverbwrapper",
     ],
 
+    static_libs: [
+        "libreverb",
+        "libreverbwrapper",
+    ],
     srcs: [
         "reverb_test.cpp",
     ],
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
index e96263c..7b0ff5e 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -91,7 +91,7 @@
     do
         for fs in ${fs_arr[*]}
         do
-            for chMask in {0..22}
+            for chMask in {0..38}
             do
                 adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
                     -o:$testdir/sinesweep_$((chMask))_$((fs)).raw -chMask:$chMask -fs:$fs $flags
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
index 86b21ae..72b370e 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
@@ -59,9 +59,9 @@
         do
             for fs in ${fs_arr[*]}
             do
-                for chMask in {0..22}
+                for chMask in {0..38}
                 do
-                    adb shell LD_LIBRARY_PATH=/system/vendor/lib/soundfx $testdir/reverb_test \
+                    adb shell $testdir/reverb_test \
                         --input $testdir/sinesweepraw.raw \
                         --output $testdir/sinesweep_$((chMask))_$((fs)).raw \
                         --chMask $chMask $flags --fs $fs --preset $preset_val
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
index 5c5f646..f107b18 100644
--- a/media/libeffects/lvm/tests/lvmtest.cpp
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -109,6 +109,22 @@
         AUDIO_CHANNEL_OUT_5POINT1POINT2,
         AUDIO_CHANNEL_OUT_7POINT1,
         AUDIO_CHANNEL_INDEX_MASK_8,
+        AUDIO_CHANNEL_INDEX_MASK_9,
+        AUDIO_CHANNEL_INDEX_MASK_10,
+        AUDIO_CHANNEL_INDEX_MASK_11,
+        AUDIO_CHANNEL_INDEX_MASK_12,
+        AUDIO_CHANNEL_INDEX_MASK_13,
+        AUDIO_CHANNEL_INDEX_MASK_14,
+        AUDIO_CHANNEL_INDEX_MASK_15,
+        AUDIO_CHANNEL_INDEX_MASK_16,
+        AUDIO_CHANNEL_INDEX_MASK_17,
+        AUDIO_CHANNEL_INDEX_MASK_18,
+        AUDIO_CHANNEL_INDEX_MASK_19,
+        AUDIO_CHANNEL_INDEX_MASK_20,
+        AUDIO_CHANNEL_INDEX_MASK_21,
+        AUDIO_CHANNEL_INDEX_MASK_22,
+        AUDIO_CHANNEL_INDEX_MASK_23,
+        AUDIO_CHANNEL_INDEX_MASK_24,
 };
 
 void printUsage() {
@@ -394,7 +410,7 @@
         params->SourceFormat = LVM_MONO;
     } else if (params->NrChannels == 2) {
         params->SourceFormat = LVM_STEREO;
-    } else if (params->NrChannels > 2 && params->NrChannels <= 8) {  // FCC_2 FCC_8
+    } else if (params->NrChannels > FCC_2 && params->NrChannels <= FCC_24) {
         params->SourceFormat = LVM_MULTICHANNEL;
     } else {
         return -EINVAL;
diff --git a/media/libeffects/lvm/tests/reverb_test.cpp b/media/libeffects/lvm/tests/reverb_test.cpp
index b7704ff..cecc975 100644
--- a/media/libeffects/lvm/tests/reverb_test.cpp
+++ b/media/libeffects/lvm/tests/reverb_test.cpp
@@ -94,6 +94,22 @@
         AUDIO_CHANNEL_OUT_5POINT1POINT2,
         AUDIO_CHANNEL_OUT_7POINT1,
         AUDIO_CHANNEL_INDEX_MASK_8,
+        AUDIO_CHANNEL_INDEX_MASK_9,
+        AUDIO_CHANNEL_INDEX_MASK_10,
+        AUDIO_CHANNEL_INDEX_MASK_11,
+        AUDIO_CHANNEL_INDEX_MASK_12,
+        AUDIO_CHANNEL_INDEX_MASK_13,
+        AUDIO_CHANNEL_INDEX_MASK_14,
+        AUDIO_CHANNEL_INDEX_MASK_15,
+        AUDIO_CHANNEL_INDEX_MASK_16,
+        AUDIO_CHANNEL_INDEX_MASK_17,
+        AUDIO_CHANNEL_INDEX_MASK_18,
+        AUDIO_CHANNEL_INDEX_MASK_19,
+        AUDIO_CHANNEL_INDEX_MASK_20,
+        AUDIO_CHANNEL_INDEX_MASK_21,
+        AUDIO_CHANNEL_INDEX_MASK_22,
+        AUDIO_CHANNEL_INDEX_MASK_23,
+        AUDIO_CHANNEL_INDEX_MASK_24,
 };
 
 constexpr int kReverbConfigChMaskCount = std::size(kReverbConfigChMask);
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index be60aae..f96928b 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -38,7 +38,7 @@
 }
 
 // reverb wrapper
-cc_library_shared {
+cc_library {
     name: "libreverbwrapper",
 
     arch: {
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 28a7a1e..92ec94f 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -1247,6 +1247,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 6e437cf..90421b9 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -732,6 +732,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index cdfc03a..01da3f8 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -576,6 +576,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
index 85ab64e..a1f6686 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -421,6 +421,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
index 7fb8a4c..657a5ce 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -476,6 +476,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 0bb6bb0..61379d2 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -16,6 +16,12 @@
             "signed-integer-overflow",
         ],
         cfi: true,
+        diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
     },
 
     ldflags: ["-Wl,-Bsymbolic"],
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 5a4b2f8..3891f23 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -724,6 +724,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
         OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index 980261c..aceaebf 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -10,6 +10,12 @@
             "signed-integer-overflow",
         ],
         cfi: true,
+        diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
     },
 
     cflags: [
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 9db6465..01174c9 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1507,6 +1507,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
index 842a7ce..d6448d3 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
@@ -491,6 +491,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index 078c8e3..24216a2 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -592,6 +592,7 @@
 }  // namespace android
 
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index 877cb5a..fe91510 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -382,6 +382,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index d777229..330cb8a 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -354,6 +354,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index f6ae1f4..176da47 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -713,6 +713,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(const char *name,
         const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
         OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 60750d9..a4b3e2f 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -412,6 +412,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index fa7db81..fb6c4e2 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -528,6 +528,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 15cde20..07bb45a 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -498,6 +498,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
index 9d5f342..9f8001f 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
@@ -864,6 +864,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
         OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 0f2ff17..bffc23a 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -355,6 +355,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index d0cb071..e9b4341 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -775,6 +775,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 5bb1879..dcd8dda 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -666,6 +666,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 0e31804..82dd171 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -273,6 +273,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 08e20cc..3daed10 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -636,6 +636,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent *createSoftOMXComponent(
         const char *name, const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/xaacdec/Android.bp b/media/libstagefright/codecs/xaacdec/Android.bp
index 5385dbc..2d90910 100644
--- a/media/libstagefright/codecs/xaacdec/Android.bp
+++ b/media/libstagefright/codecs/xaacdec/Android.bp
@@ -14,6 +14,12 @@
         // integer_overflow: true,
         misc_undefined: [ "signed-integer-overflow", "unsigned-integer-overflow", ],
         cfi: true,
+	diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
     },
 
     static_libs: ["libxaacdec"],
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
index 87e8fd4..a478642 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
@@ -1693,6 +1693,7 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 android::SoftOMXComponent* createSoftOMXComponent(const char* name,
                                                   const OMX_CALLBACKTYPE* callbacks,
                                                   OMX_PTR appData, OMX_COMPONENTTYPE** component) {
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 801dba1..192ba77 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -1430,7 +1430,13 @@
                 if (mSampleDecryptor != NULL && (nalType == 1 || nalType == 5)) {
                     uint8_t *nalData = mBuffer->data() + pos.nalOffset;
                     size_t newSize = mSampleDecryptor->processNal(nalData, pos.nalSize);
-                    // Note: the data can shrink due to unescaping
+                    // Note: the data can shrink due to unescaping, but it can never grow
+                    if (newSize > pos.nalSize) {
+                        // don't log unless verbose, since this can get called a lot if
+                        // the caller is trying to resynchronize
+                        ALOGV("expected sample size < %u, got %zu", pos.nalSize, newSize);
+                        return NULL;
+                    }
                     memcpy(accessUnit->data() + dstOffset + 4,
                             nalData,
                             newSize);
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 1145b7b..5fdd45a 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -58,7 +58,7 @@
     if (mIsClosed) {
         return;
     }
-    if (!mReader->mIsClosed) {
+    if (mReader->mIsOpen) {
         mReader->releaseImageLocked(this, releaseFenceFd);
     }
     // Should have been set to nullptr in releaseImageLocked
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index c0ceb3d..051466a 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -274,7 +274,7 @@
 
 AImageReader::~AImageReader() {
     Mutex::Autolock _l(mLock);
-    LOG_FATAL_IF("AImageReader not closed before destruction", mIsClosed != true);
+    LOG_FATAL_IF(mIsOpen, "AImageReader not closed before destruction");
 }
 
 media_status_t
@@ -348,16 +348,16 @@
     }
     mHandler = new CallbackHandler(this);
     mCbLooper->registerHandler(mHandler);
-
+    mIsOpen = true;
     return AMEDIA_OK;
 }
 
 void AImageReader::close() {
     Mutex::Autolock _l(mLock);
-    if (mIsClosed) {
+    if (!mIsOpen) {
         return;
     }
-    mIsClosed = true;
+    mIsOpen = false;
     AImageReader_ImageListener nullListener = {nullptr, nullptr};
     setImageListenerLocked(&nullListener);
 
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index 0779a71..37c606e 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -166,7 +166,7 @@
     native_handle_t*           mWindowHandle = nullptr;
 
     List<AImage*>              mAcquiredImages;
-    bool                       mIsClosed = false;
+    bool                       mIsOpen = false;
 
     Mutex                      mLock;
 };
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index a2df29b..a23d88c 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -148,7 +148,7 @@
      */
     bool            readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
 
-    using SourceMetadatas = std::vector<playback_track_metadata_t>;
+    using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
     using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
     /** Copy the track metadata in the provided iterator. Thread safe. */
     virtual void    copyMetadataTo(MetadataInserter& backInserter) const;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0b4198c..6b37fd0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -8056,10 +8056,15 @@
     StreamInHalInterface::SinkMetadata metadata;
     for (const sp<RecordTrack> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        metadata.tracks.push_back({
+        record_track_metadata_v7_t trackMetadata;
+        trackMetadata.base = {
                 .source = track->attributes().source,
                 .gain = 1, // capture tracks do not have volumes
-        });
+        };
+        trackMetadata.channel_mask = track->channelMask(),
+        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+
+        metadata.tracks.push_back(trackMetadata);
     }
     mInput->stream->updateSinkMetadata(metadata);
 }
@@ -9621,11 +9626,15 @@
     StreamOutHalInterface::SourceMetadata metadata;
     for (const sp<MmapTrack> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        metadata.tracks.push_back({
+        playback_track_metadata_v7_t trackMetadata;
+        trackMetadata.base = {
                 .usage = track->attributes().usage,
                 .content_type = track->attributes().content_type,
                 .gain = mHalVolFloat, // TODO: propagate from aaudio pre-mix volume
-        });
+        };
+        trackMetadata.channel_mask = track->channelMask(),
+        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+        metadata.tracks.push_back(trackMetadata);
     }
     mOutput->stream->updateSourceMetadata(metadata);
 }
@@ -9732,10 +9741,14 @@
     StreamInHalInterface::SinkMetadata metadata;
     for (const sp<MmapTrack> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        metadata.tracks.push_back({
+        record_track_metadata_v7_t trackMetadata;
+        trackMetadata.base = {
                 .source = track->attributes().source,
                 .gain = 1, // capture tracks do not have volumes
-        });
+        };
+        trackMetadata.channel_mask = track->channelMask(),
+        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+        metadata.tracks.push_back(trackMetadata);
     }
     mInput->stream->updateSinkMetadata(metadata);
 }
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 01d5345..38dab5b 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -253,6 +253,8 @@
     // Called to tally underrun frames in playback.
     virtual void tallyUnderrunFrames(size_t /* frames */) {}
 
+    audio_channel_mask_t channelMask() const { return mChannelMask; }
+
 protected:
     DISALLOW_COPY_AND_ASSIGN(TrackBase);
 
@@ -278,8 +280,6 @@
 
     size_t frameSize() const { return mFrameSize; }
 
-    audio_channel_mask_t channelMask() const { return mChannelMask; }
-
     virtual uint32_t sampleRate() const { return mSampleRate; }
 
     bool isStopped() const {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 178809c..b17c0bc 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1266,11 +1266,15 @@
 
 void AudioFlinger::PlaybackThread::Track::copyMetadataTo(MetadataInserter& backInserter) const
 {
-    *backInserter++ = {
+    playback_track_metadata_v7_t metadata;
+    metadata.base = {
             .usage = mAttr.usage,
             .content_type = mAttr.content_type,
             .gain = mFinalVolume,
     };
+    metadata.channel_mask = mChannelMask,
+    strncpy(metadata.tags, mAttr.tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+    *backInserter++ = metadata;
 }
 
 void AudioFlinger::PlaybackThread::Track::setTeePatches(TeePatches teePatches) {
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 19937ed..e0a0bbb 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -455,7 +455,7 @@
         device = availableDevices.getFirstExistingDevice({
                 AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
                 AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
-                AUDIO_DEVICE_IN_BUILTIN_MIC});
+                AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_IN_BUILTIN_MIC});
         break;
 
     case AUDIO_SOURCE_VOICE_COMMUNICATION:
@@ -488,7 +488,8 @@
         default:    // FORCE_NONE
             device = availableDevices.getFirstExistingDevice({
                     AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
-                    AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+                    AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BLUETOOTH_BLE,
+                    AUDIO_DEVICE_IN_BUILTIN_MIC});
             break;
 
         }
@@ -496,13 +497,25 @@
 
     case AUDIO_SOURCE_VOICE_RECOGNITION:
     case AUDIO_SOURCE_UNPROCESSED:
-    case AUDIO_SOURCE_HOTWORD:
-        if (inputSource == AUDIO_SOURCE_HOTWORD) {
-            // We should not use primary output criteria for Hotword but rather limit
-            // to devices attached to the same HW module as the build in mic
-            LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
-            availableDevices = availablePrimaryDevices;
+        if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
+            device = availableDevices.getDevice(
+                    AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
+            if (device != nullptr) break;
         }
+        // we need to make BLUETOOTH_BLE has higher priority than BUILTIN_MIC,
+        // because sometimes user want to do voice search by bt remote
+        // even if BUILDIN_MIC is available.
+        device = availableDevices.getFirstExistingDevice({
+                AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
+                AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
+                AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+
+        break;
+    case AUDIO_SOURCE_HOTWORD:
+        // We should not use primary output criteria for Hotword but rather limit
+        // to devices attached to the same HW module as the build in mic
+        LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
+        availableDevices = availablePrimaryDevices;
         if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
             device = availableDevices.getDevice(
                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
@@ -528,7 +541,8 @@
     case AUDIO_SOURCE_VOICE_PERFORMANCE:
         device = availableDevices.getFirstExistingDevice({
                 AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
-                AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+                AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BLUETOOTH_BLE,
+                AUDIO_DEVICE_IN_BUILTIN_MIC});
         break;
     case AUDIO_SOURCE_REMOTE_SUBMIX:
         device = availableDevices.getDevice(
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index a9d32d6..4bcc077 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
index a9d32d6..4bcc077 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
index eb71e28..9bafe7b 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
index e72d4db..b0ed040 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1