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