Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19d05412 authored by Phil Burk's avatar Phil Burk Committed by android-build-merger
Browse files

aaudio: fix getXRunCount

am: faeb8b20

Change-Id: I5df65477820b7297479f4cf1f41ec1d5c92cff77
parents 5fafb7bd faeb8b20
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -30,6 +30,11 @@
#define SHARING_MODE  AAUDIO_SHARING_MODE_SHARED
#define PERFORMANCE_MODE AAUDIO_PERFORMANCE_MODE_NONE

// Arbitrary period for glitches, once per second at 48000 Hz.
#define FORCED_UNDERRUN_PERIOD_FRAMES    48000
// How long to sleep in a callback to cause an intentional glitch. For testing.
#define FORCED_UNDERRUN_SLEEP_MICROS     (10 * 1000)

/**
 * Simple wrapper for AAudio that opens an output stream either in callback or blocking write mode.
 */
@@ -219,10 +224,13 @@ private:
typedef struct SineThreadedData_s {
    SineGenerator  sineOsc1;
    SineGenerator  sineOsc2;
    int64_t        framesTotal = 0;
    int64_t        nextFrameToGlitch = FORCED_UNDERRUN_PERIOD_FRAMES;
    int32_t        minNumFrames = INT32_MAX;
    int32_t        maxNumFrames = 0;
    int            scheduler;
    bool           schedulerChecked;
    bool           schedulerChecked = false;
    bool           forceUnderruns = false;
} SineThreadedData_t;

// Callback function that fills the audio output buffer.
@@ -235,11 +243,21 @@ aaudio_data_callback_result_t SimplePlayerDataCallbackProc(

    // should not happen but just in case...
    if (userData == nullptr) {
        fprintf(stderr, "ERROR - SimplePlayerDataCallbackProc needs userData\n");
        printf("ERROR - SimplePlayerDataCallbackProc needs userData\n");
        return AAUDIO_CALLBACK_RESULT_STOP;
    }
    SineThreadedData_t *sineData = (SineThreadedData_t *) userData;

    sineData->framesTotal += numFrames;

    if (sineData->forceUnderruns) {
        if (sineData->framesTotal > sineData->nextFrameToGlitch) {
            usleep(FORCED_UNDERRUN_SLEEP_MICROS);
            printf("Simulate glitch at %lld\n", (long long) sineData->framesTotal);
            sineData->nextFrameToGlitch += FORCED_UNDERRUN_PERIOD_FRAMES;
        }
    }

    if (!sineData->schedulerChecked) {
        sineData->scheduler = sched_getscheduler(gettid());
        sineData->schedulerChecked = true;
+7 −5
Original line number Diff line number Diff line
@@ -26,9 +26,7 @@
#include <aaudio/AAudio.h>
#include "AAudioExampleUtils.h"
#include "AAudioSimplePlayer.h"

// Application data that gets passed to the callback.
#define MAX_FRAME_COUNT_RECORDS    256
#include "../../utils/AAudioSimplePlayer.h"

int main(int argc, const char **argv)
{
@@ -42,9 +40,10 @@ int main(int argc, const char **argv)
    // in a buffer if we hang or crash.
    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);

    printf("%s - Play a sine sweep using an AAudio callback V0.1.1\n", argv[0]);
    printf("%s - Play a sine sweep using an AAudio callback V0.1.2\n", argv[0]);

    myData.schedulerChecked = false;
    myData.forceUnderruns = false; // set true to test AAudioStream_getXRunCount()

    if (argParser.parseArgs(argc, argv)) {
        return EXIT_FAILURE;
@@ -99,7 +98,10 @@ int main(int argc, const char **argv)
            printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state));
            break;
        }
        printf("framesWritten = %d\n", (int) AAudioStream_getFramesWritten(player.getStream()));
        printf("framesWritten = %d, underruns = %d\n",
               (int) AAudioStream_getFramesWritten(player.getStream()),
               (int) AAudioStream_getXRunCount(player.getStream())
        );
    }
    printf("Woke up now.\n");

+5 −5
Original line number Diff line number Diff line
@@ -88,11 +88,11 @@ bool AAudioMixer::mix(int trackIndex, FifoBuffer *fifo, float volume) {
        }
        partIndex++;
    }
    fifo->getFifoControllerBase()->advanceReadIndex(mFramesPerBurst - framesLeft);
    if (framesLeft > 0) {
        //ALOGW("AAudioMixer::mix() UNDERFLOW by %d / %d frames ----- UNDERFLOW !!!!!!!!!!",
        //      framesLeft, mFramesPerBurst);
    }
    // Always advance by one burst even if we do not have the data.
    // Otherwise the stream timing will drift whenever there is an underflow.
    // This actual underflow can then be detected by the client for XRun counting.
    fifo->getFifoControllerBase()->advanceReadIndex(mFramesPerBurst);

#if AAUDIO_MIXER_ATRACE_ENABLED
    ATRACE_END();
#endif /* AAUDIO_MIXER_ATRACE_ENABLED */