1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #define LOG_NDEBUG 0
19 #define LOG_TAG "AAudioStreamAtom-JNI"
20
21 #include <jni.h>
22
23 #include <aaudio/AAudio.h>
24 #include <gtest/gtest.h>
25
26 constexpr int kNumFrames = 256;
27 constexpr int64_t kMillisPerNanos = 1000000;
28 constexpr int64_t kMillisPerMicros = 1000;
29
tryOpeningStream(aaudio_direction_t direction,aaudio_performance_mode_t performanceMode)30 void tryOpeningStream(aaudio_direction_t direction, aaudio_performance_mode_t performanceMode) {
31 AAudioStreamBuilder *builder = nullptr;
32 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&builder));
33 ASSERT_NE(nullptr, builder);
34 AAudioStreamBuilder_setDirection(builder, direction);
35 AAudioStreamBuilder_setPerformanceMode(builder, performanceMode);
36
37 AAudioStream *stream = nullptr;
38 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(builder, &stream));
39 ASSERT_NE(nullptr, stream);
40 ASSERT_EQ(direction, AAudioStream_getDirection(stream));
41
42 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(stream));
43
44 int channelCount = AAudioStream_getChannelCount(stream);
45 ASSERT_GT(channelCount, 0);
46
47 std::unique_ptr<float[]> buffer(new float[kNumFrames * channelCount]);
48
49 if (direction == AAUDIO_DIRECTION_INPUT) {
50 ASSERT_EQ(kNumFrames,
51 AAudioStream_read(stream, buffer.get(), kNumFrames, 500 * kMillisPerNanos));
52 } else {
53 ASSERT_EQ(kNumFrames,
54 AAudioStream_write(stream, buffer.get(), kNumFrames, 500 * kMillisPerNanos));
55 // Total_frames_transferred is the number of frames consumed by the audio endpoint.
56 // Wait until the data is consumed by the audio endpoint.
57 // Wait in 10ms increments up to 50 times.
58 constexpr int kMaxRetries = 50;
59 constexpr int kTimeBetweenRetriesMillis = 10;
60 int numRetries = 0;
61 int framesRead = AAudioStream_getFramesRead(stream);
62 while (numRetries < kMaxRetries && framesRead < kNumFrames) {
63 usleep(kTimeBetweenRetriesMillis * kMillisPerMicros);
64 framesRead = AAudioStream_getFramesRead(stream);
65 numRetries++;
66 }
67 }
68
69 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(stream));
70
71 // Cleanup
72 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(builder));
73 ASSERT_EQ(AAUDIO_OK, AAudioStream_close(stream));
74 }
75
76 extern "C" JNIEXPORT void JNICALL
Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLowLatencyOutputStream(JNIEnv *,jobject)77 Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLowLatencyOutputStream(
78 JNIEnv *, jobject /* this */) {
79 tryOpeningStream(AAUDIO_DIRECTION_OUTPUT, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
80 }
81
82 extern "C" JNIEXPORT void JNICALL
Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLowLatencyInputStream(JNIEnv *,jobject)83 Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLowLatencyInputStream(
84 JNIEnv *, jobject /* this */) {
85 tryOpeningStream(AAUDIO_DIRECTION_INPUT, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
86 }
87
88 extern "C" JNIEXPORT void JNICALL
Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLegacyOutputStream(JNIEnv *,jobject)89 Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLegacyOutputStream(
90 JNIEnv *, jobject /* this */) {
91 tryOpeningStream(AAUDIO_DIRECTION_OUTPUT, AAUDIO_PERFORMANCE_MODE_NONE);
92 }
93
94 extern "C" JNIEXPORT void JNICALL
Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLegacyInputStream(JNIEnv *,jobject)95 Java_android_media_metrics_cts_MediaMetricsAtomHostSideTests_testAAudioLegacyInputStream(
96 JNIEnv *, jobject /* this */) {
97 tryOpeningStream(AAUDIO_DIRECTION_INPUT, AAUDIO_PERFORMANCE_MODE_NONE);
98 }
99