Loading media/libaaudio/src/core/AudioStreamBuilder.cpp +20 −15 Original line number Diff line number Diff line Loading @@ -30,12 +30,6 @@ #include "legacy/AudioStreamRecord.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; /* Loading @@ -53,6 +47,7 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction, AudioStream **audioStreamPtr) { *audioStreamPtr = nullptr; aaudio_result_t result = AAUDIO_OK; switch (direction) { case AAUDIO_DIRECTION_INPUT: Loading Loading @@ -81,20 +76,30 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction, 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) { 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(); if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && (MMAP_EXCLUSIVE_ENABLED == 0)) { ALOGE("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported"); return AAUDIO_ERROR_UNAVAILABLE; if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && (mmapExclusiveEnabled == AAUDIO_USE_NEVER)) { ALOGW("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported. Use SHARED."); sharingMode = AAUDIO_SHARING_MODE_SHARED; setSharingMode(sharingMode); } AudioStream *audioStream = nullptr; *streamPtr = nullptr; bool allowMMap = mmapEnabled != AAUDIO_USE_NEVER; 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, tryMMap, &audioStream); allowMMap, &audioStream); if (result == AAUDIO_OK) { // Open the stream using the parameters from the builder. result = audioStream->open(*this); Loading @@ -105,7 +110,7 @@ aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) { delete audioStream; audioStream = nullptr; if (isMMap) { if (isMMap && allowLegacy) { ALOGD("AudioStreamBuilder.build() MMAP stream did not open so try Legacy path"); // If MMAP stream failed to open then TRY using a legacy stream. result = builder_createStream(getDirection(), sharingMode, Loading media/libaaudio/src/utility/AAudioUtilities.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <cutils/properties.h> #include <stdint.h> #include <sys/types.h> #include <utils/Errors.h> Loading Loading @@ -322,3 +323,52 @@ int32_t AAudioConvert_framesToBytes(int32_t numFrames, *sizeInBytes = numFrames * bytesPerFrame; 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; } media/libaaudio/src/utility/AAudioUtilities.h +50 −0 Original line number Diff line number Diff line Loading @@ -170,4 +170,54 @@ aaudio_audio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t for */ 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 services/oboeservice/AAudioServiceEndpoint.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -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. #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. AAudioServiceEndpoint::AAudioServiceEndpoint(AAudioService &audioService) : mStreamInternal(audioService, true) Loading @@ -71,7 +67,13 @@ aaudio_result_t AAudioServiceEndpoint::open(int32_t deviceId, aaudio_direction_t if (result == AAUDIO_OK) { 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); } return result; Loading Loading @@ -117,7 +119,6 @@ aaudio_result_t AAudioServiceEndpoint::stopStream(AAudioServiceStreamShared *sha static void *aaudio_mixer_thread_proc(void *context) { AAudioServiceEndpoint *stream = (AAudioServiceEndpoint *) context; //LOGD("AudioStreamAAudio(): oboe_callback_thread, stream = %p", stream); if (stream != NULL) { return stream->callbackLoop(); } else { Loading services/oboeservice/AAudioServiceEndpoint.h +1 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ private: std::atomic<bool> mCallbackEnabled; int32_t mReferenceCount = 0; bool mLatencyTuningEnabled = false; // TODO implement tuning std::mutex mLockStreams; std::vector<AAudioServiceStreamShared *> mRegisteredStreams; Loading Loading
media/libaaudio/src/core/AudioStreamBuilder.cpp +20 −15 Original line number Diff line number Diff line Loading @@ -30,12 +30,6 @@ #include "legacy/AudioStreamRecord.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; /* Loading @@ -53,6 +47,7 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction, AudioStream **audioStreamPtr) { *audioStreamPtr = nullptr; aaudio_result_t result = AAUDIO_OK; switch (direction) { case AAUDIO_DIRECTION_INPUT: Loading Loading @@ -81,20 +76,30 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction, 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) { 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(); if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && (MMAP_EXCLUSIVE_ENABLED == 0)) { ALOGE("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported"); return AAUDIO_ERROR_UNAVAILABLE; if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && (mmapExclusiveEnabled == AAUDIO_USE_NEVER)) { ALOGW("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported. Use SHARED."); sharingMode = AAUDIO_SHARING_MODE_SHARED; setSharingMode(sharingMode); } AudioStream *audioStream = nullptr; *streamPtr = nullptr; bool allowMMap = mmapEnabled != AAUDIO_USE_NEVER; 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, tryMMap, &audioStream); allowMMap, &audioStream); if (result == AAUDIO_OK) { // Open the stream using the parameters from the builder. result = audioStream->open(*this); Loading @@ -105,7 +110,7 @@ aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) { delete audioStream; audioStream = nullptr; if (isMMap) { if (isMMap && allowLegacy) { ALOGD("AudioStreamBuilder.build() MMAP stream did not open so try Legacy path"); // If MMAP stream failed to open then TRY using a legacy stream. result = builder_createStream(getDirection(), sharingMode, Loading
media/libaaudio/src/utility/AAudioUtilities.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <cutils/properties.h> #include <stdint.h> #include <sys/types.h> #include <utils/Errors.h> Loading Loading @@ -322,3 +323,52 @@ int32_t AAudioConvert_framesToBytes(int32_t numFrames, *sizeInBytes = numFrames * bytesPerFrame; 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; }
media/libaaudio/src/utility/AAudioUtilities.h +50 −0 Original line number Diff line number Diff line Loading @@ -170,4 +170,54 @@ aaudio_audio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t for */ 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
services/oboeservice/AAudioServiceEndpoint.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -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. #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. AAudioServiceEndpoint::AAudioServiceEndpoint(AAudioService &audioService) : mStreamInternal(audioService, true) Loading @@ -71,7 +67,13 @@ aaudio_result_t AAudioServiceEndpoint::open(int32_t deviceId, aaudio_direction_t if (result == AAUDIO_OK) { 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); } return result; Loading Loading @@ -117,7 +119,6 @@ aaudio_result_t AAudioServiceEndpoint::stopStream(AAudioServiceStreamShared *sha static void *aaudio_mixer_thread_proc(void *context) { AAudioServiceEndpoint *stream = (AAudioServiceEndpoint *) context; //LOGD("AudioStreamAAudio(): oboe_callback_thread, stream = %p", stream); if (stream != NULL) { return stream->callbackLoop(); } else { Loading
services/oboeservice/AAudioServiceEndpoint.h +1 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ private: std::atomic<bool> mCallbackEnabled; int32_t mReferenceCount = 0; bool mLatencyTuningEnabled = false; // TODO implement tuning std::mutex mLockStreams; std::vector<AAudioServiceStreamShared *> mRegisteredStreams; Loading