1e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk/* 2e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Copyright (C) 2017 The Android Open Source Project 3e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 4e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * you may not use this file except in compliance with the License. 6e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * You may obtain a copy of the License at 7e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 8e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 9e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 10e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Unless required by applicable law or agreed to in writing, software 11e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * See the License for the specific language governing permissions and 14e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * limitations under the License. 15e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk */ 16e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 17e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk// Play sine waves using an AAudio callback. 18e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 19e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <assert.h> 20e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <unistd.h> 21e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <stdlib.h> 22e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <sched.h> 23e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <stdio.h> 24e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <math.h> 25e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <time.h> 26e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <aaudio/AAudio.h> 27629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include "AAudioExampleUtils.h" 28629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include "AAudioSimplePlayer.h" 29e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 30e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk#define NUM_SECONDS 5 31e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 32e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk// Application data that gets passed to the callback. 33e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#define MAX_FRAME_COUNT_RECORDS 256 34e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 35e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkint main(int argc, char **argv) 36e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk{ 37e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk (void)argc; // unused 38629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioSimplePlayer player; 39e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk SineThreadedData_t myData; 40e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk aaudio_result_t result; 41e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 42e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Make printf print immediately so that debug info is not stuck 43e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // in a buffer if we hang or crash. 44e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk setvbuf(stdout, nullptr, _IONBF, (size_t) 0); 45e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk printf("%s - Play a sine sweep using an AAudio callback\n", argv[0]); 46e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 47e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk myData.schedulerChecked = false; 48e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 49629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result = player.open(2, 44100, AAUDIO_FORMAT_PCM_FLOAT, 50629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent SimplePlayerDataCallbackProc, SimplePlayerErrorCallbackProc, &myData); 51e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 52e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk fprintf(stderr, "ERROR - player.open() returned %d\n", result); 53e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk goto error; 54e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 55e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("player.getFramesPerSecond() = %d\n", player.getFramesPerSecond()); 5620523edbf2f597c53b90e76694331c807e559515Phil Burk printf("player.getChannelCount() = %d\n", player.getChannelCount()); 57e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk myData.sineOsc1.setup(440.0, 48000); 58e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk myData.sineOsc1.setSweep(300.0, 600.0, 5.0); 59e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk myData.sineOsc2.setup(660.0, 48000); 60e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk myData.sineOsc2.setSweep(350.0, 900.0, 7.0); 61e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 62e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#if 0 63e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = player.prime(); // FIXME crashes AudioTrack.cpp 64e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 65e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk fprintf(stderr, "ERROR - player.prime() returned %d\n", result); 66e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk goto error; 67e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 68e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#endif 69e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 70e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = player.start(); 71e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 72e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk fprintf(stderr, "ERROR - player.start() returned %d\n", result); 73e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk goto error; 74e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 75e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 76e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("Sleep for %d seconds while audio plays in a callback thread.\n", NUM_SECONDS); 77e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk for (int second = 0; second < NUM_SECONDS; second++) 78e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk { 79e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk const struct timespec request = { .tv_sec = 1, .tv_nsec = 0 }; 80e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); 81e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 82e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk aaudio_stream_state_t state; 83e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = AAudioStream_waitForStateChange(player.getStream(), 84e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk AAUDIO_STREAM_STATE_CLOSED, 85e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk &state, 86e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 0); 87e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 88e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk fprintf(stderr, "ERROR - AAudioStream_waitForStateChange() returned %d\n", result); 89e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk goto error; 90e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 91e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { 92e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); 93e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk break; 94e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 95e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk printf("framesWritten = %d\n", (int) AAudioStream_getFramesWritten(player.getStream())); 96e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 97e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("Woke up now.\n"); 98e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 9971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk printf("call stop()\n"); 100e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = player.stop(); 101e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 102e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk goto error; 103e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 10471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk printf("call close()\n"); 105e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = player.close(); 106e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 107e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk goto error; 108e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 109e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 110e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (myData.schedulerChecked) { 111e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("scheduler = 0x%08x, SCHED_FIFO = 0x%08X\n", 112e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk myData.scheduler, 113e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk SCHED_FIFO); 114e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 115e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 116e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("SUCCESS\n"); 117e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return EXIT_SUCCESS; 118e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkerror: 119e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk player.close(); 120e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); 121e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return EXIT_FAILURE; 122e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 123e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 124