FDK update for downsampled SBR

Add missing support for downsampled SBR in libFDK

Bug 9428126

Change-Id: Idb732f8d31a115d36dd4b22916599db7fab98cae
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index 812b9d6..1dedf68 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -110,7 +110,7 @@
 /* Decoder library info */
 #define AACDECODER_LIB_VL0 2
 #define AACDECODER_LIB_VL1 5
-#define AACDECODER_LIB_VL2 0
+#define AACDECODER_LIB_VL2 1
 #define AACDECODER_LIB_TITLE "AAC Decoder Lib"
 #define AACDECODER_LIB_BUILD_DATE __DATE__
 #define AACDECODER_LIB_BUILD_TIME __TIME__
diff --git a/libFDK/include/FDK_tools_rom.h b/libFDK/include/FDK_tools_rom.h
index 2079c5b..9361c81 100644
--- a/libFDK/include/FDK_tools_rom.h
+++ b/libFDK/include/FDK_tools_rom.h
@@ -171,6 +171,9 @@
 
 extern const FIXP_QTW qmf_phaseshift_cos32[32];
 extern const FIXP_QTW qmf_phaseshift_sin32[32];
+/* Adapted analysis post-twiddles for down-sampled HQ SBR */
+extern const FIXP_QTW qmf_phaseshift_cos_downsamp32[32];
+extern const FIXP_QTW qmf_phaseshift_sin_downsamp32[32];
 extern const FIXP_QTW qmf_phaseshift_cos64[64];
 extern const FIXP_QTW qmf_phaseshift_sin64[64];
 
diff --git a/libFDK/include/qmf.h b/libFDK/include/qmf.h
index 8777960..be69477 100644
--- a/libFDK/include/qmf.h
+++ b/libFDK/include/qmf.h
@@ -137,6 +137,8 @@
 #define QMF_FLAG_MPSLDFB     16
 /* Complex Low Delay Filter Bank used in MPEG Surround Encoder allows a optimized calculation of the modulation in qmfForwardModulationHQ() */
 #define QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION  32
+/* Flag to indicate HE-AAC down-sampled SBR mode (decoder) -> adapt analysis post twiddling */
+#define QMF_FLAG_DOWNSAMPLED  64
 
 
 typedef struct
diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp
index 9f24d50..ea0be6c 100644
--- a/libFDK/src/FDK_core.cpp
+++ b/libFDK/src/FDK_core.cpp
@@ -93,7 +93,7 @@
 /* FDK tools library info */
 #define FDK_TOOLS_LIB_VL0 2
 #define FDK_TOOLS_LIB_VL1 3
-#define FDK_TOOLS_LIB_VL2 0
+#define FDK_TOOLS_LIB_VL2 1
 #define FDK_TOOLS_LIB_TITLE "FDK Tools"
 #define FDK_TOOLS_LIB_BUILD_DATE __DATE__
 #define FDK_TOOLS_LIB_BUILD_TIME __TIME__
diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp
index 0741333..c6e517e 100644
--- a/libFDK/src/FDK_tools_rom.cpp
+++ b/libFDK/src/FDK_tools_rom.cpp
@@ -1462,6 +1462,26 @@
   QFC(0xfe4d1be3), QFC(0xd1c58ace), QFC(0x2e3a7532), QFC(0x01b2e41d), QFC(0x00000000),
 };
 
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_cos_downsamp32[] =
+{
+  QTC(0x7fd8878e), QTC(0x7e9d55fc), QTC(0x7c29fbee), QTC(0x78848414), QTC(0x73b5ebd1), QTC(0x6dca0d14), QTC(0x66cf8120), QTC(0x5ed77c8a),
+  QTC(0x55f5a4d2), QTC(0x4c3fdff4), QTC(0x41ce1e65), QTC(0x36ba2014), QTC(0x2b1f34eb), QTC(0x1f19f97b), QTC(0x12c8106f), QTC(0x0647d97c),
+  QTC(0xf9b82684), QTC(0xed37ef91), QTC(0xe0e60685), QTC(0xd4e0cb15), QTC(0xc945dfec), QTC(0xbe31e19b), QTC(0xb3c0200c), QTC(0xaa0a5b2e),
+  QTC(0xa1288376), QTC(0x99307ee0), QTC(0x9235f2ec), QTC(0x8c4a142f), QTC(0x877b7bec), QTC(0x83d60412), QTC(0x8162aa04), QTC(0x80277872),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_sin_downsamp32[] =
+{
+  QTC(0x0647d97c), QTC(0x12c8106f), QTC(0x1f19f97b), QTC(0x2b1f34eb), QTC(0x36ba2014), QTC(0x41ce1e65), QTC(0x4c3fdff4), QTC(0x55f5a4d2),
+  QTC(0x5ed77c8a), QTC(0x66cf8120), QTC(0x6dca0d14), QTC(0x73b5ebd1), QTC(0x78848414), QTC(0x7c29fbee), QTC(0x7e9d55fc), QTC(0x7fd8878e),
+  QTC(0x7fd8878e), QTC(0x7e9d55fc), QTC(0x7c29fbee), QTC(0x78848414), QTC(0x73b5ebd1), QTC(0x6dca0d14), QTC(0x66cf8120), QTC(0x5ed77c8a),
+  QTC(0x55f5a4d2), QTC(0x4c3fdff4), QTC(0x41ce1e65), QTC(0x36ba2014), QTC(0x2b1f34eb), QTC(0x1f19f97b), QTC(0x12c8106f), QTC(0x0647d97c),
+};
+
 #else /* QMF_NO_POLY == 5 */
 #endif /* QMF_NO_POLY==5 */
 
diff --git a/libFDK/src/qmf.cpp b/libFDK/src/qmf.cpp
index 19c522f..54526dd 100644
--- a/libFDK/src/qmf.cpp
+++ b/libFDK/src/qmf.cpp
@@ -1017,8 +1017,14 @@
         break;
       case 32:
         h_Qmf->p_filter = qmf_64;
+        if (flags & QMF_FLAG_DOWNSAMPLED) {
+          h_Qmf->t_cos = qmf_phaseshift_cos_downsamp32;
+          h_Qmf->t_sin = qmf_phaseshift_sin_downsamp32;
+        }
+        else {
         h_Qmf->t_cos = qmf_phaseshift_cos32;
         h_Qmf->t_sin = qmf_phaseshift_sin32;
+        }
         h_Qmf->p_stride = 2;
         h_Qmf->FilterSize = 640;
         h_Qmf->filterScale = 0;
diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp
index e5922f1..1282338 100644
--- a/libSBRdec/src/sbr_dec.cpp
+++ b/libSBRdec/src/sbr_dec.cpp
@@ -760,6 +760,8 @@
   */
   {
     int qmfErr;
+    /* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */
+    const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0;
 
     qmfErr = qmfInitAnalysisFilterBank (
                     &hs->AnalysiscQMF,
@@ -768,7 +770,7 @@
                      hHeaderData->freqBandData.lowSubband,
                      hHeaderData->freqBandData.highSubband,
                      hHeaderData->numberOfAnalysisBands,
-                     qmfFlags & (~QMF_FLAG_KEEP_STATES)
+                     (qmfFlags & (~QMF_FLAG_KEEP_STATES)) | downSampledFlag
                      );
     if (qmfErr != 0) {
       return SBRDEC_UNSUPPORTED_CONFIG;
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index 830fd1e..a0668bd 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -137,7 +137,7 @@
 /* Decoder library info */
 #define SBRDECODER_LIB_VL0 2
 #define SBRDECODER_LIB_VL1 2
-#define SBRDECODER_LIB_VL2 0
+#define SBRDECODER_LIB_VL2 1
 #define SBRDECODER_LIB_TITLE "SBR Decoder"
 #define SBRDECODER_LIB_BUILD_DATE __DATE__
 #define SBRDECODER_LIB_BUILD_TIME __TIME__