1 /************************************************************************
2 IMPORTANT NOTE : this file contains two clearly delimited sections :
3 the ARCHITECTURE section (in two parts) and the USER section. Each section
4 is governed by its own copyright and license. Please check individually
5 each section for license and copyright information.
6 *************************************************************************/
7
8 /******************* BEGIN matlabplot.cpp ****************/
9 /************************************************************************
10 FAUST Architecture File
11 Copyright (C) 2003-2019 GRAME, Centre National de Creation Musicale
12 ---------------------------------------------------------------------
13 This Architecture section is free software; you can redistribute it
14 and/or modify it under the terms of the GNU General Public License
15 as published by the Free Software Foundation; either version 3 of
16 the License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; If not, see <http://www.gnu.org/licenses/>.
25
26 EXCEPTION : As a special exception, you may create a larger work
27 that contains this FAUST architecture section and distribute
28 that work under terms of your choice, so long as this FAUST
29 architecture section is not modified.
30
31 ************************************************************************
32 ************************************************************************/
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <limits.h>
38 #include <math.h>
39 #include <errno.h>
40 #include <time.h>
41 #include <unistd.h>
42 #include <string>
43 #include <iostream>
44 #include <iomanip>
45
46 #include "faust/gui/UI.h"
47 #include "faust/gui/console.h"
48 #include "faust/gui/meta.h"
49 #include "faust/audio/channels.h"
50 #include "faust/dsp/dsp-adapter.h"
51 #include "faust/dsp/dsp-combiner.h"
52
53 using namespace std;
54
55 /******************************************************************************
56 *******************************************************************************
57
58 VECTOR INTRINSICS
59
60 *******************************************************************************
61 *******************************************************************************/
62
63 <<includeIntrinsic>>
64
65 /********************END ARCHITECTURE SECTION (part 1/2)****************/
66
67 /**************************BEGIN USER SECTION **************************/
68
69 <<includeclass>>
70
71 /***************************END USER SECTION ***************************/
72
73 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
74
75 dsp* DSP;
76
77 std::list<GUI*> GUI::fGuiList;
78 ztimedmap GUI::gTimedZoneMap;
79
80 #define kFrames 512
81
main(int argc,char * argv[])82 int main(int argc, char* argv[])
83 {
84 FAUSTFLOAT start_at_sample, nb_samples, sample_rate, down_sample, up_sample, filter_type;
85
86 DSP = new mydsp();
87
88 CMDUI* interface = new CMDUI(argc, argv);
89 DSP->buildUserInterface(interface);
90
91 interface->addOption("-s", &start_at_sample, 0, 0.0, 100000000.0);
92 interface->addOption("-n", &nb_samples, 16, 0.0, 100000000.0);
93 interface->addOption("-r", &sample_rate, 44100.0, 1.0, 192000.0);
94
95 // For up/down sampling
96 interface->addOption("-ds", &down_sample, 1.0, 1.0, 16.0);
97 interface->addOption("-us", &up_sample, 1.0, 1.0, 16.0);
98 interface->addOption("-filter", &filter_type, 1.0, 1.0, 4.0);
99
100 if ((down_sample != 1.0) && (up_sample != 1.0)) {
101 cerr << "ERROR : -ds '" << down_sample << "' and -us '" << up_sample << "' cannot be used at the same time !\n";
102 exit(1);
103 }
104
105 // setup up/down sampling, FC factor is expressed as a Double<INT,DENOM> to allow template specialization
106 int filter = int(filter_type);
107 if (down_sample != 1.0) {
108 int ds = int(down_sample);
109 dsp* busN = new dsp_bus(DSP->getNumOutputs());
110 switch (filter) {
111 case 1:
112 if (ds == 2) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3<Double<45,100>, 2, float> >(busN));
113 else if (ds == 4) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3<Double<45,100>, 4, float> >(busN));
114 else if (ds == 8) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3<Double<45,100>, 8, float> >(busN));
115 else if (ds == 16) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3<Double<45,100>, 16, float> >(busN));
116 else cerr << "Downsampling factor must be a power of two and <= 16\n";
117 break;
118 case 2:
119 if (ds == 2) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass4<Double<45,100>, 2, float> >(busN));
120 else if (ds == 4) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass4<Double<45,100>, 4, float> >(busN));
121 else if (ds == 8) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass4<Double<45,100>, 8, float> >(busN));
122 else if (ds == 16) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass4<Double<45,100>, 16, float> >(busN));
123 else cerr << "Downsampling factor must be a power of two and <= 16\n";
124 break;
125 case 3:
126 if (ds == 2) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3e<Double<45,100>, 2, float> >(busN));
127 else if (ds == 4) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3e<Double<45,100>, 4, float> >(busN));
128 else if (ds == 8) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3e<Double<45,100>, 8, float> >(busN));
129 else if (ds == 16) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass3e<Double<45,100>, 16, float> >(busN));
130 else cerr << "Downsampling factor must be a power of two and <= 16\n";
131 break;
132 case 4:
133 if (ds == 2) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass6e<Double<45,100>, 2, float> >(busN));
134 else if (ds == 4) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass6e<Double<45,100>, 4, float> >(busN));
135 else if (ds == 8) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass6e<Double<45,100>, 8, float> >(busN));
136 else if (ds == 16) DSP = new dsp_sequencer(DSP, new dsp_down_sampler<LowPass6e<Double<45,100>, 16, float> >(busN));
137 break;
138 default:
139 cerr << "Incorrect filter type : " << filter << endl;
140 break;
141 }
142 } else if (up_sample != 1.0) {
143 int up = int(up_sample);
144 dsp* busN = new dsp_bus(DSP->getNumOutputs());
145 switch (filter) {
146 case 1:
147 if (up == 2) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3<Double<45,100>, 2, float> >(busN));
148 else if (up == 4) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3<Double<45,100>, 4, float> >(busN));
149 else if (up == 8) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3<Double<45,100>, 8, float> >(busN));
150 else if (up == 16) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3<Double<45,100>, 16, float> >(busN));
151 else cerr << "Upsampling factor must be a power of two and <= 16\n";
152 break;
153 case 2:
154 if (up == 2) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass4<Double<45,100>, 2, float> >(busN));
155 else if (up == 4) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass4<Double<45,100>, 4, float> >(busN));
156 else if (up == 8) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass4<Double<45,100>, 8, float> >(busN));
157 else if (up == 16) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass4<Double<45,100>, 16, float> >(busN));
158 else cerr << "Upsampling factor must be a power of two and <= 16\n";
159 break;
160 case 3:
161 if (up == 2) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3e<Double<45,100>, 2, float> >(busN));
162 else if (up == 4) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3e<Double<45,100>, 4, float> >(busN));
163 else if (up == 8) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3e<Double<45,100>, 8, float> >(busN));
164 else if (up == 16) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass3e<Double<45,100>, 16, float> >(busN));
165 else cerr << "Upsampling factor must be a power of two and <= 16\n";
166 break;
167 case 4:
168 if (up == 2) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass6e<Double<45,100>, 2, float> >(busN));
169 else if (up == 4) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass6e<Double<45,100>, 4, float> >(busN));
170 else if (up == 8) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass6e<Double<45,100>, 8, float> >(busN));
171 else if (up == 16) DSP = new dsp_sequencer(DSP, new dsp_up_sampler<LowPass6e<Double<45,100>, 16, float> >(busN));
172 break;
173 default:
174 cerr << "Incorrect filter type : " << filter << endl;
175 break;
176 }
177 }
178
179 // SR has to be read before DSP init
180 interface->process_one_init("-r");
181
182 // init signal processor and the user interface values
183 DSP->init(int(sample_rate));
184
185 // modify the UI values according to the command line options, after init
186 interface->process_command();
187
188 // prepare input channels (if any) with an impulse
189 int nins = DSP->getNumInputs();
190 channels inchan(kFrames, nins);
191 inchan.impulse(); // after each compute we will zero them
192
193 // prepare output channels
194 int nouts = DSP->getNumOutputs();
195 channels outchan(kFrames, nouts);
196
197 // print usage info:
198 printf("%% Usage: octave --persist thisfile.m\n\n");
199
200 // print matlab-compatible matrix syntax followed by a plot command:
201 printf("faustout = [ ...\n");
202
203 // skip <start> samples
204 int start = int(start_at_sample);
205 while (start > kFrames) {
206 DSP->compute(kFrames, inchan.buffers(), outchan.buffers());
207 inchan.zero();
208 start -= kFrames;
209 }
210 if (start > 0) {
211 DSP->compute(start, inchan.buffers(), outchan.buffers());
212 }
213 // end skip
214
215 int nbsamples = int(nb_samples);
216 cout << setprecision(numeric_limits<FAUSTFLOAT>::max_digits10);
217
218 // print by buffer
219 while (nbsamples > kFrames) {
220 DSP->compute(kFrames, inchan.buffers(), outchan.buffers());
221 inchan.zero();
222 for (int i = 0; i < kFrames; i++) {
223 for (int c = 0; c < nouts; c++) {
224 cout << " " << outchan.buffers()[c][i];
225 }
226 if (i < kFrames-1) {
227 printf("; ...\n");
228 } else {
229 printf("; ...\n%%---- Chunk Boundary ----\n");
230 }
231 }
232 nbsamples -= kFrames;
233 }
234
235 // print remaining frames
236 if (nbsamples) {
237 DSP->compute(nbsamples, inchan.buffers(), outchan.buffers());
238 inchan.zero();
239 for (int i = 0; i < nbsamples; i++) {
240 for (int c = 0; c < nouts; c++) {
241 cout << " " << outchan.buffers()[c][i];
242 }
243 printf("; ...\n");
244 }
245 }
246 printf("];\n\n");
247 printf("plot(faustout);\n");
248 printf("title('Plot generated by %s made using ''faust -a matlabplot.cpp ...''');\n", argv[0]);
249 printf("xlabel('Time (samples)');\n");
250 printf("ylabel('Amplitude');\n");
251 if (nouts > 0) {
252 printf("legend(");
253 for (int c = 0; c < nouts; c++) {
254 printf("'channel %d'", c+1);
255 if (c < nouts-1) { printf(","); }
256 }
257 printf(");\n");
258 printf("print -dpdf %s.pdf;\n", argv[0]);
259 }
260
261 delete DSP;
262 return 0;
263 }
264
265 /******************* END matlabplot.cpp ****************/
266