comparison projects/filter_FIR/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 021ac8a1a4f9
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;
18
19 int gPeriodSize = 8; // Period size in sensor frames
20 19
21 // Load samples from file 20 // Load samples from file
22 int initFile(string file, SampleData *smp)//float *& smp) 21 int initFile(string file, SampleData *smp)//float *& smp)
23 { 22 {
24 SNDFILE *sndfile ; 23 SNDFILE *sndfile ;
79 } 78 }
80 79
81 // Print usage information 80 // Print usage information
82 void usage(const char * processName) 81 void usage(const char * processName)
83 { 82 {
84 cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; 83 cerr << "Usage: " << processName << " [options]" << endl;
85 cerr << " -h: Print this menu\n"; 84
86 cerr << " -v: Enable verbose messages\n"; 85 BeagleRT_usage();
87 cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; 86
88 cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; 87 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"; 88 cerr << " --help [-h]: Print this menu\n";
90 } 89 }
91 90
92 int main(int argc, char *argv[]) 91 int main(int argc, char *argv[])
93 { 92 {
94 int verbose = 0; // Verbose printing level 93 RTAudioSettings settings; // Standard audio settings
95 int useMatrix = 0; // Whether to use the matrix or just audio
96 string fileName; // Name of the sample to load 94 string fileName; // Name of the sample to load
97 95
98 SampleData sampleData; // User define structure to pass data retrieved from file to render function 96 SampleData sampleData; // User define structure to pass data retrieved from file to render function
99 sampleData.samples = 0; 97 sampleData.samples = 0;
100 sampleData.sampleLen = -1; 98 sampleData.sampleLen = -1;
101 99
100
101 struct option customOptions[] =
102 {
103 {"help", 0, NULL, 'h'},
104 {"file", 1, NULL, 'f'},
105 {NULL, 0, NULL, 0}
106 };
107
108 // Set default settings
109 BeagleRT_defaultSettings(&settings);
110
102 // Parse command-line arguments 111 // Parse command-line arguments
103 while (1) { 112 while (1) {
104 int c; 113 int c;
105 if ((c = getopt(argc, argv, "hp:vms:")) < 0) 114 if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0)
106 break; 115 break;
107 switch (c) { 116 switch (c) {
108 case 'h': 117 case 'h':
109 usage(basename(argv[0])); 118 usage(basename(argv[0]));
110 exit(0); 119 exit(0);
111 case 'p':
112 gPeriodSize = atoi(optarg);
113 if(gPeriodSize < 1)
114 gPeriodSize = 1;
115 break;
116 case 'v':
117 verbose = 1;
118 break;
119 case 'm':
120 useMatrix = 1;
121 break;
122 case 'f': 120 case 'f':
123 fileName = string((char *)optarg); 121 fileName = string((char *)optarg);
124 break; 122 break;
125 case '?': 123 case '?':
126 default: 124 default:
128 exit(1); 126 exit(1);
129 } 127 }
130 } 128 }
131 129
132 if(fileName.empty()){ 130 if(fileName.empty()){
133 fileName = "filter/longsample.wav"; 131 fileName = "longsample.wav";
134 } 132 }
135 133
136 // Set verbose logging information (optional by using value > 0; default is 0) 134 if(settings.verbose) {
137 setVerboseLevel(verbose);
138
139 if(verbose) {
140 cout << "Starting with period size " << gPeriodSize << endl;
141 if(useMatrix)
142 cout << "Matrix enabled\n";
143 else
144 cout << "Matrix disabled\n";
145 cout << "Loading file " << fileName << endl; 135 cout << "Loading file " << fileName << endl;
146 } 136 }
147 137
148 // Load file 138 // Load file
149 if(initFile(fileName, &sampleData) != 0) 139 if(initFile(fileName, &sampleData) != 0)
150 { 140 {
151 cout << "Error: unable to load samples " << endl; 141 cout << "Error: unable to load samples " << endl;
152 return -1; 142 return -1;
153 } 143 }
154 144
155 if(verbose) 145 if(settings.verbose)
156 cout << "File contains " << sampleData.sampleLen << " samples" << endl; 146 cout << "File contains " << sampleData.sampleLen << " samples" << endl;
157 147
148
158 // Initialise the PRU audio device 149 // Initialise the PRU audio device
159 if(initAudio(gPeriodSize, useMatrix, &sampleData) != 0) { 150 if(BeagleRT_initAudio(&settings, &sampleData) != 0) {
160 cout << "Error: unable to initialise audio" << endl; 151 cout << "Error: unable to initialise audio" << endl;
161 return -1; 152 return -1;
162 } 153 }
163 154
164 // Start the audio device running 155 // Start the audio device running
165 if(startAudio()) { 156 if(BeagleRT_startAudio()) {
166 cout << "Error: unable to start real-time audio" << endl; 157 cout << "Error: unable to start real-time audio" << endl;
167 return -1; 158 return -1;
168 } 159 }
169 160
170 // Set up interrupt handler to catch Control-C 161 // Set up interrupt handler to catch Control-C
174 while(!gShouldStop) { 165 while(!gShouldStop) {
175 usleep(100000); 166 usleep(100000);
176 } 167 }
177 168
178 // Stop the audio device 169 // Stop the audio device
179 stopAudio(); 170 BeagleRT_stopAudio();
180
181 if(verbose) {
182 cout << "Cleaning up..." << endl;
183 }
184 171
185 // Clean up any resources allocated for audio 172 // Clean up any resources allocated for audio
186 cleanupAudio(); 173 BeagleRT_cleanupAudio();
187 174
188 // All done! 175 // All done!
189 return 0; 176 return 0;
190 } 177 }
178