test_create_audiotrack.cpp revision 4473d78d092ffc442edeaed022c7e56366e1c504
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/** 18 * Handle a DISCONNECT by only opening and starting a new stream 19 * without stopping and closing the old one. 20 * This caused the new stream to use the old disconnected device. 21 */ 22 23#include <fcntl.h> 24#include <stdio.h> 25#include <string.h> 26#include <unistd.h> 27 28#include <binder/MemoryBase.h> 29#include <binder/MemoryDealer.h> 30#include <binder/MemoryHeapBase.h> 31#include <media/AudioTrack.h> 32 33#define MAX_INPUT_FILE_LINE_LENGTH 512 34#define MAX_OUTPUT_FILE_LINE_LENGTH 512 35 36#define NUM_ARGUMENTS 10 37#define VERSION_KEY "version" 38#define VERSION_VALUE "1.0" 39 40namespace android { 41 42int readLine(FILE *inputFile, char *line, int size) { 43 int ret = 0; 44 while (true) { 45 char *str = fgets(line, size, inputFile); 46 if (str == nullptr) { 47 ret = -1; 48 break; 49 } 50 if (feof(inputFile) != 0 || ferror(inputFile) != 0) { 51 ret = -1; 52 break; 53 } 54 if (strlen(str) != 0 && str[0] != '#') { 55 break; 56 } 57 } 58 return ret; 59} 60 61bool checkVersion(FILE *inputFile) 62{ 63 char line[MAX_INPUT_FILE_LINE_LENGTH]; 64 char versionKey[MAX_INPUT_FILE_LINE_LENGTH]; 65 char versionValue[MAX_INPUT_FILE_LINE_LENGTH]; 66 67 if (readLine(inputFile, line, MAX_INPUT_FILE_LINE_LENGTH) != 0) { 68 fprintf(stderr, "Missing version in input file\n"); 69 return false; 70 } 71 72 if (sscanf(line, " %s %s", versionKey, versionValue) != 2) { 73 fprintf(stderr, "Malformed version in input file\n"); 74 return false; 75 } 76 if (strcmp(versionKey, VERSION_KEY) != 0) { 77 fprintf(stderr, "Malformed version in input file\n"); 78 return false; 79 } 80 if (strcmp(versionValue, VERSION_VALUE) != 0) { 81 fprintf(stderr, "Wrong input file version %s expecting %s\n", versionValue, VERSION_VALUE); 82 return false; 83 } 84 return true; 85} 86 87void callback(int event __unused, void* user __unused, void *info __unused) 88{ 89} 90 91void testTrack(FILE *inputFile, int outputFileFd) 92{ 93 char line[MAX_INPUT_FILE_LINE_LENGTH]; 94 uint32_t testCount = 0; 95 Vector<String16> args; 96 97 if (inputFile == nullptr) { 98 sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_DEFAULT, 99 0 /* sampleRate */, 100 AUDIO_FORMAT_DEFAULT, 101 AUDIO_CHANNEL_OUT_STEREO); 102 if (track == 0 || track->initCheck() != NO_ERROR) { 103 write(outputFileFd, "Error creating AudioTrack\n", 104 sizeof("Error creating AudioTrack\n")); 105 } else { 106 track->dump(outputFileFd, args); 107 } 108 return; 109 } 110 111 // check version 112 if (!checkVersion(inputFile)) { 113 return; 114 } 115 116 while (readLine(inputFile, line, MAX_INPUT_FILE_LINE_LENGTH) == 0) { 117 uint32_t sampleRate; 118 audio_format_t format; 119 audio_channel_mask_t channelMask; 120 size_t frameCount; 121 int32_t notificationFrames; 122 uint32_t useSharedBuffer; 123 audio_output_flags_t flags; 124 audio_session_t sessionId; 125 audio_usage_t usage; 126 audio_content_type_t contentType; 127 audio_attributes_t attributes; 128 sp<IMemory> sharedBuffer; 129 sp<MemoryDealer> heap; 130 audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 131 status_t status; 132 char statusStr[MAX_OUTPUT_FILE_LINE_LENGTH]; 133 bool offload = false; 134 bool fast = false; 135 136 if (sscanf(line, " %u %x %x %zu %d %u %x %u %u %u", 137 &sampleRate, &format, &channelMask, 138 &frameCount, ¬ificationFrames, &useSharedBuffer, 139 &flags, &sessionId, &usage, &contentType) != NUM_ARGUMENTS) { 140 fprintf(stderr, "Malformed line for test #%u in input file\n", testCount+1); 141 continue; 142 } 143 testCount++; 144 145 if (useSharedBuffer != 0) { 146 size_t heapSize = audio_channel_count_from_out_mask(channelMask) * 147 audio_bytes_per_sample(format) * frameCount; 148 heap = new MemoryDealer(heapSize, "AudioTrack Heap Base"); 149 sharedBuffer = heap->allocate(heapSize); 150 frameCount = 0; 151 notificationFrames = 0; 152 } 153 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 154 offloadInfo.sample_rate = sampleRate; 155 offloadInfo.channel_mask = channelMask; 156 offloadInfo.format = format; 157 offload = true; 158 } 159 if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) { 160 fast = true; 161 } 162 163 memset(&attributes, 0, sizeof(attributes)); 164 attributes.content_type = contentType; 165 attributes.usage = usage; 166 167 sp<AudioTrack> track = new AudioTrack(); 168 169 track->set(AUDIO_STREAM_DEFAULT, 170 sampleRate, 171 format, 172 channelMask, 173 frameCount, 174 flags, 175 (fast || offload) ? callback : nullptr, 176 nullptr, 177 notificationFrames, 178 sharedBuffer, 179 false, 180 sessionId, 181 ((fast && sharedBuffer == 0) || offload) ? 182 AudioTrack::TRANSFER_CALLBACK : AudioTrack::TRANSFER_DEFAULT, 183 offload ? &offloadInfo : nullptr, 184 getuid(), 185 getpid(), 186 &attributes, 187 false, 188 1.0f, 189 AUDIO_PORT_HANDLE_NONE); 190 status = track->initCheck(); 191 sprintf(statusStr, "\n#### Test %u status %d\n", testCount, status); 192 write(outputFileFd, statusStr, strlen(statusStr)); 193 if (status != NO_ERROR) { 194 continue; 195 } 196 track->dump(outputFileFd, args); 197 } 198} 199 200}; // namespace android 201 202 203int main(int argc, char **argv) 204{ 205 FILE *inputFile = nullptr; 206 int outputFileFd = STDOUT_FILENO; 207 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 208 int ret = 0; 209 210 if (argc > 5) { 211 fprintf(stderr, "Usage: %s [-i input_params.txt] [-o output_params.txt]\n", argv[0]); 212 return 1; 213 } 214 215 argv++; 216 while (*argv) { 217 if (strcmp(*argv, "-i") == 0) { 218 argv++; 219 if (*argv) { 220 inputFile = fopen(*argv, "r"); 221 if (inputFile == nullptr) { 222 ret = 1; 223 } 224 } else { 225 ret = 1; 226 } 227 } 228 if (strcmp(*argv, "-o") == 0) { 229 argv++; 230 if (*argv) { 231 outputFileFd = open(*argv, O_WRONLY|O_CREAT, mode); 232 if (outputFileFd < 0) { 233 ret = 1; 234 } 235 } else { 236 ret = 1; 237 } 238 argv++; 239 } 240 if (*argv) { 241 argv++; 242 } 243 } 244 245 if (ret != 0) { 246 return ret; 247 } 248 249 android::testTrack(inputFile, outputFileFd); 250 251 if (inputFile) { 252 fclose(inputFile); 253 } 254 if (outputFileFd >= 0 && outputFileFd != STDOUT_FILENO) { 255 close(outputFileFd); 256 } 257 258 return ret; 259} 260 261