AAudio: Improve buffer size calculations

This CL improves the calculations for both burst and buffer sizes.

1. This CL now uses the hardware burst size for its calculations.
2. This CL now uses a number of bursts for buffer size calculations.

Bug: 310024737
Test: OboeTester glitch test with loopback dongle
Change-Id: I04db1342a55b18a2e9b076052b4b3b0965a4c511
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 9b1ad72..8d9bf20 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -239,31 +239,35 @@
 }
 
 aaudio_result_t AudioStreamInternal::configureDataInformation(int32_t callbackFrames) {
-    int32_t deviceFramesPerBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
+    int32_t originalFramesPerBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
+    int32_t deviceFramesPerBurst = originalFramesPerBurst;
 
     // 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. The actual number of frames that we call back to
     // the app with will be 0 < N <= framesPerBurst so round up the division.
-    int32_t framesPerBurst = (static_cast<int64_t>(deviceFramesPerBurst) * getSampleRate() +
-             getDeviceSampleRate() - 1) / getDeviceSampleRate();
     int32_t burstMicros = 0;
     const int32_t burstMinMicros = android::AudioSystem::getAAudioHardwareBurstMinUsec();
     do {
         if (burstMicros > 0) {  // skip first loop
             deviceFramesPerBurst *= 2;
-            framesPerBurst *= 2;
         }
-        burstMicros = framesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
+        burstMicros = deviceFramesPerBurst * static_cast<int64_t>(1000000) / getDeviceSampleRate();
     } while (burstMicros < burstMinMicros);
     ALOGD("%s() original HW burst = %d, minMicros = %d => SW burst = %d\n",
-          __func__, deviceFramesPerBurst, burstMinMicros, framesPerBurst);
+          __func__, originalFramesPerBurst, burstMinMicros, deviceFramesPerBurst);
 
     // Validate final burst size.
-    if (framesPerBurst < MIN_FRAMES_PER_BURST || framesPerBurst > MAX_FRAMES_PER_BURST) {
-        ALOGE("%s - framesPerBurst out of range = %d", __func__, framesPerBurst);
+    if (deviceFramesPerBurst < MIN_FRAMES_PER_BURST
+            || deviceFramesPerBurst > MAX_FRAMES_PER_BURST) {
+        ALOGE("%s - deviceFramesPerBurst out of range = %d", __func__, deviceFramesPerBurst);
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
+
+    // Calculate the application framesPerBurst from the deviceFramesPerBurst
+    int32_t framesPerBurst = (static_cast<int64_t>(deviceFramesPerBurst) * getSampleRate() +
+             getDeviceSampleRate() - 1) / getDeviceSampleRate();
+
     setDeviceFramesPerBurst(deviceFramesPerBurst);
     setFramesPerBurst(framesPerBurst); // only save good value
 
@@ -894,43 +898,30 @@
 }
 
 aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) {
-    int32_t adjustedFrames = requestedFrames;
     const int32_t maximumSize = getBufferCapacity() - getFramesPerBurst();
-    // Minimum size should be a multiple number of bursts.
-    const int32_t minimumSize = 1 * getFramesPerBurst();
+    int32_t adjustedFrames = std::min(requestedFrames, maximumSize);
+    // Buffer sizes should always be a multiple of framesPerBurst.
+    int32_t numBursts = (static_cast<int64_t>(adjustedFrames) + getFramesPerBurst() - 1) /
+        getFramesPerBurst();
 
-    // Clip to minimum size so that rounding up will work better.
-    adjustedFrames = std::max(minimumSize, adjustedFrames);
-
-    // Prevent arithmetic overflow by clipping before we round.
-    if (adjustedFrames >= maximumSize) {
-        adjustedFrames = maximumSize;
-    } else {
-        // Round to the next highest burst size.
-        int32_t numBursts = (static_cast<int64_t>(adjustedFrames) + getFramesPerBurst() - 1) /
-                getFramesPerBurst();
-        adjustedFrames = numBursts * getFramesPerBurst();
-        // Clip just in case maximumSize is not a multiple of getFramesPerBurst().
-        adjustedFrames = std::min(maximumSize, adjustedFrames);
+    // Use at least one burst
+    if (numBursts == 0) {
+        numBursts = 1;
     }
 
     if (mAudioEndpoint) {
         // Clip against the actual size from the endpoint.
         int32_t actualFramesDevice = 0;
-        int32_t maximumFramesDevice = (static_cast<int64_t>(maximumSize) * getDeviceSampleRate()
-                + getSampleRate() - 1) / getSampleRate();
+        int32_t maximumFramesDevice = getDeviceBufferCapacity() - getDeviceFramesPerBurst();
         // Set to maximum size so we can write extra data when ready in order to reduce glitches.
         // The amount we keep in the buffer is controlled by mBufferSizeInFrames.
         mAudioEndpoint->setBufferSizeInFrames(maximumFramesDevice, &actualFramesDevice);
-        int32_t actualFrames = (static_cast<int64_t>(actualFramesDevice) * getSampleRate() +
-                 getDeviceSampleRate() - 1) / getDeviceSampleRate();
-        // actualFrames should be <= actual maximum size of endpoint
-        adjustedFrames = std::min(actualFrames, adjustedFrames);
+        int32_t actualNumBursts = actualFramesDevice / getDeviceFramesPerBurst();
+        numBursts = std::min(numBursts, actualNumBursts);
     }
 
-    const int32_t bufferSizeInFrames = adjustedFrames;
-    const int32_t deviceBufferSizeInFrames = static_cast<int64_t>(bufferSizeInFrames) *
-            getDeviceSampleRate() / getSampleRate();
+    const int32_t bufferSizeInFrames = numBursts * getFramesPerBurst();
+    const int32_t deviceBufferSizeInFrames = numBursts * getDeviceFramesPerBurst();
 
     if (deviceBufferSizeInFrames != mDeviceBufferSizeInFrames) {
         android::mediametrics::LogItem(mMetricsId)