blob: 5bb104600cdf3b146c46c6da9cead4a7833e9317 [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 Burk9a9e6002017-11-17 12:17:37 -080031 AAudioStream *stream,
32 void *userData,
33 void *audioData,
34 int32_t numFrames
35) {
36 (void) stream;
37 (void) userData;
38 (void) audioData;
39 (void) numFrames;
40 return AAUDIO_CALLBACK_RESULT_CONTINUE;
41}
42
Phil Burk0c15f4f2017-11-28 15:46:15 -080043constexpr int64_t NANOS_PER_MILLISECOND = 1000 * 1000;
44
Phil Burk8b4e05e2019-12-17 12:12:09 -080045void checkReleaseThenClose(aaudio_performance_mode_t perfMode,
46 aaudio_sharing_mode_t sharingMode) {
47 AAudioStreamBuilder* aaudioBuilder = nullptr;
48 AAudioStream* aaudioStream = nullptr;
49
50 // Use an AAudioStreamBuilder to contain requested parameters.
51 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
52
53 // Request stream properties.
54 AAudioStreamBuilder_setDataCallback(aaudioBuilder,
55 NoopDataCallbackProc,
56 nullptr);
57 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
58 AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode);
59
60 // Create an AAudioStream using the Builder.
61 ASSERT_EQ(AAUDIO_OK,
62 AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
63 AAudioStreamBuilder_delete(aaudioBuilder);
64
65 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
66
67 sleep(1);
68
69 EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
70
71 EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
72 aaudio_stream_state_t state = AAudioStream_getState(aaudioStream);
73 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
74
75 // We should be able to call this again without crashing.
76 EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
77 state = AAudioStream_getState(aaudioStream);
78 EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
79
80 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
81}
82
83TEST(test_various, aaudio_release_close_none) {
84 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_NONE,
85 AAUDIO_SHARING_MODE_SHARED);
86 // No EXCLUSIVE streams with MODE_NONE.
87}
88
89TEST(test_various, aaudio_release_close_low_shared) {
90 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
91 AAUDIO_SHARING_MODE_SHARED);
92}
93
94TEST(test_various, aaudio_release_close_low_exclusive) {
95 checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
96 AAUDIO_SHARING_MODE_EXCLUSIVE);
97}
98
Phil Burk4fa3b942017-12-13 17:25:24 -080099enum FunctionToCall {
100 CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH
101};
102
103void checkStateTransition(aaudio_performance_mode_t perfMode,
104 aaudio_stream_state_t originalState,
105 FunctionToCall functionToCall,
106 aaudio_result_t expectedResult,
107 aaudio_stream_state_t expectedState) {
Phil Burk0c15f4f2017-11-28 15:46:15 -0800108 AAudioStreamBuilder *aaudioBuilder = nullptr;
109 AAudioStream *aaudioStream = nullptr;
110
Phil Burk4fa3b942017-12-13 17:25:24 -0800111 // Use an AAudioStreamBuilder to contain requested parameters.
Phil Burk0c15f4f2017-11-28 15:46:15 -0800112 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
113
Phil Burk4fa3b942017-12-13 17:25:24 -0800114 // Request stream properties.
Phil Burk2581ae22017-11-21 15:47:29 -0800115 AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
Phil Burk4fa3b942017-12-13 17:25:24 -0800116 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
Phil Burk0c15f4f2017-11-28 15:46:15 -0800117
Phil Burk4fa3b942017-12-13 17:25:24 -0800118 // Create an AAudioStream using the Builder.
119 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
Phil Burk0c15f4f2017-11-28 15:46:15 -0800120
Phil Burk4fa3b942017-12-13 17:25:24 -0800121 // Verify Open State
Phil Burk0c15f4f2017-11-28 15:46:15 -0800122 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
123 EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
124 AAUDIO_STREAM_STATE_UNKNOWN, &state,
125 1000 * NANOS_PER_MILLISECOND));
126 EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
127
Phil Burk4fa3b942017-12-13 17:25:24 -0800128 // Put stream into desired state.
129 aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_UNINITIALIZED;
130 if (originalState != AAUDIO_STREAM_STATE_OPEN) {
Phil Burk0c15f4f2017-11-28 15:46:15 -0800131
Phil Burk4fa3b942017-12-13 17:25:24 -0800132 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
133
134 if (originalState != AAUDIO_STREAM_STATE_STARTING) {
135
136 ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
137 AAUDIO_STREAM_STATE_STARTING,
138 &state,
139 1000 * NANOS_PER_MILLISECOND));
140 ASSERT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
141
142 if (originalState == AAUDIO_STREAM_STATE_STOPPING) {
143 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
144 } else if (originalState == AAUDIO_STREAM_STATE_STOPPED) {
145 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
146 inputState = AAUDIO_STREAM_STATE_STOPPING;
147 } else if (originalState == AAUDIO_STREAM_STATE_PAUSING) {
148 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
149 } else if (originalState == AAUDIO_STREAM_STATE_PAUSED) {
150 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
151 inputState = AAUDIO_STREAM_STATE_PAUSING;
152 }
153 }
154 }
155
156 // Wait until past transitional state.
157 if (inputState != AAUDIO_STREAM_STATE_UNINITIALIZED) {
158 ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
159 inputState,
160 &state,
161 1000 * NANOS_PER_MILLISECOND));
162 ASSERT_EQ(originalState, state);
163 }
164
165 aaudio_stream_state_t transitionalState = originalState;
166 switch(functionToCall) {
167 case FunctionToCall::CALL_START:
168 EXPECT_EQ(expectedResult, AAudioStream_requestStart(aaudioStream));
169 transitionalState = AAUDIO_STREAM_STATE_STARTING;
170 break;
171 case FunctionToCall::CALL_STOP:
172 EXPECT_EQ(expectedResult, AAudioStream_requestStop(aaudioStream));
173 transitionalState = AAUDIO_STREAM_STATE_STOPPING;
174 break;
175 case FunctionToCall::CALL_PAUSE:
176 EXPECT_EQ(expectedResult, AAudioStream_requestPause(aaudioStream));
177 transitionalState = AAUDIO_STREAM_STATE_PAUSING;
178 break;
179 case FunctionToCall::CALL_FLUSH:
180 EXPECT_EQ(expectedResult, AAudioStream_requestFlush(aaudioStream));
181 transitionalState = AAUDIO_STREAM_STATE_FLUSHING;
182 break;
183 }
184
Phil Burk0c15f4f2017-11-28 15:46:15 -0800185 EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
Phil Burk4fa3b942017-12-13 17:25:24 -0800186 transitionalState,
187 &state,
Phil Burk0c15f4f2017-11-28 15:46:15 -0800188 1000 * NANOS_PER_MILLISECOND));
Phil Burk4fa3b942017-12-13 17:25:24 -0800189 // We should not change state when a function fails.
190 if (expectedResult != AAUDIO_OK) {
191 ASSERT_EQ(originalState, expectedState);
192 }
193 EXPECT_EQ(expectedState, state);
194 if (state != expectedState) {
195 printf("ERROR - expected %s, actual = %s\n",
196 AAudio_convertStreamStateToText(expectedState),
197 AAudio_convertStreamStateToText(state));
198 fflush(stdout);
199 }
Phil Burk0c15f4f2017-11-28 15:46:15 -0800200
201 AAudioStream_close(aaudioStream);
202 AAudioStreamBuilder_delete(aaudioBuilder);
203}
204
Phil Burk4fa3b942017-12-13 17:25:24 -0800205// TODO Use parameterized tests instead of these individual specific tests.
206
207// OPEN =================================================================
208TEST(test_various, aaudio_state_lowlat_open_start) {
209 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
210 AAUDIO_STREAM_STATE_OPEN,
211 FunctionToCall::CALL_START,
212 AAUDIO_OK,
213 AAUDIO_STREAM_STATE_STARTED);
214}
215
216TEST(test_various, aaudio_state_none_open_start) {
217 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
218 AAUDIO_STREAM_STATE_OPEN,
219 FunctionToCall::CALL_START,
220 AAUDIO_OK,
221 AAUDIO_STREAM_STATE_STARTED);
222}
223
224TEST(test_various, aaudio_state_lowlat_open_stop) {
225 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
226 AAUDIO_STREAM_STATE_OPEN,
227 FunctionToCall::CALL_STOP,
228 AAUDIO_OK,
229 AAUDIO_STREAM_STATE_STOPPED);
230}
231
232TEST(test_various, aaudio_state_none_open_stop) {
233 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
234 AAUDIO_STREAM_STATE_OPEN,
235 FunctionToCall::CALL_STOP,
236 AAUDIO_OK,
237 AAUDIO_STREAM_STATE_STOPPED);
238}
239
240TEST(test_various, aaudio_state_lowlat_open_pause) {
241 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
242 AAUDIO_STREAM_STATE_OPEN,
243 FunctionToCall::CALL_PAUSE,
244 AAUDIO_OK,
245 AAUDIO_STREAM_STATE_PAUSED);
246}
247
248TEST(test_various, aaudio_state_none_open_pause) {
249 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
250 AAUDIO_STREAM_STATE_OPEN,
251 FunctionToCall::CALL_PAUSE,
252 AAUDIO_OK,
253 AAUDIO_STREAM_STATE_PAUSED);
254}
255
256TEST(test_various, aaudio_state_lowlat_open_flush) {
257 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
258 AAUDIO_STREAM_STATE_OPEN,
259 FunctionToCall::CALL_FLUSH,
260 AAUDIO_OK,
261 AAUDIO_STREAM_STATE_FLUSHED);
262}
263
264TEST(test_various, aaudio_state_none_open_flush) {
265 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
266 AAUDIO_STREAM_STATE_OPEN,
267 FunctionToCall::CALL_FLUSH,
268 AAUDIO_OK,
269 AAUDIO_STREAM_STATE_FLUSHED);
270}
271
272
273// STARTED =================================================================
274TEST(test_various, aaudio_state_lowlat_started_start) {
275 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
276 AAUDIO_STREAM_STATE_STARTED,
277 FunctionToCall::CALL_START,
278 AAUDIO_ERROR_INVALID_STATE,
279 AAUDIO_STREAM_STATE_STARTED);
280}
281
282TEST(test_various, aaudio_state_none_started_start) {
283 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
284 AAUDIO_STREAM_STATE_STARTED,
285 FunctionToCall::CALL_START,
286 AAUDIO_ERROR_INVALID_STATE,
287 AAUDIO_STREAM_STATE_STARTED);
288}
289
290TEST(test_various, aaudio_state_lowlat_started_stop) {
291 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
292 AAUDIO_STREAM_STATE_STARTED,
293 FunctionToCall::CALL_STOP,
294 AAUDIO_OK,
295 AAUDIO_STREAM_STATE_STOPPED);
296}
297
298TEST(test_various, aaudio_state_none_started_stop) {
299 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
300 AAUDIO_STREAM_STATE_STARTED,
301 FunctionToCall::CALL_STOP,
302 AAUDIO_OK,
303 AAUDIO_STREAM_STATE_STOPPED);
304}
305
306TEST(test_various, aaudio_state_lowlat_started_pause) {
307 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
308 AAUDIO_STREAM_STATE_STARTED,
309 FunctionToCall::CALL_PAUSE,
310 AAUDIO_OK,
311 AAUDIO_STREAM_STATE_PAUSED);
312}
313
314TEST(test_various, aaudio_state_none_started_pause) {
315 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
316 AAUDIO_STREAM_STATE_STARTED,
317 FunctionToCall::CALL_PAUSE,
318 AAUDIO_OK,
319 AAUDIO_STREAM_STATE_PAUSED);
320}
321
322TEST(test_various, aaudio_state_lowlat_started_flush) {
323 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
324 AAUDIO_STREAM_STATE_STARTED,
325 FunctionToCall::CALL_FLUSH,
326 AAUDIO_ERROR_INVALID_STATE,
327 AAUDIO_STREAM_STATE_STARTED);
328}
329
330TEST(test_various, aaudio_state_none_started_flush) {
331 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
332 AAUDIO_STREAM_STATE_STARTED,
333 FunctionToCall::CALL_FLUSH,
334 AAUDIO_ERROR_INVALID_STATE,
335 AAUDIO_STREAM_STATE_STARTED);
336}
337
338// STOPPED =================================================================
339TEST(test_various, aaudio_state_lowlat_stopped_start) {
340 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
341 AAUDIO_STREAM_STATE_STOPPED,
342 FunctionToCall::CALL_START,
343 AAUDIO_OK,
344 AAUDIO_STREAM_STATE_STARTED);
345}
346
347TEST(test_various, aaudio_state_none_stopped_start) {
348 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
349 AAUDIO_STREAM_STATE_STOPPED,
350 FunctionToCall::CALL_START,
351 AAUDIO_OK,
352 AAUDIO_STREAM_STATE_STARTED);
353}
354
355TEST(test_various, aaudio_state_lowlat_stopped_stop) {
356 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
357 AAUDIO_STREAM_STATE_STOPPED,
358 FunctionToCall::CALL_STOP,
359 AAUDIO_OK,
360 AAUDIO_STREAM_STATE_STOPPED);
361}
362
363TEST(test_various, aaudio_state_none_stopped_stop) {
364 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
365 AAUDIO_STREAM_STATE_STOPPED,
366 FunctionToCall::CALL_STOP,
367 AAUDIO_OK,
368 AAUDIO_STREAM_STATE_STOPPED);
369}
370
371TEST(test_various, aaudio_state_lowlat_stopped_pause) {
372 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
373 AAUDIO_STREAM_STATE_STOPPED,
374 FunctionToCall::CALL_PAUSE,
375 AAUDIO_OK,
376 AAUDIO_STREAM_STATE_PAUSED);
377}
378
379TEST(test_various, aaudio_state_none_stopped_pause) {
380 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
381 AAUDIO_STREAM_STATE_STOPPED,
382 FunctionToCall::CALL_PAUSE,
383 AAUDIO_OK,
384 AAUDIO_STREAM_STATE_PAUSED);
385}
386
387TEST(test_various, aaudio_state_lowlat_stopped_flush) {
388 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
389 AAUDIO_STREAM_STATE_STOPPED,
390 FunctionToCall::CALL_FLUSH,
391 AAUDIO_OK,
392 AAUDIO_STREAM_STATE_FLUSHED);
393}
394
395TEST(test_various, aaudio_state_none_stopped_flush) {
396 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
397 AAUDIO_STREAM_STATE_STOPPED,
398 FunctionToCall::CALL_FLUSH,
399 AAUDIO_OK,
400 AAUDIO_STREAM_STATE_FLUSHED);
401}
402
403// PAUSED =================================================================
404TEST(test_various, aaudio_state_lowlat_paused_start) {
405checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
406 AAUDIO_STREAM_STATE_PAUSED,
407 FunctionToCall::CALL_START,
408 AAUDIO_OK,
409 AAUDIO_STREAM_STATE_STARTED);
410}
411
412TEST(test_various, aaudio_state_none_paused_start) {
413checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
414 AAUDIO_STREAM_STATE_PAUSED,
415 FunctionToCall::CALL_START,
416 AAUDIO_OK,
417 AAUDIO_STREAM_STATE_STARTED);
418}
419
420TEST(test_various, aaudio_state_lowlat_paused_stop) {
421checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
422 AAUDIO_STREAM_STATE_PAUSED,
423 FunctionToCall::CALL_STOP,
424 AAUDIO_OK,
425 AAUDIO_STREAM_STATE_STOPPED);
426}
427
428TEST(test_various, aaudio_state_none_paused_stop) {
429checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
430 AAUDIO_STREAM_STATE_PAUSED,
431 FunctionToCall::CALL_STOP,
432 AAUDIO_OK,
433 AAUDIO_STREAM_STATE_STOPPED);
434}
435
436TEST(test_various, aaudio_state_lowlat_paused_pause) {
437checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
438 AAUDIO_STREAM_STATE_PAUSED,
439 FunctionToCall::CALL_PAUSE,
440 AAUDIO_OK,
441 AAUDIO_STREAM_STATE_PAUSED);
442}
443
444TEST(test_various, aaudio_state_none_paused_pause) {
445checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
446 AAUDIO_STREAM_STATE_PAUSED,
447 FunctionToCall::CALL_PAUSE,
448 AAUDIO_OK,
449 AAUDIO_STREAM_STATE_PAUSED);
450}
451
452TEST(test_various, aaudio_state_lowlat_paused_flush) {
453checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
454 AAUDIO_STREAM_STATE_PAUSED,
455 FunctionToCall::CALL_FLUSH,
456 AAUDIO_OK,
457 AAUDIO_STREAM_STATE_FLUSHED);
458}
459
460TEST(test_various, aaudio_state_none_paused_flush) {
461checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
462 AAUDIO_STREAM_STATE_PAUSED,
463 FunctionToCall::CALL_FLUSH,
464 AAUDIO_OK,
465 AAUDIO_STREAM_STATE_FLUSHED);
466}
467
468// ==========================================================================
Phil Burk9a9e6002017-11-17 12:17:37 -0800469TEST(test_various, aaudio_set_buffer_size) {
Phil Burk2581ae22017-11-21 15:47:29 -0800470
Phil Burk9a9e6002017-11-17 12:17:37 -0800471 int32_t bufferCapacity;
472 int32_t framesPerBurst = 0;
473 int32_t actualSize = 0;
474
475 AAudioStreamBuilder *aaudioBuilder = nullptr;
476 AAudioStream *aaudioStream = nullptr;
477
478 // Use an AAudioStreamBuilder to contain requested parameters.
479 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
480
481 // Request stream properties.
Phil Burk2581ae22017-11-21 15:47:29 -0800482 AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
Phil Burk9a9e6002017-11-17 12:17:37 -0800483 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
484
485 // Create an AAudioStream using the Builder.
486 EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
487
488 // This is the number of frames that are read in one chunk by a DMA controller
489 // or a DSP or a mixer.
490 framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
491 bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
492 printf(" bufferCapacity = %d, remainder = %d\n",
493 bufferCapacity, bufferCapacity % framesPerBurst);
494
495 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
Phil Burk6363f4b2020-01-10 14:06:51 -0800496 EXPECT_GE(actualSize, 0); // 0 is legal in R
Phil Burk9a9e6002017-11-17 12:17:37 -0800497 EXPECT_LE(actualSize, bufferCapacity);
498
499 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 2 * framesPerBurst);
500 EXPECT_GT(actualSize, framesPerBurst);
501 EXPECT_LE(actualSize, bufferCapacity);
502
503 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity - 1);
504 EXPECT_GT(actualSize, framesPerBurst);
505 EXPECT_LE(actualSize, bufferCapacity);
506
507 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity);
508 EXPECT_GT(actualSize, framesPerBurst);
509 EXPECT_LE(actualSize, bufferCapacity);
510
511 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity + 1);
512 EXPECT_GT(actualSize, framesPerBurst);
513 EXPECT_LE(actualSize, bufferCapacity);
514
515 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 1234567);
516 EXPECT_GT(actualSize, framesPerBurst);
517 EXPECT_LE(actualSize, bufferCapacity);
518
519 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MAX);
520 EXPECT_GT(actualSize, framesPerBurst);
521 EXPECT_LE(actualSize, bufferCapacity);
522
523 actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MIN);
Phil Burk6363f4b2020-01-10 14:06:51 -0800524 EXPECT_GE(actualSize, 0); // 0 is legal in R
Phil Burk9a9e6002017-11-17 12:17:37 -0800525 EXPECT_LE(actualSize, bufferCapacity);
526
527 AAudioStream_close(aaudioStream);
528 AAudioStreamBuilder_delete(aaudioBuilder);
Phil Burk9a9e6002017-11-17 12:17:37 -0800529}
Phil Burk2581ae22017-11-21 15:47:29 -0800530
Phil Burk2581ae22017-11-21 15:47:29 -0800531// ************************************************************
532// Test to make sure that AAUDIO_CALLBACK_RESULT_STOP works.
533
534// Callback function that counts calls.
535aaudio_data_callback_result_t CallbackOnceProc(
536 AAudioStream *stream,
537 void *userData,
538 void *audioData,
539 int32_t numFrames
540) {
541 (void) stream;
542 (void) audioData;
543 (void) numFrames;
544
545 std::atomic<int32_t> *callbackCountPtr = (std::atomic<int32_t> *)userData;
546 (*callbackCountPtr)++;
547
548 return AAUDIO_CALLBACK_RESULT_STOP;
549}
550
551void checkCallbackOnce(aaudio_performance_mode_t perfMode) {
552
553 std::atomic<int32_t> callbackCount{0};
554
555 AAudioStreamBuilder *aaudioBuilder = nullptr;
556 AAudioStream *aaudioStream = nullptr;
557
558 // Use an AAudioStreamBuilder to contain requested parameters.
559 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
560
561 // Request stream properties.
562 AAudioStreamBuilder_setDataCallback(aaudioBuilder, CallbackOnceProc, &callbackCount);
563 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
564
565 // Create an AAudioStream using the Builder.
566 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
567 AAudioStreamBuilder_delete(aaudioBuilder);
568
569 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
570
571 sleep(1); // Give callback a chance to run many times.
572
573 EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
574
575 EXPECT_EQ(1, callbackCount.load()); // should stop after first call
576
577 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
578}
579
580TEST(test_various, aaudio_callback_once_none) {
581 checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_NONE);
582}
583
584TEST(test_various, aaudio_callback_once_lowlat) {
585 checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
586}
587
588// ************************************************************
589struct WakeUpCallbackData {
590 void wakeOther() {
591 // signal waiting test to wake up
592 {
593 std::lock_guard <std::mutex> lock(mutex);
594 finished = true;
595 }
596 conditionVariable.notify_one();
597 }
598
599 void waitForFinished() {
600 std::unique_lock <std::mutex> aLock(mutex);
601 conditionVariable.wait(aLock, [=] { return finished; });
602 }
603
604 // For signalling foreground test when callback finished
605 std::mutex mutex;
606 std::condition_variable conditionVariable;
607 bool finished = false;
608};
609
610// Test to make sure we cannot call recursively into the system from a callback.
611struct DangerousData : public WakeUpCallbackData {
612 aaudio_result_t resultStart = AAUDIO_OK;
613 aaudio_result_t resultStop = AAUDIO_OK;
614 aaudio_result_t resultPause = AAUDIO_OK;
615 aaudio_result_t resultFlush = AAUDIO_OK;
616 aaudio_result_t resultClose = AAUDIO_OK;
617};
618
619// Callback function that tries to call back into the stream.
620aaudio_data_callback_result_t DangerousDataCallbackProc(
621 AAudioStream *stream,
622 void *userData,
623 void *audioData,
624 int32_t numFrames) {
625 (void) audioData;
626 (void) numFrames;
627
628 DangerousData *data = (DangerousData *)userData;
629 data->resultStart = AAudioStream_requestStart(stream);
630 data->resultStop = AAudioStream_requestStop(stream);
631 data->resultPause = AAudioStream_requestPause(stream);
632 data->resultFlush = AAudioStream_requestFlush(stream);
633 data->resultClose = AAudioStream_close(stream);
634
635 data->wakeOther();
636
637 return AAUDIO_CALLBACK_RESULT_STOP;
638}
639
640//int main() { // To fix Android Studio formatting when editing.
641void checkDangerousCallback(aaudio_performance_mode_t perfMode) {
642 DangerousData dangerousData;
643 AAudioStreamBuilder *aaudioBuilder = nullptr;
644 AAudioStream *aaudioStream = nullptr;
645
646 // Use an AAudioStreamBuilder to contain requested parameters.
647 ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
648
649 // Request stream properties.
650 AAudioStreamBuilder_setDataCallback(aaudioBuilder, DangerousDataCallbackProc, &dangerousData);
651 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
652
653 // Create an AAudioStream using the Builder.
654 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
655 AAudioStreamBuilder_delete(aaudioBuilder);
656
657 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
658
659 dangerousData.waitForFinished();
660
661 EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
662
663 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStart);
664 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStop);
665 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultPause);
666 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultFlush);
667 EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultClose);
668
669 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
670}
671
672//int main() { // To fix Android Studio formatting when editing.
673
674TEST(test_various, aaudio_callback_blockers_none) {
675 checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_NONE);
676}
677
678TEST(test_various, aaudio_callback_blockers_lowlat) {
679 checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
680}