HulaLoop
Simple cross-platform audio loopback and recording.
CLIArgs.h
1 #ifndef HL_CLI_ARGS_H
2 #define HL_CLI_ARGS_H
3 
4 #include <cstdio>
5 #include <QCommandLineParser>
6 
7 #include <hlaudio/hlaudio.h>
8 #include <hlcontrol/hlcontrol.h>
9 
10 #include "CLICommon.h"
11 
12 using namespace hula;
13 
19 #define HL_OUT_FILE_SO "f"
20 #define HL_OUT_FILE_LO "out-file"
21 #define HL_DELAY_TIME_SO "d"
22 #define HL_DELAY_TIME_LO "delay"
23 #define HL_RECORD_TIME_SO "t"
24 #define HL_RECORD_TIME_LO "time"
25 #define HL_TRIGGER_RECORD_SO "r"
26 #define HL_TRIGGER_RECORD_LO "record"
27 #define HL_SAMPLE_RATE_SO "s"
28 #define HL_SAMPLE_RATE_LO "sample-rate"
29 #define HL_ENCODING_SO "e"
30 #define HL_ENCODING_LO "encoding"
31 #define HL_INPUT_DEVICE_SO "i"
32 #define HL_INPUT_DEVICE_LO "input-device"
33 #define HL_OUTPUT_DEVICE_SO "o"
34 #define HL_OUTPUT_DEVICE_LO "output-device"
35 #define HL_LIST_DEVICES_SO "l"
36 #define HL_LIST_DEVICES_LO "list"
37 
38 typedef struct HulaImmediateArgs
39 {
40  bool startRecord = false;
41  bool exit = false;
43 
49 void invalidArg(std::string name, QString arg, std::string message = "")
50 {
51  fprintf(stderr, "Invalid argument '%s' provided to option '%s'.\n", arg.toStdString().c_str(), name.c_str());
52  if (message.size() > 0)
53  {
54  fprintf(stderr, "%s\n", message.c_str());
55  }
56 }
57 
65 bool parseArgsQt(QCoreApplication &app, HulaImmediateArgs &extraArgs)
66 {
67  QCommandLineParser parser;
68  parser.setApplicationDescription("Simple cross-platform audio loopback and recording.");
69 
70  parser.addHelpOption();
71  parser.addVersionOption();
72 
73  parser.addOptions(
74  {
75  {{HL_OUT_FILE_SO, HL_OUT_FILE_LO}, QCoreApplication::translate("main", "Path to audio output file."), QCoreApplication::translate("main", "out-file-path")},
76  {{HL_DELAY_TIME_SO, HL_DELAY_TIME_LO}, QCoreApplication::translate("main", "Duration, in seconds, of the countdown timer before record."), QCoreApplication::translate("main", "delay")},
77  {{HL_RECORD_TIME_SO, HL_RECORD_TIME_LO}, QCoreApplication::translate("main", "Duration, in seconds, of the record."), QCoreApplication::translate("main", "record duration")},
78  {{HL_TRIGGER_RECORD_SO, HL_TRIGGER_RECORD_LO}, QCoreApplication::translate("main", "Start the countdown/record immediately.")},
79  {{HL_SAMPLE_RATE_SO, HL_SAMPLE_RATE_LO}, QCoreApplication::translate("main", "Desired sample rate of the output file."), QCoreApplication::translate("main", "sample rate")},
80  //{{"b", "bit-depth"}, QCoreApplication::translate("main", "Sample format for the output file. Valid options are 8, 8u, 16, 16u, 32, 32u, 32f. This will default to 32f.")},
81  {{HL_ENCODING_SO, HL_ENCODING_LO}, QCoreApplication::translate("main", "Encoding format for the output file. Valid options are WAV and MP3. This will default to WAV."), QCoreApplication::translate("main", "encoding")},
82  {{HL_INPUT_DEVICE_SO, HL_INPUT_DEVICE_LO}, QCoreApplication::translate("main", "System name of the input device. This will default if not provided."), QCoreApplication::translate("main", "input-device-name")},
83  {{HL_OUTPUT_DEVICE_SO, HL_OUTPUT_DEVICE_LO}, QCoreApplication::translate("main", "System name of the output device. This will default if not provided."), QCoreApplication::translate("main", "output-device-name")},
84  {{HL_LIST_DEVICES_SO, HL_LIST_DEVICES_LO}, QCoreApplication::translate("main", "List available input and output devices.")}
85 
86  // -d --delay Countdown timer before record.
87  // -l --length Record duration.
88  // -r --record Start recording/countdown timer immediately
89  // -s --sample-rate Sample rate
90  // -e --encoding Encoding format: valid formats WAV, MP3, guess from file, default to WAV
91  // -i --input-device System name of input device, will default
92  // -o --output-device System name of output device, will default
93  });
94 
95  // This will exit if any of the args are incorrect
96  parser.process(app);
97 
98  // Setup the settings module
100 
101  if (parser.isSet(HL_OUT_FILE_LO))
102  {
103  settings->setOutputFilePath(parser.value(HL_OUT_FILE_LO).toStdString());
104  }
105 
106  if (parser.isSet(HL_DELAY_TIME_LO))
107  {
108  bool ok = false;
109  double delay = parser.value(HL_DELAY_TIME_LO).toDouble(&ok);
110  if (!ok)
111  {
112  invalidArg(HL_DELAY_TIME_LO, parser.value(HL_DELAY_TIME_LO));
113  return false;
114  }
115  settings->setDelayTimer(delay);
116  }
117 
118  if (parser.isSet(HL_RECORD_TIME_LO))
119  {
120  bool ok = false;
121  double duration = parser.value(HL_RECORD_TIME_LO).toDouble(&ok);
122  if (!ok)
123  {
124  invalidArg(HL_RECORD_TIME_LO, parser.value(HL_RECORD_TIME_LO));
125  return false;
126  }
127  settings->setRecordDuration(duration);
128  }
129 
130  if (parser.isSet(HL_TRIGGER_RECORD_LO))
131  {
132  extraArgs.startRecord = true;
133  }
134 
135  if (parser.isSet(HL_SAMPLE_RATE_LO))
136  {
137  bool ok = false;
138  int rate = parser.value(HL_SAMPLE_RATE_LO).toInt(&ok);
139  if (!ok)
140  {
141  invalidArg(HL_SAMPLE_RATE_LO, parser.value(HL_SAMPLE_RATE_LO));
142  return false;
143  }
144  settings->setSampleRate(rate);
145  }
146 
147  if (parser.isSet(HL_ENCODING_LO))
148  {
149  std::string encoding = parser.value(HL_ENCODING_LO).toStdString();
150  if (encoding == "WAV")
151  {
152  encoding = WAV;
153  }
154  else
155  {
156  invalidArg(HL_ENCODING_LO, parser.value(HL_ENCODING_LO), "Only WAV format is supported at this time.");
157  return false;
158  }
159  }
160 
161  if (parser.isSet(HL_INPUT_DEVICE_LO))
162  {
163  std::string device = parser.value(HL_INPUT_DEVICE_LO).toStdString();
164  // TODO: See if we can check device list here
165  settings->setDefaultInputDeviceName(device);
166  }
167 
168  if (parser.isSet(HL_OUTPUT_DEVICE_LO))
169  {
170  std::string device = parser.value(HL_OUTPUT_DEVICE_LO).toStdString();
171  // TODO: See if we can check device list here
172  settings->setDefaultOutputDeviceName(device);
173  }
174 
175  if (parser.isSet(HL_LIST_DEVICES_LO))
176  {
177  Transport t;
178 
179  printf("\n-------- Device List --------\n");
180  printDeviceList(&t);
181 
182  extraArgs.exit = true;
183  }
184 
185  return true;
186 }
187 
188 #endif // END HL_CLI_ARGS_H
<hlcontrol/hlcontrol.h>
Definition: CLIArgs.h:38
void setDelayTimer(double)
Set the length of the delay timer in seconds.
Definition: HulaAudioSettings.cpp:269
Extra class for managing the state of the application and all audio related processes.
Definition: Transport.h:29
void setRecordDuration(double)
Get the length of the record in seconds.
Definition: HulaAudioSettings.cpp:280
void setOutputFilePath(std::string)
Set the path of the output file specified at startup or during the file save routine.
Definition: HulaAudioSettings.cpp:246
void setSampleRate(int)
Set the number of channels for the current global device configuration.
Definition: HulaAudioSettings.cpp:200
<hlaudio/hlaudio.h>
static HulaSettings * getInstance()
Retreive the singular instance of HulaSettings or construct a new one if none exists.
Definition: HulaSettings.cpp:24
void setDefaultInputDeviceName(std::string)
Set the name of the device that should be initially selected for record.
Definition: HulaAudioSettings.cpp:224
void setDefaultOutputDeviceName(std::string)
Set the name of the device that should be initially selected for playback.
Definition: HulaAudioSettings.cpp:235
Definition: Controller.h:11
Singleton class containing all settings for the application.
Definition: HulaSettings.h:12