1629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent/* 2629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Copyright (C) 2017 The Android Open Source Project 3629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * 4629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * you may not use this file except in compliance with the License. 6629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * You may obtain a copy of the License at 7629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * 8629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * 10629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Unless required by applicable law or agreed to in writing, software 11629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * See the License for the specific language governing permissions and 14629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * limitations under the License. 15629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 16629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 17629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent// Play sine waves using an AAudio callback. 18629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 19629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#ifndef AAUDIO_SIMPLE_PLAYER_H 20629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define AAUDIO_SIMPLE_PLAYER_H 21629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 22629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include <unistd.h> 23629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include <sched.h> 24629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 25629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include <aaudio/AAudio.h> 26629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include "SineGenerator.h" 27629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 28629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent//#define SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE 29629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define SHARING_MODE AAUDIO_SHARING_MODE_SHARED 30629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define PERFORMANCE_MODE AAUDIO_PERFORMANCE_MODE_NONE 31629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 32629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent/** 33629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Simple wrapper for AAudio that opens an output stream either in callback or blocking write mode. 34629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 35629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentclass AAudioSimplePlayer { 36629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentpublic: 37629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioSimplePlayer() {} 38629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent ~AAudioSimplePlayer() { 39629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent close(); 40629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent }; 41629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 42629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 43629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Call this before calling open(). 44629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * @param requestedSharingMode 45629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 46629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void setSharingMode(aaudio_sharing_mode_t requestedSharingMode) { 47629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mRequestedSharingMode = requestedSharingMode; 48629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 49629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 50629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 51629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Call this before calling open(). 52629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * @param requestedPerformanceMode 53629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 54629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void setPerformanceMode(aaudio_performance_mode_t requestedPerformanceMode) { 55629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mRequestedPerformanceMode = requestedPerformanceMode; 56629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 57629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 58629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 59629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Also known as "sample rate" 60629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Only call this after open() has been called. 61629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 62629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t getFramesPerSecond() { 63629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 64629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 65629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 66629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAudioStream_getSampleRate(mStream);; 67629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 68629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 69629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 70629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Only call this after open() has been called. 71629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 72629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t getChannelCount() { 73629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 74629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 75629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 76629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAudioStream_getChannelCount(mStream);; 77629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 78629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 79629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 80629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Open a stream 81629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 82629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t open(int channelCount, int sampSampleRate, aaudio_format_t format, 83629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_dataCallback dataProc, AAudioStream_errorCallback errorProc, 84629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userContext) { 85629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAUDIO_OK; 86629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 87629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Use an AAudioStreamBuilder to contain requested parameters. 88629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result = AAudio_createStreamBuilder(&mBuilder); 89629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) return result; 90629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 91629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent //AAudioStreamBuilder_setSampleRate(mBuilder, 44100); 92629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setPerformanceMode(mBuilder, mRequestedPerformanceMode); 93629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setSharingMode(mBuilder, mRequestedSharingMode); 94629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (dataProc != nullptr) { 95629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setDataCallback(mBuilder, dataProc, userContext); 96629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 97629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (errorProc != nullptr) { 98629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setErrorCallback(mBuilder, errorProc, userContext); 99629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 100629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setChannelCount(mBuilder, channelCount); 101629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setSampleRate(mBuilder, sampSampleRate); 102629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setFormat(mBuilder, format); 103629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent //AAudioStreamBuilder_setFramesPerDataCallback(mBuilder, CALLBACK_SIZE_FRAMES); 104629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setBufferCapacityInFrames(mBuilder, 48 * 8); 105629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 106629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent //aaudio_performance_mode_t perfMode = AAUDIO_PERFORMANCE_MODE_NONE; 107629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_performance_mode_t perfMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY; 108629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent //aaudio_performance_mode_t perfMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING; 109629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_setPerformanceMode(mBuilder, perfMode); 110629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 111629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Open an AAudioStream using the Builder. 112629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result = AAudioStreamBuilder_openStream(mBuilder, &mStream); 113629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) goto finish1; 114629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 115629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("AAudioStream_getFramesPerBurst() = %d\n", 116629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_getFramesPerBurst(mStream)); 117629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("AAudioStream_getBufferSizeInFrames() = %d\n", 118629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_getBufferSizeInFrames(mStream)); 119629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("AAudioStream_getBufferCapacityInFrames() = %d\n", 120629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_getBufferCapacityInFrames(mStream)); 121629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("AAudioStream_getPerformanceMode() = %d, requested %d\n", 122629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_getPerformanceMode(mStream), perfMode); 123629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 124629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent finish1: 125629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_delete(mBuilder); 126629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mBuilder = nullptr; 127629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 128629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 129629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 130629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t close() { 131629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream != nullptr) { 132629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("call AAudioStream_close(%p)\n", mStream); fflush(stdout); 133629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_close(mStream); 134629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mStream = nullptr; 135629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder_delete(mBuilder); 136629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mBuilder = nullptr; 137629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 138629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_OK; 139629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 140629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 141629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Write zero data to fill up the buffer and prevent underruns. 142629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t prime() { 143629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t samplesPerFrame = AAudioStream_getChannelCount(mStream); 144629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent const int numFrames = 32; 145629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float zeros[numFrames * samplesPerFrame]; 146629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent memset(zeros, 0, sizeof(zeros)); 147629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = numFrames; 148629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent while (result == numFrames) { 149629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result = AAudioStream_write(mStream, zeros, numFrames, 0); 150629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 151629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 152629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 153629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 154629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Start the stream. AAudio will start calling your callback function. 155629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t start() { 156629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestStart(mStream); 157629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 158629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("ERROR - AAudioStream_requestStart() returned %d %s\n", 159629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 160629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 161629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 162629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 163629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 164629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Stop the stream. AAudio will stop calling your callback function. 165629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t stop() { 166629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestStop(mStream); 167629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 168629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("ERROR - AAudioStream_requestStop() returned %d %s\n", 169629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 170629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 171629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t xRunCount = AAudioStream_getXRunCount(mStream); 172629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("AAudioStream_getXRunCount %d\n", xRunCount); 173629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 174629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 175629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 176629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *getStream() const { 177629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return mStream; 178629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 179629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 180629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentprivate: 181629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStreamBuilder *mBuilder = nullptr; 182629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *mStream = nullptr; 183629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_sharing_mode_t mRequestedSharingMode = SHARING_MODE; 184629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_performance_mode_t mRequestedPerformanceMode = PERFORMANCE_MODE; 185629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent}; 186629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 187629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurenttypedef struct SineThreadedData_s { 188629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent SineGenerator sineOsc1; 189629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent SineGenerator sineOsc2; 190629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int scheduler; 191629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent bool schedulerChecked; 192629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} SineThreadedData_t; 193629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 194629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent// Callback function that fills the audio output buffer. 195629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentaaudio_data_callback_result_t SimplePlayerDataCallbackProc( 196629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *stream, 197629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userData, 198629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *audioData, 199629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t numFrames 200629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent ) { 201629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 202629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // should not happen but just in case... 203629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (userData == nullptr) { 204629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - SimplePlayerDataCallbackProc needs userData\n"); 205629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_STOP; 206629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 207629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent SineThreadedData_t *sineData = (SineThreadedData_t *) userData; 208629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 209629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (!sineData->schedulerChecked) { 210629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sineData->scheduler = sched_getscheduler(gettid()); 211629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sineData->schedulerChecked = true; 212629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 213629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 214629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t samplesPerFrame = AAudioStream_getChannelCount(stream); 215629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // This code only plays on the first one or two channels. 216629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // TODO Support arbitrary number of channels. 217629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent switch (AAudioStream_getFormat(stream)) { 218629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent case AAUDIO_FORMAT_PCM_I16: { 219629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int16_t *audioBuffer = (int16_t *) audioData; 220629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Render sine waves as shorts to first channel. 221629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sineData->sineOsc1.render(&audioBuffer[0], samplesPerFrame, numFrames); 222629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Render sine waves to second channel if there is one. 223629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (samplesPerFrame > 1) { 224629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sineData->sineOsc2.render(&audioBuffer[1], samplesPerFrame, numFrames); 225629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 226629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 227629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent break; 228629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent case AAUDIO_FORMAT_PCM_FLOAT: { 229629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float *audioBuffer = (float *) audioData; 230629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Render sine waves as floats to first channel. 231629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sineData->sineOsc1.render(&audioBuffer[0], samplesPerFrame, numFrames); 232629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Render sine waves to second channel if there is one. 233629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (samplesPerFrame > 1) { 234629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sineData->sineOsc2.render(&audioBuffer[1], samplesPerFrame, numFrames); 235629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 236629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 237629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent break; 238629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent default: 239629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_STOP; 240629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 241629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 242629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_CONTINUE; 243629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} 244629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 245629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentvoid SimplePlayerErrorCallbackProc( 246629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *stream __unused, 247629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userData __unused, 248629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t error) 249629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent{ 250629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("Error Callback, error: %d\n",(int)error); 251629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} 252629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 253629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#endif //AAUDIO_SIMPLE_PLAYER_H 254