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
|
andrewm@5
|
13 #include "../include/RTAudio.h"
|
andrewm@5
|
14
|
andrewm@5
|
15 // Default command-line options for RTAudio
|
andrewm@5
|
16 struct option gDefaultLongOptions[] =
|
andrewm@5
|
17 {
|
andrewm@5
|
18 {"period", 1, NULL, 'p'},
|
andrewm@5
|
19 {"verbose", 0, NULL, 'v'},
|
andrewm@5
|
20 {"use-matrix", 1, NULL, 'm'},
|
andrewm@12
|
21 {"matrix-channels", 1, NULL, 'C'},
|
andrewm@5
|
22 {"mute-speaker", 1, NULL, 'M'},
|
andrewm@5
|
23 {"dac-level", 1, NULL, 'D'},
|
andrewm@5
|
24 {"adc-level", 1, NULL, 'A'},
|
andrewm@5
|
25 {"hp-level", 1, NULL, 'H'},
|
andrewm@5
|
26 {NULL, 0, NULL, 0}
|
andrewm@5
|
27 };
|
andrewm@5
|
28
|
andrewm@12
|
29 const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:";
|
andrewm@5
|
30
|
andrewm@5
|
31 // This function sets the default settings for the RTAudioSettings structure
|
andrewm@5
|
32 void BeagleRT_defaultSettings(RTAudioSettings *settings)
|
andrewm@5
|
33 {
|
andrewm@5
|
34 // Set default values for settings
|
andrewm@5
|
35 settings->periodSize = 8;
|
andrewm@5
|
36 settings->beginMuted = 0;
|
andrewm@5
|
37 settings->dacLevel = DEFAULT_DAC_LEVEL;
|
andrewm@5
|
38 settings->adcLevel = DEFAULT_ADC_LEVEL;
|
andrewm@5
|
39 settings->headphoneLevel = DEFAULT_HP_LEVEL;
|
andrewm@5
|
40 settings->useMatrix = 1;
|
andrewm@12
|
41 settings->numMatrixChannels = 8;
|
andrewm@5
|
42 settings->verbose = 0;
|
andrewm@5
|
43 settings->codecI2CAddress = CODEC_I2C_ADDRESS;
|
andrewm@5
|
44 settings->ampMutePin = kAmplifierMutePin;
|
andrewm@5
|
45 }
|
andrewm@5
|
46
|
andrewm@5
|
47 // This function drops in place of getopt() in the main() function
|
andrewm@5
|
48 // and handles the initialisation of the RTAudio settings using
|
andrewm@5
|
49 // standard command-line arguments. System default arguments will
|
andrewm@5
|
50 // be stored in settings, otherwise arguments will be returned
|
andrewm@5
|
51 // as getopt() normally does.
|
andrewm@5
|
52
|
andrewm@5
|
53 int BeagleRT_getopt_long(int argc, char *argv[], const char *customShortOptions, const struct option *customLongOptions, RTAudioSettings *settings)
|
andrewm@5
|
54 {
|
andrewm@5
|
55 static int firstRun = 1;
|
andrewm@5
|
56 static char totalShortOptions[256];
|
andrewm@5
|
57 static struct option totalLongOptions[256];
|
andrewm@5
|
58
|
andrewm@5
|
59 int c;
|
andrewm@5
|
60
|
andrewm@5
|
61 // Prep total option string the first time this is
|
andrewm@5
|
62 // run. As a getopt() substitute, it will be called repeatedly working its
|
andrewm@5
|
63 // way through argc and argv.
|
andrewm@5
|
64 if(firstRun) {
|
andrewm@5
|
65 firstRun = 0;
|
andrewm@5
|
66
|
andrewm@5
|
67 // Copy short options into one string
|
andrewm@5
|
68 strcpy(totalShortOptions, gDefaultShortOptions);
|
andrewm@5
|
69 strncat(totalShortOptions, customShortOptions, 256 - strlen(gDefaultShortOptions) - 1);
|
andrewm@5
|
70
|
andrewm@5
|
71 // Copy long options into one array
|
andrewm@5
|
72 int n = 0;
|
andrewm@5
|
73 while(1) {
|
andrewm@5
|
74 if(gDefaultLongOptions[n].name == NULL)
|
andrewm@5
|
75 break;
|
andrewm@5
|
76 totalLongOptions[n].name = gDefaultLongOptions[n].name;
|
andrewm@5
|
77 totalLongOptions[n].has_arg = gDefaultLongOptions[n].has_arg;
|
andrewm@5
|
78 totalLongOptions[n].flag = gDefaultLongOptions[n].flag;
|
andrewm@5
|
79 totalLongOptions[n].val = gDefaultLongOptions[n].val;
|
andrewm@5
|
80 n++;
|
andrewm@5
|
81 }
|
andrewm@5
|
82
|
andrewm@5
|
83 // Copy custom options into the array, if present
|
andrewm@5
|
84 if(customLongOptions == 0) {
|
andrewm@5
|
85 // Terminate the array
|
andrewm@5
|
86 totalLongOptions[n].name = NULL;
|
andrewm@5
|
87 totalLongOptions[n].has_arg = 0;
|
andrewm@5
|
88 totalLongOptions[n].flag = NULL;
|
andrewm@5
|
89 totalLongOptions[n].val = 0;
|
andrewm@5
|
90 }
|
andrewm@5
|
91 else {
|
andrewm@5
|
92 int customIndex = 0;
|
andrewm@5
|
93 while(n < 256) {
|
andrewm@5
|
94 if(customLongOptions[customIndex].name == NULL)
|
andrewm@5
|
95 break;
|
andrewm@5
|
96 totalLongOptions[n].name = customLongOptions[customIndex].name;
|
andrewm@5
|
97 totalLongOptions[n].has_arg = customLongOptions[customIndex].has_arg;
|
andrewm@5
|
98 totalLongOptions[n].flag = customLongOptions[customIndex].flag;
|
andrewm@5
|
99 totalLongOptions[n].val = customLongOptions[customIndex].val;
|
andrewm@5
|
100 n++;
|
andrewm@5
|
101 customIndex++;
|
andrewm@5
|
102 }
|
andrewm@5
|
103
|
andrewm@5
|
104 // Terminate the array
|
andrewm@5
|
105 totalLongOptions[n].name = NULL;
|
andrewm@5
|
106 totalLongOptions[n].has_arg = 0;
|
andrewm@5
|
107 totalLongOptions[n].flag = NULL;
|
andrewm@5
|
108 totalLongOptions[n].val = 0;
|
andrewm@5
|
109 }
|
andrewm@5
|
110 }
|
andrewm@5
|
111
|
andrewm@5
|
112 while(1) {
|
andrewm@5
|
113 if ((c = getopt_long(argc, argv, totalShortOptions, totalLongOptions, NULL)) < 0)
|
andrewm@5
|
114 return c;
|
andrewm@5
|
115
|
andrewm@5
|
116 switch (c) {
|
andrewm@5
|
117 case 'p':
|
andrewm@5
|
118 settings->periodSize = atoi(optarg);
|
andrewm@5
|
119 if(settings->periodSize < 1)
|
andrewm@5
|
120 settings->periodSize = 1;
|
andrewm@5
|
121 break;
|
andrewm@5
|
122 case 'v':
|
andrewm@5
|
123 settings->verbose = 1;
|
andrewm@5
|
124 break;
|
andrewm@5
|
125 case 'm':
|
andrewm@5
|
126 settings->useMatrix = atoi(optarg);
|
andrewm@5
|
127 break;
|
andrewm@12
|
128 case 'C':
|
andrewm@12
|
129 settings->numMatrixChannels = atoi(optarg);
|
andrewm@12
|
130 if(settings->numMatrixChannels >= 8)
|
andrewm@12
|
131 settings->numMatrixChannels = 8;
|
andrewm@12
|
132 else if(settings->numMatrixChannels >= 4)
|
andrewm@12
|
133 settings->numMatrixChannels = 4;
|
andrewm@12
|
134 else
|
andrewm@12
|
135 settings->numMatrixChannels = 2;
|
andrewm@12
|
136 break;
|
andrewm@5
|
137 case 'M':
|
andrewm@5
|
138 settings->beginMuted = atoi(optarg);
|
andrewm@5
|
139 break;
|
andrewm@5
|
140 case 'D':
|
andrewm@5
|
141 settings->dacLevel = atof(optarg);
|
andrewm@5
|
142 break;
|
andrewm@5
|
143 case 'A':
|
andrewm@5
|
144 settings->adcLevel = atof(optarg);
|
andrewm@5
|
145 break;
|
andrewm@5
|
146 case 'H':
|
andrewm@5
|
147 settings->headphoneLevel = atof(optarg);
|
andrewm@5
|
148 break;
|
andrewm@5
|
149 case '?':
|
andrewm@5
|
150 default:
|
andrewm@5
|
151 return c;
|
andrewm@5
|
152 }
|
andrewm@5
|
153 }
|
andrewm@5
|
154 }
|
andrewm@5
|
155
|
andrewm@5
|
156 // This function prints standard usage information for default arguments
|
andrewm@5
|
157 // Call from within your own usage function
|
andrewm@5
|
158 void BeagleRT_usage()
|
andrewm@5
|
159 {
|
andrewm@12
|
160 std::cerr << " --period [-p] period: Set the hardware period (buffer) size in matrix samples\n";
|
andrewm@12
|
161 std::cerr << " --dac-level [-D] dBs: Set the DAC output level (0dB max; -63.5dB min)\n";
|
andrewm@12
|
162 std::cerr << " --adc-level [-A] dBs: Set the ADC input level (0dB max; -12dB min)\n";
|
andrewm@12
|
163 std::cerr << " --hp-level [-H] dBs: Set the headphone output level (0dB max; -63.5dB min)\n";
|
andrewm@12
|
164 std::cerr << " --mute-speaker [-M] val: Set whether to mute the speaker initially (default: no)\n";
|
andrewm@12
|
165 std::cerr << " --use-matrix [-m] val: Set whether to use ADC/DAC matrix\n";
|
andrewm@12
|
166 std::cerr << " --matrix-channels [-C] val: Set the number of ADC/DAC channels (default: 8)\n";
|
andrewm@12
|
167 std::cerr << " --verbose [-v]: Enable verbose logging information\n";
|
andrewm@5
|
168 }
|