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// Record input using AAudio and display the peak amplitudes. 18629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 19629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#ifndef AAUDIO_SIMPLE_RECORDER_H 20629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define AAUDIO_SIMPLE_RECORDER_H 21629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 22629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#include <aaudio/AAudio.h> 23753c9f326b9505004576996091a64a43271634a0Phil Burk#include "AAudioArgsParser.h" 24629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 25629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent//#define SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE 26629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define SHARING_MODE AAUDIO_SHARING_MODE_SHARED 27629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define PERFORMANCE_MODE AAUDIO_PERFORMANCE_MODE_NONE 28753c9f326b9505004576996091a64a43271634a0Phil Burk 29629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent/** 30629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Simple wrapper for AAudio that opens an input stream either in callback or blocking read mode. 31629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 32629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentclass AAudioSimpleRecorder { 33629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentpublic: 34629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioSimpleRecorder() {} 35629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent ~AAudioSimpleRecorder() { 36629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent close(); 37629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent }; 38629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 39629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 40629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Call this before calling open(). 41629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * @param requestedSharingMode 42629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 43629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void setSharingMode(aaudio_sharing_mode_t requestedSharingMode) { 44629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mRequestedSharingMode = requestedSharingMode; 45629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 46629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 47629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 48629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Call this before calling open(). 49629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * @param requestedPerformanceMode 50629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 51629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void setPerformanceMode(aaudio_performance_mode_t requestedPerformanceMode) { 52629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mRequestedPerformanceMode = requestedPerformanceMode; 53629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 54629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 55629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 56629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Also known as "sample rate" 57629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Only call this after open() has been called. 58629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 59753c9f326b9505004576996091a64a43271634a0Phil Burk int32_t getFramesPerSecond() const { 60753c9f326b9505004576996091a64a43271634a0Phil Burk return getSampleRate(); // alias 61753c9f326b9505004576996091a64a43271634a0Phil Burk } 62753c9f326b9505004576996091a64a43271634a0Phil Burk 63753c9f326b9505004576996091a64a43271634a0Phil Burk /** 64753c9f326b9505004576996091a64a43271634a0Phil Burk * Only call this after open() has been called. 65753c9f326b9505004576996091a64a43271634a0Phil Burk */ 66753c9f326b9505004576996091a64a43271634a0Phil Burk int32_t getSampleRate() const { 67629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 68629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 69629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 70753c9f326b9505004576996091a64a43271634a0Phil Burk return AAudioStream_getSampleRate(mStream); 71629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 72629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 73629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 74629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Only call this after open() has been called. 75629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 76fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk int32_t getChannelCount() { 77629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 78629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 79629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 802829428ff26be1e1a33d161a54e3f988a1299db9Glenn Kasten return AAudioStream_getChannelCount(mStream);; 81629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 82fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk 83fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk /** 84fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk * @deprecated use getChannelCount() 85fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk */ 86fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk int32_t getSamplesPerFrame() { 87fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk return getChannelCount(); 88fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk } 89fcf9efd59e36759ee7df66fdfce4f8eedeb376e4Phil Burk 90629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 91629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Only call this after open() has been called. 92629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 93629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int64_t getFramesRead() { 94629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 95629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 96629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 97753c9f326b9505004576996091a64a43271634a0Phil Burk return AAudioStream_getFramesRead(mStream); 98753c9f326b9505004576996091a64a43271634a0Phil Burk } 99753c9f326b9505004576996091a64a43271634a0Phil Burk 100753c9f326b9505004576996091a64a43271634a0Phil Burk aaudio_result_t open(const AAudioParameters ¶meters, 101753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_dataCallback dataCallback = nullptr, 102753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_errorCallback errorCallback = nullptr, 103753c9f326b9505004576996091a64a43271634a0Phil Burk void *userContext = nullptr) { 104753c9f326b9505004576996091a64a43271634a0Phil Burk aaudio_result_t result = AAUDIO_OK; 105753c9f326b9505004576996091a64a43271634a0Phil Burk 106753c9f326b9505004576996091a64a43271634a0Phil Burk // Use an AAudioStreamBuilder to contain requested parameters. 107753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder *builder = nullptr; 108753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudio_createStreamBuilder(&builder); 109753c9f326b9505004576996091a64a43271634a0Phil Burk if (result != AAUDIO_OK) return result; 110753c9f326b9505004576996091a64a43271634a0Phil Burk 111753c9f326b9505004576996091a64a43271634a0Phil Burk parameters.applyParameters(builder); // apply args 112753c9f326b9505004576996091a64a43271634a0Phil Burk 113753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_INPUT); 114753c9f326b9505004576996091a64a43271634a0Phil Burk 115753c9f326b9505004576996091a64a43271634a0Phil Burk if (dataCallback != nullptr) { 116753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDataCallback(builder, dataCallback, userContext); 117753c9f326b9505004576996091a64a43271634a0Phil Burk } 118753c9f326b9505004576996091a64a43271634a0Phil Burk if (errorCallback != nullptr) { 119753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setErrorCallback(builder, errorCallback, userContext); 120753c9f326b9505004576996091a64a43271634a0Phil Burk } 121753c9f326b9505004576996091a64a43271634a0Phil Burk 122753c9f326b9505004576996091a64a43271634a0Phil Burk // Open an AAudioStream using the Builder. 123753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudioStreamBuilder_openStream(builder, &mStream); 124753c9f326b9505004576996091a64a43271634a0Phil Burk if (result != AAUDIO_OK) { 125753c9f326b9505004576996091a64a43271634a0Phil Burk fprintf(stderr, "ERROR - AAudioStreamBuilder_openStream() returned %d %s\n", 126753c9f326b9505004576996091a64a43271634a0Phil Burk result, AAudio_convertResultToText(result)); 127753c9f326b9505004576996091a64a43271634a0Phil Burk } 128753c9f326b9505004576996091a64a43271634a0Phil Burk 129753c9f326b9505004576996091a64a43271634a0Phil Burk if (result == AAUDIO_OK) { 130753c9f326b9505004576996091a64a43271634a0Phil Burk int32_t sizeInBursts = parameters.getNumberOfBursts(); 131753c9f326b9505004576996091a64a43271634a0Phil Burk if (sizeInBursts > 0) { 132753c9f326b9505004576996091a64a43271634a0Phil Burk int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mStream); 133753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_setBufferSizeInFrames(mStream, sizeInBursts * framesPerBurst); 134753c9f326b9505004576996091a64a43271634a0Phil Burk } 135753c9f326b9505004576996091a64a43271634a0Phil Burk } 136753c9f326b9505004576996091a64a43271634a0Phil Burk 137753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_delete(builder); 138753c9f326b9505004576996091a64a43271634a0Phil Burk return result; 139629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 140629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 141629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 142629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Open a stream 143629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 144629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t open(int channelCount, int sampSampleRate, aaudio_format_t format, 145753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_dataCallback dataProc, 146753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_errorCallback errorProc, 147629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userContext) { 148629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAUDIO_OK; 149629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 150629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Use an AAudioStreamBuilder to contain requested parameters. 151753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder *builder = nullptr; 152753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudio_createStreamBuilder(&builder); 153629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) return result; 154629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 155753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_INPUT); 156753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setPerformanceMode(builder, mRequestedPerformanceMode); 157753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setSharingMode(builder, mRequestedSharingMode); 158629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (dataProc != nullptr) { 159753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDataCallback(builder, dataProc, userContext); 160629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 161629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (errorProc != nullptr) { 162753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setErrorCallback(builder, errorProc, userContext); 163629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 164753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setChannelCount(builder, channelCount); 165753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setSampleRate(builder, sampSampleRate); 166753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setFormat(builder, format); 167629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 168629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Open an AAudioStream using the Builder. 169753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudioStreamBuilder_openStream(builder, &mStream); 170629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 171629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStreamBuilder_openStream() returned %d %s\n", 172629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 173629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 174629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 175753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_delete(builder); 176629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 177629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 178629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 179629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t close() { 180629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream != nullptr) { 181629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_close(mStream); 182629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mStream = nullptr; 183629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 184629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_OK; 185629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 186629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 187629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Write zero data to fill up the buffer and prevent underruns. 188629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t prime() { 1892829428ff26be1e1a33d161a54e3f988a1299db9Glenn Kasten int32_t samplesPerFrame = AAudioStream_getChannelCount(mStream); 190629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent const int numFrames = 32; // arbitrary 191629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float zeros[numFrames * samplesPerFrame]; 192629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent memset(zeros, 0, sizeof(zeros)); 193629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = numFrames; 194629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent while (result == numFrames) { 195629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result = AAudioStream_write(mStream, zeros, numFrames, 0); 196629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 197629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 198629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 199629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 200629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Start the stream. AAudio will start calling your callback function. 201629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t start() { 202629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestStart(mStream); 203629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 204629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d %s\n", 205629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 206629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 207629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 208629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 209629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 210629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Stop the stream. AAudio will stop calling your callback function. 211629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t stop() { 212629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestStop(mStream); 213629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 214629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStream_requestStop() returned %d %s\n", 215629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 216629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 217629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 218629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 219629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 220629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Pause the stream. AAudio will stop calling your callback function. 221629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t pause() { 222629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestPause(mStream); 223629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 224629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStream_requestPause() returned %d %s\n", 225629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 226629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 227629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 228629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 229629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 230629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *getStream() const { 231629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return mStream; 232629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 233629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 234629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentprivate: 235629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *mStream = nullptr; 236629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_sharing_mode_t mRequestedSharingMode = SHARING_MODE; 237629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_performance_mode_t mRequestedPerformanceMode = PERFORMANCE_MODE; 238629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent}; 239629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 240629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent// Application data that gets passed to the callback. 241629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurenttypedef struct PeakTrackerData { 242629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float peakLevel; 243629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} PeakTrackerData_t; 244629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 245629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define DECAY_FACTOR 0.999 246629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 247629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent// Callback function that fills the audio output buffer. 248629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentaaudio_data_callback_result_t SimpleRecorderDataCallbackProc( 249629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *stream, 250629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userData, 251629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *audioData, 252629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t numFrames 253629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent ) { 254629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 255629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // should not happen but just in case... 256629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (userData == nullptr) { 257629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - SimpleRecorderDataCallbackProc needs userData\n"); 258629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_STOP; 259629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 260629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent PeakTrackerData_t *data = (PeakTrackerData_t *) userData; 261629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // printf("MyCallbackProc(): frameCount = %d\n", numFrames); 2622829428ff26be1e1a33d161a54e3f988a1299db9Glenn Kasten int32_t samplesPerFrame = AAudioStream_getChannelCount(stream); 263629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float sample; 264629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // This code assume mono or stereo. 265629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent switch (AAudioStream_getFormat(stream)) { 266629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent case AAUDIO_FORMAT_PCM_I16: { 267629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int16_t *audioBuffer = (int16_t *) audioData; 268629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Peak follower 269629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 270629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sample = audioBuffer[frameIndex * samplesPerFrame] * (1.0/32768); 271629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel *= DECAY_FACTOR; 272629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (sample > data->peakLevel) { 273629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel = sample; 274629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 275629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 276629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 277629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent break; 278629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent case AAUDIO_FORMAT_PCM_FLOAT: { 279629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float *audioBuffer = (float *) audioData; 280629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Peak follower 281629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 282629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sample = audioBuffer[frameIndex * samplesPerFrame]; 283629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel *= DECAY_FACTOR; 284629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (sample > data->peakLevel) { 285629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel = sample; 286629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 287629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 288629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 289629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent break; 290629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent default: 291629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_STOP; 292629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 293629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 294629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_CONTINUE; 295629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} 296629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 297629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentvoid SimpleRecorderErrorCallbackProc( 298629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *stream __unused, 299629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userData __unused, 300629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t error) 301629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent{ 302629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("Error Callback, error: %d\n",(int)error); 303629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} 304629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 305629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#endif //AAUDIO_SIMPLE_RECORDER_H 306