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