Mercurial > hg > beaglert
comparison projects/filter_IIR/main.cpp @ 5:09f03ac40fcc
API improvements and cleanups. Now all common audio command-line options can be parsed automatically.
| author | andrewm |
|---|---|
| date | Sat, 08 Nov 2014 16:16:55 +0100 |
| parents | f34c63568523 |
| children | 323a4eb9b7c0 |
comparison
equal
deleted
inserted
replaced
| 4:f34c63568523 | 5:09f03ac40fcc |
|---|---|
| 8 #include <iostream> | 8 #include <iostream> |
| 9 #include <cstdlib> | 9 #include <cstdlib> |
| 10 #include <libgen.h> | 10 #include <libgen.h> |
| 11 #include <signal.h> | 11 #include <signal.h> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <getopt.h> | |
| 13 #include <sndfile.h> // to load audio files | 14 #include <sndfile.h> // to load audio files |
| 14 #include "../../include/RTAudio.h" | 15 #include "../../include/RTAudio.h" |
| 15 #include "SampleData.h" | 16 #include "SampleData.h" |
| 16 | 17 |
| 17 using namespace std; | 18 using namespace std; |
| 68 sf_close(sndfile); | 69 sf_close(sndfile); |
| 69 | 70 |
| 70 return 0; | 71 return 0; |
| 71 } | 72 } |
| 72 | 73 |
| 73 | |
| 74 // Handle Ctrl-C by requesting that the audio rendering stop | 74 // Handle Ctrl-C by requesting that the audio rendering stop |
| 75 void interrupt_handler(int var) | 75 void interrupt_handler(int var) |
| 76 { | 76 { |
| 77 //rt_task_delete ((RT_TASK *) &gTriggerSamplesTask); | 77 //rt_task_delete ((RT_TASK *) &gTriggerSamplesTask); |
| 78 gShouldStop = true; | 78 gShouldStop = true; |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Print usage information | 81 // Print usage information |
| 82 void usage(const char * processName) | 82 void usage(const char * processName) |
| 83 { | 83 { |
| 84 cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; | 84 cerr << "Usage: " << processName << " [options]" << endl; |
| 85 cerr << " -h: Print this menu\n"; | 85 |
| 86 cerr << " -v: Enable verbose messages\n"; | 86 BeagleRT_usage(); |
| 87 cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; | 87 |
| 88 cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; | 88 cerr << " --file [-f] filename: Name of the file to load (default is \"longsample.wav\")\n"; |
| 89 cerr << " -f filename: Name of the file to load (default is \"sample.wav\")\n"; | 89 cerr << " --cutfreq [-c] freq: Set the cut off frequency of the filter in Hz\n"; |
| 90 cerr << " -c freq: Set the cut off frequency of the filter in Hz\n"; | 90 cerr << " --help [-h]: Print this menu\n"; |
| 91 } | 91 } |
| 92 | 92 |
| 93 int main(int argc, char *argv[]) | 93 int main(int argc, char *argv[]) |
| 94 { | 94 { |
| 95 int verbose = 0; // Verbose printing level | 95 RTAudioSettings settings; // Standard audio settings |
| 96 int periodSize = 8; // Period size in sensor frames | |
| 97 int useMatrix = 0; // Whether to use the matrix or just audio | |
| 98 string fileName; // Name of the sample to load | 96 string fileName; // Name of the sample to load |
| 99 | 97 |
| 100 SampleData sampleData; // User define structure to pass data retrieved from file to render function | 98 SampleData sampleData; // User define structure to pass data retrieved from file to render function |
| 101 sampleData.samples = 0; | 99 sampleData.samples = 0; |
| 102 sampleData.sampleLen = -1; | 100 sampleData.sampleLen = -1; |
| 103 | 101 |
| 102 | |
| 103 struct option customOptions[] = | |
| 104 { | |
| 105 {"help", 0, NULL, 'h'}, | |
| 106 {"cutfreq", 1, NULL, 'c'}, | |
| 107 {"file", 1, NULL, 'f'}, | |
| 108 {NULL, 0, NULL, 0} | |
| 109 }; | |
| 110 | |
| 111 // Set default settings | |
| 112 BeagleRT_defaultSettings(&settings); | |
| 113 | |
| 104 // Parse command-line arguments | 114 // Parse command-line arguments |
| 105 while (1) { | 115 while (1) { |
| 106 int c; | 116 int c; |
| 107 if ((c = getopt(argc, argv, "hp:vms:")) < 0) | 117 if ((c = BeagleRT_getopt_long(argc, argv, "hf:c:", customOptions, &settings)) < 0) |
| 108 break; | 118 break; |
| 109 switch (c) { | 119 switch (c) { |
| 110 case 'h': | 120 case 'h': |
| 111 usage(basename(argv[0])); | 121 usage(basename(argv[0])); |
| 112 exit(0); | 122 exit(0); |
| 113 case 'p': | |
| 114 periodSize = atoi(optarg); | |
| 115 if(periodSize < 1) | |
| 116 periodSize = 1; | |
| 117 break; | |
| 118 case 'v': | |
| 119 verbose = 1; | |
| 120 break; | |
| 121 case 'm': | |
| 122 useMatrix = 1; | |
| 123 break; | |
| 124 case 'f': | 123 case 'f': |
| 125 fileName = string((char *)optarg); | 124 fileName = string((char *)optarg); |
| 126 break; | 125 break; |
| 127 case 'c': | 126 case 'c': |
| 128 gCutFreq = atof(optarg); | 127 gCutFreq = atof(optarg); |
| 133 exit(1); | 132 exit(1); |
| 134 } | 133 } |
| 135 } | 134 } |
| 136 | 135 |
| 137 if(fileName.empty()){ | 136 if(fileName.empty()){ |
| 138 fileName = "filter/longsample.wav"; | 137 fileName = "longsample.wav"; |
| 139 } | 138 } |
| 140 | 139 |
| 141 // Set verbose logging information (optional by using value > 0; default is 0) | 140 if(settings.verbose) { |
| 142 setVerboseLevel(verbose); | |
| 143 | |
| 144 if(verbose) { | |
| 145 cout << "Starting with period size " << periodSize << " and cut-off frequency" << gCutFreq << endl; | |
| 146 if(useMatrix) | |
| 147 cout << "Matrix enabled\n"; | |
| 148 else | |
| 149 cout << "Matrix disabled\n"; | |
| 150 cout << "Loading file " << fileName << endl; | 141 cout << "Loading file " << fileName << endl; |
| 151 } | 142 } |
| 152 | 143 |
| 153 // Load file | 144 // Load file |
| 154 if(initFile(fileName, &sampleData) != 0) | 145 if(initFile(fileName, &sampleData) != 0) |
| 155 { | 146 { |
| 156 cout << "Error: unable to load samples " << endl; | 147 cout << "Error: unable to load samples " << endl; |
| 157 return -1; | 148 return -1; |
| 158 } | 149 } |
| 159 | 150 |
| 160 if(verbose) | 151 if(settings.verbose) |
| 161 cout << "File contains " << sampleData.sampleLen << " samples" << endl; | 152 cout << "File contains " << sampleData.sampleLen << " samples" << endl; |
| 162 | 153 |
| 154 | |
| 163 // Initialise the PRU audio device | 155 // Initialise the PRU audio device |
| 164 if(initAudio(periodSize, useMatrix, &sampleData) != 0) { | 156 if(BeagleRT_initAudio(&settings, &sampleData) != 0) { |
| 165 cout << "Error: unable to initialise audio" << endl; | 157 cout << "Error: unable to initialise audio" << endl; |
| 166 return -1; | 158 return -1; |
| 167 } | 159 } |
| 168 | 160 |
| 169 // Start the audio device running | 161 // Start the audio device running |
| 170 if(startAudio()) { | 162 if(BeagleRT_startAudio()) { |
| 171 cout << "Error: unable to start real-time audio" << endl; | 163 cout << "Error: unable to start real-time audio" << endl; |
| 172 return -1; | 164 return -1; |
| 173 } | 165 } |
| 174 | 166 |
| 175 // Set up interrupt handler to catch Control-C | 167 // Set up interrupt handler to catch Control-C |
| 179 while(!gShouldStop) { | 171 while(!gShouldStop) { |
| 180 usleep(100000); | 172 usleep(100000); |
| 181 } | 173 } |
| 182 | 174 |
| 183 // Stop the audio device | 175 // Stop the audio device |
| 184 stopAudio(); | 176 BeagleRT_stopAudio(); |
| 185 | |
| 186 if(verbose) { | |
| 187 cout << "Cleaning up..." << endl; | |
| 188 } | |
| 189 | 177 |
| 190 // Clean up any resources allocated for audio | 178 // Clean up any resources allocated for audio |
| 191 cleanupAudio(); | 179 BeagleRT_cleanupAudio(); |
| 192 | 180 |
| 193 // All done! | 181 // All done! |
| 194 return 0; | 182 return 0; |
| 195 } | 183 } |
| 184 |
