blob: cbf863fec7c1dfc6bc3dbb0ad5725eb396cd7faf [file] [log] [blame]
Phil Burk9a9e6002017-11-17 12:17:37 -08001/*
2 * Copyright (C) 2017 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 various AAudio features including AAudioStream_setBufferSizeInFrames().
18
Phil Burk2581ae22017-11-21 15:47:29 -080019#include <condition_variable>
20#include <mutex>
Phil Burk9a9e6002017-11-17 12:17:37 -080021#include <stdio.h>
Phil Burk9a9e6002017-11-17 12:17:37 -080022
23#include <android-base/macros.h>
24#include <aaudio/AAudio.h>
25
26#include <gtest/gtest.h>
Phil Burk2581ae22017-11-21 15:47:29 -080027#include <unistd.h>
28
Phil Burk9a9e6002017-11-17 12:17:37 -080029// Callback function that does nothing.
Phil Burk2581ae22017-11-21 15:47:29 -080030aaudio_data_callback_result_t NoopDataCallbackProc(
Phil Burk9cf23822020-04-17 11:53:35 -070031 AAudioStream * stream,
32 void * /* userData */,
Phil Burk9a9e6002017-11-17 12:17:37 -080033 void *audioData,
34 int32_t numFrames
35) {
Phil Burk33f03f62020-08-07 18:50:04 +000036 aaudio_direction_t direction = AAudioStream_getDirection(stream);
37 if (direction == AAUDIO_DIRECTION_INPUT) {
38 return AAUDIO_CALLBACK_RESULT_CONTINUE;
39 }
40 // Check to make sure the buffer is initialized to all zeros.
Phil Burk9cf23822020-04-17 11:53:35 -070041 int channels = AAudioStream_getChannelCount(stream);
42 int numSamples = channels * numFrames;
43 bool allZeros = true;
44 float * const floatData = reinterpret_cast<float *>(audioData);
45 for (int i = 0; i < numSamples; i++) {
46 allZeros &= (floatData[i] == 0.0f);
47 floatData[i] = 0.0f;
48 }
49 EXPECT_TRUE(allZeros);
Phil Burk9a9e6002017-11-17 12:17:37 -080050 return AAUDIO_CALLBACK_RESULT_CONTINUE;
51}
52
Phil Burk0c15f4f2017-11-28 15:46:15 -080053constexpr int64_t NANOS_PER_MILLISECOND = 1000 * 1000;
54
Phil Burk8b4e05e2019-12-17 12:12:09 -080055void checkReleaseThenClose(aaudio_performance_mode_t perfMode,
Phil Burk33f03f62020-08-07 18:50:04 +000056 aaudio_sharing_mode_t sharingMode,
57 aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT) {
Phil Burk8b4e05e2019-12-17 12:12:09 -080058 AAudioStreamBuilder* aaudioBuilder = nullptr;
59 AAudioStream* aaudioStream = nullptr;
60
61 // Use an AAudioStreamBuilder to contain requested parameters.
62 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
63
64 // Request stream properties.
65 AAudioStreamBuilder_setDataCallback(aaudioBuilder,
66 NoopDataCallbackProc,
67 nullptr);
68 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
69 AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode);
Phil Burk33f03f62020-08-07 18:50:04 +000070 AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
Phil Burk9cf23822020-04-17 11:53:35 -070071 AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
Phil Burk8b4e05e2019-12-17 12:12:09 -080072
73 // Create an AAudioStream using the Builder.
74 ASSERT_EQ(AAUDIO_OK,
75 AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
76 AAudioStreamBuilder_delete(aaudioBuilder);
77
78 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
79
80 sleep(1);
81
82 EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
83
84 EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
Phil Burkcc131ba2020-04-17 08:25:30 -070085 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
Phil Burk8b4e05e2019-12-17 12:12:09 -080086
87 // We should be able to call this again without crashing.
88 EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
Phil Burkcc131ba2020-04-17 08:25:30 -070089 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
90
91 // We expect these not to crash.
92 AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
93 AAudioStream_setBufferSizeInFrames(aaudioStream, 99999999);
94
95 // We should NOT be able to start or change a stream after it has been released.
96 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestStart(aaudioStream));
97 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
Phil Burk33f03f62020-08-07 18:50:04 +000098 // Pause is only implemented for OUTPUT.
99 if (direction == AAUDIO_DIRECTION_OUTPUT) {
100 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE,
101 AAudioStream_requestPause(aaudioStream));
102 }
Phil Burkcc131ba2020-04-17 08:25:30 -0700103 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
104 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestStop(aaudioStream));
105 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
106
107 // Does this crash?
Phil Burk33f03f62020-08-07 18:50:04 +0000108 EXPECT_GT(AAudioStream_getFramesRead(aaudioStream), 0);
109 EXPECT_GT(AAudioStream_getFramesWritten(aaudioStream), 0);
110 EXPECT_GT(AAudioStream_getFramesPerBurst(aaudioStream), 0);
111 EXPECT_GE(AAudioStream_getXRunCount(aaudioStream), 0);
112 EXPECT_GT(AAudioStream_getBufferCapacityInFrames(aaudioStream), 0);
113 EXPECT_GT(AAudioStream_getBufferSizeInFrames(aaudioStream), 0);
114
115 int64_t timestampFrames = 0;
116 int64_t timestampNanos = 0;
117 aaudio_result_t result = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
118 &timestampFrames, &timestampNanos);
119 EXPECT_TRUE(result == AAUDIO_ERROR_INVALID_STATE || result == AAUDIO_ERROR_UNIMPLEMENTED);
Phil Burkcc131ba2020-04-17 08:25:30 -0700120
121 // Verify Closing State. Does this crash?
122 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
123 EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
124 AAUDIO_STREAM_STATE_UNKNOWN, &state,
125 500 * NANOS_PER_MILLISECOND));
Phil Burk8b4e05e2019-12-17 12:12:09 -0800126 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
127
128 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
129}
130
Phil Burk33f03f62020-08-07 18:50:04 +0000131TEST(test_various, aaudio_release_close_none_output) {
Phil Burk8b4e05e2019-12-17 12:12:09 -0800132 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_NONE,
Phil Burk33f03f62020-08-07 18:50:04 +0000133 AAUDIO_SHARING_MODE_SHARED,
134 AAUDIO_DIRECTION_OUTPUT);
Phil Burk8b4e05e2019-12-17 12:12:09 -0800135 // No EXCLUSIVE streams with MODE_NONE.
136}
137
Phil Burk33f03f62020-08-07 18:50:04 +0000138TEST(test_various, aaudio_release_close_none_input) {
139 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_NONE,
140 AAUDIO_SHARING_MODE_SHARED,
141 AAUDIO_DIRECTION_INPUT);
142 // No EXCLUSIVE streams with MODE_NONE.
Phil Burk8b4e05e2019-12-17 12:12:09 -0800143}
144
Phil Burk33f03f62020-08-07 18:50:04 +0000145TEST(test_various, aaudio_release_close_low_shared_output) {
Phil Burk8b4e05e2019-12-17 12:12:09 -0800146 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
Phil Burk33f03f62020-08-07 18:50:04 +0000147 AAUDIO_SHARING_MODE_SHARED,
148 AAUDIO_DIRECTION_OUTPUT);
149}
150
151TEST(test_various, aaudio_release_close_low_shared_input) {
152 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
153 AAUDIO_SHARING_MODE_SHARED,
154 AAUDIO_DIRECTION_INPUT);
155}
156
157TEST(test_various, aaudio_release_close_low_exclusive_output) {
158 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
159 AAUDIO_SHARING_MODE_EXCLUSIVE,
160 AAUDIO_DIRECTION_OUTPUT);
161}
162
163TEST(test_various, aaudio_release_close_low_exclusive_input) {
164 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
165 AAUDIO_SHARING_MODE_EXCLUSIVE,
166 AAUDIO_DIRECTION_INPUT);
Phil Burk8b4e05e2019-12-17 12:12:09 -0800167}
168
Phil Burk4fa3b942017-12-13 17:25:24 -0800169enum FunctionToCall {
Phil Burk29112a12020-06-25 07:52:45 -0700170 CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH, CALL_RELEASE
Phil Burk4fa3b942017-12-13 17:25:24 -0800171};
172
173void checkStateTransition(aaudio_performance_mode_t perfMode,
174 aaudio_stream_state_t originalState,
175 FunctionToCall functionToCall,
176 aaudio_result_t expectedResult,
177 aaudio_stream_state_t expectedState) {
Phil Burk0c15f4f2017-11-28 15:46:15 -0800178 AAudioStreamBuilder *aaudioBuilder = nullptr;
179 AAudioStream *aaudioStream = nullptr;
180
Phil Burk4fa3b942017-12-13 17:25:24 -0800181 // Use an AAudioStreamBuilder to contain requested parameters.
Phil Burk0c15f4f2017-11-28 15:46:15 -0800182 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
183
Phil Burk4fa3b942017-12-13 17:25:24 -0800184 // Request stream properties.
Phil Burk2581ae22017-11-21 15:47:29 -0800185 AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
Phil Burk4fa3b942017-12-13 17:25:24 -0800186 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
Phil Burk9cf23822020-04-17 11:53:35 -0700187 AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
Phil Burk0c15f4f2017-11-28 15:46:15 -0800188
Phil Burk4fa3b942017-12-13 17:25:24 -0800189 // Create an AAudioStream using the Builder.
190 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
Phil Burk0c15f4f2017-11-28 15:46:15 -0800191
Phil Burk4fa3b942017-12-13 17:25:24 -0800192 // Verify Open State
Phil Burk0c15f4f2017-11-28 15:46:15 -0800193 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
194 EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
195 AAUDIO_STREAM_STATE_UNKNOWN, &state,
196 1000 * NANOS_PER_MILLISECOND));
197 EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
198
Phil Burk4fa3b942017-12-13 17:25:24 -0800199 // Put stream into desired state.
200 aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_UNINITIALIZED;
201 if (originalState != AAUDIO_STREAM_STATE_OPEN) {
Phil Burk0c15f4f2017-11-28 15:46:15 -0800202
Phil Burk4fa3b942017-12-13 17:25:24 -0800203 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
204
205 if (originalState != AAUDIO_STREAM_STATE_STARTING) {
206
207 ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
208 AAUDIO_STREAM_STATE_STARTING,
209 &state,
210 1000 * NANOS_PER_MILLISECOND));
211 ASSERT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
212
213 if (originalState == AAUDIO_STREAM_STATE_STOPPING) {
214 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
215 } else if (originalState == AAUDIO_STREAM_STATE_STOPPED) {
216 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
217 inputState = AAUDIO_STREAM_STATE_STOPPING;
218 } else if (originalState == AAUDIO_STREAM_STATE_PAUSING) {
219 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
220 } else if (originalState == AAUDIO_STREAM_STATE_PAUSED) {
221 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
222 inputState = AAUDIO_STREAM_STATE_PAUSING;
Phil Burk29112a12020-06-25 07:52:45 -0700223 } else if (originalState == AAUDIO_STREAM_STATE_FLUSHING) {
224 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
225 // We can only flush() after pause is complete.
226 ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
227 AAUDIO_STREAM_STATE_PAUSING,
228 &state,
229 1000 * NANOS_PER_MILLISECOND));
230 ASSERT_EQ(AAUDIO_STREAM_STATE_PAUSED, state);
231 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestFlush(aaudioStream));
232 // That will put the stream into the FLUSHING state.
233 // The FLUSHING state will persist until we process functionToCall.
234 // That is because the transition to FLUSHED is caused by the callback,
235 // or by calling write() or waitForStateChange(). But those will not
236 // occur.
237 } else if (originalState == AAUDIO_STREAM_STATE_CLOSING) {
238 ASSERT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
Phil Burk4fa3b942017-12-13 17:25:24 -0800239 }
240 }
241 }
242
Phil Burk29112a12020-06-25 07:52:45 -0700243 // Wait until we get past the transitional state if requested.
Phil Burk4fa3b942017-12-13 17:25:24 -0800244 if (inputState != AAUDIO_STREAM_STATE_UNINITIALIZED) {
245 ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
246 inputState,
247 &state,
248 1000 * NANOS_PER_MILLISECOND));
249 ASSERT_EQ(originalState, state);
250 }
251
252 aaudio_stream_state_t transitionalState = originalState;
253 switch(functionToCall) {
254 case FunctionToCall::CALL_START:
255 EXPECT_EQ(expectedResult, AAudioStream_requestStart(aaudioStream));
256 transitionalState = AAUDIO_STREAM_STATE_STARTING;
257 break;
258 case FunctionToCall::CALL_STOP:
259 EXPECT_EQ(expectedResult, AAudioStream_requestStop(aaudioStream));
260 transitionalState = AAUDIO_STREAM_STATE_STOPPING;
261 break;
262 case FunctionToCall::CALL_PAUSE:
263 EXPECT_EQ(expectedResult, AAudioStream_requestPause(aaudioStream));
264 transitionalState = AAUDIO_STREAM_STATE_PAUSING;
265 break;
266 case FunctionToCall::CALL_FLUSH:
267 EXPECT_EQ(expectedResult, AAudioStream_requestFlush(aaudioStream));
268 transitionalState = AAUDIO_STREAM_STATE_FLUSHING;
269 break;
Phil Burk29112a12020-06-25 07:52:45 -0700270 case FunctionToCall::CALL_RELEASE:
271 EXPECT_EQ(expectedResult, AAudioStream_release(aaudioStream));
272 // Set to UNINITIALIZED so the waitForStateChange() below will
273 // will return immediately with the current state.
274 transitionalState = AAUDIO_STREAM_STATE_UNINITIALIZED;
275 break;
Phil Burk4fa3b942017-12-13 17:25:24 -0800276 }
277
Phil Burk29112a12020-06-25 07:52:45 -0700278 EXPECT_EQ(AAUDIO_OK,
279 AAudioStream_waitForStateChange(aaudioStream,
280 transitionalState,
281 &state,
282 1000 * NANOS_PER_MILLISECOND));
283
Phil Burk4fa3b942017-12-13 17:25:24 -0800284 // We should not change state when a function fails.
285 if (expectedResult != AAUDIO_OK) {
286 ASSERT_EQ(originalState, expectedState);
287 }
288 EXPECT_EQ(expectedState, state);
289 if (state != expectedState) {
290 printf("ERROR - expected %s, actual = %s\n",
291 AAudio_convertStreamStateToText(expectedState),
292 AAudio_convertStreamStateToText(state));
293 fflush(stdout);
294 }
Phil Burk0c15f4f2017-11-28 15:46:15 -0800295
296 AAudioStream_close(aaudioStream);
297 AAudioStreamBuilder_delete(aaudioBuilder);
298}
299
Phil Burk4fa3b942017-12-13 17:25:24 -0800300// TODO Use parameterized tests instead of these individual specific tests.
301
302// OPEN =================================================================
303TEST(test_various, aaudio_state_lowlat_open_start) {
304 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
305 AAUDIO_STREAM_STATE_OPEN,
306 FunctionToCall::CALL_START,
307 AAUDIO_OK,
308 AAUDIO_STREAM_STATE_STARTED);
309}
310
311TEST(test_various, aaudio_state_none_open_start) {
312 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
313 AAUDIO_STREAM_STATE_OPEN,
314 FunctionToCall::CALL_START,
315 AAUDIO_OK,
316 AAUDIO_STREAM_STATE_STARTED);
317}
318
319TEST(test_various, aaudio_state_lowlat_open_stop) {
320 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
321 AAUDIO_STREAM_STATE_OPEN,
322 FunctionToCall::CALL_STOP,
323 AAUDIO_OK,
324 AAUDIO_STREAM_STATE_STOPPED);
325}
326
327TEST(test_various, aaudio_state_none_open_stop) {
328 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
329 AAUDIO_STREAM_STATE_OPEN,
330 FunctionToCall::CALL_STOP,
331 AAUDIO_OK,
332 AAUDIO_STREAM_STATE_STOPPED);
333}
334
335TEST(test_various, aaudio_state_lowlat_open_pause) {
336 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
337 AAUDIO_STREAM_STATE_OPEN,
338 FunctionToCall::CALL_PAUSE,
339 AAUDIO_OK,
340 AAUDIO_STREAM_STATE_PAUSED);
341}
342
343TEST(test_various, aaudio_state_none_open_pause) {
344 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
345 AAUDIO_STREAM_STATE_OPEN,
346 FunctionToCall::CALL_PAUSE,
347 AAUDIO_OK,
348 AAUDIO_STREAM_STATE_PAUSED);
349}
350
351TEST(test_various, aaudio_state_lowlat_open_flush) {
352 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
353 AAUDIO_STREAM_STATE_OPEN,
354 FunctionToCall::CALL_FLUSH,
355 AAUDIO_OK,
356 AAUDIO_STREAM_STATE_FLUSHED);
357}
358
359TEST(test_various, aaudio_state_none_open_flush) {
360 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
361 AAUDIO_STREAM_STATE_OPEN,
362 FunctionToCall::CALL_FLUSH,
363 AAUDIO_OK,
364 AAUDIO_STREAM_STATE_FLUSHED);
365}
366
367
368// STARTED =================================================================
369TEST(test_various, aaudio_state_lowlat_started_start) {
370 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
371 AAUDIO_STREAM_STATE_STARTED,
372 FunctionToCall::CALL_START,
373 AAUDIO_ERROR_INVALID_STATE,
374 AAUDIO_STREAM_STATE_STARTED);
375}
376
377TEST(test_various, aaudio_state_none_started_start) {
378 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
379 AAUDIO_STREAM_STATE_STARTED,
380 FunctionToCall::CALL_START,
381 AAUDIO_ERROR_INVALID_STATE,
382 AAUDIO_STREAM_STATE_STARTED);
383}
384
385TEST(test_various, aaudio_state_lowlat_started_stop) {
386 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
387 AAUDIO_STREAM_STATE_STARTED,
388 FunctionToCall::CALL_STOP,
389 AAUDIO_OK,
390 AAUDIO_STREAM_STATE_STOPPED);
391}
392
393TEST(test_various, aaudio_state_none_started_stop) {
394 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
395 AAUDIO_STREAM_STATE_STARTED,
396 FunctionToCall::CALL_STOP,
397 AAUDIO_OK,
398 AAUDIO_STREAM_STATE_STOPPED);
399}
400
401TEST(test_various, aaudio_state_lowlat_started_pause) {
402 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
403 AAUDIO_STREAM_STATE_STARTED,
404 FunctionToCall::CALL_PAUSE,
405 AAUDIO_OK,
406 AAUDIO_STREAM_STATE_PAUSED);
407}
408
409TEST(test_various, aaudio_state_none_started_pause) {
410 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
411 AAUDIO_STREAM_STATE_STARTED,
412 FunctionToCall::CALL_PAUSE,
413 AAUDIO_OK,
414 AAUDIO_STREAM_STATE_PAUSED);
415}
416
417TEST(test_various, aaudio_state_lowlat_started_flush) {
418 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
419 AAUDIO_STREAM_STATE_STARTED,
420 FunctionToCall::CALL_FLUSH,
421 AAUDIO_ERROR_INVALID_STATE,
422 AAUDIO_STREAM_STATE_STARTED);
423}
424
425TEST(test_various, aaudio_state_none_started_flush) {
426 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
427 AAUDIO_STREAM_STATE_STARTED,
428 FunctionToCall::CALL_FLUSH,
429 AAUDIO_ERROR_INVALID_STATE,
430 AAUDIO_STREAM_STATE_STARTED);
431}
432
433// STOPPED =================================================================
434TEST(test_various, aaudio_state_lowlat_stopped_start) {
435 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
436 AAUDIO_STREAM_STATE_STOPPED,
437 FunctionToCall::CALL_START,
438 AAUDIO_OK,
439 AAUDIO_STREAM_STATE_STARTED);
440}
441
442TEST(test_various, aaudio_state_none_stopped_start) {
443 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
444 AAUDIO_STREAM_STATE_STOPPED,
445 FunctionToCall::CALL_START,
446 AAUDIO_OK,
447 AAUDIO_STREAM_STATE_STARTED);
448}
449
450TEST(test_various, aaudio_state_lowlat_stopped_stop) {
451 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
452 AAUDIO_STREAM_STATE_STOPPED,
453 FunctionToCall::CALL_STOP,
454 AAUDIO_OK,
455 AAUDIO_STREAM_STATE_STOPPED);
456}
457
458TEST(test_various, aaudio_state_none_stopped_stop) {
459 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
460 AAUDIO_STREAM_STATE_STOPPED,
461 FunctionToCall::CALL_STOP,
462 AAUDIO_OK,
463 AAUDIO_STREAM_STATE_STOPPED);
464}
465
466TEST(test_various, aaudio_state_lowlat_stopped_pause) {
467 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
468 AAUDIO_STREAM_STATE_STOPPED,
469 FunctionToCall::CALL_PAUSE,
470 AAUDIO_OK,
471 AAUDIO_STREAM_STATE_PAUSED);
472}
473
474TEST(test_various, aaudio_state_none_stopped_pause) {
475 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
476 AAUDIO_STREAM_STATE_STOPPED,
477 FunctionToCall::CALL_PAUSE,
478 AAUDIO_OK,
479 AAUDIO_STREAM_STATE_PAUSED);
480}
481
482TEST(test_various, aaudio_state_lowlat_stopped_flush) {
483 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
484 AAUDIO_STREAM_STATE_STOPPED,
485 FunctionToCall::CALL_FLUSH,
486 AAUDIO_OK,
487 AAUDIO_STREAM_STATE_FLUSHED);
488}
489
490TEST(test_various, aaudio_state_none_stopped_flush) {
491 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
492 AAUDIO_STREAM_STATE_STOPPED,
493 FunctionToCall::CALL_FLUSH,
494 AAUDIO_OK,
495 AAUDIO_STREAM_STATE_FLUSHED);
496}
497
498// PAUSED =================================================================
499TEST(test_various, aaudio_state_lowlat_paused_start) {
500checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
501 AAUDIO_STREAM_STATE_PAUSED,
502 FunctionToCall::CALL_START,
503 AAUDIO_OK,
504 AAUDIO_STREAM_STATE_STARTED);
505}
506
507TEST(test_various, aaudio_state_none_paused_start) {
508checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
509 AAUDIO_STREAM_STATE_PAUSED,
510 FunctionToCall::CALL_START,
511 AAUDIO_OK,
512 AAUDIO_STREAM_STATE_STARTED);
513}
514
515TEST(test_various, aaudio_state_lowlat_paused_stop) {
516checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
517 AAUDIO_STREAM_STATE_PAUSED,
518 FunctionToCall::CALL_STOP,
519 AAUDIO_OK,
520 AAUDIO_STREAM_STATE_STOPPED);
521}
522
523TEST(test_various, aaudio_state_none_paused_stop) {
524checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
525 AAUDIO_STREAM_STATE_PAUSED,
526 FunctionToCall::CALL_STOP,
527 AAUDIO_OK,
528 AAUDIO_STREAM_STATE_STOPPED);
529}
530
531TEST(test_various, aaudio_state_lowlat_paused_pause) {
532checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
533 AAUDIO_STREAM_STATE_PAUSED,
534 FunctionToCall::CALL_PAUSE,
535 AAUDIO_OK,
536 AAUDIO_STREAM_STATE_PAUSED);
537}
538
539TEST(test_various, aaudio_state_none_paused_pause) {
540checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
541 AAUDIO_STREAM_STATE_PAUSED,
542 FunctionToCall::CALL_PAUSE,
543 AAUDIO_OK,
544 AAUDIO_STREAM_STATE_PAUSED);
545}
546
547TEST(test_various, aaudio_state_lowlat_paused_flush) {
548checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
549 AAUDIO_STREAM_STATE_PAUSED,
550 FunctionToCall::CALL_FLUSH,
551 AAUDIO_OK,
552 AAUDIO_STREAM_STATE_FLUSHED);
553}
554
555TEST(test_various, aaudio_state_none_paused_flush) {
556checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
557 AAUDIO_STREAM_STATE_PAUSED,
558 FunctionToCall::CALL_FLUSH,
559 AAUDIO_OK,
560 AAUDIO_STREAM_STATE_FLUSHED);
561}
562
Phil Burk29112a12020-06-25 07:52:45 -0700563// FLUSHING ================================================================
564TEST(test_various, aaudio_state_lowlat_flushing_start) {
565checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
566 AAUDIO_STREAM_STATE_FLUSHING,
567 FunctionToCall::CALL_START,
568 AAUDIO_OK,
569 AAUDIO_STREAM_STATE_STARTED);
570}
571
572TEST(test_various, aaudio_state_none_flushing_start) {
573checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
574 AAUDIO_STREAM_STATE_FLUSHING,
575 FunctionToCall::CALL_START,
576 AAUDIO_OK,
577 AAUDIO_STREAM_STATE_STARTED);
578}
579
580TEST(test_various, aaudio_state_lowlat_flushing_release) {
581checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
582 AAUDIO_STREAM_STATE_FLUSHING,
583 FunctionToCall::CALL_RELEASE,
584 AAUDIO_OK,
585 AAUDIO_STREAM_STATE_CLOSING);
586}
587
588TEST(test_various, aaudio_state_none_flushing_release) {
589checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
590 AAUDIO_STREAM_STATE_FLUSHING,
591 FunctionToCall::CALL_RELEASE,
592 AAUDIO_OK,
593 AAUDIO_STREAM_STATE_CLOSING);
594}
595
596TEST(test_various, aaudio_state_lowlat_starting_release) {
597checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
598 AAUDIO_STREAM_STATE_STARTING,
599 FunctionToCall::CALL_RELEASE,
600 AAUDIO_OK,
601 AAUDIO_STREAM_STATE_CLOSING);
602}
603
604TEST(test_various, aaudio_state_none_starting_release) {
605checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
606 AAUDIO_STREAM_STATE_STARTING,
607 FunctionToCall::CALL_RELEASE,
608 AAUDIO_OK,
609 AAUDIO_STREAM_STATE_CLOSING);
610}
611
612// CLOSING ================================================================
613TEST(test_various, aaudio_state_lowlat_closing_start) {
614checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
615 AAUDIO_STREAM_STATE_CLOSING,
616 FunctionToCall::CALL_START,
617 AAUDIO_ERROR_INVALID_STATE,
618 AAUDIO_STREAM_STATE_CLOSING);
619}
620
621TEST(test_various, aaudio_state_none_closing_start) {
622checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
623 AAUDIO_STREAM_STATE_CLOSING,
624 FunctionToCall::CALL_START,
625 AAUDIO_ERROR_INVALID_STATE,
626 AAUDIO_STREAM_STATE_CLOSING);
627}
628
629TEST(test_various, aaudio_state_lowlat_closing_stop) {
630checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
631 AAUDIO_STREAM_STATE_CLOSING,
632 FunctionToCall::CALL_STOP,
633 AAUDIO_ERROR_INVALID_STATE,
634 AAUDIO_STREAM_STATE_CLOSING);
635}
636
637TEST(test_various, aaudio_state_none_closing_stop) {
638checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
639 AAUDIO_STREAM_STATE_CLOSING,
640 FunctionToCall::CALL_STOP,
641 AAUDIO_ERROR_INVALID_STATE,
642 AAUDIO_STREAM_STATE_CLOSING);
643}
644
Phil Burk4fa3b942017-12-13 17:25:24 -0800645// ==========================================================================
Phil Burk9a9e6002017-11-17 12:17:37 -0800646TEST(test_various, aaudio_set_buffer_size) {
Phil Burk2581ae22017-11-21 15:47:29 -0800647
Phil Burk9a9e6002017-11-17 12:17:37 -0800648 int32_t bufferCapacity;
649 int32_t framesPerBurst = 0;
650 int32_t actualSize = 0;
651
652 AAudioStreamBuilder *aaudioBuilder = nullptr;
653 AAudioStream *aaudioStream = nullptr;
654
655 // Use an AAudioStreamBuilder to contain requested parameters.
656 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
657
658 // Request stream properties.
Phil Burk2581ae22017-11-21 15:47:29 -0800659 AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
Phil Burk9a9e6002017-11-17 12:17:37 -0800660 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
661
662 // Create an AAudioStream using the Builder.
663 EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
664
665 // This is the number of frames that are read in one chunk by a DMA controller
666 // or a DSP or a mixer.
667 framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
668 bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
669 printf(" bufferCapacity = %d, remainder = %d\n",
670 bufferCapacity, bufferCapacity % framesPerBurst);
671
672 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
Phil Burk6363f4b2020-01-10 14:06:51 -0800673 EXPECT_GE(actualSize, 0); // 0 is legal in R
Phil Burk9a9e6002017-11-17 12:17:37 -0800674 EXPECT_LE(actualSize, bufferCapacity);
675
676 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 2 * framesPerBurst);
677 EXPECT_GT(actualSize, framesPerBurst);
678 EXPECT_LE(actualSize, bufferCapacity);
679
680 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity - 1);
681 EXPECT_GT(actualSize, framesPerBurst);
682 EXPECT_LE(actualSize, bufferCapacity);
683
684 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity);
685 EXPECT_GT(actualSize, framesPerBurst);
686 EXPECT_LE(actualSize, bufferCapacity);
687
688 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity + 1);
689 EXPECT_GT(actualSize, framesPerBurst);
690 EXPECT_LE(actualSize, bufferCapacity);
691
692 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 1234567);
693 EXPECT_GT(actualSize, framesPerBurst);
694 EXPECT_LE(actualSize, bufferCapacity);
695
696 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MAX);
697 EXPECT_GT(actualSize, framesPerBurst);
698 EXPECT_LE(actualSize, bufferCapacity);
699
700 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MIN);
Phil Burk6363f4b2020-01-10 14:06:51 -0800701 EXPECT_GE(actualSize, 0); // 0 is legal in R
Phil Burk9a9e6002017-11-17 12:17:37 -0800702 EXPECT_LE(actualSize, bufferCapacity);
703
704 AAudioStream_close(aaudioStream);
705 AAudioStreamBuilder_delete(aaudioBuilder);
Phil Burk9a9e6002017-11-17 12:17:37 -0800706}
Phil Burk2581ae22017-11-21 15:47:29 -0800707
Phil Burk2581ae22017-11-21 15:47:29 -0800708// ************************************************************
709// Test to make sure that AAUDIO_CALLBACK_RESULT_STOP works.
710
711// Callback function that counts calls.
712aaudio_data_callback_result_t CallbackOnceProc(
713 AAudioStream *stream,
714 void *userData,
715 void *audioData,
716 int32_t numFrames
717) {
718 (void) stream;
719 (void) audioData;
720 (void) numFrames;
721
722 std::atomic<int32_t> *callbackCountPtr = (std::atomic<int32_t> *)userData;
723 (*callbackCountPtr)++;
724
725 return AAUDIO_CALLBACK_RESULT_STOP;
726}
727
728void checkCallbackOnce(aaudio_performance_mode_t perfMode) {
729
730 std::atomic<int32_t> callbackCount{0};
731
732 AAudioStreamBuilder *aaudioBuilder = nullptr;
733 AAudioStream *aaudioStream = nullptr;
734
735 // Use an AAudioStreamBuilder to contain requested parameters.
736 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
737
738 // Request stream properties.
739 AAudioStreamBuilder_setDataCallback(aaudioBuilder, CallbackOnceProc, &callbackCount);
740 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
741
742 // Create an AAudioStream using the Builder.
743 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
744 AAudioStreamBuilder_delete(aaudioBuilder);
745
746 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
747
748 sleep(1); // Give callback a chance to run many times.
749
750 EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
751
752 EXPECT_EQ(1, callbackCount.load()); // should stop after first call
753
754 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
755}
756
757TEST(test_various, aaudio_callback_once_none) {
758 checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_NONE);
759}
760
761TEST(test_various, aaudio_callback_once_lowlat) {
762 checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
763}
764
765// ************************************************************
766struct WakeUpCallbackData {
767 void wakeOther() {
768 // signal waiting test to wake up
769 {
770 std::lock_guard <std::mutex> lock(mutex);
771 finished = true;
772 }
773 conditionVariable.notify_one();
774 }
775
776 void waitForFinished() {
777 std::unique_lock <std::mutex> aLock(mutex);
778 conditionVariable.wait(aLock, [=] { return finished; });
779 }
780
781 // For signalling foreground test when callback finished
782 std::mutex mutex;
783 std::condition_variable conditionVariable;
784 bool finished = false;
785};
786
787// Test to make sure we cannot call recursively into the system from a callback.
788struct DangerousData : public WakeUpCallbackData {
789 aaudio_result_t resultStart = AAUDIO_OK;
790 aaudio_result_t resultStop = AAUDIO_OK;
791 aaudio_result_t resultPause = AAUDIO_OK;
792 aaudio_result_t resultFlush = AAUDIO_OK;
793 aaudio_result_t resultClose = AAUDIO_OK;
794};
795
796// Callback function that tries to call back into the stream.
797aaudio_data_callback_result_t DangerousDataCallbackProc(
798 AAudioStream *stream,
799 void *userData,
800 void *audioData,
801 int32_t numFrames) {
802 (void) audioData;
803 (void) numFrames;
804
805 DangerousData *data = (DangerousData *)userData;
806 data->resultStart = AAudioStream_requestStart(stream);
807 data->resultStop = AAudioStream_requestStop(stream);
808 data->resultPause = AAudioStream_requestPause(stream);
809 data->resultFlush = AAudioStream_requestFlush(stream);
810 data->resultClose = AAudioStream_close(stream);
811
812 data->wakeOther();
813
814 return AAUDIO_CALLBACK_RESULT_STOP;
815}
816
817//int main() { // To fix Android Studio formatting when editing.
818void checkDangerousCallback(aaudio_performance_mode_t perfMode) {
819 DangerousData dangerousData;
820 AAudioStreamBuilder *aaudioBuilder = nullptr;
821 AAudioStream *aaudioStream = nullptr;
822
823 // Use an AAudioStreamBuilder to contain requested parameters.
824 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
825
826 // Request stream properties.
827 AAudioStreamBuilder_setDataCallback(aaudioBuilder, DangerousDataCallbackProc, &dangerousData);
828 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
829
830 // Create an AAudioStream using the Builder.
831 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
832 AAudioStreamBuilder_delete(aaudioBuilder);
833
834 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
835
836 dangerousData.waitForFinished();
837
838 EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
839
840 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStart);
841 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStop);
842 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultPause);
843 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultFlush);
844 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultClose);
845
846 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
847}
848
849//int main() { // To fix Android Studio formatting when editing.
850
851TEST(test_various, aaudio_callback_blockers_none) {
852 checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_NONE);
853}
854
855TEST(test_various, aaudio_callback_blockers_lowlat) {
856 checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
857}