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

Commit ef1b98e7 authored by Phil Burk's avatar Phil Burk Committed by android-build-merger
Browse files

Merge "aaudio: control MMAP mode using system properties" into oc-dev

am: c2bc4385

Change-Id: Ie5928922053d7013d28506def9c1e4ff23bc424d
parents 4e8d0076 c2bc4385
Loading
Loading
Loading
Loading
+20 −15
Original line number Original line Diff line number Diff line
@@ -30,12 +30,6 @@
#include "legacy/AudioStreamRecord.h"
#include "legacy/AudioStreamRecord.h"
#include "legacy/AudioStreamTrack.h"
#include "legacy/AudioStreamTrack.h"


// Enable a mixer in AAudio service that will mix streams to an ALSA MMAP buffer.
#define MMAP_SHARED_ENABLED      0

// Enable AAUDIO_SHARING_MODE_EXCLUSIVE that uses an ALSA MMAP buffer directly.
#define MMAP_EXCLUSIVE_ENABLED   0

using namespace aaudio;
using namespace aaudio;


/*
/*
@@ -53,6 +47,7 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction,
                                         AudioStream **audioStreamPtr) {
                                         AudioStream **audioStreamPtr) {
    *audioStreamPtr = nullptr;
    *audioStreamPtr = nullptr;
    aaudio_result_t result = AAUDIO_OK;
    aaudio_result_t result = AAUDIO_OK;

    switch (direction) {
    switch (direction) {


        case AAUDIO_DIRECTION_INPUT:
        case AAUDIO_DIRECTION_INPUT:
@@ -81,20 +76,30 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction,
    return result;
    return result;
}
}


// Try to open using MMAP path if that is enabled.
// Fall back to Legacy path is MMAP not available.
aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
    AudioStream *audioStream = nullptr;
    *streamPtr = nullptr;

    int32_t mmapEnabled = AAudioProperty_getMMapEnabled();
    int32_t mmapExclusiveEnabled = AAudioProperty_getMMapExclusiveEnabled();
    ALOGD("AudioStreamBuilder(): mmapEnabled = %d, mmapExclusiveEnabled = %d",
          mmapEnabled, mmapExclusiveEnabled);

    aaudio_sharing_mode_t sharingMode = getSharingMode();
    aaudio_sharing_mode_t sharingMode = getSharingMode();
    if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && (MMAP_EXCLUSIVE_ENABLED == 0)) {
    if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE)
        ALOGE("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported");
        && (mmapExclusiveEnabled == AAUDIO_USE_NEVER)) {
        return AAUDIO_ERROR_UNAVAILABLE;
        ALOGW("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported. Use SHARED.");
        sharingMode = AAUDIO_SHARING_MODE_SHARED;
        setSharingMode(sharingMode);
    }
    }


    AudioStream *audioStream = nullptr;
    bool allowMMap = mmapEnabled != AAUDIO_USE_NEVER;
    *streamPtr = nullptr;
    bool allowLegacy = mmapEnabled != AAUDIO_USE_ALWAYS;


    bool tryMMap = ((sharingMode == AAUDIO_SHARING_MODE_SHARED) && MMAP_SHARED_ENABLED) ||
            ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && MMAP_EXCLUSIVE_ENABLED);
    aaudio_result_t result = builder_createStream(getDirection(), sharingMode,
    aaudio_result_t result = builder_createStream(getDirection(), sharingMode,
                                                  tryMMap, &audioStream);
                                                  allowMMap, &audioStream);
    if (result == AAUDIO_OK) {
    if (result == AAUDIO_OK) {
        // Open the stream using the parameters from the builder.
        // Open the stream using the parameters from the builder.
        result = audioStream->open(*this);
        result = audioStream->open(*this);
@@ -105,7 +110,7 @@ aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
            delete audioStream;
            delete audioStream;
            audioStream = nullptr;
            audioStream = nullptr;


            if (isMMap) {
            if (isMMap && allowLegacy) {
                ALOGD("AudioStreamBuilder.build() MMAP stream did not open so try Legacy path");
                ALOGD("AudioStreamBuilder.build() MMAP stream did not open so try Legacy path");
                // If MMAP stream failed to open then TRY using a legacy stream.
                // If MMAP stream failed to open then TRY using a legacy stream.
                result = builder_createStream(getDirection(), sharingMode,
                result = builder_createStream(getDirection(), sharingMode,
+50 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/Log.h>


#include <cutils/properties.h>
#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/Errors.h>
@@ -322,3 +323,52 @@ int32_t AAudioConvert_framesToBytes(int32_t numFrames,
    *sizeInBytes = numFrames * bytesPerFrame;
    *sizeInBytes = numFrames * bytesPerFrame;
    return AAUDIO_OK;
    return AAUDIO_OK;
}
}

static int32_t AAudioProperty_getMMapProperty(const char *propName,
                                              int32_t defaultValue,
                                              const char * caller) {
    int32_t prop = property_get_int32(AAUDIO_PROP_MMAP_ENABLED, defaultValue);
    switch (prop) {
        case AAUDIO_USE_NEVER:
        case AAUDIO_USE_ALWAYS:
        case AAUDIO_USE_AUTO:
            break;
        default:
            ALOGE("%s: invalid = %d", caller, prop);
            prop = defaultValue;
            break;
    }
    return prop;
}

int32_t AAudioProperty_getMMapEnabled() {
    return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_ENABLED,
                                          AAUDIO_USE_NEVER, __func__);
}

int32_t AAudioProperty_getMMapExclusiveEnabled() {
    return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_ENABLED,
                                          AAUDIO_USE_NEVER, __func__);
}

int32_t AAudioProperty_getMixerBursts() {
    const int32_t defaultBursts = 2; // arbitrary
    const int32_t maxBursts = 1024; // arbitrary
    int32_t prop = property_get_int32(AAUDIO_PROP_MIXER_BURSTS, defaultBursts); // use 2 for double buffered
    if (prop < 1 || prop > maxBursts) {
        ALOGE("AAudioProperty_getMixerBursts: invalid = %d", prop);
        prop = defaultBursts;
    }
    return prop;
}

int32_t AAudioProperty_getHardwareBurstMinMicros() {
    const int32_t defaultMicros = 1000; // arbitrary
    const int32_t maxMicros = 1000 * 1000; // arbitrary
    int32_t prop = property_get_int32(AAUDIO_PROP_HW_BURST_MIN_USEC, defaultMicros);
    if (prop < 1 || prop > maxMicros) {
        ALOGE("AAudioProperty_getHardwareBurstMinMicros: invalid = %d", prop);
        prop = defaultMicros;
    }
    return prop;
}
+50 −0
Original line number Original line Diff line number Diff line
@@ -170,4 +170,54 @@ aaudio_audio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t for
 */
 */
int32_t AAudioConvert_formatToSizeInBytes(aaudio_audio_format_t format);
int32_t AAudioConvert_formatToSizeInBytes(aaudio_audio_format_t format);



// Note that this code may be replaced by Settings or by some other system configuration tool.

enum : int32_t {
    // Related feature is disabled
    AAUDIO_USE_NEVER = 0,
    // If related feature works then use it. Otherwise fall back to something else.
    AAUDIO_USE_AUTO = 1,
    // Related feature must be used. If not available then fail.
    AAUDIO_USE_ALWAYS = 2
};

#define AAUDIO_PROP_MMAP_ENABLED           "aaudio.mmap_enabled"

/**
 * Read system property.
 * @return AAUDIO_USE_NEVER or AAUDIO_USE_AUTO or AAUDIO_USE_ALWAYS
 */
int32_t AAudioProperty_getMMapEnabled();

#define AAUDIO_PROP_MMAP_EXCLUSIVE_ENABLED "aaudio.mmap_exclusive_enabled"

/**
 * Read system property.
 * @return AAUDIO_USE_NEVER or AAUDIO_USE_AUTO or AAUDIO_USE_ALWAYS
 */
int32_t AAudioProperty_getMMapExclusiveEnabled();

#define AAUDIO_PROP_MIXER_BURSTS           "aaudio.mixer_bursts"

/**
 * Read system property.
 * @return number of bursts per mixer cycle
 */
int32_t AAudioProperty_getMixerBursts();

#define AAUDIO_PROP_HW_BURST_MIN_USEC      "aaudio.hw_burst_min_usec"

/**
 * Read system property.
 * This is handy in case the DMA is bursting too quickly for the CPU to keep up.
 * For example, there may be a DMA burst every 100 usec but you only
 * want to feed the MMAP buffer every 2000 usec.
 *
 * This will affect the framesPerBurst for an MMAP stream.
 *
 * @return minimum number of microseconds for a MMAP HW burst
 */
int32_t AAudioProperty_getHardwareBurstMinMicros();

#endif //UTILITY_AAUDIO_UTILITIES_H
#endif //UTILITY_AAUDIO_UTILITIES_H
+7 −6
Original line number Original line Diff line number Diff line
@@ -44,10 +44,6 @@ using namespace aaudio; // TODO just import names needed
// This is the maximum size in frames. The effective size can be tuned smaller at runtime.
// This is the maximum size in frames. The effective size can be tuned smaller at runtime.
#define DEFAULT_BUFFER_CAPACITY   (48 * 8)
#define DEFAULT_BUFFER_CAPACITY   (48 * 8)


// Use 2 for "double buffered"
#define BUFFER_SIZE_IN_BURSTS     2
#define BURSTS_PER_MIX_LOOP       1

// The mStreamInternal will use a service interface that does not go through Binder.
// The mStreamInternal will use a service interface that does not go through Binder.
AAudioServiceEndpoint::AAudioServiceEndpoint(AAudioService &audioService)
AAudioServiceEndpoint::AAudioServiceEndpoint(AAudioService &audioService)
        : mStreamInternal(audioService, true)
        : mStreamInternal(audioService, true)
@@ -71,7 +67,13 @@ aaudio_result_t AAudioServiceEndpoint::open(int32_t deviceId, aaudio_direction_t
    if (result == AAUDIO_OK) {
    if (result == AAUDIO_OK) {
        mMixer.allocate(mStreamInternal.getSamplesPerFrame(), mStreamInternal.getFramesPerBurst());
        mMixer.allocate(mStreamInternal.getSamplesPerFrame(), mStreamInternal.getFramesPerBurst());


        int32_t desiredBufferSize = BUFFER_SIZE_IN_BURSTS * mStreamInternal.getFramesPerBurst();
        int32_t burstsPerBuffer = AAudioProperty_getMixerBursts();
        if (burstsPerBuffer == 0) {
            mLatencyTuningEnabled = true;
            burstsPerBuffer = 2;
        }
        ALOGD("AAudioServiceEndpoint(): burstsPerBuffer = %d", burstsPerBuffer);
        int32_t desiredBufferSize = burstsPerBuffer * mStreamInternal.getFramesPerBurst();
        mStreamInternal.setBufferSize(desiredBufferSize);
        mStreamInternal.setBufferSize(desiredBufferSize);
    }
    }
    return result;
    return result;
@@ -117,7 +119,6 @@ aaudio_result_t AAudioServiceEndpoint::stopStream(AAudioServiceStreamShared *sha


static void *aaudio_mixer_thread_proc(void *context) {
static void *aaudio_mixer_thread_proc(void *context) {
    AAudioServiceEndpoint *stream = (AAudioServiceEndpoint *) context;
    AAudioServiceEndpoint *stream = (AAudioServiceEndpoint *) context;
    //LOGD("AudioStreamAAudio(): oboe_callback_thread, stream = %p", stream);
    if (stream != NULL) {
    if (stream != NULL) {
        return stream->callbackLoop();
        return stream->callbackLoop();
    } else {
    } else {
+1 −0
Original line number Original line Diff line number Diff line
@@ -77,6 +77,7 @@ private:


    std::atomic<bool>        mCallbackEnabled;
    std::atomic<bool>        mCallbackEnabled;
    int32_t                  mReferenceCount = 0;
    int32_t                  mReferenceCount = 0;
    bool                     mLatencyTuningEnabled = false; // TODO implement tuning


    std::mutex               mLockStreams;
    std::mutex               mLockStreams;
    std::vector<AAudioServiceStreamShared *> mRegisteredStreams;
    std::vector<AAudioServiceStreamShared *> mRegisteredStreams;
Loading