Loading media/libaaudio/tests/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -182,7 +182,10 @@ cc_test { name: "test_full_queue", defaults: ["libaaudio_tests_defaults"], srcs: ["test_full_queue.cpp"], shared_libs: ["libaaudio"], shared_libs: [ "libaaudio", "liblog" ], } cc_test { Loading media/libaaudio/tests/test_full_queue.cpp +115 −21 Original line number Diff line number Diff line Loading @@ -17,31 +17,43 @@ // Test whether a stream dies if it is written to after a delay. // Maybe because the message queue from the AAudio service fills up. #define LOG_TAG "test_full_queue" //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <stdio.h> #include <unistd.h> #include <aaudio/AAudio.h> #include <gtest/gtest.h> #include <cstdlib> #include <algorithm> constexpr int64_t kNanosPerSecond = 1000000000; constexpr int64_t kTimeoutNanos = kNanosPerSecond / 2; constexpr int64_t kNanosPerMillisecond = 1e6; constexpr int64_t kMicrosPerMillisecond = 1000; constexpr int64_t kTimeoutNanos = 50 * kNanosPerMillisecond; constexpr int kNumFrames = 256; constexpr int kChannelCount = 2; constexpr int kNumSamples = kChannelCount * kNumFrames; static void checkFullQueue(aaudio_performance_mode_t perfMode, aaudio_sharing_mode_t sharingMode, int32_t sleepMillis) { std::unique_ptr<float[]> buffer = std::make_unique<float[]>( kNumFrames * kChannelCount); aaudio_result_t result; std::unique_ptr<float[]> buffer = std::make_unique<float[]>(kNumSamples); for (int i = 0; i < kNumSamples; i++) { buffer[i] = (drand48() - 0.5) * 0.05; // random buzzy waveform } AAudioStreamBuilder *aaudioBuilder = nullptr; // Use an AAudioStreamBuilder to contain requested parameters. ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder)); AAudioStreamBuilder_setChannelCount(aaudioBuilder, kChannelCount); // Request stream properties. AAudioStreamBuilder_setChannelCount(aaudioBuilder, kChannelCount); AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode); AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode); // Create an AAudioStream using the Builder. AAudioStream *aaudioStream = nullptr; Loading @@ -49,16 +61,74 @@ static void checkFullQueue(aaudio_performance_mode_t perfMode, &aaudioStream)); AAudioStreamBuilder_delete(aaudioBuilder); int bufferSize = std::max( 2 * AAudioStream_getFramesPerBurst(aaudioStream), 2 * kNumFrames ); AAudioStream_setBufferSizeInFrames(aaudioStream, bufferSize); EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream)); #if 0 int32_t capacity = AAudioStream_getBufferCapacityInFrames(aaudioStream); ASSERT_LT(20, capacity); int numWrites = 30 * capacity / kNumFrames; #else int32_t sampleRate = AAudioStream_getSampleRate(aaudioStream); EXPECT_LT(7000, sampleRate); int numWrites = 1 * sampleRate / kNumFrames; #endif for (int i = 0; i < numWrites/2; i++) { result = AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kTimeoutNanos); EXPECT_EQ(kNumFrames, result); if (kNumFrames != result) break; } // Sleep for awhile. This might kill the stream. usleep(sleepMillis * 1000); // 1000 millis in a microsecond ALOGD("%s() start sleeping %d millis", __func__, sleepMillis); usleep(sleepMillis * kMicrosPerMillisecond); ALOGD("%s() start writing", __func__); // Let CPU catch up with the hardware. int64_t framesRead = AAudioStream_getFramesRead(aaudioStream); int64_t framesWritten = AAudioStream_getFramesWritten(aaudioStream); ALOGD("%s() after hang, read = %jd, written = %jd, w-r = %jd", __func__, (intmax_t) framesRead, (intmax_t) framesWritten, (intmax_t)(framesWritten - framesRead)); int countDown = 2 * sleepMillis * sampleRate / (kNumFrames * 1000); do { result = AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kTimeoutNanos); for (int i = 0; i < 10; i++) { const aaudio_result_t result = AAudioStream_write(aaudioStream, ALOGD("%s() catching up, wrote %d frames", __func__, result); framesRead = AAudioStream_getFramesRead(aaudioStream); framesWritten = AAudioStream_getFramesWritten(aaudioStream); countDown--; } while ((framesRead > framesWritten) && (countDown > 0) && (kNumFrames == result)); EXPECT_LE(framesRead, framesWritten); EXPECT_GT(countDown, 0); EXPECT_EQ(kNumFrames, result); ALOGD("%s() after catch up, read = %jd, written = %jd, w-r = %jd", __func__, (intmax_t) framesRead, (intmax_t) framesWritten, (intmax_t)(framesWritten - framesRead)); // Try to keep the stream full. for (int i = 0; i < numWrites; i++) { ALOGD("%s() try to write", __func__); result = AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kTimeoutNanos); ALOGD("%s() wrote %d frames", __func__, result); EXPECT_EQ(kNumFrames, result); if (kNumFrames != result) break; } Loading @@ -68,26 +138,50 @@ static void checkFullQueue(aaudio_performance_mode_t perfMode, EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream)); } TEST(test_full_queue, aaudio_full_queue_perf_none_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 50 /* sleepMillis */); // ==== Default Latency, SHARED =========== TEST(test_full_queue, aaudio_full_queue_perf_none_sh_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_SHARING_MODE_SHARED, 50 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_sh_400) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_SHARING_MODE_SHARED, 400 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_sh_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_SHARING_MODE_SHARED, 1000 /* sleepMillis */); } // ==== Low Latency, SHARED =========== TEST(test_full_queue, aaudio_full_queue_low_latency_sh_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_SHARED, 50 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_200) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 200 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_sh_400) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_SHARED, 400 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 1000 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_sh_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_SHARED, 1000 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_low_latency_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 50 /* sleepMillis */); // ==== Low Latency, EXCLUSIVE =========== TEST(test_full_queue, aaudio_full_queue_low_latency_excl_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_EXCLUSIVE, 50 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_low_latency_200) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 200 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_excl_400) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_EXCLUSIVE, 400 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_low_latency_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 1000 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_excl_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_EXCLUSIVE, 1000 /* sleepMillis */); } Loading
media/libaaudio/tests/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -182,7 +182,10 @@ cc_test { name: "test_full_queue", defaults: ["libaaudio_tests_defaults"], srcs: ["test_full_queue.cpp"], shared_libs: ["libaaudio"], shared_libs: [ "libaaudio", "liblog" ], } cc_test { Loading
media/libaaudio/tests/test_full_queue.cpp +115 −21 Original line number Diff line number Diff line Loading @@ -17,31 +17,43 @@ // Test whether a stream dies if it is written to after a delay. // Maybe because the message queue from the AAudio service fills up. #define LOG_TAG "test_full_queue" //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <stdio.h> #include <unistd.h> #include <aaudio/AAudio.h> #include <gtest/gtest.h> #include <cstdlib> #include <algorithm> constexpr int64_t kNanosPerSecond = 1000000000; constexpr int64_t kTimeoutNanos = kNanosPerSecond / 2; constexpr int64_t kNanosPerMillisecond = 1e6; constexpr int64_t kMicrosPerMillisecond = 1000; constexpr int64_t kTimeoutNanos = 50 * kNanosPerMillisecond; constexpr int kNumFrames = 256; constexpr int kChannelCount = 2; constexpr int kNumSamples = kChannelCount * kNumFrames; static void checkFullQueue(aaudio_performance_mode_t perfMode, aaudio_sharing_mode_t sharingMode, int32_t sleepMillis) { std::unique_ptr<float[]> buffer = std::make_unique<float[]>( kNumFrames * kChannelCount); aaudio_result_t result; std::unique_ptr<float[]> buffer = std::make_unique<float[]>(kNumSamples); for (int i = 0; i < kNumSamples; i++) { buffer[i] = (drand48() - 0.5) * 0.05; // random buzzy waveform } AAudioStreamBuilder *aaudioBuilder = nullptr; // Use an AAudioStreamBuilder to contain requested parameters. ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder)); AAudioStreamBuilder_setChannelCount(aaudioBuilder, kChannelCount); // Request stream properties. AAudioStreamBuilder_setChannelCount(aaudioBuilder, kChannelCount); AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode); AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode); // Create an AAudioStream using the Builder. AAudioStream *aaudioStream = nullptr; Loading @@ -49,16 +61,74 @@ static void checkFullQueue(aaudio_performance_mode_t perfMode, &aaudioStream)); AAudioStreamBuilder_delete(aaudioBuilder); int bufferSize = std::max( 2 * AAudioStream_getFramesPerBurst(aaudioStream), 2 * kNumFrames ); AAudioStream_setBufferSizeInFrames(aaudioStream, bufferSize); EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream)); #if 0 int32_t capacity = AAudioStream_getBufferCapacityInFrames(aaudioStream); ASSERT_LT(20, capacity); int numWrites = 30 * capacity / kNumFrames; #else int32_t sampleRate = AAudioStream_getSampleRate(aaudioStream); EXPECT_LT(7000, sampleRate); int numWrites = 1 * sampleRate / kNumFrames; #endif for (int i = 0; i < numWrites/2; i++) { result = AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kTimeoutNanos); EXPECT_EQ(kNumFrames, result); if (kNumFrames != result) break; } // Sleep for awhile. This might kill the stream. usleep(sleepMillis * 1000); // 1000 millis in a microsecond ALOGD("%s() start sleeping %d millis", __func__, sleepMillis); usleep(sleepMillis * kMicrosPerMillisecond); ALOGD("%s() start writing", __func__); // Let CPU catch up with the hardware. int64_t framesRead = AAudioStream_getFramesRead(aaudioStream); int64_t framesWritten = AAudioStream_getFramesWritten(aaudioStream); ALOGD("%s() after hang, read = %jd, written = %jd, w-r = %jd", __func__, (intmax_t) framesRead, (intmax_t) framesWritten, (intmax_t)(framesWritten - framesRead)); int countDown = 2 * sleepMillis * sampleRate / (kNumFrames * 1000); do { result = AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kTimeoutNanos); for (int i = 0; i < 10; i++) { const aaudio_result_t result = AAudioStream_write(aaudioStream, ALOGD("%s() catching up, wrote %d frames", __func__, result); framesRead = AAudioStream_getFramesRead(aaudioStream); framesWritten = AAudioStream_getFramesWritten(aaudioStream); countDown--; } while ((framesRead > framesWritten) && (countDown > 0) && (kNumFrames == result)); EXPECT_LE(framesRead, framesWritten); EXPECT_GT(countDown, 0); EXPECT_EQ(kNumFrames, result); ALOGD("%s() after catch up, read = %jd, written = %jd, w-r = %jd", __func__, (intmax_t) framesRead, (intmax_t) framesWritten, (intmax_t)(framesWritten - framesRead)); // Try to keep the stream full. for (int i = 0; i < numWrites; i++) { ALOGD("%s() try to write", __func__); result = AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kTimeoutNanos); ALOGD("%s() wrote %d frames", __func__, result); EXPECT_EQ(kNumFrames, result); if (kNumFrames != result) break; } Loading @@ -68,26 +138,50 @@ static void checkFullQueue(aaudio_performance_mode_t perfMode, EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream)); } TEST(test_full_queue, aaudio_full_queue_perf_none_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 50 /* sleepMillis */); // ==== Default Latency, SHARED =========== TEST(test_full_queue, aaudio_full_queue_perf_none_sh_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_SHARING_MODE_SHARED, 50 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_sh_400) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_SHARING_MODE_SHARED, 400 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_sh_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_SHARING_MODE_SHARED, 1000 /* sleepMillis */); } // ==== Low Latency, SHARED =========== TEST(test_full_queue, aaudio_full_queue_low_latency_sh_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_SHARED, 50 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_200) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 200 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_sh_400) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_SHARED, 400 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_perf_none_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 1000 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_sh_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_SHARED, 1000 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_low_latency_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 50 /* sleepMillis */); // ==== Low Latency, EXCLUSIVE =========== TEST(test_full_queue, aaudio_full_queue_low_latency_excl_50) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_EXCLUSIVE, 50 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_low_latency_200) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 200 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_excl_400) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_EXCLUSIVE, 400 /* sleepMillis */); } TEST(test_full_queue, aaudio_full_queue_low_latency_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 1000 /* sleepMillis */); TEST(test_full_queue, aaudio_full_queue_low_latency_excl_1000) { checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_SHARING_MODE_EXCLUSIVE, 1000 /* sleepMillis */); }