Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c7a2664 authored by Vlad Popa's avatar Vlad Popa
Browse files

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
parent 26acc3e9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ cc_library_shared {
    // ],
    // static_libs: ["libsndfile"],

    shared_libs: [
        "libmediautils",
    ],

    header_libs: ["libaudiohal_headers"],

    export_include_dirs: ["include"],
+34 −0
Original line number Diff line number Diff line
@@ -50,6 +50,14 @@ ssize_t AudioStreamOutSink::negotiate(const NBAIO_Format offers[], size_t numOff
        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 @@ ssize_t AudioStreamOutSink::write(const void *buffer, size_t count)
    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 @@ status_t AudioStreamOutSink::getTimestamp(ExtendedTimestamp &timestamp)
    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
+7 −0
Original line number Diff line number Diff line
@@ -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 @@ public:

    // 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 @@ public:
private:
    sp<StreamOutHalInterface> mStream;
    size_t              mStreamBufferSizeBytes; // as reported by get_buffer_size()
    mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
};

}   // namespace android
+6 −13
Original line number Diff line number Diff line
@@ -3428,12 +3428,6 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
        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 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
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()
+0 −2
Original line number Diff line number Diff line
@@ -1215,8 +1215,6 @@ protected:
    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.
Loading