blob: 4fc5b9f51ac6700c1bcebdb3c0fa4243b7f1fd0f [file] [log] [blame]
Phil Burk44795232017-06-30 16:27:38 -07001/*
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
Phil Burk67ed9da2017-09-06 16:26:52 -070020#define MAX_CHANNELS 8
21
Phil Burk44795232017-06-30 16:27:38 -070022#include <cctype>
23#include <unistd.h>
24#include <stdio.h>
25#include <stdlib.h>
26
27#include <aaudio/AAudio.h>
28#include <aaudio/AAudioTesting.h>
Phil Burka5222e22017-07-28 13:31:14 -070029
30#include "AAudioExampleUtils.h"
Phil Burk44795232017-06-30 16:27:38 -070031
32// TODO use this as a base class within AAudio
33class AAudioParameters {
34public:
35
36 /**
37 * This is also known as samplesPerFrame.
38 */
39 int32_t getChannelCount() const {
40 return mChannelCount;
41 }
42
43 void setChannelCount(int32_t channelCount) {
Phil Burk67ed9da2017-09-06 16:26:52 -070044 if (channelCount > MAX_CHANNELS) {
45 printf("Sorry, MAX of %d channels!\n", MAX_CHANNELS);
46 channelCount = MAX_CHANNELS;
47 }
Phil Burk44795232017-06-30 16:27:38 -070048 mChannelCount = channelCount;
49 }
50
51 int32_t getSampleRate() const {
52 return mSampleRate;
53 }
54
55 void setSampleRate(int32_t sampleRate) {
56 mSampleRate = sampleRate;
57 }
58
59 aaudio_format_t getFormat() const {
60 return mFormat;
61 }
62
63 void setFormat(aaudio_format_t format) {
64 mFormat = format;
65 }
66
67 aaudio_sharing_mode_t getSharingMode() const {
68 return mSharingMode;
69 }
70
71 void setSharingMode(aaudio_sharing_mode_t sharingMode) {
72 mSharingMode = sharingMode;
73 }
74
75 int32_t getBufferCapacity() const {
76 return mBufferCapacity;
77 }
78
79 void setBufferCapacity(int32_t frames) {
80 mBufferCapacity = frames;
81 }
82
83 int32_t getPerformanceMode() const {
84 return mPerformanceMode;
85 }
86
87 void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
88 mPerformanceMode = performanceMode;
89 }
90
Phil Burk6d6f3f62018-01-12 17:27:54 -080091 aaudio_usage_t getUsage() const {
92 return mUsage;
93 }
94
95 void setUsage(aaudio_usage_t usage) {
96 mUsage = usage;
97 }
98
99 aaudio_content_type_t getContentType() const {
100 return mContentType;
101 }
102
103 void setContentType(aaudio_content_type_t contentType) {
104 mContentType = contentType;
105 }
106
107 aaudio_input_preset_t getInputPreset() const {
108 return mInputPreset;
109 }
110
111 void setInputPreset(aaudio_input_preset_t inputPreset) {
112 mInputPreset = inputPreset;
113 }
114
Phil Burk44795232017-06-30 16:27:38 -0700115 int32_t getDeviceId() const {
116 return mDeviceId;
117 }
118
119 void setDeviceId(int32_t deviceId) {
120 mDeviceId = deviceId;
121 }
122
123 int32_t getNumberOfBursts() const {
124 return mNumberOfBursts;
125 }
126
127 void setNumberOfBursts(int32_t numBursts) {
128 mNumberOfBursts = numBursts;
129 }
130
131 /**
132 * Apply these parameters to a stream builder.
133 * @param builder
134 */
135 void applyParameters(AAudioStreamBuilder *builder) const {
136 AAudioStreamBuilder_setChannelCount(builder, mChannelCount);
137 AAudioStreamBuilder_setFormat(builder, mFormat);
138 AAudioStreamBuilder_setSampleRate(builder, mSampleRate);
139 AAudioStreamBuilder_setBufferCapacityInFrames(builder, mBufferCapacity);
140 AAudioStreamBuilder_setDeviceId(builder, mDeviceId);
141 AAudioStreamBuilder_setSharingMode(builder, mSharingMode);
142 AAudioStreamBuilder_setPerformanceMode(builder, mPerformanceMode);
Phil Burk6d6f3f62018-01-12 17:27:54 -0800143 AAudioStreamBuilder_setUsage(builder, mUsage);
144 AAudioStreamBuilder_setContentType(builder, mContentType);
145 AAudioStreamBuilder_setInputPreset(builder, mInputPreset);
Phil Burk44795232017-06-30 16:27:38 -0700146 }
147
148private:
149 int32_t mChannelCount = AAUDIO_UNSPECIFIED;
150 aaudio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED;
151 int32_t mSampleRate = AAUDIO_UNSPECIFIED;
152
153 int32_t mBufferCapacity = AAUDIO_UNSPECIFIED;
154 int32_t mDeviceId = AAUDIO_UNSPECIFIED;
155 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
156 aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
157
Phil Burk6d6f3f62018-01-12 17:27:54 -0800158 aaudio_usage_t mUsage = AAUDIO_UNSPECIFIED;
159 aaudio_content_type_t mContentType = AAUDIO_UNSPECIFIED;
160 aaudio_input_preset_t mInputPreset = AAUDIO_UNSPECIFIED;
161
Phil Burkfcf9efd2017-07-14 08:25:08 -0700162 int32_t mNumberOfBursts = AAUDIO_UNSPECIFIED;
Phil Burk44795232017-06-30 16:27:38 -0700163};
164
165class AAudioArgsParser : public AAudioParameters {
166public:
167 AAudioArgsParser() = default;
168 ~AAudioArgsParser() = default;
169
170 enum {
171 DEFAULT_DURATION_SECONDS = 5
172 };
173
174 /**
175 * @param arg
176 * @return true if the argument was not handled
177 */
178 bool parseArg(const char *arg) {
179 bool unrecognized = false;
180 if (arg[0] == '-') {
181 char option = arg[1];
182 switch (option) {
183 case 'b':
184 setBufferCapacity(atoi(&arg[2]));
185 break;
186 case 'c':
187 setChannelCount(atoi(&arg[2]));
188 break;
189 case 'd':
Phil Burke008d022017-08-23 12:56:15 -0700190 setDeviceId(atoi(&arg[2]));
191 break;
Phil Burk6d6f3f62018-01-12 17:27:54 -0800192 case 'i':
193 setInputPreset(atoi(&arg[2]));
Phil Burk44795232017-06-30 16:27:38 -0700194 break;
Phil Burkfcf9efd2017-07-14 08:25:08 -0700195 case 'm': {
196 aaudio_policy_t policy = AAUDIO_POLICY_AUTO;
197 if (strlen(arg) > 2) {
198 policy = atoi(&arg[2]);
199 }
200 AAudio_setMMapPolicy(policy);
201 } break;
Phil Burk44795232017-06-30 16:27:38 -0700202 case 'n':
203 setNumberOfBursts(atoi(&arg[2]));
204 break;
205 case 'p':
206 setPerformanceMode(parsePerformanceMode(arg[2]));
207 break;
208 case 'r':
209 setSampleRate(atoi(&arg[2]));
210 break;
Phil Burk6d6f3f62018-01-12 17:27:54 -0800211 case 's':
212 mDurationSeconds = atoi(&arg[2]);
213 break;
214 case 'u':
215 setUsage(atoi(&arg[2]));
216 break;
Phil Burk44795232017-06-30 16:27:38 -0700217 case 'x':
218 setSharingMode(AAUDIO_SHARING_MODE_EXCLUSIVE);
219 break;
Phil Burk6d6f3f62018-01-12 17:27:54 -0800220 case 'y':
221 setContentType(atoi(&arg[2]));
222 break;
Phil Burk44795232017-06-30 16:27:38 -0700223 default:
224 unrecognized = true;
225 break;
226 }
227 }
228 return unrecognized;
229 }
230
231 /**
232 *
233 * @param argc
234 * @param argv
235 * @return true if an unrecognized argument was passed
236 */
237 bool parseArgs(int argc, const char **argv) {
238 for (int i = 1; i < argc; i++) {
239 const char *arg = argv[i];
240 if (parseArg(arg)) {
241 usage();
242 return true;
243 }
244
245 }
246 return false;
247 }
248
249 static void usage() {
Phil Burk6d6f3f62018-01-12 17:27:54 -0800250 printf("-c{channels} -d{deviceId} -m{mmapPolicy} -n{burstsPerBuffer} -p{perfMode}");
251 printf(" -r{rate} -s{seconds} -x\n");
Phil Burk44795232017-06-30 16:27:38 -0700252 printf(" Default values are UNSPECIFIED unless otherwise stated.\n");
253 printf(" -b{bufferCapacity} frames\n");
254 printf(" -c{channels} for example 2 for stereo\n");
Phil Burke008d022017-08-23 12:56:15 -0700255 printf(" -d{deviceId} default is %d\n", AAUDIO_UNSPECIFIED);
Phil Burk6d6f3f62018-01-12 17:27:54 -0800256 printf(" -i{inputPreset} eg. 5 for AAUDIO_INPUT_PRESET_CAMCORDER\n");
Phil Burkfcf9efd2017-07-14 08:25:08 -0700257 printf(" -m{0|1|2|3} set MMAP policy\n");
Phil Burk6d6f3f62018-01-12 17:27:54 -0800258 printf(" 0 = _UNSPECIFIED, use aaudio.mmap_policy system property, default\n");
259 printf(" 1 = _NEVER, never use MMAP\n");
260 printf(" 2 = _AUTO, use MMAP if available, default for -m with no number\n");
261 printf(" 3 = _ALWAYS, use MMAP or fail\n");
Phil Burk44795232017-06-30 16:27:38 -0700262 printf(" -n{numberOfBursts} for setBufferSize\n");
263 printf(" -p{performanceMode} set output AAUDIO_PERFORMANCE_MODE*, default NONE\n");
264 printf(" n for _NONE\n");
265 printf(" l for _LATENCY\n");
266 printf(" p for _POWER_SAVING;\n");
267 printf(" -r{sampleRate} for example 44100\n");
Phil Burk6d6f3f62018-01-12 17:27:54 -0800268 printf(" -s{duration} in seconds, default is %d\n", DEFAULT_DURATION_SECONDS);
269 printf(" -u{usage} eg. 14 for AAUDIO_USAGE_GAME\n");
Phil Burk44795232017-06-30 16:27:38 -0700270 printf(" -x to use EXCLUSIVE mode\n");
Phil Burk6d6f3f62018-01-12 17:27:54 -0800271 printf(" -y{contentType} eg. 1 for AAUDIO_CONTENT_TYPE_SPEECH\n");
Phil Burk44795232017-06-30 16:27:38 -0700272 }
273
274 static aaudio_performance_mode_t parsePerformanceMode(char c) {
275 aaudio_performance_mode_t mode = AAUDIO_PERFORMANCE_MODE_NONE;
276 switch (c) {
277 case 'n':
278 mode = AAUDIO_PERFORMANCE_MODE_NONE;
279 break;
280 case 'l':
281 mode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
282 break;
283 case 'p':
284 mode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING;
285 break;
286 default:
287 printf("ERROR invalid performance mode %c\n", c);
288 break;
289 }
290 return mode;
291 }
292
293 /**
294 * Print stream parameters in comparison with requested values.
295 * @param stream
296 */
Phil Burka5222e22017-07-28 13:31:14 -0700297 void compareWithStream(AAudioStream *stream) const {
Phil Burk44795232017-06-30 16:27:38 -0700298
299 printf(" DeviceId: requested = %d, actual = %d\n",
300 getDeviceId(), AAudioStream_getDeviceId(stream));
301
302 aaudio_stream_state_t state = AAudioStream_getState(stream);
303 printf(" State: %s\n", AAudio_convertStreamStateToText(state));
304
305 // Check to see what kind of stream we actually got.
306 printf(" SampleRate: requested = %d, actual = %d\n",
307 getSampleRate(), AAudioStream_getSampleRate(stream));
308
309 printf(" ChannelCount: requested = %d, actual = %d\n",
310 getChannelCount(), AAudioStream_getChannelCount(stream));
311
312 printf(" DataFormat: requested = %d, actual = %d\n",
313 getFormat(), AAudioStream_getFormat(stream));
314
315 int32_t framesPerBurst = AAudioStream_getFramesPerBurst(stream);
316 int32_t sizeFrames = AAudioStream_getBufferSizeInFrames(stream);
317 printf(" Buffer: burst = %d\n", framesPerBurst);
318 if (framesPerBurst > 0) {
319 printf(" Buffer: size = %d = (%d * %d) + %d\n",
320 sizeFrames,
321 (sizeFrames / framesPerBurst),
322 framesPerBurst,
323 (sizeFrames % framesPerBurst));
324 }
325 printf(" Capacity: requested = %d, actual = %d\n", getBufferCapacity(),
326 AAudioStream_getBufferCapacityInFrames(stream));
327
328 printf(" SharingMode: requested = %s, actual = %s\n",
329 getSharingModeText(getSharingMode()),
330 getSharingModeText(AAudioStream_getSharingMode(stream)));
331
332 printf(" PerformanceMode: requested = %d, actual = %d\n",
333 getPerformanceMode(), AAudioStream_getPerformanceMode(stream));
Phil Burk6d6f3f62018-01-12 17:27:54 -0800334
335 printf(" Usage: requested = %d, actual = %d\n",
336 getUsage(), AAudioStream_getUsage(stream));
337 printf(" ContentType: requested = %d, actual = %d\n",
338 getContentType(), AAudioStream_getContentType(stream));
339
340 if (AAudioStream_getDirection(stream) == AAUDIO_DIRECTION_INPUT) {
341 printf(" InputPreset: requested = %d, actual = %d\n",
342 getInputPreset(), AAudioStream_getInputPreset(stream));
343 }
344
Phil Burk44795232017-06-30 16:27:38 -0700345 printf(" Is MMAP used? %s\n", AAudioStream_isMMapUsed(stream)
346 ? "yes" : "no");
347
348 }
349
350 int32_t getDurationSeconds() const {
351 return mDurationSeconds;
352 }
353
354 void setDurationSeconds(int32_t seconds) {
355 mDurationSeconds = seconds;
356 }
357
358private:
359 int32_t mDurationSeconds = DEFAULT_DURATION_SECONDS;
360};
361
362#endif // AAUDIO_EXAMPLE_ARGS_PARSER_H