annotate core/RTAudioCommandLine.cpp @ 39:638bc1ae2500 staging

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