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

Commit f1533004 authored by Phil Burk's avatar Phil Burk
Browse files

aaudio: fix hang option in write_sine_callback

Was colliding with -z option for capacity.
Also print data size in output buffer.

Test: adb shell write_sine_callback -pl -n2 -h8 -s10
Change-Id: If64f0876d3a2e1a95426dddf122693dbf3a314cd
parent ffb2516c
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -32,8 +32,6 @@


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


#define MAX_TIMESTAMPS                   16
#define MAX_TIMESTAMPS                   16


@@ -275,7 +273,7 @@ typedef struct SineThreadedData_s {


    int                scheduler = 0;
    int                scheduler = 0;
    bool               schedulerChecked = false;
    bool               schedulerChecked = false;
    bool               forceUnderruns = false;
    int32_t            hangTimeMSec = 0;


    AAudioSimplePlayer simplePlayer;
    AAudioSimplePlayer simplePlayer;
    int32_t            callbackCount = 0;
    int32_t            callbackCount = 0;
@@ -327,10 +325,12 @@ aaudio_data_callback_result_t SimplePlayerDataCallbackProc(
        sineData->setupSineSweeps();
        sineData->setupSineSweeps();
    }
    }


    if (sineData->forceUnderruns) {
    if (sineData->hangTimeMSec > 0) {
        if (sineData->framesTotal > sineData->nextFrameToGlitch) {
        if (sineData->framesTotal > sineData->nextFrameToGlitch) {
            usleep(FORCED_UNDERRUN_SLEEP_MICROS);
            usleep(sineData->hangTimeMSec * 1000);
            printf("Simulate glitch at %lld\n", (long long) sineData->framesTotal);
            printf("Hang callback at %lld frames for %d msec\n",
                    (long long) sineData->framesTotal,
                   sineData->hangTimeMSec);
            sineData->nextFrameToGlitch += FORCED_UNDERRUN_PERIOD_FRAMES;
            sineData->nextFrameToGlitch += FORCED_UNDERRUN_PERIOD_FRAMES;
        }
        }
    }
    }
+29 −13
Original line number Original line Diff line number Diff line
@@ -26,11 +26,14 @@
#include <string.h>
#include <string.h>
#include <time.h>
#include <time.h>
#include <aaudio/AAudio.h>
#include <aaudio/AAudio.h>

#include "AAudioExampleUtils.h"
#include "AAudioExampleUtils.h"
#include "AAudioSimplePlayer.h"
#include "AAudioSimplePlayer.h"
#include "AAudioArgsParser.h"
#include "AAudioArgsParser.h"


#define APP_VERSION  "0.1.5"
#define APP_VERSION  "0.1.6"

constexpr int32_t kDefaultHangTimeMSec = 10;


/**
/**
 * Open stream, play some sine waves, then close the stream.
 * Open stream, play some sine waves, then close the stream.
@@ -41,7 +44,7 @@
static aaudio_result_t testOpenPlayClose(AAudioArgsParser &argParser,
static aaudio_result_t testOpenPlayClose(AAudioArgsParser &argParser,
                                         int32_t loopCount,
                                         int32_t loopCount,
                                         int32_t prefixToneMsec,
                                         int32_t prefixToneMsec,
                                         bool forceUnderruns)
                                         int32_t hangTimeMSec)
{
{
    SineThreadedData_t myData;
    SineThreadedData_t myData;
    AAudioSimplePlayer &player = myData.simplePlayer;
    AAudioSimplePlayer &player = myData.simplePlayer;
@@ -53,10 +56,12 @@ static aaudio_result_t testOpenPlayClose(AAudioArgsParser &argParser,
    printf("----------------------- run complete test --------------------------\n");
    printf("----------------------- run complete test --------------------------\n");
    myData.schedulerChecked = false;
    myData.schedulerChecked = false;
    myData.callbackCount = 0;
    myData.callbackCount = 0;
    myData.forceUnderruns = forceUnderruns; // test AAudioStream_getXRunCount()
    myData.hangTimeMSec = hangTimeMSec; // test AAudioStream_getXRunCount()


    result = player.open(argParser,
    result = player.open(argParser,
                         SimplePlayerDataCallbackProc, SimplePlayerErrorCallbackProc, &myData);
                         SimplePlayerDataCallbackProc,
                         SimplePlayerErrorCallbackProc,
                         &myData);
    if (result != AAUDIO_OK) {
    if (result != AAUDIO_OK) {
        fprintf(stderr, "ERROR -  player.open() returned %s\n",
        fprintf(stderr, "ERROR -  player.open() returned %s\n",
                AAudio_convertResultToText(result));
                AAudio_convertResultToText(result));
@@ -115,12 +120,17 @@ static aaudio_result_t testOpenPlayClose(AAudioArgsParser &argParser,
            int64_t millis =
            int64_t millis =
                    (getNanoseconds(CLOCK_MONOTONIC) - startedAtNanos) / NANOS_PER_MILLISECOND;
                    (getNanoseconds(CLOCK_MONOTONIC) - startedAtNanos) / NANOS_PER_MILLISECOND;
            result = myData.waker.get();
            result = myData.waker.get();
            const int32_t framesWritten = (int32_t) AAudioStream_getFramesWritten(player.getStream());
            const int32_t framesRead = (int32_t) AAudioStream_getFramesRead(player.getStream());
            const int32_t xruns = AAudioStream_getXRunCount(player.getStream());
            printf(" waker result = %d, at %6d millis"
            printf(" waker result = %d, at %6d millis"
                           ", second = %3d, framesWritten = %8d, underruns = %d\n",
                           ", second = %3d, frames written %8d - read %8d = %8d, underruns = %d\n",
                   result, (int) millis,
                   result, (int) millis,
                   second,
                   second,
                   (int) AAudioStream_getFramesWritten(player.getStream()),
                   framesWritten,
                   (int) AAudioStream_getXRunCount(player.getStream()));
                   framesRead,
                   framesWritten - framesRead,
                   xruns);
            if (result != AAUDIO_OK) {
            if (result != AAUDIO_OK) {
                disconnected = (result == AAUDIO_ERROR_DISCONNECTED);
                disconnected = (result == AAUDIO_ERROR_DISCONNECTED);
                bailOut = true;
                bailOut = true;
@@ -210,7 +220,9 @@ static void usage() {
    AAudioArgsParser::usage();
    AAudioArgsParser::usage();
    printf("      -l{count} loopCount start/stop, every other one is silent\n");
    printf("      -l{count} loopCount start/stop, every other one is silent\n");
    printf("      -t{msec}  play a high pitched tone at the beginning\n");
    printf("      -t{msec}  play a high pitched tone at the beginning\n");
    printf("      -z        force periodic underruns by sleeping in callback\n");
    printf("      -h{msec}  force periodic underruns by hanging in callback\n");
    printf("                If no value specified then %d used.\n",
            kDefaultHangTimeMSec);
}
}


int main(int argc, const char **argv)
int main(int argc, const char **argv)
@@ -219,13 +231,14 @@ int main(int argc, const char **argv)
    aaudio_result_t    result;
    aaudio_result_t    result;
    int32_t            loopCount = 1;
    int32_t            loopCount = 1;
    int32_t            prefixToneMsec = 0;
    int32_t            prefixToneMsec = 0;
    bool               forceUnderruns = false;
    int32_t            hangTimeMSec = 0;


    // Make printf print immediately so that debug info is not stuck
    // Make printf print immediately so that debug info is not stuck
    // in a buffer if we hang or crash.
    // in a buffer if we hang or crash.
    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);


    printf("%s - Play a sine sweep using an AAudio callback V%s\n", argv[0], APP_VERSION);
    printf("%s - Play a sine sweep using an AAudio callback V%s\n",
        argv[0], APP_VERSION);


    for (int i = 1; i < argc; i++) {
    for (int i = 1; i < argc; i++) {
        const char *arg = argv[i];
        const char *arg = argv[i];
@@ -240,8 +253,10 @@ int main(int argc, const char **argv)
                    case 't':
                    case 't':
                        prefixToneMsec = atoi(&arg[2]);
                        prefixToneMsec = atoi(&arg[2]);
                        break;
                        break;
                    case 'z':
                    case 'h':
                        forceUnderruns = true;  // Zzzzzzz
                        hangTimeMSec = (arg[2]) // value specified?
                                ? atoi(&arg[2])
                                : kDefaultHangTimeMSec;
                        break;
                        break;
                    default:
                    default:
                        usage();
                        usage();
@@ -257,7 +272,8 @@ int main(int argc, const char **argv)
    }
    }


    // Keep looping until we can complete the test without disconnecting.
    // Keep looping until we can complete the test without disconnecting.
    while((result = testOpenPlayClose(argParser, loopCount, prefixToneMsec, forceUnderruns))
    while((result = testOpenPlayClose(argParser, loopCount,
            prefixToneMsec, hangTimeMSec))
            == AAUDIO_ERROR_DISCONNECTED);
            == AAUDIO_ERROR_DISCONNECTED);


    return (result) ? EXIT_FAILURE : EXIT_SUCCESS;
    return (result) ? EXIT_FAILURE : EXIT_SUCCESS;