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
main(int argc,char ** argv)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\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