annotate core/RTAudioCommandLine.cpp @ 46:eac5d8f40b48 newapi

Fixed file structure to reflect merging include files into BeagleRT.h
author andrewm
date Thu, 28 May 2015 14:38:00 -0400
parents 579c86316008
children 643cbee74eda
rev   line source
andrewm@5 1 /*
andrewm@5 2 * RTAudioCommandLine.cpp
andrewm@5 3 *
andrewm@5 4 * Created on: Nov 8, 2014
andrewm@5 5 * Author: parallels
andrewm@5 6 */
andrewm@5 7
andrewm@5 8 #include <iostream>
andrewm@5 9 #include <cstdlib>
andrewm@5 10 #include <cstring>
andrewm@5 11 #include <getopt.h>
andrewm@45 12 #include "../include/BeagleRT.h"
giuliomoro@24 13
giuliomoro@23 14 #ifndef OPT_PRU_FILE
andrewm@45 15 #define OPT_PRU_FILE 176 // this is an extended ASCII code
giuliomoro@23 16 #endif
andrewm@5 17
andrewm@5 18 // Default command-line options for RTAudio
andrewm@5 19 struct option gDefaultLongOptions[] =
andrewm@5 20 {
andrewm@5 21 {"period", 1, NULL, 'p'},
andrewm@5 22 {"verbose", 0, NULL, 'v'},
giuliomoro@19 23 {"use-analog", 1, NULL, 'm'},
giuliomoro@23 24 {"use-digital-gpio", 1, NULL, 'g'},
giuliomoro@19 25 {"analog-channels", 1, NULL, 'C'},
giuliomoro@24 26 {"digital-channels", 1, NULL, 'G'},
andrewm@5 27 {"mute-speaker", 1, NULL, 'M'},
andrewm@5 28 {"dac-level", 1, NULL, 'D'},
andrewm@5 29 {"adc-level", 1, NULL, 'A'},
andrewm@5 30 {"hp-level", 1, NULL, 'H'},
giuliomoro@24 31 {"receive-port", 1, NULL, 'r'},
giuliomoro@24 32 {"transmit-port", 1, NULL, 't'},
andrewm@45 33 {"server-name", 1, NULL, 's'},
andrewm@45 34 {"pru-file", 1, NULL, OPT_PRU_FILE},
andrewm@5 35 {NULL, 0, NULL, 0}
andrewm@5 36 };
giuliomoro@24 37
giuliomoro@24 38 const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:g:G:r:t:s:";
andrewm@5 39
andrewm@45 40 // This function sets the default settings for the BeagleRTInitSettings structure
andrewm@45 41 void BeagleRT_defaultSettings(BeagleRTInitSettings *settings)
andrewm@5 42 {
andrewm@5 43 // Set default values for settings
andrewm@5 44 settings->periodSize = 8;
andrewm@45 45 settings->useAnalog = 1;
andrewm@45 46 settings->useDigital = 1;
andrewm@45 47 settings->numAnalogChannels = 8;
andrewm@45 48 settings->numDigitalChannels = 16;
andrewm@45 49
andrewm@5 50 settings->beginMuted = 0;
andrewm@5 51 settings->dacLevel = DEFAULT_DAC_LEVEL;
andrewm@5 52 settings->adcLevel = DEFAULT_ADC_LEVEL;
andrewm@5 53 settings->headphoneLevel = DEFAULT_HP_LEVEL;
andrewm@45 54
andrewm@5 55 settings->verbose = 0;
andrewm@45 56 settings->pruFilename[0] = '\0';
andrewm@45 57
andrewm@45 58 // These two deliberately have no command-line flags by default.
andrewm@45 59 // A given program might prefer one mode or another, but it's unlikely
andrewm@45 60 // the user would want to switch at runtime
andrewm@45 61 settings->interleave = 1;
andrewm@45 62 settings->analogOutputsPersist = 1;
andrewm@45 63
andrewm@5 64 settings->codecI2CAddress = CODEC_I2C_ADDRESS;
andrewm@45 65 settings->receivePort = 9998;
andrewm@45 66 settings->transmitPort = 9999;
giuliomoro@24 67 strcpy(settings->serverName, "127.0.0.1");
andrewm@5 68 settings->ampMutePin = kAmplifierMutePin;
andrewm@5 69 }
andrewm@5 70
andrewm@5 71 // This function drops in place of getopt() in the main() function
andrewm@5 72 // and handles the initialisation of the RTAudio settings using
andrewm@5 73 // standard command-line arguments. System default arguments will
andrewm@5 74 // be stored in settings, otherwise arguments will be returned
andrewm@5 75 // as getopt() normally does.
andrewm@5 76
andrewm@45 77 int BeagleRT_getopt_long(int argc, char *argv[], const char *customShortOptions, const struct option *customLongOptions, BeagleRTInitSettings *settings)
andrewm@5 78 {
andrewm@5 79 static int firstRun = 1;
andrewm@5 80 static char totalShortOptions[256];
andrewm@5 81 static struct option totalLongOptions[256];
andrewm@5 82
andrewm@5 83 int c;
andrewm@5 84
andrewm@5 85 // Prep total option string the first time this is
andrewm@5 86 // run. As a getopt() substitute, it will be called repeatedly working its
andrewm@5 87 // way through argc and argv.
andrewm@5 88 if(firstRun) {
andrewm@5 89 firstRun = 0;
andrewm@5 90
andrewm@5 91 // Copy short options into one string
andrewm@5 92 strcpy(totalShortOptions, gDefaultShortOptions);
andrewm@5 93 strncat(totalShortOptions, customShortOptions, 256 - strlen(gDefaultShortOptions) - 1);
andrewm@5 94
andrewm@5 95 // Copy long options into one array
andrewm@5 96 int n = 0;
andrewm@5 97 while(1) {
andrewm@5 98 if(gDefaultLongOptions[n].name == NULL)
andrewm@5 99 break;
andrewm@5 100 totalLongOptions[n].name = gDefaultLongOptions[n].name;
andrewm@5 101 totalLongOptions[n].has_arg = gDefaultLongOptions[n].has_arg;
andrewm@5 102 totalLongOptions[n].flag = gDefaultLongOptions[n].flag;
andrewm@5 103 totalLongOptions[n].val = gDefaultLongOptions[n].val;
andrewm@5 104 n++;
andrewm@5 105 }
andrewm@5 106
andrewm@5 107 // Copy custom options into the array, if present
andrewm@5 108 if(customLongOptions == 0) {
andrewm@5 109 // Terminate the array
andrewm@5 110 totalLongOptions[n].name = NULL;
andrewm@5 111 totalLongOptions[n].has_arg = 0;
andrewm@5 112 totalLongOptions[n].flag = NULL;
andrewm@5 113 totalLongOptions[n].val = 0;
andrewm@5 114 }
andrewm@5 115 else {
andrewm@5 116 int customIndex = 0;
andrewm@5 117 while(n < 256) {
andrewm@5 118 if(customLongOptions[customIndex].name == NULL)
andrewm@5 119 break;
andrewm@5 120 totalLongOptions[n].name = customLongOptions[customIndex].name;
andrewm@5 121 totalLongOptions[n].has_arg = customLongOptions[customIndex].has_arg;
andrewm@5 122 totalLongOptions[n].flag = customLongOptions[customIndex].flag;
andrewm@5 123 totalLongOptions[n].val = customLongOptions[customIndex].val;
andrewm@5 124 n++;
andrewm@5 125 customIndex++;
andrewm@5 126 }
andrewm@5 127
andrewm@5 128 // Terminate the array
andrewm@5 129 totalLongOptions[n].name = NULL;
andrewm@5 130 totalLongOptions[n].has_arg = 0;
andrewm@5 131 totalLongOptions[n].flag = NULL;
andrewm@5 132 totalLongOptions[n].val = 0;
andrewm@5 133 }
andrewm@5 134 }
andrewm@5 135
andrewm@5 136 while(1) {
andrewm@5 137 if ((c = getopt_long(argc, argv, totalShortOptions, totalLongOptions, NULL)) < 0)
andrewm@5 138 return c;
andrewm@5 139
andrewm@5 140 switch (c) {
andrewm@5 141 case 'p':
andrewm@5 142 settings->periodSize = atoi(optarg);
andrewm@5 143 if(settings->periodSize < 1)
andrewm@5 144 settings->periodSize = 1;
andrewm@5 145 break;
andrewm@5 146 case 'v':
andrewm@5 147 settings->verbose = 1;
andrewm@5 148 break;
andrewm@5 149 case 'm':
giuliomoro@19 150 settings->useAnalog = atoi(optarg);
andrewm@5 151 break;
giuliomoro@16 152 case 'g':
giuliomoro@19 153 settings->useDigital = atoi(optarg);
giuliomoro@19 154 settings->numDigitalChannels = 0;
giuliomoro@16 155 break;
andrewm@12 156 case 'C':
giuliomoro@19 157 settings->numAnalogChannels = atoi(optarg);
giuliomoro@19 158 if(settings->numAnalogChannels >= 8)
giuliomoro@19 159 settings->numAnalogChannels = 8;
giuliomoro@19 160 else if(settings->numAnalogChannels >= 4)
giuliomoro@19 161 settings->numAnalogChannels = 4;
andrewm@12 162 else
giuliomoro@19 163 settings->numAnalogChannels = 2;
andrewm@12 164 break;
giuliomoro@16 165 case 'G':
giuliomoro@19 166 settings->numDigitalChannels = atoi(optarg);
giuliomoro@19 167 if(settings->numDigitalChannels >= 16)
giuliomoro@19 168 settings->numDigitalChannels = 16;
giuliomoro@19 169 else if (settings->numDigitalChannels < 1){
giuliomoro@19 170 settings->numDigitalChannels = 0;
giuliomoro@19 171 settings->useDigital = 0; //TODO: this actually works only if -G 0 is specified after -g 1.
giuliomoro@19 172 //No worries, though: disabling numDigital will only prevent the pins from being exported.
giuliomoro@16 173 }
giuliomoro@16 174 break;
andrewm@5 175 case 'M':
andrewm@5 176 settings->beginMuted = atoi(optarg);
andrewm@5 177 break;
andrewm@5 178 case 'D':
andrewm@5 179 settings->dacLevel = atof(optarg);
andrewm@5 180 break;
andrewm@5 181 case 'A':
andrewm@5 182 settings->adcLevel = atof(optarg);
andrewm@5 183 break;
andrewm@5 184 case 'H':
andrewm@5 185 settings->headphoneLevel = atof(optarg);
andrewm@5 186 break;
giuliomoro@24 187 case 'r':
giuliomoro@24 188 settings->receivePort = atoi(optarg);
giuliomoro@24 189 break;
giuliomoro@24 190 case 't':
giuliomoro@24 191 settings->transmitPort = atoi(optarg);
giuliomoro@24 192 break;
giuliomoro@24 193 case 's':
giuliomoro@24 194 if(strlen(optarg)<MAX_SERVERNAME_LENGTH)
giuliomoro@24 195 strcpy(settings->serverName, optarg);
giuliomoro@24 196 else
giuliomoro@24 197 std::cerr << "Warning: server name is too long (>" << MAX_SERVERNAME_LENGTH << " characters)."
giuliomoro@24 198 " Using default severName Instead ( " << settings->serverName << " ).\n";
giuliomoro@24 199 break;
giuliomoro@29 200 case OPT_PRU_FILE:
andrewm@45 201 if(strlen(optarg) < MAX_PRU_FILENAME_LENGTH)
giuliomoro@16 202 strcpy(settings->pruFilename, optarg);
giuliomoro@16 203 else
giuliomoro@16 204 std::cerr << "Warning: filename for the PRU code is too long (>" << MAX_PRU_FILENAME_LENGTH << " characters). Using embedded PRU code instead\n";
giuliomoro@16 205 break;
andrewm@5 206 case '?':
andrewm@5 207 default:
andrewm@5 208 return c;
andrewm@5 209 }
andrewm@5 210 }
andrewm@5 211 }
andrewm@5 212
andrewm@5 213 // This function prints standard usage information for default arguments
andrewm@5 214 // Call from within your own usage function
andrewm@5 215 void BeagleRT_usage()
andrewm@5 216 {
giuliomoro@19 217 std::cerr << " --period [-p] period: Set the hardware period (buffer) size in analog samples\n";
giuliomoro@16 218 std::cerr << " --dac-level [-D] dBs: Set the DAC output level (0dB max; -63.5dB min)\n";
giuliomoro@16 219 std::cerr << " --adc-level [-A] dBs: Set the ADC input level (0dB max; -12dB min)\n";
giuliomoro@16 220 std::cerr << " --hp-level [-H] dBs: Set the headphone output level (0dB max; -63.5dB min)\n";
giuliomoro@16 221 std::cerr << " --mute-speaker [-M] val: Set whether to mute the speaker initially (default: no)\n";
giuliomoro@19 222 std::cerr << " --use-analog [-m] val: Set whether to use ADC/DAC analog (default: yes)\n";
giuliomoro@24 223 std::cerr << " --use-digital [-g] val: Set whether to use digital GPIO channels (default: yes)\n";
giuliomoro@19 224 std::cerr << " --analog-channels [-C] val: Set the number of ADC/DAC channels (default: 8)\n";
giuliomoro@31 225 std::cerr << " --digital-channels [-G] val: Set the number of GPIO channels (default: 16)\n";
giuliomoro@24 226 std::cerr << " --digital-channels [-G] val: Set the number of digital GPIO channels (default: 16)\n";
giuliomoro@24 227 std::cerr << " --receive-port [-r] val: Set the receive port (default: 9998)\n";
giuliomoro@24 228 std::cerr << " --transmit-port [-t] val: Set the transmit port (default: 9999)\n";
giuliomoro@24 229 std::cerr << " --server-name [-s] val: Set the destination server name (default: '127.0.0.1')\n";
giuliomoro@24 230 std::cerr << " --pru-file val: Set an optional external file to use for the PRU binary code\n";
giuliomoro@16 231 std::cerr << " --verbose [-v]: Enable verbose logging information\n";
andrewm@5 232 }
giuliomoro@16 233