Loading media/libaaudio/src/client/AudioStreamInternal.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -232,6 +232,24 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) { mCallbackBuffer = new uint8_t[callbackBufferSize]; } // For debugging and analyzing the distribution of MMAP timestamps. // For OUTPUT, use a NEGATIVE offset to move the CPU writes further BEFORE the HW reads. // For INPUT, use a POSITIVE offset to move the CPU reads further AFTER the HW writes. // You can use this offset to reduce glitching. // You can also use this offset to force glitching. By iterating over multiple // values you can reveal the distribution of the hardware timing jitter. if (mAudioEndpoint.isFreeRunning()) { // MMAP? int32_t offsetMicros = (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? AAudioProperty_getOutputMMapOffsetMicros() : AAudioProperty_getInputMMapOffsetMicros(); // This log is used to debug some tricky glitch issues. Please leave. ALOGD_IF(offsetMicros, "%s() - %s mmap offset = %d micros", __func__, (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "output" : "input", offsetMicros); mTimeOffsetNanos = offsetMicros * AAUDIO_NANOS_PER_MICROSECOND; } setState(AAUDIO_STREAM_STATE_OPEN); return result; Loading Loading @@ -478,7 +496,8 @@ aaudio_result_t AudioStreamInternal::onTimestampService(AAudioServiceMessage *me #if LOG_TIMESTAMPS logTimestamp(*message); #endif processTimestamp(message->timestamp.position, message->timestamp.timestamp); processTimestamp(message->timestamp.position, message->timestamp.timestamp + mTimeOffsetNanos); return AAUDIO_OK; } Loading media/libaaudio/src/client/AudioStreamInternal.h +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ private: // By delaying slightly we can avoid waking up before other side is ready. const int32_t mWakeupDelayNanos; // delay past typical wakeup jitter const int32_t mMinimumSleepNanos; // minimum sleep while polling int32_t mTimeOffsetNanos = 0; // add to time part of an MMAP timestamp AudioEndpointParcelable mEndPointParcelable; // description of the buffers filled by service EndpointDescriptor mEndpointDescriptor; // buffer description with resolved addresses Loading media/libaaudio/src/utility/AAudioUtilities.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,30 @@ int32_t AAudioProperty_getHardwareBurstMinMicros() { return prop; } static int32_t AAudioProperty_getMMapOffsetMicros(const char *functionName, const char *propertyName) { const int32_t minMicros = -20000; // arbitrary const int32_t defaultMicros = 0; // arbitrary const int32_t maxMicros = 20000; // arbitrary int32_t prop = property_get_int32(propertyName, defaultMicros); if (prop < minMicros) { ALOGW("%s: clipped %d to %d", functionName, prop, minMicros); prop = minMicros; } else if (prop > maxMicros) { ALOGW("%s: clipped %d to %d", functionName, prop, minMicros); prop = maxMicros; } return prop; } int32_t AAudioProperty_getInputMMapOffsetMicros() { return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC); } int32_t AAudioProperty_getOutputMMapOffsetMicros() { return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC); } aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) { aaudio_result_t result = AAUDIO_OK; switch (state) { Loading media/libaaudio/src/utility/AAudioUtilities.h +17 −10 Original line number Diff line number Diff line Loading @@ -94,31 +94,26 @@ audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask( // Note that this code may be replaced by Settings or by some other system configuration tool. #define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy" /** * Read system property. * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS */ int32_t AAudioProperty_getMMapPolicy(); #define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy" #define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy" /** * Read system property. * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS */ int32_t AAudioProperty_getMMapExclusivePolicy(); #define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts" #define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy" /** * Read system property. * @return number of bursts per AAudio service mixer cycle */ int32_t AAudioProperty_getMixerBursts(); #define AAUDIO_PROP_HW_BURST_MIN_USEC "aaudio.hw_burst_min_usec" #define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts" /** * Read a system property that specifies the number of extra microseconds that a thread Loading @@ -130,7 +125,6 @@ int32_t AAudioProperty_getMixerBursts(); * @return number of microseconds to delay the wakeup. */ int32_t AAudioProperty_getWakeupDelayMicros(); #define AAUDIO_PROP_WAKEUP_DELAY_USEC "aaudio.wakeup_delay_usec" /** Loading @@ -139,7 +133,6 @@ int32_t AAudioProperty_getWakeupDelayMicros(); * @return minimum number of microseconds to sleep. */ int32_t AAudioProperty_getMinimumSleepMicros(); #define AAUDIO_PROP_MINIMUM_SLEEP_USEC "aaudio.minimum_sleep_usec" /** Loading @@ -153,7 +146,21 @@ int32_t AAudioProperty_getMinimumSleepMicros(); * @return minimum number of microseconds for a MMAP HW burst */ int32_t AAudioProperty_getHardwareBurstMinMicros(); #define AAUDIO_PROP_HW_BURST_MIN_USEC "aaudio.hw_burst_min_usec" /** * Read a system property that specifies an offset that will be added to MMAP timestamps. * This can be used to correct bias in the timestamp. * It can also be used to analyze the time distribution of the timestamp * by progressively modifying the offset and listening for glitches. * * @return number of microseconds to offset the time part of an MMAP timestamp */ int32_t AAudioProperty_getInputMMapOffsetMicros(); #define AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC "aaudio.in_mmap_offset_usec" int32_t AAudioProperty_getOutputMMapOffsetMicros(); #define AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC "aaudio.out_mmap_offset_usec" /** * Is flush allowed for the given state? Loading Loading
media/libaaudio/src/client/AudioStreamInternal.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -232,6 +232,24 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) { mCallbackBuffer = new uint8_t[callbackBufferSize]; } // For debugging and analyzing the distribution of MMAP timestamps. // For OUTPUT, use a NEGATIVE offset to move the CPU writes further BEFORE the HW reads. // For INPUT, use a POSITIVE offset to move the CPU reads further AFTER the HW writes. // You can use this offset to reduce glitching. // You can also use this offset to force glitching. By iterating over multiple // values you can reveal the distribution of the hardware timing jitter. if (mAudioEndpoint.isFreeRunning()) { // MMAP? int32_t offsetMicros = (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? AAudioProperty_getOutputMMapOffsetMicros() : AAudioProperty_getInputMMapOffsetMicros(); // This log is used to debug some tricky glitch issues. Please leave. ALOGD_IF(offsetMicros, "%s() - %s mmap offset = %d micros", __func__, (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "output" : "input", offsetMicros); mTimeOffsetNanos = offsetMicros * AAUDIO_NANOS_PER_MICROSECOND; } setState(AAUDIO_STREAM_STATE_OPEN); return result; Loading Loading @@ -478,7 +496,8 @@ aaudio_result_t AudioStreamInternal::onTimestampService(AAudioServiceMessage *me #if LOG_TIMESTAMPS logTimestamp(*message); #endif processTimestamp(message->timestamp.position, message->timestamp.timestamp); processTimestamp(message->timestamp.position, message->timestamp.timestamp + mTimeOffsetNanos); return AAUDIO_OK; } Loading
media/libaaudio/src/client/AudioStreamInternal.h +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ private: // By delaying slightly we can avoid waking up before other side is ready. const int32_t mWakeupDelayNanos; // delay past typical wakeup jitter const int32_t mMinimumSleepNanos; // minimum sleep while polling int32_t mTimeOffsetNanos = 0; // add to time part of an MMAP timestamp AudioEndpointParcelable mEndPointParcelable; // description of the buffers filled by service EndpointDescriptor mEndpointDescriptor; // buffer description with resolved addresses Loading
media/libaaudio/src/utility/AAudioUtilities.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,30 @@ int32_t AAudioProperty_getHardwareBurstMinMicros() { return prop; } static int32_t AAudioProperty_getMMapOffsetMicros(const char *functionName, const char *propertyName) { const int32_t minMicros = -20000; // arbitrary const int32_t defaultMicros = 0; // arbitrary const int32_t maxMicros = 20000; // arbitrary int32_t prop = property_get_int32(propertyName, defaultMicros); if (prop < minMicros) { ALOGW("%s: clipped %d to %d", functionName, prop, minMicros); prop = minMicros; } else if (prop > maxMicros) { ALOGW("%s: clipped %d to %d", functionName, prop, minMicros); prop = maxMicros; } return prop; } int32_t AAudioProperty_getInputMMapOffsetMicros() { return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC); } int32_t AAudioProperty_getOutputMMapOffsetMicros() { return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC); } aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) { aaudio_result_t result = AAUDIO_OK; switch (state) { Loading
media/libaaudio/src/utility/AAudioUtilities.h +17 −10 Original line number Diff line number Diff line Loading @@ -94,31 +94,26 @@ audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask( // Note that this code may be replaced by Settings or by some other system configuration tool. #define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy" /** * Read system property. * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS */ int32_t AAudioProperty_getMMapPolicy(); #define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy" #define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy" /** * Read system property. * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS */ int32_t AAudioProperty_getMMapExclusivePolicy(); #define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts" #define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy" /** * Read system property. * @return number of bursts per AAudio service mixer cycle */ int32_t AAudioProperty_getMixerBursts(); #define AAUDIO_PROP_HW_BURST_MIN_USEC "aaudio.hw_burst_min_usec" #define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts" /** * Read a system property that specifies the number of extra microseconds that a thread Loading @@ -130,7 +125,6 @@ int32_t AAudioProperty_getMixerBursts(); * @return number of microseconds to delay the wakeup. */ int32_t AAudioProperty_getWakeupDelayMicros(); #define AAUDIO_PROP_WAKEUP_DELAY_USEC "aaudio.wakeup_delay_usec" /** Loading @@ -139,7 +133,6 @@ int32_t AAudioProperty_getWakeupDelayMicros(); * @return minimum number of microseconds to sleep. */ int32_t AAudioProperty_getMinimumSleepMicros(); #define AAUDIO_PROP_MINIMUM_SLEEP_USEC "aaudio.minimum_sleep_usec" /** Loading @@ -153,7 +146,21 @@ int32_t AAudioProperty_getMinimumSleepMicros(); * @return minimum number of microseconds for a MMAP HW burst */ int32_t AAudioProperty_getHardwareBurstMinMicros(); #define AAUDIO_PROP_HW_BURST_MIN_USEC "aaudio.hw_burst_min_usec" /** * Read a system property that specifies an offset that will be added to MMAP timestamps. * This can be used to correct bias in the timestamp. * It can also be used to analyze the time distribution of the timestamp * by progressively modifying the offset and listening for glitches. * * @return number of microseconds to offset the time part of an MMAP timestamp */ int32_t AAudioProperty_getInputMMapOffsetMicros(); #define AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC "aaudio.in_mmap_offset_usec" int32_t AAudioProperty_getOutputMMapOffsetMicros(); #define AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC "aaudio.out_mmap_offset_usec" /** * Is flush allowed for the given state? Loading