Loading media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h +40 −10 Original line number Diff line number Diff line Loading @@ -495,7 +495,7 @@ public: } void printStatus() override { printf("state = %d, echo gain = %f ", mState, mEchoGain); printf("st = %d, echo gain = %f ", mState, mEchoGain); } static void sendImpulse(float *outputData, int outputChannelCount) { Loading Loading @@ -670,7 +670,7 @@ public: printf(LOOPBACK_RESULT_TAG "phase.offset = %7.5f\n", mPhaseOffset); printf(LOOPBACK_RESULT_TAG "ref.phase = %7.5f\n", mPhase); printf(LOOPBACK_RESULT_TAG "frames.accumulated = %6d\n", mFramesAccumulated); printf(LOOPBACK_RESULT_TAG "sine.period = %6d\n", mPeriod); printf(LOOPBACK_RESULT_TAG "sine.period = %6d\n", mSinePeriod); printf(LOOPBACK_RESULT_TAG "test.state = %6d\n", mState); printf(LOOPBACK_RESULT_TAG "frame.count = %6d\n", mFrameCounter); // Did we ever get a lock? Loading @@ -684,7 +684,7 @@ public: } void printStatus() override { printf(" state = %d, glitches = %3d,", mState, mGlitchCount); printf("st = %d, #gl = %3d,", mState, mGlitchCount); } double calculateMagnitude(double *phasePtr = NULL) { Loading @@ -709,6 +709,8 @@ public: void process(float *inputData, int inputChannelCount, float *outputData, int outputChannelCount, int numFrames) override { mProcessCount++; float peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames); if (peak > mPeakAmplitude) { mPeakAmplitude = peak; Loading @@ -720,6 +722,7 @@ public: float sinOut = sinf(mPhase); switch (mState) { case STATE_IDLE: case STATE_IMMUNE: case STATE_WAITING_FOR_SIGNAL: break; Loading @@ -728,7 +731,7 @@ public: mCosAccumulator += sample * cosf(mPhase); mFramesAccumulated++; // Must be a multiple of the period or the calculation will not be accurate. if (mFramesAccumulated == mPeriod * 4) { if (mFramesAccumulated == mSinePeriod * PERIODS_NEEDED_FOR_LOCK) { mPhaseOffset = 0.0; mMagnitude = calculateMagnitude(&mPhaseOffset); if (mMagnitude > mThreshold) { Loading @@ -754,7 +757,22 @@ public: // mFrameCounter, mGlitchCount, predicted, sample); mState = STATE_IMMUNE; //printf("%5d: switch to STATE_IMMUNE\n", mFrameCounter); mDownCounter = mPeriod; // Set duration of IMMUNE state. mDownCounter = mSinePeriod; // Set duration of IMMUNE state. } // Track incoming signal and slowly adjust magnitude to account // for drift in the DRC or AGC. mSinAccumulator += sample * sinOut; mCosAccumulator += sample * cosf(mPhase); mFramesAccumulated++; // Must be a multiple of the period or the calculation will not be accurate. if (mFramesAccumulated == mSinePeriod) { const double coefficient = 0.1; double phaseOffset = 0.0; double magnitude = calculateMagnitude(&phaseOffset); // One pole averaging filter. mMagnitude = (mMagnitude * (1.0 - coefficient)) + (magnitude * coefficient); resetAccumulator(); } } break; } Loading @@ -775,6 +793,9 @@ public: // Do these once per buffer. switch (mState) { case STATE_IDLE: mState = STATE_IMMUNE; // so we can tell when break; case STATE_IMMUNE: mDownCounter -= numFrames; if (mDownCounter <= 0) { Loading Loading @@ -805,21 +826,29 @@ public: void reset() override { mGlitchCount = 0; mState = STATE_IMMUNE; mPhaseIncrement = 2.0 * M_PI / mPeriod; printf("phaseInc = %f for period %d\n", mPhaseIncrement, mPeriod); mDownCounter = IMMUNE_FRAME_COUNT; mPhaseIncrement = 2.0 * M_PI / mSinePeriod; printf("phaseInc = %f for period %d\n", mPhaseIncrement, mSinePeriod); resetAccumulator(); mProcessCount = 0; } private: enum sine_state_t { STATE_IDLE, STATE_IMMUNE, STATE_WAITING_FOR_SIGNAL, STATE_WAITING_FOR_LOCK, STATE_LOCKED }; int mPeriod = 79; enum constants { IMMUNE_FRAME_COUNT = 48 * 500, PERIODS_NEEDED_FOR_LOCK = 8 }; int mSinePeriod = 79; double mPhaseIncrement = 0.0; double mPhase = 0.0; double mPhaseOffset = 0.0; Loading @@ -828,18 +857,19 @@ private: double mThreshold = 0.005; double mTolerance = 0.01; int32_t mFramesAccumulated = 0; int32_t mProcessCount = 0; double mSinAccumulator = 0.0; double mCosAccumulator = 0.0; int32_t mGlitchCount = 0; double mPeakAmplitude = 0.0; int mDownCounter = 4000; int mDownCounter = IMMUNE_FRAME_COUNT; int32_t mFrameCounter = 0; float mOutputAmplitude = 0.75; PseudoRandom mWhiteNoise; float mNoiseAmplitude = 0.00; // Used to experiment with warbling caused by DRC. sine_state_t mState = STATE_IMMUNE; sine_state_t mState = STATE_IDLE; }; Loading media/libaaudio/examples/loopback/src/loopback.cpp +45 −28 Original line number Diff line number Diff line Loading @@ -38,21 +38,25 @@ // Tag for machine readable results as property = value pairs #define RESULT_TAG "RESULT: " #define NUM_SECONDS 5 #define PERIOD_MILLIS 1000 #define NUM_INPUT_CHANNELS 1 #define FILENAME_ALL "/data/loopback_all.wav" #define FILENAME_ECHOS "/data/loopback_echos.wav" #define APP_VERSION "0.2.01" #define APP_VERSION "0.2.03" constexpr int kNumCallbacksToDrain = 20; constexpr int kNumCallbacksToDiscard = 20; struct LoopbackData { AAudioStream *inputStream = nullptr; int32_t inputFramesMaximum = 0; int16_t *inputShortData = nullptr; float *inputFloatData = nullptr; int16_t peakShort = 0; aaudio_format_t actualInputFormat = AAUDIO_FORMAT_INVALID; int32_t actualInputChannelCount = 0; int32_t actualOutputChannelCount = 0; int32_t inputBuffersToDiscard = 10; int32_t numCallbacksToDrain = kNumCallbacksToDrain; int32_t numCallbacksToDiscard = kNumCallbacksToDiscard; int32_t minNumFrames = INT32_MAX; int32_t maxNumFrames = 0; int32_t insufficientReadCount = 0; Loading Loading @@ -131,23 +135,32 @@ static aaudio_data_callback_result_t MyDataCallbackProc( myData->minNumFrames = numFrames; } if (myData->inputBuffersToDiscard > 0) { // Silence the output. int32_t numBytes = numFrames * myData->actualOutputChannelCount * sizeof(float); memset(audioData, 0 /* value */, numBytes); if (myData->numCallbacksToDrain > 0) { // Drain the input. do { framesRead = readFormattedData(myData, numFrames); // Ignore errors because input stream may not be started yet. } while (framesRead > 0); myData->numCallbacksToDrain--; } else if (myData->numCallbacksToDiscard > 0) { // Ignore. Allow the input to fill back up to equilibrium with the output. framesRead = readFormattedData(myData, numFrames); if (framesRead < 0) { result = AAUDIO_CALLBACK_RESULT_STOP; } else if (framesRead > 0) { myData->inputBuffersToDiscard--; } } while (framesRead > 0); // Silence the output. int32_t numBytes = numFrames * myData->actualOutputChannelCount * sizeof(float); memset(audioData, 0 /* value */, numBytes); myData->numCallbacksToDiscard--; } else { int32_t numInputBytes = numFrames * myData->actualInputChannelCount * sizeof(float); memset(myData->inputFloatData, 0 /* value */, numInputBytes); // Process data after equilibrium. int64_t inputFramesWritten = AAudioStream_getFramesWritten(myData->inputStream); int64_t inputFramesRead = AAudioStream_getFramesRead(myData->inputStream); int64_t framesAvailable = inputFramesWritten - inputFramesRead; Loading @@ -155,6 +168,7 @@ static aaudio_data_callback_result_t MyDataCallbackProc( if (framesRead < 0) { result = AAUDIO_CALLBACK_RESULT_STOP; } else { if (framesRead < numFrames) { if(framesRead < (int32_t) framesAvailable) { printf("insufficient but numFrames = %d, framesRead = %d, available = %d\n", Loading @@ -172,13 +186,13 @@ static aaudio_data_callback_result_t MyDataCallbackProc( // Save for later. myData->audioRecording.write(myData->inputFloatData, myData->actualInputChannelCount, framesRead); numFrames); // Analyze the data. myData->loopbackProcessor->process(myData->inputFloatData, myData->actualInputChannelCount, outputData, myData->actualOutputChannelCount, framesRead); numFrames); myData->isDone = myData->loopbackProcessor->isDone(); if (myData->isDone) { result = AAUDIO_CALLBACK_RESULT_STOP; Loading Loading @@ -366,7 +380,9 @@ int main(int argc, const char **argv) } int32_t requestedDuration = argParser.getDurationSeconds(); int32_t recordingDuration = std::min(60, requestedDuration); int32_t requestedDurationMillis = requestedDuration * MILLIS_PER_SECOND; int32_t timeMillis = 0; int32_t recordingDuration = std::min(60 * 5, requestedDuration); switch(testMode) { case TEST_SINE_MAGNITUDE: Loading Loading @@ -449,7 +465,6 @@ int main(int argc, const char **argv) // Allocate a buffer for the audio data. loopbackData.inputFramesMaximum = 32 * AAudioStream_getFramesPerBurst(inputStream); loopbackData.inputBuffersToDiscard = 200; if (loopbackData.actualInputFormat == AAUDIO_FORMAT_PCM_I16) { loopbackData.inputShortData = new int16_t[loopbackData.inputFramesMaximum Loading @@ -460,23 +475,23 @@ int main(int argc, const char **argv) loopbackData.loopbackProcessor->reset(); result = recorder.start(); // Start OUTPUT first so INPUT does not overflow. result = player.start(); if (result != AAUDIO_OK) { printf("ERROR - AAudioStream_requestStart(input) returned %d = %s\n", printf("ERROR - AAudioStream_requestStart(output) returned %d = %s\n", result, AAudio_convertResultToText(result)); goto finish; } result = player.start(); result = recorder.start(); if (result != AAUDIO_OK) { printf("ERROR - AAudioStream_requestStart(output) returned %d = %s\n", printf("ERROR - AAudioStream_requestStart(input) returned %d = %s\n", result, AAudio_convertResultToText(result)); goto finish; } printf("------- sleep while the callback runs --------------\n"); fflush(stdout); for (int i = requestedDuration; i > 0 ; i--) { printf("------- sleep and log while the callback runs --------------\n"); while (timeMillis <= requestedDurationMillis) { if (loopbackData.inputError != AAUDIO_OK) { printf(" ERROR on input stream\n"); break; Loading @@ -487,10 +502,9 @@ int main(int argc, const char **argv) printf(" test says it is done!\n"); break; } else { sleep(1); printf("%4d: ", i); // Log a line of stream data. printf("%7.3f: ", 0.001 * timeMillis); // display in seconds loopbackData.loopbackProcessor->printStatus(); printf(" insf %3d,", (int) loopbackData.insufficientReadCount); int64_t inputFramesWritten = AAudioStream_getFramesWritten(inputStream); Loading @@ -498,7 +512,7 @@ int main(int argc, const char **argv) int64_t outputFramesWritten = AAudioStream_getFramesWritten(outputStream); int64_t outputFramesRead = AAudioStream_getFramesRead(outputStream); static const int textOffset = strlen("AAUDIO_STREAM_STATE_"); // strip this off printf(" INPUT: wr %7lld - rd %7lld = %5lld, state %s, oruns %3d | ", printf(" | INPUT: wr %7lld - rd %7lld = %5lld, st %8s, oruns %3d", (long long) inputFramesWritten, (long long) inputFramesRead, (long long) (inputFramesWritten - inputFramesRead), Loading @@ -506,7 +520,7 @@ int main(int argc, const char **argv) AAudioStream_getState(inputStream))[textOffset], AAudioStream_getXRunCount(inputStream)); printf(" OUTPUT: wr %7lld - rd %7lld = %5lld, state %s, uruns %3d\n", printf(" | OUTPUT: wr %7lld - rd %7lld = %5lld, st %8s, uruns %3d\n", (long long) outputFramesWritten, (long long) outputFramesRead, (long long) (outputFramesWritten - outputFramesRead), Loading @@ -515,6 +529,9 @@ int main(int argc, const char **argv) AAudioStream_getXRunCount(outputStream) ); } int32_t periodMillis = (timeMillis < 2000) ? PERIOD_MILLIS / 4 : PERIOD_MILLIS; usleep(periodMillis * 1000); timeMillis += periodMillis; } result = player.stop(); Loading Loading
media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h +40 −10 Original line number Diff line number Diff line Loading @@ -495,7 +495,7 @@ public: } void printStatus() override { printf("state = %d, echo gain = %f ", mState, mEchoGain); printf("st = %d, echo gain = %f ", mState, mEchoGain); } static void sendImpulse(float *outputData, int outputChannelCount) { Loading Loading @@ -670,7 +670,7 @@ public: printf(LOOPBACK_RESULT_TAG "phase.offset = %7.5f\n", mPhaseOffset); printf(LOOPBACK_RESULT_TAG "ref.phase = %7.5f\n", mPhase); printf(LOOPBACK_RESULT_TAG "frames.accumulated = %6d\n", mFramesAccumulated); printf(LOOPBACK_RESULT_TAG "sine.period = %6d\n", mPeriod); printf(LOOPBACK_RESULT_TAG "sine.period = %6d\n", mSinePeriod); printf(LOOPBACK_RESULT_TAG "test.state = %6d\n", mState); printf(LOOPBACK_RESULT_TAG "frame.count = %6d\n", mFrameCounter); // Did we ever get a lock? Loading @@ -684,7 +684,7 @@ public: } void printStatus() override { printf(" state = %d, glitches = %3d,", mState, mGlitchCount); printf("st = %d, #gl = %3d,", mState, mGlitchCount); } double calculateMagnitude(double *phasePtr = NULL) { Loading @@ -709,6 +709,8 @@ public: void process(float *inputData, int inputChannelCount, float *outputData, int outputChannelCount, int numFrames) override { mProcessCount++; float peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames); if (peak > mPeakAmplitude) { mPeakAmplitude = peak; Loading @@ -720,6 +722,7 @@ public: float sinOut = sinf(mPhase); switch (mState) { case STATE_IDLE: case STATE_IMMUNE: case STATE_WAITING_FOR_SIGNAL: break; Loading @@ -728,7 +731,7 @@ public: mCosAccumulator += sample * cosf(mPhase); mFramesAccumulated++; // Must be a multiple of the period or the calculation will not be accurate. if (mFramesAccumulated == mPeriod * 4) { if (mFramesAccumulated == mSinePeriod * PERIODS_NEEDED_FOR_LOCK) { mPhaseOffset = 0.0; mMagnitude = calculateMagnitude(&mPhaseOffset); if (mMagnitude > mThreshold) { Loading @@ -754,7 +757,22 @@ public: // mFrameCounter, mGlitchCount, predicted, sample); mState = STATE_IMMUNE; //printf("%5d: switch to STATE_IMMUNE\n", mFrameCounter); mDownCounter = mPeriod; // Set duration of IMMUNE state. mDownCounter = mSinePeriod; // Set duration of IMMUNE state. } // Track incoming signal and slowly adjust magnitude to account // for drift in the DRC or AGC. mSinAccumulator += sample * sinOut; mCosAccumulator += sample * cosf(mPhase); mFramesAccumulated++; // Must be a multiple of the period or the calculation will not be accurate. if (mFramesAccumulated == mSinePeriod) { const double coefficient = 0.1; double phaseOffset = 0.0; double magnitude = calculateMagnitude(&phaseOffset); // One pole averaging filter. mMagnitude = (mMagnitude * (1.0 - coefficient)) + (magnitude * coefficient); resetAccumulator(); } } break; } Loading @@ -775,6 +793,9 @@ public: // Do these once per buffer. switch (mState) { case STATE_IDLE: mState = STATE_IMMUNE; // so we can tell when break; case STATE_IMMUNE: mDownCounter -= numFrames; if (mDownCounter <= 0) { Loading Loading @@ -805,21 +826,29 @@ public: void reset() override { mGlitchCount = 0; mState = STATE_IMMUNE; mPhaseIncrement = 2.0 * M_PI / mPeriod; printf("phaseInc = %f for period %d\n", mPhaseIncrement, mPeriod); mDownCounter = IMMUNE_FRAME_COUNT; mPhaseIncrement = 2.0 * M_PI / mSinePeriod; printf("phaseInc = %f for period %d\n", mPhaseIncrement, mSinePeriod); resetAccumulator(); mProcessCount = 0; } private: enum sine_state_t { STATE_IDLE, STATE_IMMUNE, STATE_WAITING_FOR_SIGNAL, STATE_WAITING_FOR_LOCK, STATE_LOCKED }; int mPeriod = 79; enum constants { IMMUNE_FRAME_COUNT = 48 * 500, PERIODS_NEEDED_FOR_LOCK = 8 }; int mSinePeriod = 79; double mPhaseIncrement = 0.0; double mPhase = 0.0; double mPhaseOffset = 0.0; Loading @@ -828,18 +857,19 @@ private: double mThreshold = 0.005; double mTolerance = 0.01; int32_t mFramesAccumulated = 0; int32_t mProcessCount = 0; double mSinAccumulator = 0.0; double mCosAccumulator = 0.0; int32_t mGlitchCount = 0; double mPeakAmplitude = 0.0; int mDownCounter = 4000; int mDownCounter = IMMUNE_FRAME_COUNT; int32_t mFrameCounter = 0; float mOutputAmplitude = 0.75; PseudoRandom mWhiteNoise; float mNoiseAmplitude = 0.00; // Used to experiment with warbling caused by DRC. sine_state_t mState = STATE_IMMUNE; sine_state_t mState = STATE_IDLE; }; Loading
media/libaaudio/examples/loopback/src/loopback.cpp +45 −28 Original line number Diff line number Diff line Loading @@ -38,21 +38,25 @@ // Tag for machine readable results as property = value pairs #define RESULT_TAG "RESULT: " #define NUM_SECONDS 5 #define PERIOD_MILLIS 1000 #define NUM_INPUT_CHANNELS 1 #define FILENAME_ALL "/data/loopback_all.wav" #define FILENAME_ECHOS "/data/loopback_echos.wav" #define APP_VERSION "0.2.01" #define APP_VERSION "0.2.03" constexpr int kNumCallbacksToDrain = 20; constexpr int kNumCallbacksToDiscard = 20; struct LoopbackData { AAudioStream *inputStream = nullptr; int32_t inputFramesMaximum = 0; int16_t *inputShortData = nullptr; float *inputFloatData = nullptr; int16_t peakShort = 0; aaudio_format_t actualInputFormat = AAUDIO_FORMAT_INVALID; int32_t actualInputChannelCount = 0; int32_t actualOutputChannelCount = 0; int32_t inputBuffersToDiscard = 10; int32_t numCallbacksToDrain = kNumCallbacksToDrain; int32_t numCallbacksToDiscard = kNumCallbacksToDiscard; int32_t minNumFrames = INT32_MAX; int32_t maxNumFrames = 0; int32_t insufficientReadCount = 0; Loading Loading @@ -131,23 +135,32 @@ static aaudio_data_callback_result_t MyDataCallbackProc( myData->minNumFrames = numFrames; } if (myData->inputBuffersToDiscard > 0) { // Silence the output. int32_t numBytes = numFrames * myData->actualOutputChannelCount * sizeof(float); memset(audioData, 0 /* value */, numBytes); if (myData->numCallbacksToDrain > 0) { // Drain the input. do { framesRead = readFormattedData(myData, numFrames); // Ignore errors because input stream may not be started yet. } while (framesRead > 0); myData->numCallbacksToDrain--; } else if (myData->numCallbacksToDiscard > 0) { // Ignore. Allow the input to fill back up to equilibrium with the output. framesRead = readFormattedData(myData, numFrames); if (framesRead < 0) { result = AAUDIO_CALLBACK_RESULT_STOP; } else if (framesRead > 0) { myData->inputBuffersToDiscard--; } } while (framesRead > 0); // Silence the output. int32_t numBytes = numFrames * myData->actualOutputChannelCount * sizeof(float); memset(audioData, 0 /* value */, numBytes); myData->numCallbacksToDiscard--; } else { int32_t numInputBytes = numFrames * myData->actualInputChannelCount * sizeof(float); memset(myData->inputFloatData, 0 /* value */, numInputBytes); // Process data after equilibrium. int64_t inputFramesWritten = AAudioStream_getFramesWritten(myData->inputStream); int64_t inputFramesRead = AAudioStream_getFramesRead(myData->inputStream); int64_t framesAvailable = inputFramesWritten - inputFramesRead; Loading @@ -155,6 +168,7 @@ static aaudio_data_callback_result_t MyDataCallbackProc( if (framesRead < 0) { result = AAUDIO_CALLBACK_RESULT_STOP; } else { if (framesRead < numFrames) { if(framesRead < (int32_t) framesAvailable) { printf("insufficient but numFrames = %d, framesRead = %d, available = %d\n", Loading @@ -172,13 +186,13 @@ static aaudio_data_callback_result_t MyDataCallbackProc( // Save for later. myData->audioRecording.write(myData->inputFloatData, myData->actualInputChannelCount, framesRead); numFrames); // Analyze the data. myData->loopbackProcessor->process(myData->inputFloatData, myData->actualInputChannelCount, outputData, myData->actualOutputChannelCount, framesRead); numFrames); myData->isDone = myData->loopbackProcessor->isDone(); if (myData->isDone) { result = AAUDIO_CALLBACK_RESULT_STOP; Loading Loading @@ -366,7 +380,9 @@ int main(int argc, const char **argv) } int32_t requestedDuration = argParser.getDurationSeconds(); int32_t recordingDuration = std::min(60, requestedDuration); int32_t requestedDurationMillis = requestedDuration * MILLIS_PER_SECOND; int32_t timeMillis = 0; int32_t recordingDuration = std::min(60 * 5, requestedDuration); switch(testMode) { case TEST_SINE_MAGNITUDE: Loading Loading @@ -449,7 +465,6 @@ int main(int argc, const char **argv) // Allocate a buffer for the audio data. loopbackData.inputFramesMaximum = 32 * AAudioStream_getFramesPerBurst(inputStream); loopbackData.inputBuffersToDiscard = 200; if (loopbackData.actualInputFormat == AAUDIO_FORMAT_PCM_I16) { loopbackData.inputShortData = new int16_t[loopbackData.inputFramesMaximum Loading @@ -460,23 +475,23 @@ int main(int argc, const char **argv) loopbackData.loopbackProcessor->reset(); result = recorder.start(); // Start OUTPUT first so INPUT does not overflow. result = player.start(); if (result != AAUDIO_OK) { printf("ERROR - AAudioStream_requestStart(input) returned %d = %s\n", printf("ERROR - AAudioStream_requestStart(output) returned %d = %s\n", result, AAudio_convertResultToText(result)); goto finish; } result = player.start(); result = recorder.start(); if (result != AAUDIO_OK) { printf("ERROR - AAudioStream_requestStart(output) returned %d = %s\n", printf("ERROR - AAudioStream_requestStart(input) returned %d = %s\n", result, AAudio_convertResultToText(result)); goto finish; } printf("------- sleep while the callback runs --------------\n"); fflush(stdout); for (int i = requestedDuration; i > 0 ; i--) { printf("------- sleep and log while the callback runs --------------\n"); while (timeMillis <= requestedDurationMillis) { if (loopbackData.inputError != AAUDIO_OK) { printf(" ERROR on input stream\n"); break; Loading @@ -487,10 +502,9 @@ int main(int argc, const char **argv) printf(" test says it is done!\n"); break; } else { sleep(1); printf("%4d: ", i); // Log a line of stream data. printf("%7.3f: ", 0.001 * timeMillis); // display in seconds loopbackData.loopbackProcessor->printStatus(); printf(" insf %3d,", (int) loopbackData.insufficientReadCount); int64_t inputFramesWritten = AAudioStream_getFramesWritten(inputStream); Loading @@ -498,7 +512,7 @@ int main(int argc, const char **argv) int64_t outputFramesWritten = AAudioStream_getFramesWritten(outputStream); int64_t outputFramesRead = AAudioStream_getFramesRead(outputStream); static const int textOffset = strlen("AAUDIO_STREAM_STATE_"); // strip this off printf(" INPUT: wr %7lld - rd %7lld = %5lld, state %s, oruns %3d | ", printf(" | INPUT: wr %7lld - rd %7lld = %5lld, st %8s, oruns %3d", (long long) inputFramesWritten, (long long) inputFramesRead, (long long) (inputFramesWritten - inputFramesRead), Loading @@ -506,7 +520,7 @@ int main(int argc, const char **argv) AAudioStream_getState(inputStream))[textOffset], AAudioStream_getXRunCount(inputStream)); printf(" OUTPUT: wr %7lld - rd %7lld = %5lld, state %s, uruns %3d\n", printf(" | OUTPUT: wr %7lld - rd %7lld = %5lld, st %8s, uruns %3d\n", (long long) outputFramesWritten, (long long) outputFramesRead, (long long) (outputFramesWritten - outputFramesRead), Loading @@ -515,6 +529,9 @@ int main(int argc, const char **argv) AAudioStream_getXRunCount(outputStream) ); } int32_t periodMillis = (timeMillis < 2000) ? PERIOD_MILLIS / 4 : PERIOD_MILLIS; usleep(periodMillis * 1000); timeMillis += periodMillis; } result = player.stop(); Loading