comparison examples/04-Audio/FFT-phase-vocoder/main.cpp @ 464:8fcfbfb32aa0 prerelease

Examples reorder with subdirectories. Added header to each project. Moved Doxygen to bottom of render.cpp.
author Robert Jack <robert.h.jack@gmail.com>
date Mon, 20 Jun 2016 16:20:38 +0100
parents
children
comparison
equal deleted inserted replaced
463:c47709e8b5c9 464:8fcfbfb32aa0
1 /*
2 ____ _____ _ _
3 | __ )| ____| | / \
4 | _ \| _| | | / _ \
5 | |_) | |___| |___ / ___ \
6 |____/|_____|_____/_/ \_\
7
8 The platform for ultra-low latency audio and sensor processing
9
10 http://bela.io
11
12 A project of the Augmented Instruments Laboratory within the
13 Centre for Digital Music at Queen Mary University of London.
14 http://www.eecs.qmul.ac.uk/~andrewm
15
16 (c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
17 Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
18 Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
19
20 The Bela software is distributed under the GNU Lesser General Public License
21 (LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
22 */
23
24 #include <iostream>
25 #include <cstdlib>
26 #include <cstdio>
27 #include <libgen.h>
28 #include <signal.h>
29 #include <getopt.h>
30 #include <unistd.h>
31 #include <sys/time.h>
32 #include <sndfile.h> // to load audio files
33 #include "SampleData.h"
34 #include <Bela.h>
35
36 using namespace std;
37
38 // Global variables used by getCurrentTime()
39 unsigned long long gFirstSeconds, gFirstMicroseconds;
40
41 // Load samples from file
42 int initFile(string file, SampleData *smp)//float *& smp)
43 {
44 SNDFILE *sndfile ;
45 SF_INFO sfinfo ;
46
47 if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
48 cout << "Couldn't open file " << file << endl;
49 return 1;
50 }
51
52 int numChan = sfinfo.channels;
53 if(numChan != 1)
54 {
55 cout << "Error: " << file << " is not a mono file" << endl;
56 return 1;
57 }
58
59 smp->sampleLen = sfinfo.frames * numChan;
60 smp->samples = new float[smp->sampleLen];
61 if(smp == NULL){
62 cout << "Could not allocate buffer" << endl;
63 return 1;
64 }
65
66 int subformat = sfinfo.format & SF_FORMAT_SUBMASK;
67 int readcount = sf_read_float(sndfile, smp->samples, smp->sampleLen);
68
69 // Pad with zeros in case we couldn't read whole file
70 for(int k = readcount; k <smp->sampleLen; k++)
71 smp->samples[k] = 0;
72
73 if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
74 double scale ;
75 int m ;
76
77 sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
78 if (scale < 1e-10)
79 scale = 1.0 ;
80 else
81 scale = 32700.0 / scale ;
82 cout << "File samples scale = " << scale << endl;
83
84 for (m = 0; m < smp->sampleLen; m++)
85 smp->samples[m] *= scale;
86 }
87
88 sf_close(sndfile);
89
90 return 0;
91 }
92
93
94 // Handle Ctrl-C by requesting that the audio rendering stop
95 void interrupt_handler(int var)
96 {
97 gShouldStop = true;
98 }
99
100 // Print usage information
101 void usage(const char * processName)
102 {
103 cerr << "Usage: " << processName << " [options]" << endl;
104
105 Bela_usage();
106
107 cerr << " --help [-h]: Print this menu\n";
108 }
109
110 /* Function which returns the time since start of the program
111 * in (fractional) seconds.
112 */
113 double getCurrentTime(void) {
114 unsigned long long result;
115 struct timeval tv;
116
117 gettimeofday(&tv, NULL);
118 result = (tv.tv_sec - gFirstSeconds) * 1000000ULL + (tv.tv_usec - gFirstMicroseconds);
119 return (double)result / 1000000.0;
120 }
121 extern SampleData gSampleData;
122 int main(int argc, char *argv[])
123 {
124 BelaInitSettings settings; // Standard audio settings
125 struct timeval tv;
126 string fileName; // Name of the sample to load
127
128 struct option customOptions[] =
129 {
130 {"help", 0, NULL, 'h'},
131 {"file", 1, NULL, 'f'},
132 {NULL, 0, NULL, 0}
133 };
134
135 gSampleData.samples = 0;
136 gSampleData.sampleLen = -1;
137
138 // Set default settings
139 Bela_defaultSettings(&settings);
140
141 settings.periodSize = 32; // Larger period size by default, for testing
142
143 // Parse command-line arguments
144 while (1) {
145 int c;
146 if ((c = Bela_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0)
147 break;
148 switch (c) {
149 case 'h':
150 usage(basename(argv[0]));
151 exit(0);
152 case 'f':
153 fileName = string((char *)optarg);
154 break;
155 case '?':
156 default:
157 usage(basename(argv[0]));
158 exit(1);
159 }
160 }
161
162 if(fileName.empty()){
163 fileName = "sample.wav";
164 }
165
166
167 // Load file
168 if(initFile(fileName, &gSampleData) != 0)
169 {
170 cout << "Error: unable to load samples " << endl;
171 return -1;
172 }
173
174 if(settings.verbose)
175 cout << "File contains " << gSampleData.sampleLen << " samples" << endl;
176
177
178 // Initialise the PRU audio device
179 if(Bela_initAudio(&settings, &gSampleData) != 0) {
180 cout << "Error: unable to initialise audio" << endl;
181 return -1;
182 }
183
184 // Initialise time
185 gettimeofday(&tv, NULL);
186 gFirstSeconds = tv.tv_sec;
187 gFirstMicroseconds = tv.tv_usec;
188
189 // Start the audio device running
190 if(Bela_startAudio()) {
191 cout << "Error: unable to start real-time audio" << endl;
192 return -1;
193 }
194
195 // Set up interrupt handler to catch Control-C
196 signal(SIGINT, interrupt_handler);
197 signal(SIGTERM, interrupt_handler);
198
199 // Run until told to stop
200 while(!gShouldStop) {
201 usleep(100000);
202 }
203
204 // Stop the audio device
205 Bela_stopAudio();
206
207 // Clean up any resources allocated for audio
208 Bela_cleanupAudio();
209
210 // All done!
211 return 0;
212 }