1a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk/*
2a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * Copyright (C) 2018 The Android Open Source Project
3a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk *
4a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * you may not use this file except in compliance with the License.
6a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * You may obtain a copy of the License at
7a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk *
8a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk *
10a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * Unless required by applicable law or agreed to in writing, software
11a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * See the License for the specific language governing permissions and
14a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk * limitations under the License.
15a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk */
16a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
17a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk// Test AAudio SessionId, which is used to associate Effects with a stream
18a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
19a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk#include <stdio.h>
20a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk#include <unistd.h>
21a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
22a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk#include <aaudio/AAudio.h>
23a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk#include <gtest/gtest.h>
24a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
25a11f9357196db29e6f8f05b91334524de4f3207ePhil Burkconstexpr int64_t kNanosPerSecond = 1000000000;
26a11f9357196db29e6f8f05b91334524de4f3207ePhil Burkconstexpr int kNumFrames = 256;
27a11f9357196db29e6f8f05b91334524de4f3207ePhil Burkconstexpr int kChannelCount = 2;
28a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
29a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk// Test AAUDIO_SESSION_ID_NONE default
30a11f9357196db29e6f8f05b91334524de4f3207ePhil Burkstatic void checkSessionIdNone(aaudio_performance_mode_t perfMode) {
31a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
32a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    float *buffer = new float[kNumFrames * kChannelCount];
33a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
34a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder *aaudioBuilder = nullptr;
35a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
36a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStream *aaudioStream1 = nullptr;
37a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    int32_t       sessionId1 = 0;
38a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
39a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Use an AAudioStreamBuilder to contain requested parameters.
40a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
41a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
42a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Request stream properties.
43a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
44a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
45a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Create an AAudioStream using the Builder.
46a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream1));
47a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
48a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Since we did not request or specify a SessionID, we should get NONE
49a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    sessionId1 = AAudioStream_getSessionId(aaudioStream1);
50a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_SESSION_ID_NONE, sessionId1);
51a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
52a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
53a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
54a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1, buffer, kNumFrames, kNanosPerSecond));
55a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
56a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
57a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
58a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
59a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    delete[] buffer;
60a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_delete(aaudioBuilder);
61a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
62a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
63a11f9357196db29e6f8f05b91334524de4f3207ePhil BurkTEST(test_session_id, aaudio_session_id_none_perfnone) {
64a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    checkSessionIdNone(AAUDIO_PERFORMANCE_MODE_NONE);
65a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
66a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
67a11f9357196db29e6f8f05b91334524de4f3207ePhil BurkTEST(test_session_id, aaudio_session_id_none_lowlat) {
68a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    checkSessionIdNone(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
69a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
70a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
71a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk// Test AAUDIO_SESSION_ID_ALLOCATE
72a11f9357196db29e6f8f05b91334524de4f3207ePhil Burkstatic void checkSessionIdAllocate(aaudio_performance_mode_t perfMode,
73a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                   aaudio_direction_t direction) {
74a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
75a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    float *buffer = new float[kNumFrames * kChannelCount];
76a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
77a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder *aaudioBuilder = nullptr;
78a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
79a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStream *aaudioStream1 = nullptr;
80a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    int32_t       sessionId1 = 0;
81a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStream *aaudioStream2 = nullptr;
82a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    int32_t       sessionId2 = 0;
83a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
84a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Use an AAudioStreamBuilder to contain requested parameters.
85a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
86a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
87a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Request stream properties.
88a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
89a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // This stream could be input or output.
90a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
91a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
92a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Ask AAudio to allocate a Session ID.
93a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_setSessionId(aaudioBuilder, AAUDIO_SESSION_ID_ALLOCATE);
94a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
95a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Create an AAudioStream using the Builder.
96a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream1));
97a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
98a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Get the allocated ID from the stream.
99a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    sessionId1 = AAudioStream_getSessionId(aaudioStream1);
10067fdd894bf7e09a544348a9f8298427bc9b3fe85Phil Burk
10167fdd894bf7e09a544348a9f8298427bc9b3fe85Phil Burk    // Check for invalid session IDs.
10267fdd894bf7e09a544348a9f8298427bc9b3fe85Phil Burk    ASSERT_NE(AAUDIO_SESSION_ID_NONE, sessionId1);
10367fdd894bf7e09a544348a9f8298427bc9b3fe85Phil Burk    ASSERT_NE(AAUDIO_SESSION_ID_ALLOCATE, sessionId1);
104a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
105a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
106a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
107a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    if (direction == AAUDIO_DIRECTION_INPUT) {
108a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk        ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream1,
109a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                                buffer, kNumFrames, kNanosPerSecond));
110a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    } else {
111a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk        ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1,
112a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                         buffer, kNumFrames, kNanosPerSecond));
113a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    }
114a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
115a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
116a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
117a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Now open a second stream using the same session ID. ==================
118a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_setSessionId(aaudioBuilder, sessionId1);
119a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
120a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Reverse direction for second stream.
121a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    aaudio_direction_t otherDirection = (direction == AAUDIO_DIRECTION_OUTPUT)
122a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                        ? AAUDIO_DIRECTION_INPUT
123a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                        : AAUDIO_DIRECTION_OUTPUT;
124a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_setDirection(aaudioBuilder, otherDirection);
125a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
126a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Create an AAudioStream using the Builder.
127a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream2));
128a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
129a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // Get the allocated ID from the stream.
130a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    // It should match the ID that we set it to in the builder.
131a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    sessionId2 = AAudioStream_getSessionId(aaudioStream2);
132a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(sessionId1, sessionId2);
133a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
134a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream2));
135a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
136a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    if (otherDirection == AAUDIO_DIRECTION_INPUT) {
137a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk        ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream2,
138a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                                 buffer, kNumFrames, kNanosPerSecond));
139a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    } else {
140a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk        ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream2,
141a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk                                                 buffer, kNumFrames, kNanosPerSecond));
142a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    }
143a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
144a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream2));
145a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
146a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream2));
147a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
148a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
149a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
150a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    delete[] buffer;
151a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    AAudioStreamBuilder_delete(aaudioBuilder);
152a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
153a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
154a11f9357196db29e6f8f05b91334524de4f3207ePhil BurkTEST(test_session_id, aaudio_session_id_alloc_perfnone_in) {
155a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_DIRECTION_INPUT);
156a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
157a11f9357196db29e6f8f05b91334524de4f3207ePhil BurkTEST(test_session_id, aaudio_session_id_alloc_perfnone_out) {
158a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_DIRECTION_OUTPUT);
159a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
160a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk
161a11f9357196db29e6f8f05b91334524de4f3207ePhil BurkTEST(test_session_id, aaudio_session_id_alloc_lowlat_in) {
162a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_DIRECTION_INPUT);
163a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
164a11f9357196db29e6f8f05b91334524de4f3207ePhil BurkTEST(test_session_id, aaudio_session_id_alloc_lowlat_out) {
165a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk    checkSessionIdAllocate(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_DIRECTION_OUTPUT);
166a11f9357196db29e6f8f05b91334524de4f3207ePhil Burk}
167