CSD: Add Mel processing for FastMixer

Moved the MelProcessor into the AudioStreamOutSink. This should be ok
now to use in the FastMixer since the new MelProcessor logic is not
blocking and the callbacks are executed asynchronously in the MelWorker.

Test: OboeTester + dumpsys and logs
Bug: 264255998
Change-Id: Idce0a2653b4f8fa42ea12893c6e77e765806f3b1
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index e9422cc..89e9806 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -68,6 +68,10 @@
     // ],
     // static_libs: ["libsndfile"],
 
+    shared_libs: [
+        "libmediautils",
+    ],
+
     header_libs: ["libaudiohal_headers"],
 
     export_include_dirs: ["include"],
diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp
index 581867f..8c54a3a 100644
--- a/media/libnbaio/AudioStreamOutSink.cpp
+++ b/media/libnbaio/AudioStreamOutSink.cpp
@@ -50,6 +50,14 @@
         mFormat = Format_from_SR_C(config.sample_rate,
                 audio_channel_count_from_out_mask(config.channel_mask), config.format);
         mFrameSize = Format_frameSize(mFormat);
+
+        // update format for MEL computation
+        auto processor = mMelProcessor.load();
+        if (processor) {
+            processor->updateAudioFormat(config.sample_rate,
+                                         audio_channel_count_from_out_mask(config.channel_mask),
+                                         config.format);
+        }
     }
     return NBAIO_Sink::negotiate(offers, numOffers, counterOffers, numCounterOffers);
 }
@@ -63,8 +71,15 @@
     size_t written;
     status_t ret = mStream->write(buffer, count * mFrameSize, &written);
     if (ret == OK && written > 0) {
+        // Send to MelProcessor for sound dose measurement.
+        auto processor = mMelProcessor.load();
+        if (processor) {
+            processor->process(buffer, written);
+        }
+
         written /= mFrameSize;
         mFramesWritten += written;
+
         return written;
     } else {
         // FIXME verify HAL implementations are returning the correct error codes e.g. WOULD_BLOCK
@@ -85,4 +100,23 @@
     return OK;
 }
 
+void AudioStreamOutSink::startMelComputation(const sp<audio_utils::MelProcessor>& processor)
+{
+    ALOGV("%s start mel computation for device %d", __func__, processor->getDeviceId());
+    mMelProcessor = processor;
+    // update format for MEL computation
+    if (processor) {
+        processor->updateAudioFormat(mFormat.mSampleRate,  mFormat.mChannelCount, mFormat.mFormat);
+    }
+}
+
+void AudioStreamOutSink::stopMelComputation()
+{
+    auto melProcessor = mMelProcessor.load();
+    if (melProcessor != nullptr) {
+        ALOGV("%s stop mel computation for device %d", __func__, melProcessor->getDeviceId());
+        mMelProcessor = nullptr;
+    }
+}
+
 }   // namespace android
diff --git a/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h b/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
index 635f67f..7b5aa06 100644
--- a/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
+++ b/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
@@ -17,7 +17,9 @@
 #ifndef ANDROID_AUDIO_STREAM_OUT_SINK_H
 #define ANDROID_AUDIO_STREAM_OUT_SINK_H
 
+#include <audio_utils/MelProcessor.h>
 #include <media/nbaio/NBAIO.h>
+#include <mediautils/Synchronization.h>
 
 namespace android {
 
@@ -48,6 +50,10 @@
 
     // NBAIO_Sink end
 
+    void startMelComputation(const sp<audio_utils::MelProcessor>& processor);
+
+    void stopMelComputation();
+
 #if 0   // until necessary
     sp<StreamOutHalInterface> stream() const { return mStream; }
 #endif
@@ -55,6 +61,7 @@
 private:
     sp<StreamOutHalInterface> mStream;
     size_t              mStreamBufferSizeBytes; // as reported by get_buffer_size()
+    mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
 };
 
 }   // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c617ef7..0f65aec 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3428,12 +3428,6 @@
         if (framesWritten > 0) {
             bytesWritten = framesWritten * mFrameSize;
 
-            // Send to MelProcessor for sound dose measurement.
-            auto processor = mMelProcessor.load();
-            if (processor) {
-                processor->process((char *)mSinkBuffer + offset, bytesWritten);
-            }
-
 #ifdef TEE_SINK
             mTee.write((char *)mSinkBuffer + offset, framesWritten);
 #endif
@@ -3479,15 +3473,14 @@
 void AudioFlinger::PlaybackThread::startMelComputation(
         const sp<audio_utils::MelProcessor>& processor)
 {
-    ALOGV("%s: starting mel processor for thread %d", __func__, id());
-    mMelProcessor = processor;
+    auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
+    outputSink->startMelComputation(processor);
 }
 
-void AudioFlinger::PlaybackThread::stopMelComputation() {
-    if (mMelProcessor.load() != nullptr) {
-        ALOGV("%s: stopping mel processor for thread %d", __func__, id());
-        mMelProcessor = nullptr;
-    }
+void AudioFlinger::PlaybackThread::stopMelComputation()
+{
+    auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
+    outputSink->stopMelComputation();
 }
 
 void AudioFlinger::PlaybackThread::threadLoop_drain()
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 47d5333..f0062bc 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1215,8 +1215,6 @@
     audio_channel_mask_t            mMixerChannelMask = AUDIO_CHANNEL_NONE;
 
 private:
-    mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
-
     // mMasterMute is in both PlaybackThread and in AudioFlinger.  When a
     // PlaybackThread needs to find out if master-muted, it checks it's local
     // copy rather than the one in AudioFlinger.  This optimization saves a lock.
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index 03a14d0..2f82e17 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -74,7 +74,7 @@
     } else {
         ALOGV("%s: creating new callback for stream id %d", __func__, streamHandle);
         sp<audio_utils::MelProcessor> melProcessor = sp<audio_utils::MelProcessor>::make(
-                sampleRate, channelCount, format, *this, deviceId, mRs2Value);
+                sampleRate, channelCount, format, this, deviceId, mRs2Value);
         const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
         if (activeTypeIt != mActiveDeviceTypes.end()) {
             melProcessor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);