• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "test_aaudio.h"
26 #include "utils.h"
27 
28 constexpr int kNumFrames = 256;
29 constexpr int kChannelCount = 2;
30 
31 // Test AAUDIO_SESSION_ID_NONE default
checkSessionIdNone(aaudio_performance_mode_t perfMode)32 static void checkSessionIdNone(aaudio_performance_mode_t perfMode) {
33     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
34 
35     std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
36 
37     AAudioStreamBuilder *aaudioBuilder = nullptr;
38 
39     AAudioStream *aaudioStream1 = nullptr;
40     int32_t       sessionId1 = 0;
41 
42     // Use an AAudioStreamBuilder to contain requested parameters.
43     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
44 
45     // Request stream properties.
46     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
47 
48     // Create an AAudioStream using the Builder.
49     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream1));
50 
51     // Since we did not request or specify a SessionID, we should get NONE
52     sessionId1 = AAudioStream_getSessionId(aaudioStream1);
53     ASSERT_EQ(AAUDIO_SESSION_ID_NONE, sessionId1);
54 
55     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
56 
57     ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1, buffer.get(), kNumFrames, NANOS_PER_SECOND));
58 
59     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
60 
61     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
62     AAudioStreamBuilder_delete(aaudioBuilder);
63 }
64 
65 class AAudioTestSessionId : public AAudioCtsBase {};
66 
TEST_F(AAudioTestSessionId,aaudio_session_id_none_perfnone)67 TEST_F(AAudioTestSessionId, aaudio_session_id_none_perfnone) {
68     checkSessionIdNone(AAUDIO_PERFORMANCE_MODE_NONE);
69 }
70 
TEST_F(AAudioTestSessionId,aaudio_session_id_none_lowlat)71 TEST_F(AAudioTestSessionId, aaudio_session_id_none_lowlat) {
72     checkSessionIdNone(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
73 }
74 
75 // Test AAUDIO_SESSION_ID_ALLOCATE
checkSessionIdAllocate(aaudio_performance_mode_t perfMode,aaudio_direction_t direction)76 static void checkSessionIdAllocate(aaudio_performance_mode_t perfMode,
77                                    aaudio_direction_t direction) {
78     // Since this test creates streams in both directions, it can't work
79     // if either of them is not supported by the device.
80     if (!deviceSupportsFeature(FEATURE_RECORDING)
81             || !deviceSupportsFeature(FEATURE_PLAYBACK)) return;
82 
83     std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
84 
85     AAudioStreamBuilder *aaudioBuilder = nullptr;
86 
87     AAudioStream *aaudioStream1 = nullptr;
88     int32_t       sessionId1 = 0;
89     AAudioStream *aaudioStream2 = nullptr;
90     int32_t       sessionId2 = 0;
91 
92     // Use an AAudioStreamBuilder to contain requested parameters.
93     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
94 
95     // Request stream properties.
96     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
97     // This stream could be input or output.
98     AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
99 
100     // Ask AAudio to allocate a Session ID.
101     AAudioStreamBuilder_setSessionId(aaudioBuilder, AAUDIO_SESSION_ID_ALLOCATE);
102 
103     // Create an AAudioStream using the Builder.
104     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream1));
105 
106     // Get the allocated ID from the stream.
107     sessionId1 = AAudioStream_getSessionId(aaudioStream1);
108 
109     // Check for invalid session IDs.
110     ASSERT_NE(AAUDIO_SESSION_ID_NONE, sessionId1);
111     ASSERT_NE(AAUDIO_SESSION_ID_ALLOCATE, sessionId1);
112 
113     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
114 
115     if (direction == AAUDIO_DIRECTION_INPUT) {
116         ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream1,
117                                                 buffer.get(), kNumFrames, NANOS_PER_SECOND));
118     } else {
119         ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1,
120                                          buffer.get(), kNumFrames, NANOS_PER_SECOND));
121     }
122 
123     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
124 
125     // Now open a second stream using the same session ID. ==================
126     AAudioStreamBuilder_setSessionId(aaudioBuilder, sessionId1);
127 
128     // Reverse direction for second stream.
129     aaudio_direction_t otherDirection = (direction == AAUDIO_DIRECTION_OUTPUT)
130                                         ? AAUDIO_DIRECTION_INPUT
131                                         : AAUDIO_DIRECTION_OUTPUT;
132     AAudioStreamBuilder_setDirection(aaudioBuilder, otherDirection);
133 
134     // Create an AAudioStream using the Builder.
135     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream2));
136 
137     // Get the allocated ID from the stream.
138     // It should match the ID that we set it to in the builder.
139     sessionId2 = AAudioStream_getSessionId(aaudioStream2);
140     ASSERT_EQ(sessionId1, sessionId2);
141 
142     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream2));
143 
144     if (otherDirection == AAUDIO_DIRECTION_INPUT) {
145         ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream2,
146                                                  buffer.get(), kNumFrames, NANOS_PER_SECOND));
147     } else {
148         ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream2,
149                                                  buffer.get(), kNumFrames, NANOS_PER_SECOND));
150     }
151 
152     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream2));
153 
154     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream2));
155 
156 
157     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
158     AAudioStreamBuilder_delete(aaudioBuilder);
159 }
160 
TEST_F(AAudioTestSessionId,aaudio_session_id_alloc_perfnone_in)161 TEST_F(AAudioTestSessionId, aaudio_session_id_alloc_perfnone_in) {
162     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_DIRECTION_INPUT);
163 }
TEST_F(AAudioTestSessionId,aaudio_session_id_alloc_perfnone_out)164 TEST_F(AAudioTestSessionId, aaudio_session_id_alloc_perfnone_out) {
165     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_DIRECTION_OUTPUT);
166 }
167 
TEST_F(AAudioTestSessionId,aaudio_session_id_alloc_lowlat_in)168 TEST_F(AAudioTestSessionId, aaudio_session_id_alloc_lowlat_in) {
169     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_DIRECTION_INPUT);
170 }
TEST_F(AAudioTestSessionId,aaudio_session_id_alloc_lowlat_out)171 TEST_F(AAudioTestSessionId, aaudio_session_id_alloc_lowlat_out) {
172     checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_DIRECTION_OUTPUT);
173 }
174