AAudioSimpleRecorder.h revision 753c9f326b9505004576996091a64a43271634a0
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 */ 76629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t getSamplesPerFrame() { 77629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 78629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 79629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 802829428ff26be1e1a33d161a54e3f988a1299db9Glenn Kasten return AAudioStream_getChannelCount(mStream);; 81629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 82629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 83629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Only call this after open() has been called. 84629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 85629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int64_t getFramesRead() { 86629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream == nullptr) { 87629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_ERROR_INVALID_STATE; 88629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 89753c9f326b9505004576996091a64a43271634a0Phil Burk return AAudioStream_getFramesRead(mStream); 90753c9f326b9505004576996091a64a43271634a0Phil Burk } 91753c9f326b9505004576996091a64a43271634a0Phil Burk 92753c9f326b9505004576996091a64a43271634a0Phil Burk aaudio_result_t open(const AAudioParameters ¶meters, 93753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_dataCallback dataCallback = nullptr, 94753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_errorCallback errorCallback = nullptr, 95753c9f326b9505004576996091a64a43271634a0Phil Burk void *userContext = nullptr) { 96753c9f326b9505004576996091a64a43271634a0Phil Burk aaudio_result_t result = AAUDIO_OK; 97753c9f326b9505004576996091a64a43271634a0Phil Burk 98753c9f326b9505004576996091a64a43271634a0Phil Burk // Use an AAudioStreamBuilder to contain requested parameters. 99753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder *builder = nullptr; 100753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudio_createStreamBuilder(&builder); 101753c9f326b9505004576996091a64a43271634a0Phil Burk if (result != AAUDIO_OK) return result; 102753c9f326b9505004576996091a64a43271634a0Phil Burk 103753c9f326b9505004576996091a64a43271634a0Phil Burk parameters.applyParameters(builder); // apply args 104753c9f326b9505004576996091a64a43271634a0Phil Burk 105753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_INPUT); 106753c9f326b9505004576996091a64a43271634a0Phil Burk 107753c9f326b9505004576996091a64a43271634a0Phil Burk if (dataCallback != nullptr) { 108753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDataCallback(builder, dataCallback, userContext); 109753c9f326b9505004576996091a64a43271634a0Phil Burk } 110753c9f326b9505004576996091a64a43271634a0Phil Burk if (errorCallback != nullptr) { 111753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setErrorCallback(builder, errorCallback, userContext); 112753c9f326b9505004576996091a64a43271634a0Phil Burk } 113753c9f326b9505004576996091a64a43271634a0Phil Burk 114753c9f326b9505004576996091a64a43271634a0Phil Burk // Open an AAudioStream using the Builder. 115753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudioStreamBuilder_openStream(builder, &mStream); 116753c9f326b9505004576996091a64a43271634a0Phil Burk if (result != AAUDIO_OK) { 117753c9f326b9505004576996091a64a43271634a0Phil Burk fprintf(stderr, "ERROR - AAudioStreamBuilder_openStream() returned %d %s\n", 118753c9f326b9505004576996091a64a43271634a0Phil Burk result, AAudio_convertResultToText(result)); 119753c9f326b9505004576996091a64a43271634a0Phil Burk } 120753c9f326b9505004576996091a64a43271634a0Phil Burk 121753c9f326b9505004576996091a64a43271634a0Phil Burk if (result == AAUDIO_OK) { 122753c9f326b9505004576996091a64a43271634a0Phil Burk int32_t sizeInBursts = parameters.getNumberOfBursts(); 123753c9f326b9505004576996091a64a43271634a0Phil Burk if (sizeInBursts > 0) { 124753c9f326b9505004576996091a64a43271634a0Phil Burk int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mStream); 125753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_setBufferSizeInFrames(mStream, sizeInBursts * framesPerBurst); 126753c9f326b9505004576996091a64a43271634a0Phil Burk } 127753c9f326b9505004576996091a64a43271634a0Phil Burk } 128753c9f326b9505004576996091a64a43271634a0Phil Burk 129753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_delete(builder); 130753c9f326b9505004576996091a64a43271634a0Phil Burk return result; 131629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 132629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 133629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent /** 134629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent * Open a stream 135629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent */ 136629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t open(int channelCount, int sampSampleRate, aaudio_format_t format, 137753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_dataCallback dataProc, 138753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStream_errorCallback errorProc, 139629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userContext) { 140629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAUDIO_OK; 141629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 142629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Use an AAudioStreamBuilder to contain requested parameters. 143753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder *builder = nullptr; 144753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudio_createStreamBuilder(&builder); 145629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) return result; 146629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 147753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_INPUT); 148753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setPerformanceMode(builder, mRequestedPerformanceMode); 149753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setSharingMode(builder, mRequestedSharingMode); 150629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (dataProc != nullptr) { 151753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setDataCallback(builder, dataProc, userContext); 152629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 153629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (errorProc != nullptr) { 154753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setErrorCallback(builder, errorProc, userContext); 155629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 156753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setChannelCount(builder, channelCount); 157753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setSampleRate(builder, sampSampleRate); 158753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_setFormat(builder, format); 159629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 160629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Open an AAudioStream using the Builder. 161753c9f326b9505004576996091a64a43271634a0Phil Burk result = AAudioStreamBuilder_openStream(builder, &mStream); 162629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 163629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStreamBuilder_openStream() returned %d %s\n", 164629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 165629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 166629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 167753c9f326b9505004576996091a64a43271634a0Phil Burk AAudioStreamBuilder_delete(builder); 168629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 169629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 170629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 171629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t close() { 172629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (mStream != nullptr) { 173629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("call AAudioStream_close(%p)\n", mStream); fflush(stdout); 174629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream_close(mStream); 175629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent mStream = nullptr; 176629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 177629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_OK; 178629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 179629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 180629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Write zero data to fill up the buffer and prevent underruns. 181629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t prime() { 1822829428ff26be1e1a33d161a54e3f988a1299db9Glenn Kasten int32_t samplesPerFrame = AAudioStream_getChannelCount(mStream); 183629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent const int numFrames = 32; // arbitrary 184629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float zeros[numFrames * samplesPerFrame]; 185629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent memset(zeros, 0, sizeof(zeros)); 186629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = numFrames; 187629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent while (result == numFrames) { 188629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result = AAudioStream_write(mStream, zeros, numFrames, 0); 189629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 190629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 191629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 192629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 193629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Start the stream. AAudio will start calling your callback function. 194629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t start() { 195629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestStart(mStream); 196629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 197629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d %s\n", 198629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 199629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 200629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 201629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 202629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 203629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Stop the stream. AAudio will stop calling your callback function. 204629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t stop() { 205629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestStop(mStream); 206629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 207629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStream_requestStop() returned %d %s\n", 208629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 209629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 210629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 211629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 212629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 213629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Pause the stream. AAudio will stop calling your callback function. 214629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t pause() { 215629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t result = AAudioStream_requestPause(mStream); 216629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (result != AAUDIO_OK) { 217629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - AAudioStream_requestPause() returned %d %s\n", 218629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent result, AAudio_convertResultToText(result)); 219629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 220629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return result; 221629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 222629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 223629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *getStream() const { 224629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return mStream; 225629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 226629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 227629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentprivate: 228629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *mStream = nullptr; 229629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_sharing_mode_t mRequestedSharingMode = SHARING_MODE; 230629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_performance_mode_t mRequestedPerformanceMode = PERFORMANCE_MODE; 231629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent}; 232629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 233629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent// Application data that gets passed to the callback. 234629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurenttypedef struct PeakTrackerData { 235629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float peakLevel; 236629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} PeakTrackerData_t; 237629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 238629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#define DECAY_FACTOR 0.999 239629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 240629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent// Callback function that fills the audio output buffer. 241629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentaaudio_data_callback_result_t SimpleRecorderDataCallbackProc( 242629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *stream, 243629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userData, 244629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *audioData, 245629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int32_t numFrames 246629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent ) { 247629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 248629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // should not happen but just in case... 249629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (userData == nullptr) { 250629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent fprintf(stderr, "ERROR - SimpleRecorderDataCallbackProc needs userData\n"); 251629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_STOP; 252629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 253629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent PeakTrackerData_t *data = (PeakTrackerData_t *) userData; 254629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // printf("MyCallbackProc(): frameCount = %d\n", numFrames); 2552829428ff26be1e1a33d161a54e3f988a1299db9Glenn Kasten int32_t samplesPerFrame = AAudioStream_getChannelCount(stream); 256629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float sample; 257629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // This code assume mono or stereo. 258629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent switch (AAudioStream_getFormat(stream)) { 259629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent case AAUDIO_FORMAT_PCM_I16: { 260629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent int16_t *audioBuffer = (int16_t *) audioData; 261629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Peak follower 262629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 263629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sample = audioBuffer[frameIndex * samplesPerFrame] * (1.0/32768); 264629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel *= DECAY_FACTOR; 265629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (sample > data->peakLevel) { 266629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel = sample; 267629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 268629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 269629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 270629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent break; 271629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent case AAUDIO_FORMAT_PCM_FLOAT: { 272629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent float *audioBuffer = (float *) audioData; 273629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent // Peak follower 274629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 275629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent sample = audioBuffer[frameIndex * samplesPerFrame]; 276629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel *= DECAY_FACTOR; 277629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent if (sample > data->peakLevel) { 278629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent data->peakLevel = sample; 279629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 280629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 281629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 282629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent break; 283629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent default: 284629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_STOP; 285629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent } 286629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 287629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent return AAUDIO_CALLBACK_RESULT_CONTINUE; 288629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} 289629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 290629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurentvoid SimpleRecorderErrorCallbackProc( 291629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent AAudioStream *stream __unused, 292629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent void *userData __unused, 293629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent aaudio_result_t error) 294629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent{ 295629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent printf("Error Callback, error: %d\n",(int)error); 296629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent} 297629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent 298629afae6135e6dc1e88ab4080f984fb30b3cdd7cEric Laurent#endif //AAUDIO_SIMPLE_RECORDER_H 299