Home | History | Annotate | Download | only in utils
      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      */
     37     int32_t getChannelCount() const {
     38         return mChannelCount;
     39     }
     40 
     41     void setChannelCount(int32_t channelCount) {
     42         mChannelCount = channelCount;
     43     }
     44 
     45     int32_t getSampleRate() const {
     46         return mSampleRate;
     47     }
     48 
     49     void setSampleRate(int32_t sampleRate) {
     50         mSampleRate = sampleRate;
     51     }
     52 
     53     aaudio_format_t getFormat() const {
     54         return mFormat;
     55     }
     56 
     57     void setFormat(aaudio_format_t format) {
     58         mFormat = format;
     59     }
     60 
     61     aaudio_sharing_mode_t getSharingMode() const {
     62         return mSharingMode;
     63     }
     64 
     65     void setSharingMode(aaudio_sharing_mode_t sharingMode) {
     66         mSharingMode = sharingMode;
     67     }
     68 
     69     int32_t getBufferCapacity() const {
     70         return mBufferCapacity;
     71     }
     72 
     73     void setBufferCapacity(int32_t frames) {
     74         mBufferCapacity = frames;
     75     }
     76 
     77     int32_t getPerformanceMode() const {
     78         return mPerformanceMode;
     79     }
     80 
     81     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
     82         mPerformanceMode = performanceMode;
     83     }
     84 
     85     int32_t getDeviceId() const {
     86         return mDeviceId;
     87     }
     88 
     89     void setDeviceId(int32_t deviceId) {
     90         mDeviceId = deviceId;
     91     }
     92 
     93     int32_t getNumberOfBursts() const {
     94         return mNumberOfBursts;
     95     }
     96 
     97     void setNumberOfBursts(int32_t numBursts) {
     98         mNumberOfBursts = numBursts;
     99     }
    100 
    101     /**
    102      * Apply these parameters to a stream builder.
    103      * @param builder
    104      */
    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      */
    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      */
    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 
    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 
    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      */
    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 
    289     int32_t getDurationSeconds() const {
    290         return mDurationSeconds;
    291     }
    292 
    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