Frequency Domain implementation of Dynamics Processing Effect

Ported the frequency domain implementation of the effect from the
development sandbox.

Bug: 64161702
Bug: 38266419

Test: manual with Triton app. Cts tests. Listening tests.
Change-Id: I9417beba2f98f2a677f0857c7976bf76a0e0d8e0
diff --git a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
index 56cd247..55383eb 100644
--- a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
+++ b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
@@ -28,6 +28,7 @@
 
 #include <audio_effects/effect_dynamicsprocessing.h>
 #include <dsp/DPBase.h>
+#include <dsp/DPFrequency.h>
 
 //#define VERY_VERY_VERBOSE_LOGGING
 #ifdef VERY_VERY_VERBOSE_LOGGING
@@ -186,7 +187,7 @@
     pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
-    pContext->mConfig.inputCfg.samplingRate = 44100;
+    pContext->mConfig.inputCfg.samplingRate = 48000;
     pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
     pContext->mConfig.inputCfg.bufferProvider.cookie = NULL;
@@ -194,7 +195,7 @@
     pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
     pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
-    pContext->mConfig.outputCfg.samplingRate = 44100;
+    pContext->mConfig.outputCfg.samplingRate = 48000;
     pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
     pContext->mConfig.outputCfg.bufferProvider.cookie = NULL;
@@ -209,17 +210,52 @@
 }
 
 void DP_changeVariant(DynamicsProcessingContext *pContext, int newVariant) {
-    if (pContext->mPDynamics != NULL) {
-        delete pContext->mPDynamics;
-        pContext->mPDynamics = NULL;
-    }
+    ALOGV("DP_changeVariant from %d to %d", pContext->mCurrentVariant, newVariant);
     switch(newVariant) {
-    //TODO: actually instantiate one of the variants. For now all instantiate the base;
-    default:
-        pContext->mCurrentVariant = newVariant;
-        pContext->mPDynamics = new dp_fx::DPBase();
+    case VARIANT_FAVOR_FREQUENCY_RESOLUTION: {
+        pContext->mCurrentVariant = VARIANT_FAVOR_FREQUENCY_RESOLUTION;
+        delete pContext->mPDynamics;
+        pContext->mPDynamics = new dp_fx::DPFrequency();
         break;
     }
+    default: {
+        ALOGW("DynamicsProcessing variant %d not available for creation", newVariant);
+        break;
+    }
+    } //switch
+}
+
+static inline bool isPowerOf2(unsigned long n) {
+    return (n & (n - 1)) == 0;
+}
+
+void DP_configureVariant(DynamicsProcessingContext *pContext, int newVariant) {
+    ALOGV("DP_configureVariant %d", newVariant);
+    switch(newVariant) {
+    case VARIANT_FAVOR_FREQUENCY_RESOLUTION: {
+        int32_t minBlockSize = (int32_t)dp_fx::DPFrequency::getMinBockSize();
+        int32_t desiredBlock = pContext->mPreferredFrameDuration *
+                pContext->mConfig.inputCfg.samplingRate / 1000.0f;
+        int32_t currentBlock = desiredBlock;
+        ALOGV(" sampling rate: %d, desiredBlock size %0.2f (%d) samples",
+                pContext->mConfig.inputCfg.samplingRate, pContext->mPreferredFrameDuration,
+                desiredBlock);
+        if (desiredBlock < minBlockSize) {
+            currentBlock = minBlockSize;
+        } else if (!isPowerOf2(desiredBlock)) {
+            //find next highest power of 2.
+            currentBlock = 1 << (32 - __builtin_clz(desiredBlock));
+        }
+        ((dp_fx::DPFrequency*)pContext->mPDynamics)->configure(currentBlock,
+                currentBlock/2,
+                pContext->mConfig.inputCfg.samplingRate);
+        break;
+    }
+    default: {
+        ALOGE("DynamicsProcessing variant %d not available to configure", newVariant);
+        break;
+    }
+    }
 }
 
 //
@@ -312,6 +348,7 @@
                         pContext->mConfig.inputCfg.channels);
         pContext->mPDynamics->processSamples(inBuffer->f32, inBuffer->f32,
                 inBuffer->frameCount * channelCount);
+
         if (inBuffer->raw != outBuffer->raw) {
             if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
                 for (size_t i = 0; i < outBuffer->frameCount * channelCount; i++) {
@@ -518,7 +555,8 @@
     if (pChannel == NULL) {
         return NULL;
     }
-    dp_fx::DPEq *pEq = eqType == DP_PARAM_PRE_EQ ? pChannel->getPreEq() : pChannel->getPostEq();
+    dp_fx::DPEq *pEq = (eqType == DP_PARAM_PRE_EQ ? pChannel->getPreEq() :
+            (eqType == DP_PARAM_POST_EQ ? pChannel->getPostEq() : NULL));
     ALOGE_IF(pEq == NULL,"DPEq NULL invalid eq");
     return pEq;
 }
@@ -699,8 +737,10 @@
 //              eqBand.getGain()};
         const int32_t channel = params[1];
         const int32_t band = params[2];
+        int eqCommand = (command == DP_PARAM_PRE_EQ_BAND ? DP_PARAM_PRE_EQ :
+                (command == DP_PARAM_POST_EQ_BAND ? DP_PARAM_POST_EQ : -1));
 
-        dp_fx::DPEqBand *pEqBand = DP_getEqBand(pContext, channel, command, band);
+        dp_fx::DPEqBand *pEqBand = DP_getEqBand(pContext, channel, eqCommand, band);
         if (pEqBand == NULL) {
             ALOGE("%s get PARAM_*_EQ_BAND invalid channel %d or band %d", __func__, channel, band);
             status = -EINVAL;
@@ -923,6 +963,8 @@
                 mbcInUse != 0, (uint32_t)mbcBandCount,
                 postEqInUse != 0, (uint32_t)postEqBandCount,
                 limiterInUse != 0);
+
+        DP_configureVariant(pContext, variant);
         break;
     }
     case DP_PARAM_INPUT_GAIN: {
@@ -1015,7 +1057,9 @@
                 (command == DP_PARAM_PRE_EQ_BAND ? "preEqBand" : "postEqBand"), channel, band,
                 enabled, cutoffFrequency, gain);
 
-        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, command);
+        int eqCommand = (command == DP_PARAM_PRE_EQ_BAND ? DP_PARAM_PRE_EQ :
+                (command == DP_PARAM_POST_EQ_BAND ? DP_PARAM_POST_EQ : -1));
+        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, eqCommand);
         if (pEq == NULL) {
             ALOGE("%s set PARAM_*_EQ_BAND invalid channel %d or command %d", __func__, channel,
                     command);