1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// Record input using AAudio and display the peak amplitudes. 18 19#include <assert.h> 20#include <unistd.h> 21#include <stdlib.h> 22#include <stdio.h> 23#include <math.h> 24#include <time.h> 25#include <aaudio/AAudio.h> 26#include "AAudioExampleUtils.h" 27#include "AAudioSimpleRecorder.h" 28 29int main(int argc, const char **argv) 30{ 31 AAudioArgsParser argParser; 32 AAudioSimpleRecorder recorder; 33 PeakTrackerData_t myData = {0.0}; 34 AAudioStream *aaudioStream = nullptr; 35 aaudio_result_t result; 36 aaudio_stream_state_t state; 37 38 int loopsNeeded = 0; 39 const int displayRateHz = 20; // arbitrary 40 41 // Make printf print immediately so that debug info is not stuck 42 // in a buffer if we hang or crash. 43 setvbuf(stdout, nullptr, _IONBF, (size_t) 0); 44 printf("%s - Display audio input using an AAudio callback, V0.1.3\n", argv[0]); 45 46 if (argParser.parseArgs(argc, argv)) { 47 return EXIT_FAILURE; 48 } 49 50 result = recorder.open(argParser, 51 SimpleRecorderDataCallbackProc, 52 SimpleRecorderErrorCallbackProc, 53 &myData); 54 if (result != AAUDIO_OK) { 55 fprintf(stderr, "ERROR - recorder.open() returned %d\n", result); 56 printf("IMPORTANT - Did you remember to enter: adb root\n"); 57 goto error; 58 } 59 aaudioStream = recorder.getStream(); 60 argParser.compareWithStream(aaudioStream); 61 62 printf("recorder.getFramesPerSecond() = %d\n", recorder.getFramesPerSecond()); 63 printf("recorder.getSamplesPerFrame() = %d\n", recorder.getSamplesPerFrame()); 64 65 result = recorder.start(); 66 if (result != AAUDIO_OK) { 67 fprintf(stderr, "ERROR - recorder.start() returned %d\n", result); 68 goto error; 69 } 70 71 printf("Sleep for %d seconds while audio record in a callback thread.\n", 72 argParser.getDurationSeconds()); 73 loopsNeeded = argParser.getDurationSeconds() * displayRateHz; 74 for (int i = 0; i < loopsNeeded; i++) 75 { 76 const struct timespec request = { .tv_sec = 0, 77 .tv_nsec = NANOS_PER_SECOND / displayRateHz }; 78 (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); 79 printf("%08d: ", (int)recorder.getFramesRead()); 80 displayPeakLevel(myData.peakLevel); 81 82 result = AAudioStream_waitForStateChange(aaudioStream, 83 AAUDIO_STREAM_STATE_CLOSED, 84 &state, 85 0); 86 if (result != AAUDIO_OK) { 87 fprintf(stderr, "ERROR - AAudioStream_waitForStateChange() returned %d\n", result); 88 goto error; 89 } 90 if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { 91 printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); 92 break; 93 } 94 } 95 printf("Woke up. Stop for a moment.\n"); 96 97 result = recorder.stop(); 98 if (result != AAUDIO_OK) { 99 goto error; 100 } 101 usleep(2000 * 1000); 102 result = recorder.start(); 103 if (result != AAUDIO_OK) { 104 fprintf(stderr, "ERROR - recorder.start() returned %d\n", result); 105 goto error; 106 } 107 108 printf("Sleep for %d seconds while audio records in a callback thread.\n", 109 argParser.getDurationSeconds()); 110 for (int i = 0; i < loopsNeeded; i++) 111 { 112 const struct timespec request = { .tv_sec = 0, 113 .tv_nsec = NANOS_PER_SECOND / displayRateHz }; 114 (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); 115 printf("%08d: ", (int)recorder.getFramesRead()); 116 displayPeakLevel(myData.peakLevel); 117 118 state = AAudioStream_getState(aaudioStream); 119 if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { 120 printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); 121 break; 122 } 123 } 124 printf("Woke up now.\n"); 125 argParser.compareWithStream(aaudioStream); 126 127 result = recorder.stop(); 128 if (result != AAUDIO_OK) { 129 goto error; 130 } 131 result = recorder.close(); 132 if (result != AAUDIO_OK) { 133 goto error; 134 } 135 136 printf("SUCCESS\n"); 137 return EXIT_SUCCESS; 138error: 139 recorder.close(); 140 printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); 141 return EXIT_FAILURE; 142} 143 144