test_timestamps.cpp revision 97350f9df7252c881f011a410fcd9e6d766d2bee
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#include <unistd.h>
21
22#include <aaudio/AAudio.h>
23#include <aaudio/AAudioTesting.h>
24
25#include "utils/AAudioExampleUtils.h"
26
27#define DEFAULT_TIMEOUT_NANOS  ((int64_t)1000000000)
28
29int main(int argc, char **argv) {
30    (void) argc;
31    (void *)argv;
32
33    aaudio_result_t result = AAUDIO_OK;
34
35    int32_t triesLeft = 3;
36    int32_t bufferCapacity;
37    int32_t framesPerBurst = 0;
38    float *buffer = nullptr;
39
40    int32_t actualChannelCount = 0;
41    int32_t actualSampleRate = 0;
42    int32_t originalBufferSize = 0;
43    int32_t requestedBufferSize = 0;
44    int32_t finalBufferSize = 0;
45    aaudio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_FLOAT;
46    aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
47    int32_t framesMax;
48    int64_t framesTotal;
49    int64_t printAt;
50    int samplesPerBurst;
51    int64_t previousFramePosition = -1;
52
53    AAudioStreamBuilder *aaudioBuilder = nullptr;
54    AAudioStream *aaudioStream = nullptr;
55
56    // Make printf print immediately so that debug info is not stuck
57    // in a buffer if we hang or crash.
58    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
59
60    printf("Test Timestamps V0.1.1\n");
61
62    AAudio_setMMapPolicy(AAUDIO_POLICY_AUTO);
63
64    // Use an AAudioStreamBuilder to contain requested parameters.
65    result = AAudio_createStreamBuilder(&aaudioBuilder);
66    if (result != AAUDIO_OK) {
67        printf("AAudio_createStreamBuilder returned %s",
68               AAudio_convertResultToText(result));
69        goto finish;
70    }
71
72    // Request stream properties.
73    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
74    //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_NONE);
75    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
76
77    // Create an AAudioStream using the Builder.
78    result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
79    if (result != AAUDIO_OK) {
80        printf("AAudioStreamBuilder_openStream returned %s",
81               AAudio_convertResultToText(result));
82        goto finish;
83    }
84
85    // Check to see what kind of stream we actually got.
86    actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
87    actualChannelCount = AAudioStream_getChannelCount(aaudioStream);
88    actualDataFormat = AAudioStream_getFormat(aaudioStream);
89
90    printf("-------- chans = %3d, rate = %6d format = %d\n",
91            actualChannelCount, actualSampleRate, actualDataFormat);
92    printf("    Is MMAP used? %s\n", AAudioStream_isMMapUsed(aaudioStream)
93                                   ? "yes" : "no");
94
95    // This is the number of frames that are read in one chunk by a DMA controller
96    // or a DSP or a mixer.
97    framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
98    printf("    framesPerBurst = %3d\n", framesPerBurst);
99
100    originalBufferSize = AAudioStream_getBufferSizeInFrames(aaudioStream);
101    requestedBufferSize = 2 * framesPerBurst;
102    finalBufferSize = AAudioStream_setBufferSizeInFrames(aaudioStream, requestedBufferSize);
103
104    printf("    BufferSize: original = %4d, requested = %4d, final = %4d\n",
105           originalBufferSize, requestedBufferSize, finalBufferSize);
106
107    samplesPerBurst = framesPerBurst * actualChannelCount;
108    buffer = new float[samplesPerBurst];
109
110    result = AAudioStream_requestStart(aaudioStream);
111    if (result != AAUDIO_OK) {
112        printf("AAudioStream_requestStart returned %s",
113               AAudio_convertResultToText(result));
114        goto finish;
115    }
116
117    // Play silence very briefly.
118    framesMax = actualSampleRate * 4;
119    framesTotal = 0;
120    printAt = actualSampleRate;
121    while (result == AAUDIO_OK && framesTotal < framesMax) {
122        int32_t framesWritten = AAudioStream_write(aaudioStream,
123                                                   buffer, framesPerBurst,
124                                                   DEFAULT_TIMEOUT_NANOS);
125        if (framesWritten < 0) {
126            result = framesWritten;
127            printf("write() returned %s, frames = %d\n",
128                   AAudio_convertResultToText(result), (int)framesTotal);
129            printf("  frames = %d\n", (int)framesTotal);
130        } else if (framesWritten != framesPerBurst) {
131            printf("write() returned %d, frames = %d\n", framesWritten, (int)framesTotal);
132            result = AAUDIO_ERROR_TIMEOUT;
133        } else {
134            framesTotal += framesWritten;
135            if (framesTotal >= printAt) {
136                printf("frames = %d\n", (int)framesTotal);
137                printAt += actualSampleRate;
138            }
139        }
140
141        // Print timestamps.
142        int64_t framePosition = 0;
143        int64_t frameTime = 0;
144        aaudio_result_t timeResult;
145        timeResult = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
146                                           &framePosition, &frameTime);
147
148        if (timeResult == AAUDIO_OK) {
149            if (framePosition > (previousFramePosition + 5000)) {
150                int64_t realTime = getNanoseconds();
151                int64_t framesWritten = AAudioStream_getFramesWritten(aaudioStream);
152
153                double latencyMillis = calculateLatencyMillis(framePosition, frameTime,
154                                                              framesWritten, realTime,
155                                                              actualSampleRate);
156
157                printf("--- timestamp: result = %4d, position = %lld, at %lld nanos"
158                               ", latency = %7.2f msec\n",
159                       timeResult,
160                       (long long) framePosition,
161                       (long long) frameTime,
162                       latencyMillis);
163                previousFramePosition = framePosition;
164            }
165        }
166    }
167
168    result = AAudioStream_requestStop(aaudioStream);
169    if (result != AAUDIO_OK) {
170        printf("AAudioStream_requestStop returned %s\n",
171               AAudio_convertResultToText(result));
172    }
173    result = AAudioStream_close(aaudioStream);
174    if (result != AAUDIO_OK) {
175        printf("AAudioStream_close returned %s\n",
176               AAudio_convertResultToText(result));
177    }
178    aaudioStream = nullptr;
179
180
181finish:
182    if (aaudioStream != nullptr) {
183        AAudioStream_close(aaudioStream);
184    }
185    AAudioStreamBuilder_delete(aaudioBuilder);
186    delete[] buffer;
187    printf("result = %d = %s\n", result, AAudio_convertResultToText(result));
188}
189