1 /*
2  * Copyright (C) 2018 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 // Test AAudio SessionId, which is used to associate Effects with a stream
18 
19 #include <stdio.h>
20 #include <unistd.h>
21 
22 #include <aaudio/AAudio.h>
23 #include <gtest/gtest.h>
24 
25 constexpr int64_t kNanosPerSecond = 1000000000;
26 constexpr int kNumFrames = 256;
27 constexpr int kChannelCount = 2;
28 
29 // Test AAUDIO_SESSION_ID_NONE default
checkSessionIdNone(aaudio_performance_mode_t perfMode)30 static void checkSessionIdNone(aaudio_performance_mode_t perfMode) {
31 
32     float *buffer = new float[kNumFrames * kChannelCount];
33 
34     AAudioStreamBuilder *aaudioBuilder = nullptr;
35 
36     AAudioStream *aaudioStream1 = nullptr;
37     int32_t       sessionId1 = 0;
38 
39     // Use an AAudioStreamBuilder to contain requested parameters.
40     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
41 
42     // Request stream properties.
43     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
44 
45     // Create an AAudioStream using the Builder.
46     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream1));
47 
48     // Since we did not request or specify a SessionID, we should get NONE
49     sessionId1 = AAudioStream_getSessionId(aaudioStream1);
50     ASSERT_EQ(AAUDIO_SESSION_ID_NONE, sessionId1);
51 
52     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
53 
54     ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1, buffer, kNumFrames, kNanosPerSecond));
55 
56     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
57 
58     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
59     delete[] buffer;
60     AAudioStreamBuilder_delete(aaudioBuilder);
61 }
62 
TEST(test_session_id,aaudio_session_id_none_perfnone)63 TEST(test_session_id, aaudio_session_id_none_perfnone) {
64     checkSessionIdNone(AAUDIO_PERFORMANCE_MODE_NONE);
65 }
66 
TEST(test_session_id,aaudio_session_id_none_lowlat)67 TEST(test_session_id, aaudio_session_id_none_lowlat) {
68     checkSessionIdNone(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
69 }
70 
71 // Test AAUDIO_SESSION_ID_ALLOCATE
checkSessionIdAllocate(aaudio_performance_mode_t perfMode,aaudio_direction_t direction)72 static void checkSessionIdAllocate(aaudio_performance_mode_t perfMode,
73                                    aaudio_direction_t direction) {
74 
75     float *buffer = new float[kNumFrames * kChannelCount];
76 
77     AAudioStreamBuilder *aaudioBuilder = nullptr;
78 
79     AAudioStream *aaudioStream1 = nullptr;
80     int32_t       sessionId1 = 0;
81     AAudioStream *aaudioStream2 = nullptr;
82     int32_t       sessionId2 = 0;
83 
84     // Use an AAudioStreamBuilder to contain requested parameters.
85     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
86 
87     // Request stream properties.
88     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
89     // This stream could be input or output.
90     AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
91 
92     // Ask AAudio to allocate a Session ID.
93     AAudioStreamBuilder_setSessionId(aaudioBuilder, AAUDIO_SESSION_ID_ALLOCATE);
94 
95     // Create an AAudioStream using the Builder.
96     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream1));
97 
98     // Get the allocated ID from the stream.
99     sessionId1 = AAudioStream_getSessionId(aaudioStream1);
100 
101     // Check for invalid session IDs.
102     ASSERT_NE(AAUDIO_SESSION_ID_NONE, sessionId1);
103     ASSERT_NE(AAUDIO_SESSION_ID_ALLOCATE, sessionId1);
104 
105     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
106 
107     if (direction == AAUDIO_DIRECTION_INPUT) {
108         ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream1,
109                                                 buffer, kNumFrames, kNanosPerSecond));
110     } else {
111         ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1,
112                                          buffer, kNumFrames, kNanosPerSecond));
113     }
114 
115     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
116 
117     // Now open a second stream using the same session ID. ==================
118     AAudioStreamBuilder_setSessionId(aaudioBuilder, sessionId1);
119 
120     // Reverse direction for second stream.
121     aaudio_direction_t otherDirection = (direction == AAUDIO_DIRECTION_OUTPUT)
122                                         ? AAUDIO_DIRECTION_INPUT
123                                         : AAUDIO_DIRECTION_OUTPUT;
124     AAudioStreamBuilder_setDirection(aaudioBuilder, otherDirection);
125 
126     // Create an AAudioStream using the Builder.
127     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream2));
128 
129     // Get the allocated ID from the stream.
130     // It should match the ID that we set it to in the builder.
131     sessionId2 = AAudioStream_getSessionId(aaudioStream2);
132     ASSERT_EQ(sessionId1, sessionId2);
133 
134     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream2));
135 
136     if (otherDirection == AAUDIO_DIRECTION_INPUT) {
137         ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream2,
138                                                  buffer, kNumFrames, kNanosPerSecond));
139     } else {
140         ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream2,
141                                                  buffer, kNumFrames, kNanosPerSecond));
142     }
143 
144     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream2));
145 
146     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream2));
147 
148 
149     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
150     delete[] buffer;
151     AAudioStreamBuilder_delete(aaudioBuilder);
152 }
153 
TEST(test_session_id,aaudio_session_id_alloc_perfnone_in)154 TEST(test_session_id, aaudio_session_id_alloc_perfnone_in) {
155     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_DIRECTION_INPUT);
156 }
TEST(test_session_id,aaudio_session_id_alloc_perfnone_out)157 TEST(test_session_id, aaudio_session_id_alloc_perfnone_out) {
158     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_DIRECTION_OUTPUT);
159 }
160 
TEST(test_session_id,aaudio_session_id_alloc_lowlat_in)161 TEST(test_session_id, aaudio_session_id_alloc_lowlat_in) {
162     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_DIRECTION_INPUT);
163 }
TEST(test_session_id,aaudio_session_id_alloc_lowlat_out)164 TEST(test_session_id, aaudio_session_id_alloc_lowlat_out) {
165     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_DIRECTION_OUTPUT);
166 }
167