aaudio: use actual DSP burst size in timing model

This will more accurately track the read or write
position of the DSP.

The client sometimes aggregates multiple hardware bursts
to avoid waking up too often. This can make it look like the DSP has
processed a larger amount of memory than it really has.
With this change, the timing model will advance in sync with the hardware.

Bug: 117834966
Bug: 130911274
Test: see bug for repro steps
Change-Id: Id22f1f313e02f0514665ee5ac144cab4684e3bc1
gugelfrei
Phil Burk 6 years ago
parent 9730f4d7d2
commit 3c4e6b5038

@ -76,6 +76,7 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
aaudio_result_t result = AAUDIO_OK;
int32_t capacity;
int32_t framesPerBurst;
int32_t framesPerHardwareBurst;
AAudioStreamRequest request;
AAudioStreamConfiguration configurationOutput;
@ -90,6 +91,9 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
return result;
}
const int32_t burstMinMicros = AAudioProperty_getHardwareBurstMinMicros();
int32_t burstMicros = 0;
// We have to do volume scaling. So we prefer FLOAT format.
if (getFormat() == AUDIO_FORMAT_DEFAULT) {
setFormat(AUDIO_FORMAT_PCM_FLOAT);
@ -173,8 +177,22 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
goto error;
}
// Validate result from server.
framesPerBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
framesPerHardwareBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
// Scale up the burst size to meet the minimum equivalent in microseconds.
// This is to avoid waking the CPU too often when the HW burst is very small
// or at high sample rates.
framesPerBurst = framesPerHardwareBurst;
do {
if (burstMicros > 0) { // skip first loop
framesPerBurst *= 2;
}
burstMicros = framesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
} while (burstMicros < burstMinMicros);
ALOGD("%s() original HW burst = %d, minMicros = %d => SW burst = %d\n",
__func__, framesPerHardwareBurst, burstMinMicros, framesPerBurst);
// Validate final burst size.
if (framesPerBurst < MIN_FRAMES_PER_BURST || framesPerBurst > MAX_FRAMES_PER_BURST) {
ALOGE("%s - framesPerBurst out of range = %d", __func__, framesPerBurst);
result = AAUDIO_ERROR_OUT_OF_RANGE;
@ -190,7 +208,7 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
}
mClockModel.setSampleRate(getSampleRate());
mClockModel.setFramesPerBurst(mFramesPerBurst);
mClockModel.setFramesPerBurst(framesPerHardwareBurst);
if (isDataCallbackSet()) {
mCallbackFrames = builder.getFramesPerDataCallback();

@ -77,9 +77,6 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques
audio_config_base_t config;
audio_port_handle_t deviceId;
int32_t burstMinMicros = AAudioProperty_getHardwareBurstMinMicros();
int32_t burstMicros = 0;
copyFrom(request.getConstantConfiguration());
aaudio_direction_t direction = getDirection();
@ -235,24 +232,12 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques
setFormat(config.format);
setSampleRate(config.sample_rate);
// Scale up the burst size to meet the minimum equivalent in microseconds.
// This is to avoid waking the CPU too often when the HW burst is very small
// or at high sample rates.
do {
if (burstMicros > 0) { // skip first loop
mFramesPerBurst *= 2;
}
burstMicros = mFramesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
} while (burstMicros < burstMinMicros);
ALOGD("%s() original burst = %d, minMicros = %d => burst = %d\n",
__func__, mMmapBufferinfo.burst_size_frames, burstMinMicros, mFramesPerBurst);
ALOGD("%s() actual rate = %d, channels = %d, deviceId = %d\n",
__func__, getSampleRate(), getSamplesPerFrame(), deviceId);
ALOGD("%s() actual rate = %d, channels = %d"
", deviceId = %d, capacity = %d\n",
__func__, getSampleRate(), getSamplesPerFrame(), deviceId, getBufferCapacity());
ALOGD("%s() format = 0x%08x, frame size = %d",
__func__, getFormat(), calculateBytesPerFrame());
ALOGD("%s() format = 0x%08x, frame size = %d, burst size = %d",
__func__, getFormat(), calculateBytesPerFrame(), mFramesPerBurst);
return result;

Loading…
Cancel
Save