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