Loading drm/libmediadrm/CryptoHal.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -269,12 +269,16 @@ void CryptoHal::clearHeapBase(int32_t seqNum) { * TODO: Add a releaseSharedBuffer method in a future DRM HAL * API version to make this explicit. */ uint32_t bufferId = mHeapBases.valueFor(seqNum).getBufferId(); ssize_t index = mHeapBases.indexOfKey(seqNum); if (index >= 0) { if (mPlugin != NULL) { uint32_t bufferId = mHeapBases[index].getBufferId(); Return<void> hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId); ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); } mHeapBases.removeItem(seqNum); } } status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) { ssize_t offset; Loading media/extractors/mp4/MPEG4Extractor.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -1710,7 +1710,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { const char *mime; CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime)); if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) if (!strncmp(mime, "audio/", 6)) { // for audio, use 128KB max_size = 1024 * 128; } else if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { // AVC & HEVC requires compression ratio of at least 2, and uses // macroblocks Loading Loading @@ -3963,9 +3966,10 @@ status_t MPEG4Source::start(MetaDataBase *params) { } // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize. const size_t kInitialBuffers = 2; const size_t kMaxBuffers = 8; const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers); mGroup = new MediaBufferGroup(buffers, max_size); const size_t realMaxBuffers = min(kMaxBufferSize / max_size, kMaxBuffers); mGroup = new MediaBufferGroup(kInitialBuffers, max_size, realMaxBuffers); mSrcBuffer = new (std::nothrow) uint8_t[max_size]; if (mSrcBuffer == NULL) { // file probably specified a bad max size Loading media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h +25 −10 Original line number Diff line number Diff line Loading @@ -41,12 +41,16 @@ #define MAX_ZEROTH_PARTIAL_BINS 40 constexpr double MAX_ECHO_GAIN = 10.0; // based on experiments, otherwise autocorrelation too noisy // A narrow impulse seems to have better immunity against over estimating the // latency due to detecting subharmonics by the auto-correlator. static const float s_Impulse[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.2f, // silence on each side of the impulse 0.5f, 0.9999f, 0.0f, -0.9999, -0.5f, // bipolar -0.2f, 0.0f, 0.0f, 0.0f, 0.0f 0.0f, 0.0f, 0.0f, 0.0f, 0.3f, // silence on each side of the impulse 0.99f, 0.0f, -0.99f, // bipolar with one zero crossing in middle -0.3f, 0.0f, 0.0f, 0.0f, 0.0f }; constexpr int32_t kImpulseSizeInFrames = (int32_t)(sizeof(s_Impulse) / sizeof(s_Impulse[0])); class PseudoRandom { public: PseudoRandom() {} Loading Loading @@ -498,13 +502,23 @@ public: printf("st = %d, echo gain = %f ", mState, mEchoGain); } static void sendImpulse(float *outputData, int outputChannelCount) { for (float sample : s_Impulse) { void sendImpulses(float *outputData, int outputChannelCount, int numFrames) { while (numFrames-- > 0) { float sample = s_Impulse[mSampleIndex++]; if (mSampleIndex >= kImpulseSizeInFrames) { mSampleIndex = 0; } *outputData = sample; outputData += outputChannelCount; } } void sendOneImpulse(float *outputData, int outputChannelCount) { mSampleIndex = 0; sendImpulses(outputData, outputChannelCount, kImpulseSizeInFrames); } void process(float *inputData, int inputChannelCount, float *outputData, int outputChannelCount, int numFrames) override { Loading @@ -530,7 +544,7 @@ public: break; case STATE_MEASURING_GAIN: sendImpulse(outputData, outputChannelCount); sendImpulses(outputData, outputChannelCount, numFrames); peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames); // If we get several in a row then go to next state. if (peak > mPulseThreshold) { Loading @@ -548,7 +562,7 @@ public: nextState = STATE_WAITING_FOR_SILENCE; } } } else { } else if (numFrames > kImpulseSizeInFrames){ // ignore short callbacks mDownCounter = 8; } break; Loading @@ -574,7 +588,7 @@ public: case STATE_SENDING_PULSE: mAudioRecording.write(inputData, inputChannelCount, numFrames); sendImpulse(outputData, outputChannelCount); sendOneImpulse(outputData, outputChannelCount); nextState = STATE_GATHERING_ECHOS; //printf("%5d: switch to STATE_GATHERING_ECHOS\n", mLoopCounter); break; Loading Loading @@ -634,8 +648,9 @@ private: STATE_FAILED }; int mDownCounter = 500; int mLoopCounter = 0; int32_t mDownCounter = 500; int32_t mLoopCounter = 0; int32_t mSampleIndex = 0; float mPulseThreshold = 0.02f; float mSilenceThreshold = 0.002f; float mMeasuredLoopGain = 0.0f; Loading media/libaaudio/examples/loopback/src/loopback.cpp +61 −22 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ #define NUM_INPUT_CHANNELS 1 #define FILENAME_ALL "/data/loopback_all.wav" #define FILENAME_ECHOS "/data/loopback_echos.wav" #define APP_VERSION "0.2.03" #define APP_VERSION "0.2.04" constexpr int kNumCallbacksToDrain = 20; constexpr int kNumCallbacksToDiscard = 20; Loading Loading @@ -98,6 +98,9 @@ static int32_t readFormattedData(LoopbackData *myData, int32_t numFrames) { framesRead = AAudioStream_read(myData->inputStream, myData->inputFloatData, numFrames, 0 /* timeoutNanoseconds */); } else { printf("ERROR actualInputFormat = %d\n", myData->actualInputFormat); assert(false); } if (framesRead < 0) { myData->inputError = framesRead; Loading @@ -121,7 +124,7 @@ static aaudio_data_callback_result_t MyDataCallbackProc( float *outputData = (float *) audioData; // Read audio data from the input stream. int32_t framesRead; int32_t actualFramesRead; if (numFrames > myData->inputFramesMaximum) { myData->inputError = AAUDIO_ERROR_OUT_OF_RANGE; Loading @@ -141,16 +144,23 @@ static aaudio_data_callback_result_t MyDataCallbackProc( if (myData->numCallbacksToDrain > 0) { // Drain the input. int32_t totalFramesRead = 0; do { framesRead = readFormattedData(myData, numFrames); actualFramesRead = readFormattedData(myData, numFrames); if (actualFramesRead) { totalFramesRead += actualFramesRead; } // Ignore errors because input stream may not be started yet. } while (framesRead > 0); } while (actualFramesRead > 0); // Only counts if we actually got some data. if (totalFramesRead > 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) { actualFramesRead = readFormattedData(myData, numFrames); if (actualFramesRead < 0) { result = AAUDIO_CALLBACK_RESULT_STOP; } myData->numCallbacksToDiscard--; Loading @@ -164,21 +174,29 @@ static aaudio_data_callback_result_t MyDataCallbackProc( int64_t inputFramesWritten = AAudioStream_getFramesWritten(myData->inputStream); int64_t inputFramesRead = AAudioStream_getFramesRead(myData->inputStream); int64_t framesAvailable = inputFramesWritten - inputFramesRead; framesRead = readFormattedData(myData, numFrames); if (framesRead < 0) { actualFramesRead = readFormattedData(myData, numFrames); if (actualFramesRead < 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", numFrames, framesRead, (int) framesAvailable); if (actualFramesRead < numFrames) { if(actualFramesRead < (int32_t) framesAvailable) { printf("insufficient but numFrames = %d" ", actualFramesRead = %d" ", inputFramesWritten = %d" ", inputFramesRead = %d" ", available = %d\n", numFrames, actualFramesRead, (int) inputFramesWritten, (int) inputFramesRead, (int) framesAvailable); } myData->insufficientReadCount++; myData->insufficientReadFrames += numFrames - framesRead; // deficit myData->insufficientReadFrames += numFrames - actualFramesRead; // deficit } int32_t numSamples = framesRead * myData->actualInputChannelCount; int32_t numSamples = actualFramesRead * myData->actualInputChannelCount; if (myData->actualInputFormat == AAUDIO_FORMAT_PCM_I16) { convertPcm16ToFloat(myData->inputShortData, myData->inputFloatData, numSamples); Loading Loading @@ -216,6 +234,7 @@ static void MyErrorCallbackProc( static void usage() { printf("Usage: aaudio_loopback [OPTION]...\n\n"); AAudioArgsParser::usage(); printf(" -B{frames} input capacity in frames\n"); printf(" -C{channels} number of input channels\n"); printf(" -F{0,1,2} input format, 1=I16, 2=FLOAT\n"); printf(" -g{gain} recirculating loopback gain\n"); Loading Loading @@ -319,9 +338,11 @@ int main(int argc, const char **argv) aaudio_sharing_mode_t requestedInputSharingMode = AAUDIO_SHARING_MODE_SHARED; int requestedInputChannelCount = NUM_INPUT_CHANNELS; aaudio_format_t requestedInputFormat = AAUDIO_FORMAT_UNSPECIFIED; const aaudio_format_t requestedOutputFormat = AAUDIO_FORMAT_PCM_FLOAT; int32_t requestedInputCapacity = -1; aaudio_performance_mode_t inputPerformanceLevel = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY; int32_t outputFramesPerBurst = 0; aaudio_format_t actualOutputFormat = AAUDIO_FORMAT_INVALID; int32_t actualSampleRate = 0; int written = 0; Loading @@ -342,6 +363,9 @@ int main(int argc, const char **argv) if (arg[0] == '-') { char option = arg[1]; switch (option) { case 'B': requestedInputCapacity = atoi(&arg[2]); break; case 'C': requestedInputChannelCount = atoi(&arg[2]); break; Loading Loading @@ -408,7 +432,6 @@ int main(int argc, const char **argv) } printf("OUTPUT stream ----------------------------------------\n"); argParser.setFormat(requestedOutputFormat); result = player.open(argParser, MyDataCallbackProc, MyErrorCallbackProc, &loopbackData); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - player.open() returned %d\n", result); Loading @@ -417,11 +440,15 @@ int main(int argc, const char **argv) outputStream = player.getStream(); actualOutputFormat = AAudioStream_getFormat(outputStream); assert(actualOutputFormat == AAUDIO_FORMAT_PCM_FLOAT); if (actualOutputFormat != AAUDIO_FORMAT_PCM_FLOAT) { fprintf(stderr, "ERROR - only AAUDIO_FORMAT_PCM_FLOAT supported\n"); exit(1); } actualSampleRate = AAudioStream_getSampleRate(outputStream); loopbackData.audioRecording.allocate(recordingDuration * actualSampleRate); loopbackData.audioRecording.setSampleRate(actualSampleRate); outputFramesPerBurst = AAudioStream_getFramesPerBurst(outputStream); argParser.compareWithStream(outputStream); Loading @@ -435,8 +462,11 @@ int main(int argc, const char **argv) // Make sure the input buffer has plenty of capacity. // Extra capacity on input should not increase latency if we keep it drained. int32_t inputBufferCapacity = requestedInputCapacity; if (inputBufferCapacity < 0) { int32_t outputBufferCapacity = AAudioStream_getBufferCapacityInFrames(outputStream); int32_t inputBufferCapacity = 2 * outputBufferCapacity; inputBufferCapacity = 2 * outputBufferCapacity; } argParser.setBufferCapacity(inputBufferCapacity); result = recorder.open(argParser); Loading @@ -457,6 +487,15 @@ int main(int argc, const char **argv) argParser.compareWithStream(inputStream); // If the input stream is too small then we cannot satisfy the output callback. { int32_t actualCapacity = AAudioStream_getBufferCapacityInFrames(inputStream); if (actualCapacity < 2 * outputFramesPerBurst) { fprintf(stderr, "ERROR - input capacity < 2 * outputFramesPerBurst\n"); goto finish; } } // ------- Setup loopbackData ----------------------------- loopbackData.actualInputFormat = AAudioStream_getFormat(inputStream); Loading Loading @@ -499,7 +538,7 @@ int main(int argc, const char **argv) printf(" ERROR on output stream\n"); break; } else if (loopbackData.isDone) { printf(" test says it is done!\n"); printf(" Test says it is DONE!\n"); break; } else { // Log a line of stream data. Loading media/libaaudio/examples/loopback/src/loopback.sh +22 −2 Original line number Diff line number Diff line #!/system/bin/sh # Run a loopback test in the background after a delay. # To run the script enter: # To run the script, enter these commands once: # adb disable-verity # adb reboot # adb remount # adb sync # adb push loopback.sh /data/ # For each test run: # adb shell "nohup sh /data/loopback.sh &" # Quickly connect USB audio if needed, either manually or via Tigertail switch. # Wait until the test completes, restore USB to host if needed, and then: # adb pull /data/loopreport.txt # adb pull /data/loopback_all.wav # adb pull /data/loopback_echos.wav SLEEP_TIME=10 TEST_COMMAND="aaudio_loopback -pl -Pl -C1 -n2 -m2 -tm -d5" TEST_COMMAND="/data/nativetest/aaudio_loopback/aaudio_loopback -pl -Pl -C1 -n2 -m2 -te -d5" # Partial list of options: # -pl (output) performance mode: low latency # -Pl input performance mode: low latency # -C1 input channel count: 1 # -n2 number of bursts: 2 # -m2 mmap policy: 2 # -t? test mode: -tm for sine magnitude, -te for echo latency, -tf for file latency # -d5 device ID # For full list of available options, see AAudioArgsParser.h and loopback.cpp echo "Plug in USB Mir and Fun Plug." echo "Test will start in ${SLEEP_TIME} seconds: ${TEST_COMMAND}" Loading Loading
drm/libmediadrm/CryptoHal.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -269,12 +269,16 @@ void CryptoHal::clearHeapBase(int32_t seqNum) { * TODO: Add a releaseSharedBuffer method in a future DRM HAL * API version to make this explicit. */ uint32_t bufferId = mHeapBases.valueFor(seqNum).getBufferId(); ssize_t index = mHeapBases.indexOfKey(seqNum); if (index >= 0) { if (mPlugin != NULL) { uint32_t bufferId = mHeapBases[index].getBufferId(); Return<void> hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId); ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); } mHeapBases.removeItem(seqNum); } } status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) { ssize_t offset; Loading
media/extractors/mp4/MPEG4Extractor.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -1710,7 +1710,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { const char *mime; CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime)); if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) if (!strncmp(mime, "audio/", 6)) { // for audio, use 128KB max_size = 1024 * 128; } else if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { // AVC & HEVC requires compression ratio of at least 2, and uses // macroblocks Loading Loading @@ -3963,9 +3966,10 @@ status_t MPEG4Source::start(MetaDataBase *params) { } // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize. const size_t kInitialBuffers = 2; const size_t kMaxBuffers = 8; const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers); mGroup = new MediaBufferGroup(buffers, max_size); const size_t realMaxBuffers = min(kMaxBufferSize / max_size, kMaxBuffers); mGroup = new MediaBufferGroup(kInitialBuffers, max_size, realMaxBuffers); mSrcBuffer = new (std::nothrow) uint8_t[max_size]; if (mSrcBuffer == NULL) { // file probably specified a bad max size Loading
media/libaaudio/examples/loopback/src/LoopbackAnalyzer.h +25 −10 Original line number Diff line number Diff line Loading @@ -41,12 +41,16 @@ #define MAX_ZEROTH_PARTIAL_BINS 40 constexpr double MAX_ECHO_GAIN = 10.0; // based on experiments, otherwise autocorrelation too noisy // A narrow impulse seems to have better immunity against over estimating the // latency due to detecting subharmonics by the auto-correlator. static const float s_Impulse[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.2f, // silence on each side of the impulse 0.5f, 0.9999f, 0.0f, -0.9999, -0.5f, // bipolar -0.2f, 0.0f, 0.0f, 0.0f, 0.0f 0.0f, 0.0f, 0.0f, 0.0f, 0.3f, // silence on each side of the impulse 0.99f, 0.0f, -0.99f, // bipolar with one zero crossing in middle -0.3f, 0.0f, 0.0f, 0.0f, 0.0f }; constexpr int32_t kImpulseSizeInFrames = (int32_t)(sizeof(s_Impulse) / sizeof(s_Impulse[0])); class PseudoRandom { public: PseudoRandom() {} Loading Loading @@ -498,13 +502,23 @@ public: printf("st = %d, echo gain = %f ", mState, mEchoGain); } static void sendImpulse(float *outputData, int outputChannelCount) { for (float sample : s_Impulse) { void sendImpulses(float *outputData, int outputChannelCount, int numFrames) { while (numFrames-- > 0) { float sample = s_Impulse[mSampleIndex++]; if (mSampleIndex >= kImpulseSizeInFrames) { mSampleIndex = 0; } *outputData = sample; outputData += outputChannelCount; } } void sendOneImpulse(float *outputData, int outputChannelCount) { mSampleIndex = 0; sendImpulses(outputData, outputChannelCount, kImpulseSizeInFrames); } void process(float *inputData, int inputChannelCount, float *outputData, int outputChannelCount, int numFrames) override { Loading @@ -530,7 +544,7 @@ public: break; case STATE_MEASURING_GAIN: sendImpulse(outputData, outputChannelCount); sendImpulses(outputData, outputChannelCount, numFrames); peak = measurePeakAmplitude(inputData, inputChannelCount, numFrames); // If we get several in a row then go to next state. if (peak > mPulseThreshold) { Loading @@ -548,7 +562,7 @@ public: nextState = STATE_WAITING_FOR_SILENCE; } } } else { } else if (numFrames > kImpulseSizeInFrames){ // ignore short callbacks mDownCounter = 8; } break; Loading @@ -574,7 +588,7 @@ public: case STATE_SENDING_PULSE: mAudioRecording.write(inputData, inputChannelCount, numFrames); sendImpulse(outputData, outputChannelCount); sendOneImpulse(outputData, outputChannelCount); nextState = STATE_GATHERING_ECHOS; //printf("%5d: switch to STATE_GATHERING_ECHOS\n", mLoopCounter); break; Loading Loading @@ -634,8 +648,9 @@ private: STATE_FAILED }; int mDownCounter = 500; int mLoopCounter = 0; int32_t mDownCounter = 500; int32_t mLoopCounter = 0; int32_t mSampleIndex = 0; float mPulseThreshold = 0.02f; float mSilenceThreshold = 0.002f; float mMeasuredLoopGain = 0.0f; Loading
media/libaaudio/examples/loopback/src/loopback.cpp +61 −22 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ #define NUM_INPUT_CHANNELS 1 #define FILENAME_ALL "/data/loopback_all.wav" #define FILENAME_ECHOS "/data/loopback_echos.wav" #define APP_VERSION "0.2.03" #define APP_VERSION "0.2.04" constexpr int kNumCallbacksToDrain = 20; constexpr int kNumCallbacksToDiscard = 20; Loading Loading @@ -98,6 +98,9 @@ static int32_t readFormattedData(LoopbackData *myData, int32_t numFrames) { framesRead = AAudioStream_read(myData->inputStream, myData->inputFloatData, numFrames, 0 /* timeoutNanoseconds */); } else { printf("ERROR actualInputFormat = %d\n", myData->actualInputFormat); assert(false); } if (framesRead < 0) { myData->inputError = framesRead; Loading @@ -121,7 +124,7 @@ static aaudio_data_callback_result_t MyDataCallbackProc( float *outputData = (float *) audioData; // Read audio data from the input stream. int32_t framesRead; int32_t actualFramesRead; if (numFrames > myData->inputFramesMaximum) { myData->inputError = AAUDIO_ERROR_OUT_OF_RANGE; Loading @@ -141,16 +144,23 @@ static aaudio_data_callback_result_t MyDataCallbackProc( if (myData->numCallbacksToDrain > 0) { // Drain the input. int32_t totalFramesRead = 0; do { framesRead = readFormattedData(myData, numFrames); actualFramesRead = readFormattedData(myData, numFrames); if (actualFramesRead) { totalFramesRead += actualFramesRead; } // Ignore errors because input stream may not be started yet. } while (framesRead > 0); } while (actualFramesRead > 0); // Only counts if we actually got some data. if (totalFramesRead > 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) { actualFramesRead = readFormattedData(myData, numFrames); if (actualFramesRead < 0) { result = AAUDIO_CALLBACK_RESULT_STOP; } myData->numCallbacksToDiscard--; Loading @@ -164,21 +174,29 @@ static aaudio_data_callback_result_t MyDataCallbackProc( int64_t inputFramesWritten = AAudioStream_getFramesWritten(myData->inputStream); int64_t inputFramesRead = AAudioStream_getFramesRead(myData->inputStream); int64_t framesAvailable = inputFramesWritten - inputFramesRead; framesRead = readFormattedData(myData, numFrames); if (framesRead < 0) { actualFramesRead = readFormattedData(myData, numFrames); if (actualFramesRead < 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", numFrames, framesRead, (int) framesAvailable); if (actualFramesRead < numFrames) { if(actualFramesRead < (int32_t) framesAvailable) { printf("insufficient but numFrames = %d" ", actualFramesRead = %d" ", inputFramesWritten = %d" ", inputFramesRead = %d" ", available = %d\n", numFrames, actualFramesRead, (int) inputFramesWritten, (int) inputFramesRead, (int) framesAvailable); } myData->insufficientReadCount++; myData->insufficientReadFrames += numFrames - framesRead; // deficit myData->insufficientReadFrames += numFrames - actualFramesRead; // deficit } int32_t numSamples = framesRead * myData->actualInputChannelCount; int32_t numSamples = actualFramesRead * myData->actualInputChannelCount; if (myData->actualInputFormat == AAUDIO_FORMAT_PCM_I16) { convertPcm16ToFloat(myData->inputShortData, myData->inputFloatData, numSamples); Loading Loading @@ -216,6 +234,7 @@ static void MyErrorCallbackProc( static void usage() { printf("Usage: aaudio_loopback [OPTION]...\n\n"); AAudioArgsParser::usage(); printf(" -B{frames} input capacity in frames\n"); printf(" -C{channels} number of input channels\n"); printf(" -F{0,1,2} input format, 1=I16, 2=FLOAT\n"); printf(" -g{gain} recirculating loopback gain\n"); Loading Loading @@ -319,9 +338,11 @@ int main(int argc, const char **argv) aaudio_sharing_mode_t requestedInputSharingMode = AAUDIO_SHARING_MODE_SHARED; int requestedInputChannelCount = NUM_INPUT_CHANNELS; aaudio_format_t requestedInputFormat = AAUDIO_FORMAT_UNSPECIFIED; const aaudio_format_t requestedOutputFormat = AAUDIO_FORMAT_PCM_FLOAT; int32_t requestedInputCapacity = -1; aaudio_performance_mode_t inputPerformanceLevel = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY; int32_t outputFramesPerBurst = 0; aaudio_format_t actualOutputFormat = AAUDIO_FORMAT_INVALID; int32_t actualSampleRate = 0; int written = 0; Loading @@ -342,6 +363,9 @@ int main(int argc, const char **argv) if (arg[0] == '-') { char option = arg[1]; switch (option) { case 'B': requestedInputCapacity = atoi(&arg[2]); break; case 'C': requestedInputChannelCount = atoi(&arg[2]); break; Loading Loading @@ -408,7 +432,6 @@ int main(int argc, const char **argv) } printf("OUTPUT stream ----------------------------------------\n"); argParser.setFormat(requestedOutputFormat); result = player.open(argParser, MyDataCallbackProc, MyErrorCallbackProc, &loopbackData); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - player.open() returned %d\n", result); Loading @@ -417,11 +440,15 @@ int main(int argc, const char **argv) outputStream = player.getStream(); actualOutputFormat = AAudioStream_getFormat(outputStream); assert(actualOutputFormat == AAUDIO_FORMAT_PCM_FLOAT); if (actualOutputFormat != AAUDIO_FORMAT_PCM_FLOAT) { fprintf(stderr, "ERROR - only AAUDIO_FORMAT_PCM_FLOAT supported\n"); exit(1); } actualSampleRate = AAudioStream_getSampleRate(outputStream); loopbackData.audioRecording.allocate(recordingDuration * actualSampleRate); loopbackData.audioRecording.setSampleRate(actualSampleRate); outputFramesPerBurst = AAudioStream_getFramesPerBurst(outputStream); argParser.compareWithStream(outputStream); Loading @@ -435,8 +462,11 @@ int main(int argc, const char **argv) // Make sure the input buffer has plenty of capacity. // Extra capacity on input should not increase latency if we keep it drained. int32_t inputBufferCapacity = requestedInputCapacity; if (inputBufferCapacity < 0) { int32_t outputBufferCapacity = AAudioStream_getBufferCapacityInFrames(outputStream); int32_t inputBufferCapacity = 2 * outputBufferCapacity; inputBufferCapacity = 2 * outputBufferCapacity; } argParser.setBufferCapacity(inputBufferCapacity); result = recorder.open(argParser); Loading @@ -457,6 +487,15 @@ int main(int argc, const char **argv) argParser.compareWithStream(inputStream); // If the input stream is too small then we cannot satisfy the output callback. { int32_t actualCapacity = AAudioStream_getBufferCapacityInFrames(inputStream); if (actualCapacity < 2 * outputFramesPerBurst) { fprintf(stderr, "ERROR - input capacity < 2 * outputFramesPerBurst\n"); goto finish; } } // ------- Setup loopbackData ----------------------------- loopbackData.actualInputFormat = AAudioStream_getFormat(inputStream); Loading Loading @@ -499,7 +538,7 @@ int main(int argc, const char **argv) printf(" ERROR on output stream\n"); break; } else if (loopbackData.isDone) { printf(" test says it is done!\n"); printf(" Test says it is DONE!\n"); break; } else { // Log a line of stream data. Loading
media/libaaudio/examples/loopback/src/loopback.sh +22 −2 Original line number Diff line number Diff line #!/system/bin/sh # Run a loopback test in the background after a delay. # To run the script enter: # To run the script, enter these commands once: # adb disable-verity # adb reboot # adb remount # adb sync # adb push loopback.sh /data/ # For each test run: # adb shell "nohup sh /data/loopback.sh &" # Quickly connect USB audio if needed, either manually or via Tigertail switch. # Wait until the test completes, restore USB to host if needed, and then: # adb pull /data/loopreport.txt # adb pull /data/loopback_all.wav # adb pull /data/loopback_echos.wav SLEEP_TIME=10 TEST_COMMAND="aaudio_loopback -pl -Pl -C1 -n2 -m2 -tm -d5" TEST_COMMAND="/data/nativetest/aaudio_loopback/aaudio_loopback -pl -Pl -C1 -n2 -m2 -te -d5" # Partial list of options: # -pl (output) performance mode: low latency # -Pl input performance mode: low latency # -C1 input channel count: 1 # -n2 number of bursts: 2 # -m2 mmap policy: 2 # -t? test mode: -tm for sine magnitude, -te for echo latency, -tf for file latency # -d5 device ID # For full list of available options, see AAudioArgsParser.h and loopback.cpp echo "Plug in USB Mir and Fun Plug." echo "Test will start in ${SLEEP_TIME} seconds: ${TEST_COMMAND}" Loading