Merge "aaudio: offset MMAP timestamps"

gugelfrei
TreeHugger Robot 5 years ago committed by Android (Google) Code Review
commit b362012ad4

@ -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;
@ -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;
}

@ -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

@ -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) {

@ -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
@ -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"
/**
@ -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"
/**
@ -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…
Cancel
Save