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 #ifndef AAUDIO_EXAMPLE_ARGS_PARSER_H 18 #define AAUDIO_EXAMPLE_ARGS_PARSER_H 19 20 #include <cctype> 21 #include <unistd.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 25 #include <aaudio/AAudio.h> 26 #include <aaudio/AAudioTesting.h> 27 28 #include "AAudioExampleUtils.h" 29 30 // TODO use this as a base class within AAudio 31 class AAudioParameters { 32 public: 33 34 /** 35 * This is also known as samplesPerFrame. 36 */ getChannelCount()37 int32_t getChannelCount() const { 38 return mChannelCount; 39 } 40 setChannelCount(int32_t channelCount)41 void setChannelCount(int32_t channelCount) { 42 mChannelCount = channelCount; 43 } 44 getSampleRate()45 int32_t getSampleRate() const { 46 return mSampleRate; 47 } 48 setSampleRate(int32_t sampleRate)49 void setSampleRate(int32_t sampleRate) { 50 mSampleRate = sampleRate; 51 } 52 getFormat()53 aaudio_format_t getFormat() const { 54 return mFormat; 55 } 56 setFormat(aaudio_format_t format)57 void setFormat(aaudio_format_t format) { 58 mFormat = format; 59 } 60 getSharingMode()61 aaudio_sharing_mode_t getSharingMode() const { 62 return mSharingMode; 63 } 64 setSharingMode(aaudio_sharing_mode_t sharingMode)65 void setSharingMode(aaudio_sharing_mode_t sharingMode) { 66 mSharingMode = sharingMode; 67 } 68 getBufferCapacity()69 int32_t getBufferCapacity() const { 70 return mBufferCapacity; 71 } 72 setBufferCapacity(int32_t frames)73 void setBufferCapacity(int32_t frames) { 74 mBufferCapacity = frames; 75 } 76 getPerformanceMode()77 int32_t getPerformanceMode() const { 78 return mPerformanceMode; 79 } 80 setPerformanceMode(aaudio_performance_mode_t performanceMode)81 void setPerformanceMode(aaudio_performance_mode_t performanceMode) { 82 mPerformanceMode = performanceMode; 83 } 84 getDeviceId()85 int32_t getDeviceId() const { 86 return mDeviceId; 87 } 88 setDeviceId(int32_t deviceId)89 void setDeviceId(int32_t deviceId) { 90 mDeviceId = deviceId; 91 } 92 getNumberOfBursts()93 int32_t getNumberOfBursts() const { 94 return mNumberOfBursts; 95 } 96 setNumberOfBursts(int32_t numBursts)97 void setNumberOfBursts(int32_t numBursts) { 98 mNumberOfBursts = numBursts; 99 } 100 101 /** 102 * Apply these parameters to a stream builder. 103 * @param builder 104 */ applyParameters(AAudioStreamBuilder * builder)105 void applyParameters(AAudioStreamBuilder *builder) const { 106 AAudioStreamBuilder_setChannelCount(builder, mChannelCount); 107 AAudioStreamBuilder_setFormat(builder, mFormat); 108 AAudioStreamBuilder_setSampleRate(builder, mSampleRate); 109 AAudioStreamBuilder_setBufferCapacityInFrames(builder, mBufferCapacity); 110 AAudioStreamBuilder_setDeviceId(builder, mDeviceId); 111 AAudioStreamBuilder_setSharingMode(builder, mSharingMode); 112 AAudioStreamBuilder_setPerformanceMode(builder, mPerformanceMode); 113 } 114 115 private: 116 int32_t mChannelCount = AAUDIO_UNSPECIFIED; 117 aaudio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED; 118 int32_t mSampleRate = AAUDIO_UNSPECIFIED; 119 120 int32_t mBufferCapacity = AAUDIO_UNSPECIFIED; 121 int32_t mDeviceId = AAUDIO_UNSPECIFIED; 122 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED; 123 aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE; 124 125 int32_t mNumberOfBursts = AAUDIO_UNSPECIFIED; 126 }; 127 128 class AAudioArgsParser : public AAudioParameters { 129 public: 130 AAudioArgsParser() = default; 131 ~AAudioArgsParser() = default; 132 133 enum { 134 DEFAULT_DURATION_SECONDS = 5 135 }; 136 137 /** 138 * @param arg 139 * @return true if the argument was not handled 140 */ parseArg(const char * arg)141 bool parseArg(const char *arg) { 142 bool unrecognized = false; 143 if (arg[0] == '-') { 144 char option = arg[1]; 145 switch (option) { 146 case 'b': 147 setBufferCapacity(atoi(&arg[2])); 148 break; 149 case 'c': 150 setChannelCount(atoi(&arg[2])); 151 break; 152 case 'd': 153 setDeviceId(atoi(&arg[2])); 154 break; 155 case 's': 156 mDurationSeconds = atoi(&arg[2]); 157 break; 158 case 'm': { 159 aaudio_policy_t policy = AAUDIO_POLICY_AUTO; 160 if (strlen(arg) > 2) { 161 policy = atoi(&arg[2]); 162 } 163 AAudio_setMMapPolicy(policy); 164 } break; 165 case 'n': 166 setNumberOfBursts(atoi(&arg[2])); 167 break; 168 case 'p': 169 setPerformanceMode(parsePerformanceMode(arg[2])); 170 break; 171 case 'r': 172 setSampleRate(atoi(&arg[2])); 173 break; 174 case 'x': 175 setSharingMode(AAUDIO_SHARING_MODE_EXCLUSIVE); 176 break; 177 default: 178 unrecognized = true; 179 break; 180 } 181 } 182 return unrecognized; 183 } 184 185 /** 186 * 187 * @param argc 188 * @param argv 189 * @return true if an unrecognized argument was passed 190 */ parseArgs(int argc,const char ** argv)191 bool parseArgs(int argc, const char **argv) { 192 for (int i = 1; i < argc; i++) { 193 const char *arg = argv[i]; 194 if (parseArg(arg)) { 195 usage(); 196 return true; 197 } 198 199 } 200 return false; 201 } 202 usage()203 static void usage() { 204 printf("-c{channels} -d{duration} -m -n{burstsPerBuffer} -p{perfMode} -r{rate} -x\n"); 205 printf(" Default values are UNSPECIFIED unless otherwise stated.\n"); 206 printf(" -b{bufferCapacity} frames\n"); 207 printf(" -c{channels} for example 2 for stereo\n"); 208 printf(" -d{deviceId} default is %d\n", AAUDIO_UNSPECIFIED); 209 printf(" -s{duration} in seconds, default is %d\n", DEFAULT_DURATION_SECONDS); 210 printf(" -m{0|1|2|3} set MMAP policy\n"); 211 printf(" 0 = _UNSPECIFIED, default\n"); 212 printf(" 1 = _NEVER\n"); 213 printf(" 2 = _AUTO, also if -m is used with no number\n"); 214 printf(" 3 = _ALWAYS\n"); 215 printf(" -n{numberOfBursts} for setBufferSize\n"); 216 printf(" -p{performanceMode} set output AAUDIO_PERFORMANCE_MODE*, default NONE\n"); 217 printf(" n for _NONE\n"); 218 printf(" l for _LATENCY\n"); 219 printf(" p for _POWER_SAVING;\n"); 220 printf(" -r{sampleRate} for example 44100\n"); 221 printf(" -x to use EXCLUSIVE mode\n"); 222 } 223 parsePerformanceMode(char c)224 static aaudio_performance_mode_t parsePerformanceMode(char c) { 225 aaudio_performance_mode_t mode = AAUDIO_PERFORMANCE_MODE_NONE; 226 switch (c) { 227 case 'n': 228 mode = AAUDIO_PERFORMANCE_MODE_NONE; 229 break; 230 case 'l': 231 mode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY; 232 break; 233 case 'p': 234 mode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING; 235 break; 236 default: 237 printf("ERROR invalid performance mode %c\n", c); 238 break; 239 } 240 return mode; 241 } 242 243 /** 244 * Print stream parameters in comparison with requested values. 245 * @param stream 246 */ compareWithStream(AAudioStream * stream)247 void compareWithStream(AAudioStream *stream) const { 248 249 printf(" DeviceId: requested = %d, actual = %d\n", 250 getDeviceId(), AAudioStream_getDeviceId(stream)); 251 252 aaudio_stream_state_t state = AAudioStream_getState(stream); 253 printf(" State: %s\n", AAudio_convertStreamStateToText(state)); 254 255 // Check to see what kind of stream we actually got. 256 printf(" SampleRate: requested = %d, actual = %d\n", 257 getSampleRate(), AAudioStream_getSampleRate(stream)); 258 259 printf(" ChannelCount: requested = %d, actual = %d\n", 260 getChannelCount(), AAudioStream_getChannelCount(stream)); 261 262 printf(" DataFormat: requested = %d, actual = %d\n", 263 getFormat(), AAudioStream_getFormat(stream)); 264 265 int32_t framesPerBurst = AAudioStream_getFramesPerBurst(stream); 266 int32_t sizeFrames = AAudioStream_getBufferSizeInFrames(stream); 267 printf(" Buffer: burst = %d\n", framesPerBurst); 268 if (framesPerBurst > 0) { 269 printf(" Buffer: size = %d = (%d * %d) + %d\n", 270 sizeFrames, 271 (sizeFrames / framesPerBurst), 272 framesPerBurst, 273 (sizeFrames % framesPerBurst)); 274 } 275 printf(" Capacity: requested = %d, actual = %d\n", getBufferCapacity(), 276 AAudioStream_getBufferCapacityInFrames(stream)); 277 278 printf(" SharingMode: requested = %s, actual = %s\n", 279 getSharingModeText(getSharingMode()), 280 getSharingModeText(AAudioStream_getSharingMode(stream))); 281 282 printf(" PerformanceMode: requested = %d, actual = %d\n", 283 getPerformanceMode(), AAudioStream_getPerformanceMode(stream)); 284 printf(" Is MMAP used? %s\n", AAudioStream_isMMapUsed(stream) 285 ? "yes" : "no"); 286 287 } 288 getDurationSeconds()289 int32_t getDurationSeconds() const { 290 return mDurationSeconds; 291 } 292 setDurationSeconds(int32_t seconds)293 void setDurationSeconds(int32_t seconds) { 294 mDurationSeconds = seconds; 295 } 296 297 private: 298 int32_t mDurationSeconds = DEFAULT_DURATION_SECONDS; 299 }; 300 301 #endif // AAUDIO_EXAMPLE_ARGS_PARSER_H 302