18dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk/* 28dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * Copyright (C) 2017 The Android Open Source Project 38dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * 48dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 58dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * you may not use this file except in compliance with the License. 68dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * You may obtain a copy of the License at 78dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * 88dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * http://www.apache.org/licenses/LICENSE-2.0 98dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * 108dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * Unless required by applicable law or agreed to in writing, software 118dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * distributed under the License is distributed on an "AS IS" BASIS, 128dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * See the License for the specific language governing permissions and 148dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk * limitations under the License. 158dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk */ 168dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 178dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk// Play sine waves using AAudio. 188dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 198dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk#include <stdio.h> 208dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk//#include <stdlib.h> 218dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk//#include <math.h> 228dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 238dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk#include <android-base/macros.h> 248dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk#include <aaudio/AAudio.h> 258dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 268dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk#include <gtest/gtest.h> 278dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 288dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burkstatic const char *getSharingModeText(aaudio_sharing_mode_t mode) { 298dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk const char *modeText = "unknown"; 308dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk switch (mode) { 318dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk case AAUDIO_SHARING_MODE_EXCLUSIVE: 328dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk modeText = "EXCLUSIVE"; 338dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk break; 348dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk case AAUDIO_SHARING_MODE_SHARED: 358dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk modeText = "SHARED"; 368dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk break; 378dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk default: 388dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk break; 398dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 408dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk return modeText; 418dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk} 428dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 438dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk// Callback function that fills the audio output buffer. 448dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burkaaudio_data_callback_result_t MyDataCallbackProc( 458dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStream *stream, 468dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk void *userData, 478dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk void *audioData, 488dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t numFrames 498dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk) { 508dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk (void) stream; 518dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk (void) userData; 528dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk (void) audioData; 538dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk (void) numFrames; 548dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk return AAUDIO_CALLBACK_RESULT_CONTINUE; 558dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk} 568dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 578dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burkstatic void testOpenOptions(aaudio_direction_t direction, 588dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t channelCount, 598dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t sampleRate, 609dca9824da74d50be02bc81f539cc77b7bde678aPhil Burk aaudio_format_t format) { 618dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 628dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk aaudio_result_t result = AAUDIO_OK; 638dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 648dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t bufferCapacity; 658dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t framesPerBurst = 0; 668dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 678dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t actualChannelCount = 0; 688dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t actualSampleRate = 0; 699dca9824da74d50be02bc81f539cc77b7bde678aPhil Burk aaudio_format_t actualDataFormat = AAUDIO_FORMAT_UNSPECIFIED; 708dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED; 718dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk aaudio_direction_t actualDirection; 728dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 738dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder *aaudioBuilder = nullptr; 748dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStream *aaudioStream = nullptr; 758dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 768dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk printf("TestOpen: dir = %d, chans = %3d, rate = %6d format = %d\n", 778dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk direction, channelCount, sampleRate, format); 788dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 798dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // Use an AAudioStreamBuilder to contain requested parameters. 808dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder)); 818dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 828dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // Request stream properties. 838dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_setDirection(aaudioBuilder, direction); 848dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_setSampleRate(aaudioBuilder, sampleRate); 858dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount); 868dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_setFormat(aaudioBuilder, format); 878dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_setDataCallback(aaudioBuilder, MyDataCallbackProc, nullptr); 888dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 898dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_NONE); 908dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); 918dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_POWER_SAVING); 928dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 938dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // Create an AAudioStream using the Builder. 948dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream); 958dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk if (result != AAUDIO_OK) { 968dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk printf("Stream not opened! That may be OK.\n"); 978dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk goto finish; 988dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 998dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1008dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // Check to see what kind of stream we actually got. 1018dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk actualSampleRate = AAudioStream_getSampleRate(aaudioStream); 1028dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk actualChannelCount = AAudioStream_getChannelCount(aaudioStream); 1038dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk actualDataFormat = AAudioStream_getFormat(aaudioStream); 1048dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk actualDirection = AAudioStream_getDirection(aaudioStream); 1058dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1068dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk printf(" dir = %d, chans = %3d, rate = %6d format = %d\n", 1078dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk direction, actualChannelCount, actualSampleRate, actualDataFormat); 1088dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1098dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // If we ask for something specific then we should get that. 1108dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk if (channelCount != AAUDIO_UNSPECIFIED) { 1118dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk EXPECT_EQ(channelCount, actualChannelCount); 1128dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1138dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk if (sampleRate != AAUDIO_UNSPECIFIED) { 1148dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk EXPECT_EQ(sampleRate, actualSampleRate); 1158dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1168dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk if (format != AAUDIO_FORMAT_UNSPECIFIED) { 1178dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk EXPECT_EQ(format, actualDataFormat); 1188dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1198dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk EXPECT_EQ(direction, actualDirection); 1208dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1218dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // This is the number of frames that are read in one chunk by a DMA controller 1228dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // or a DSP or a mixer. 1238dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream); 1248dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream); 1258dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk printf(" bufferCapacity = %d, remainder = %d\n", 1268dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk bufferCapacity, bufferCapacity % framesPerBurst); 1278dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1288dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burkfinish: 1298dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStream_close(aaudioStream); 1308dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAudioStreamBuilder_delete(aaudioBuilder); 1318dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk printf(" result = %d = %s\n", result, AAudio_convertResultToText(result)); 1328dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk} 1338dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1348dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk//void foo() { // for tricking the Android Studio formatter 1358dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil BurkTEST(test_open_params, aaudio_open_all) { 1368dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk aaudio_direction_t directions[] = {AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT}; 1379dca9824da74d50be02bc81f539cc77b7bde678aPhil Burk aaudio_format_t formats[] = {AAUDIO_FORMAT_UNSPECIFIED, 1389dca9824da74d50be02bc81f539cc77b7bde678aPhil Burk AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT}; 1398dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk int32_t rates[] = {AAUDIO_UNSPECIFIED, 22050, 32000, 44100, 48000, 88200, 96000, 37913, 59132}; 1408dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1418dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // Make printf print immediately so that debug info is not stuck 1428dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk // in a buffer if we hang or crash. 1438dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk setvbuf(stdout, nullptr, _IONBF, (size_t) 0); 1448dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk 1458dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk for (uint dirIndex = 0;dirIndex < arraysize(directions); dirIndex++) { 1468dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk aaudio_direction_t direction = directions[dirIndex]; 1478dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk for (int32_t channelCount = 0; channelCount <= 8; channelCount++) { 1488dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk testOpenOptions(direction, channelCount, 1498dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk AAUDIO_UNSPECIFIED, AAUDIO_FORMAT_UNSPECIFIED); 1508dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1518dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk for (uint i = 0; i < arraysize(rates); i++) { 1528dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk testOpenOptions(direction, AAUDIO_UNSPECIFIED, rates[i], AAUDIO_FORMAT_UNSPECIFIED); 1538dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1548dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk for (uint i = 0; i < arraysize(formats); i++) { 1558dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk testOpenOptions(direction, AAUDIO_UNSPECIFIED, AAUDIO_UNSPECIFIED, formats[i]); 1568dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1578dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk } 1588dd7fedba00b4f21e3428cbb5d5a5014ef9ef49dPhil Burk} 159