annotate core/RTAudioCommandLine.cpp @ 151:e9c9404e3d1f ClockSync

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