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 // Play silence and recover from dead servers or disconnected devices.
18 
19 #include <stdio.h>
20 
21 #include <aaudio/AAudio.h>
22 
23 
24 #define DEFAULT_TIMEOUT_NANOS  ((int64_t)1000000000)
25 
main(int argc,char ** argv)26 int main(int argc, char **argv) {
27     (void) argc;
28     (void) argv;
29 
30     aaudio_result_t result = AAUDIO_OK;
31 
32     int32_t triesLeft = 3;
33     int32_t bufferCapacity;
34     int32_t framesPerBurst = 0;
35     float *buffer = nullptr;
36 
37     int32_t actualChannelCount = 0;
38     int32_t actualSampleRate = 0;
39     aaudio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_FLOAT;
40 
41     AAudioStreamBuilder *aaudioBuilder = nullptr;
42     AAudioStream *aaudioStream = nullptr;
43 
44     // Make printf print immediately so that debug info is not stuck
45     // in a buffer if we hang or crash.
46     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
47 
48     printf("TestRecovery:\n");
49 
50     // Use an AAudioStreamBuilder to contain requested parameters.
51     result = AAudio_createStreamBuilder(&aaudioBuilder);
52     if (result != AAUDIO_OK) {
53         printf("AAudio_createStreamBuilder returned %s",
54                AAudio_convertResultToText(result));
55         goto finish;
56     }
57 
58     // Request stream properties.
59     AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
60 
61     while (triesLeft-- > 0) {
62         // Create an AAudioStream using the Builder.
63         result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
64         if (result != AAUDIO_OK) {
65             printf("AAudioStreamBuilder_openStream returned %s",
66                    AAudio_convertResultToText(result));
67             goto finish;
68         }
69 
70         // Check to see what kind of stream we actually got.
71         actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
72         actualChannelCount = AAudioStream_getChannelCount(aaudioStream);
73         actualDataFormat = AAudioStream_getFormat(aaudioStream);
74 
75         printf("-------- chans = %3d, rate = %6d format = %d\n",
76                 actualChannelCount, actualSampleRate, actualDataFormat);
77 
78         // This is the number of frames that are read in one chunk by a DMA controller
79         // or a DSP or a mixer.
80         framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
81         bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
82         printf("         bufferCapacity = %d, framesPerBurst = %d\n",
83         bufferCapacity, framesPerBurst);
84 
85         int samplesPerBurst = framesPerBurst * actualChannelCount;
86         buffer = new float[samplesPerBurst];
87 
88         result = AAudioStream_requestStart(aaudioStream);
89         if (result != AAUDIO_OK) {
90             printf("AAudioStream_requestStart returned %s",
91                    AAudio_convertResultToText(result));
92             goto finish;
93         }
94 
95         // Play silence for awhile.
96         int32_t framesMax = actualSampleRate * 20;
97         int64_t framesTotal = 0;
98         int64_t printAt = actualSampleRate;
99         while (result == AAUDIO_OK && framesTotal < framesMax) {
100             int32_t framesWritten = AAudioStream_write(aaudioStream,
101                                                        buffer, framesPerBurst,
102                                                        DEFAULT_TIMEOUT_NANOS);
103             if (framesWritten < 0) {
104                 result = framesWritten;
105                 printf("write() returned %s, frames = %d\n",
106                        AAudio_convertResultToText(result), (int)framesTotal);
107                 printf("  frames = %d\n", (int)framesTotal);
108             } else if (framesWritten != framesPerBurst) {
109                 printf("write() returned %d, frames = %d\n", framesWritten, (int)framesTotal);
110                 result = AAUDIO_ERROR_TIMEOUT;
111             } else {
112                 framesTotal += framesWritten;
113                 if (framesTotal >= printAt) {
114                     printf("frames = %d\n", (int)framesTotal);
115                     printAt += actualSampleRate;
116                 }
117             }
118         }
119         result = AAudioStream_requestStop(aaudioStream);
120         if (result != AAUDIO_OK) {
121             printf("AAudioStream_requestStop returned %s\n",
122                    AAudio_convertResultToText(result));
123         }
124         result = AAudioStream_close(aaudioStream);
125         if (result != AAUDIO_OK) {
126             printf("AAudioStream_close returned %s\n",
127                    AAudio_convertResultToText(result));
128         }
129         aaudioStream = nullptr;
130     }
131 
132 finish:
133     if (aaudioStream != nullptr) {
134         AAudioStream_close(aaudioStream);
135     }
136     AAudioStreamBuilder_delete(aaudioBuilder);
137     delete[] buffer;
138     printf("          result = %d = %s\n", result, AAudio_convertResultToText(result));
139 }
140