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 29 #define NUM_SECONDS 5 30 31 int main(int argc, char **argv) 32 { 33 (void)argc; // unused 34 AAudioSimpleRecorder recorder; 35 PeakTrackerData_t myData = {0.0}; 36 aaudio_result_t result; 37 aaudio_stream_state_t state; 38 const int displayRateHz = 20; // arbitrary 39 const int loopsNeeded = NUM_SECONDS * displayRateHz; 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.2\n", argv[0]); 45 46 result = recorder.open(2, 48000, AAUDIO_FORMAT_PCM_I16, 47 SimpleRecorderDataCallbackProc, SimpleRecorderErrorCallbackProc, &myData); 48 if (result != AAUDIO_OK) { 49 fprintf(stderr, "ERROR - recorder.open() returned %d\n", result); 50 goto error; 51 } 52 printf("recorder.getFramesPerSecond() = %d\n", recorder.getFramesPerSecond()); 53 printf("recorder.getSamplesPerFrame() = %d\n", recorder.getSamplesPerFrame()); 54 55 result = recorder.start(); 56 if (result != AAUDIO_OK) { 57 fprintf(stderr, "ERROR - recorder.start() returned %d\n", result); 58 goto error; 59 } 60 61 printf("Sleep for %d seconds while audio record in a callback thread.\n", NUM_SECONDS); 62 for (int i = 0; i < loopsNeeded; i++) 63 { 64 const struct timespec request = { .tv_sec = 0, 65 .tv_nsec = NANOS_PER_SECOND / displayRateHz }; 66 (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); 67 printf("%08d: ", (int)recorder.getFramesRead()); 68 displayPeakLevel(myData.peakLevel); 69 70 result = AAudioStream_waitForStateChange(recorder.getStream(), 71 AAUDIO_STREAM_STATE_CLOSED, 72 &state, 73 0); 74 if (result != AAUDIO_OK) { 75 fprintf(stderr, "ERROR - AAudioStream_waitForStateChange() returned %d\n", result); 76 goto error; 77 } 78 if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { 79 printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); 80 break; 81 } 82 } 83 printf("Woke up. Stop for a moment.\n"); 84 85 result = recorder.stop(); 86 if (result != AAUDIO_OK) { 87 goto error; 88 } 89 usleep(2000 * 1000); 90 result = recorder.start(); 91 if (result != AAUDIO_OK) { 92 fprintf(stderr, "ERROR - recorder.start() returned %d\n", result); 93 goto error; 94 } 95 96 printf("Sleep for %d seconds while audio records in a callback thread.\n", NUM_SECONDS); 97 for (int i = 0; i < loopsNeeded; i++) 98 { 99 const struct timespec request = { .tv_sec = 0, 100 .tv_nsec = NANOS_PER_SECOND / displayRateHz }; 101 (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); 102 printf("%08d: ", (int)recorder.getFramesRead()); 103 displayPeakLevel(myData.peakLevel); 104 105 state = AAudioStream_getState(recorder.getStream()); 106 if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { 107 printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); 108 break; 109 } 110 } 111 printf("Woke up now.\n"); 112 113 result = recorder.stop(); 114 if (result != AAUDIO_OK) { 115 goto error; 116 } 117 result = recorder.close(); 118 if (result != AAUDIO_OK) { 119 goto error; 120 } 121 122 printf("SUCCESS\n"); 123 return EXIT_SUCCESS; 124 error: 125 recorder.close(); 126 printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); 127 return EXIT_FAILURE; 128 } 129 130