├── .gitignore
├── Blipper.dsp
├── BlipperPatch.hpp
├── DroneBoxPatch.hpp
├── DualFreqShifter.dsp
├── DualFreqShifterPatch.hpp
├── DualPitchShifter.dsp
├── DualPitchShifterPatch.hpp
├── FrequencyShifter.lib
├── IIRHilbert.lib
├── README.md
├── StereoFreqShifter.dsp
├── StereoFreqShifterPatch.hpp
├── ThruZeroFlanger.dsp
├── ThruZeroFlangerPatch.hpp
├── WeirdPhaser.dsp
├── WeirdPhaserPatch.hpp
├── XFMPatch.hpp
├── buildVSTVersions.py
└── updateFaustPatches.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *-svg
--------------------------------------------------------------------------------
/Blipper.dsp:
--------------------------------------------------------------------------------
1 | declare name "Blipper";
2 | declare description "Envelope Follower controlling pitch of a triangle oscillator, good with percussive input";
3 | declare author "Oli Larkin (contact@olilarkin.co.uk)";
4 | declare copyright "Oliver Larkin";
5 | declare version "0.2";
6 | declare licence "GPL";
7 |
8 | import("stdfaust.lib");
9 |
10 | basepitch = hslider("BasePitch [unit:semitones] [OWL:PARAMETER_A]", 60, 24, 96, 0.1) : si.smooth(ba.tau2pole(0.01));
11 | pitchmod = hslider("PitchMod [unit:semitones] [OWL:PARAMETER_B]", 24, -64, 64, 1) : si.smooth(ba.tau2pole(0.005));
12 | //attack = hslider("Attack [unit:ms] [OWL:PARAMETER_C]", 2, 2, 1000, 1) : *(0.001) : max(1.0/float(ma.SR));
13 | release = hslider("Release [unit:ms] [OWL:PARAMETER_C]", 20, 2, 100, 1) : *(0.001) : max(1.0/float(ma.SR));
14 | attack = 0.005;
15 | mix = hslider("Mix[OWL:PARAMETER_D]", 0.5, 0, 1, 0.01) : si.smooth(ba.tau2pole(0.005));
16 |
17 | process(l, r) = l, r <: *(1-mix), *(1-mix), mono2stereo :> _,_
18 | with {
19 | mono2stereo = + : pc2 * mix <: _,_;
20 | pc2 = an.amp_follower_ud(attack, release) <: (ba.midikey2hz(basepitch + (pitchmod * _)): os.triangle), _ : *;
21 | };
22 |
--------------------------------------------------------------------------------
/BlipperPatch.hpp:
--------------------------------------------------------------------------------
1 | /* ------------------------------------------------------------
2 | author: "Oli Larkin (contact@olilarkin.co.uk)"
3 | copyright: "Oliver Larkin"
4 | name: "Blipper"
5 | version: "0.2"
6 | Code generated with Faust 2.0.a41 (http://faust.grame.fr)
7 | ------------------------------------------------------------ */
8 |
9 | #ifndef __Blipper_H__
10 | #define __Blipper_H__
11 | /************************************************************************
12 |
13 | IMPORTANT NOTE : this file contains two clearly delimited sections :
14 | the ARCHITECTURE section (in two parts) and the USER section. Each section
15 | is governed by its own copyright and license. Please check individually
16 | each section for license and copyright information.
17 | *************************************************************************/
18 |
19 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
20 |
21 | /************************************************************************
22 | FAUST Architecture File
23 | Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
24 | ---------------------------------------------------------------------
25 | This Architecture section is free software; you can redistribute it
26 | and/or modify it under the terms of the GNU General Public License
27 | as published by the Free Software Foundation; either version 3 of
28 | the License, or (at your option) any later version.
29 |
30 | This program is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with this program; If not, see .
37 |
38 | EXCEPTION : As a special exception, you may create a larger work
39 | that contains this FAUST architecture section and distribute
40 | that work under terms of your choice, so long as this FAUST
41 | architecture section is not modified.
42 |
43 |
44 | ************************************************************************
45 | ************************************************************************/
46 |
47 | #ifndef __BlipperPatch_h__
48 | #define __BlipperPatch_h__
49 |
50 | #include "StompBox.h"
51 | #include
52 | #include
53 | #include
54 |
55 |
56 | #ifndef __FaustCommonInfrastructure__
57 | #define __FaustCommonInfrastructure__
58 |
59 |
60 | /************************************************************************
61 | IMPORTANT NOTE : this file contains two clearly delimited sections :
62 | the ARCHITECTURE section (in two parts) and the USER section. Each section
63 | is governed by its own copyright and license. Please check individually
64 | each section for license and copyright information.
65 | *************************************************************************/
66 |
67 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
68 |
69 | /************************************************************************
70 | FAUST Architecture File
71 | Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
72 | ---------------------------------------------------------------------
73 | This Architecture section is free software; you can redistribute it
74 | and/or modify it under the terms of the GNU General Public License
75 | as published by the Free Software Foundation; either version 3 of
76 | the License, or (at your option) any later version.
77 |
78 | This program is distributed in the hope that it will be useful,
79 | but WITHOUT ANY WARRANTY; without even the implied warranty of
80 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 | GNU General Public License for more details.
82 |
83 | You should have received a copy of the GNU General Public License
84 | along with this program; If not, see .
85 |
86 | EXCEPTION : As a special exception, you may create a larger work
87 | that contains this FAUST architecture section and distribute
88 | that work under terms of your choice, so long as this FAUST
89 | architecture section is not modified.
90 |
91 |
92 | ************************************************************************
93 | ************************************************************************/
94 |
95 | /******************************************************************************
96 | *******************************************************************************
97 |
98 | FAUST DSP
99 |
100 | *******************************************************************************
101 | *******************************************************************************/
102 |
103 | #ifndef __dsp__
104 | #define __dsp__
105 |
106 | #ifndef FAUSTFLOAT
107 | #define FAUSTFLOAT float
108 | #endif
109 |
110 | class UI;
111 |
112 | //----------------------------------------------------------------
113 | // Signal processor definition
114 | //----------------------------------------------------------------
115 |
116 | class dsp {
117 |
118 | protected:
119 | int fSamplingFreq;
120 |
121 | public:
122 | dsp() {}
123 | virtual ~dsp() {}
124 |
125 | virtual int getNumInputs() = 0;
126 | virtual int getNumOutputs() = 0;
127 | virtual void buildUserInterface(UI* ui_interface) = 0;
128 | virtual void init(int samplingRate) = 0;
129 | virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
130 | };
131 |
132 | // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
133 | // flags to avoid costly denormals
134 | #ifdef __SSE__
135 | #include
136 | #ifdef __SSE2__
137 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
138 | #else
139 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
140 | #endif
141 | #else
142 | #define AVOIDDENORMALS
143 | #endif
144 |
145 | #endif
146 | #ifndef FAUST_UI_H
147 | #define FAUST_UI_H
148 |
149 | #ifndef FAUSTFLOAT
150 | #define FAUSTFLOAT float
151 | #endif
152 |
153 | /*******************************************************************************
154 | * UI : Faust User Interface
155 | * This abstract class contains only the method that the faust compiler can
156 | * generate to describe a DSP interface.
157 | ******************************************************************************/
158 |
159 | class UI
160 | {
161 |
162 | public:
163 |
164 | UI() {}
165 |
166 | virtual ~UI() {}
167 |
168 | // -- widget's layouts
169 |
170 | virtual void openTabBox(const char* label) = 0;
171 | virtual void openHorizontalBox(const char* label) = 0;
172 | virtual void openVerticalBox(const char* label) = 0;
173 | virtual void closeBox() = 0;
174 |
175 | // -- active widgets
176 |
177 | virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
178 | virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
179 | virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
180 | virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
181 | virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
182 |
183 | // -- passive widgets
184 |
185 | virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
186 | virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
187 |
188 | // -- metadata declarations
189 |
190 | virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val) {}
191 | };
192 |
193 | #endif
194 |
195 |
196 |
197 | struct Meta
198 | {
199 | virtual void declare(const char* key, const char* value) = 0;
200 | };
201 |
202 |
203 |
204 | /**************************************************************************************
205 |
206 | OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
207 | and a faust widget
208 |
209 | ***************************************************************************************/
210 |
211 | class OwlWidget
212 | {
213 | protected:
214 | Patch* fPatch; // needed to register and read owl parameters
215 | PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
216 | FAUSTFLOAT* fZone; // Faust widget zone
217 | const char* fLabel; // Faust widget label
218 | float fMin; // Faust widget minimal value
219 | float fSpan; // Faust widget value span (max-min)
220 |
221 | public:
222 | OwlWidget() :
223 | fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
224 | OwlWidget(const OwlWidget& w) :
225 | fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
226 | OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
227 | fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
228 | void bind() { fPatch->registerParameter(fParameter, fLabel); }
229 | void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
230 |
231 | };
232 |
233 |
234 | /**************************************************************************************
235 |
236 | OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
237 | the mapping between owl parameters and faust widgets. It relies on specific
238 | metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
239 | faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
240 | (the second knob).
241 |
242 | ***************************************************************************************/
243 |
244 | // The maximun number of mappings between owl parameters and faust widgets
245 | #define MAXOWLWIDGETS 8
246 |
247 | class OwlUI : public UI
248 | {
249 | Patch* fPatch;
250 | PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
251 | int fIndex; // number of OwlWidgets collected so far
252 | OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
253 |
254 | // check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
255 | void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
256 | if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
257 | fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
258 | fTable[fIndex].bind();
259 | fIndex++;
260 | }
261 | fParameter = PARAMETER_F; // clear current parameter ID
262 | }
263 |
264 | // we dont want to create a widget by-ut we clear the current parameter ID just in case
265 | void skip() {
266 | fParameter = PARAMETER_F; // clear current parameter ID
267 | }
268 |
269 | public:
270 |
271 | OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
272 |
273 | virtual ~OwlUI() {}
274 |
275 | // should be called before compute() to update widget's zones registered as Owl parameters
276 | void update() {
277 | for (int i=0; i
325 |
326 | float faustpower2_f(float value) {
327 | return (value * value);
328 |
329 | }
330 |
331 | #ifndef FAUSTCLASS
332 | #define FAUSTCLASS Blipper
333 | #endif
334 |
335 | class Blipper : public dsp {
336 |
337 | private:
338 |
339 | float fVec2[4096];
340 | int iVec0[2];
341 | float fRec0[2];
342 | float fRec2[2];
343 | float fRec1[2];
344 | float fRec5[2];
345 | float fRec6[2];
346 | float fRec4[2];
347 | float fVec1[2];
348 | float fRec3[2];
349 | int fSamplingFreq;
350 | int iConst0;
351 | float fConst1;
352 | float fConst2;
353 | FAUSTFLOAT fHslider0;
354 | float fConst3;
355 | float fConst4;
356 | float fConst5;
357 | float fConst6;
358 | FAUSTFLOAT fHslider1;
359 | float fConst7;
360 | float fConst8;
361 | FAUSTFLOAT fHslider2;
362 | FAUSTFLOAT fHslider3;
363 | int IOTA;
364 | float fConst9;
365 |
366 | public:
367 |
368 | void static metadata(Meta* m) {
369 | m->declare("author", "Oli Larkin (contact@olilarkin.co.uk)");
370 | m->declare("copyright", "Oliver Larkin");
371 | m->declare("description", "Envelope Follower controlling pitch of a triangle oscillator, good with percussive input");
372 | m->declare("effect.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
373 | m->declare("effect.lib/copyright", "Julius O. Smith III");
374 | m->declare("effect.lib/exciter_author", "Priyanka Shekar (pshekar@ccrma.stanford.edu)");
375 | m->declare("effect.lib/exciter_copyright", "Copyright (c) 2013 Priyanka Shekar");
376 | m->declare("effect.lib/exciter_license", "MIT License (MIT)");
377 | m->declare("effect.lib/exciter_name", "Harmonic Exciter");
378 | m->declare("effect.lib/exciter_version", "1.0");
379 | m->declare("effect.lib/license", "STK-4.3");
380 | m->declare("effect.lib/name", "Faust Audio Effect Library");
381 | m->declare("effect.lib/version", "1.33");
382 | m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
383 | m->declare("filter.lib/copyright", "Julius O. Smith III");
384 | m->declare("filter.lib/license", "STK-4.3");
385 | m->declare("filter.lib/name", "Faust Filter Library");
386 | m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/");
387 | m->declare("filter.lib/version", "1.29");
388 | m->declare("licence", "GPL");
389 | m->declare("math.lib/author", "GRAME");
390 | m->declare("math.lib/copyright", "GRAME");
391 | m->declare("math.lib/license", "LGPL with exception");
392 | m->declare("math.lib/name", "Math Library");
393 | m->declare("math.lib/version", "1.0");
394 | m->declare("music.lib/author", "GRAME");
395 | m->declare("music.lib/copyright", "GRAME");
396 | m->declare("music.lib/license", "LGPL with exception");
397 | m->declare("music.lib/name", "Music Library");
398 | m->declare("music.lib/version", "1.0");
399 | m->declare("name", "Blipper");
400 | m->declare("oscillator.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
401 | m->declare("oscillator.lib/copyright", "Julius O. Smith III");
402 | m->declare("oscillator.lib/license", "STK-4.3");
403 | m->declare("oscillator.lib/name", "Faust Oscillator Library");
404 | m->declare("oscillator.lib/version", "1.11");
405 | m->declare("version", "0.2");
406 | }
407 |
408 | virtual int getNumInputs() {
409 | return 2;
410 |
411 | }
412 | virtual int getNumOutputs() {
413 | return 2;
414 |
415 | }
416 | virtual int getInputRate(int channel) {
417 | int rate;
418 | switch (channel) {
419 | case 0: {
420 | rate = 1;
421 | break;
422 | }
423 | case 1: {
424 | rate = 1;
425 | break;
426 | }
427 | default: {
428 | rate = -1;
429 | break;
430 | }
431 |
432 | }
433 | return rate;
434 |
435 | }
436 | virtual int getOutputRate(int channel) {
437 | int rate;
438 | switch (channel) {
439 | case 0: {
440 | rate = 1;
441 | break;
442 | }
443 | case 1: {
444 | rate = 1;
445 | break;
446 | }
447 | default: {
448 | rate = -1;
449 | break;
450 | }
451 |
452 | }
453 | return rate;
454 |
455 | }
456 |
457 | static void classInit(int samplingFreq) {
458 |
459 | }
460 |
461 | virtual void instanceInit(int samplingFreq) {
462 | fSamplingFreq = samplingFreq;
463 | for (int i0 = 0; (i0 < 2); i0 = (i0 + 1)) {
464 | iVec0[i0] = 0;
465 |
466 | }
467 | iConst0 = min(192000, max(1, fSamplingFreq));
468 | fConst1 = expf((0.f - (200.f / float(iConst0))));
469 | fConst2 = (1.f - fConst1);
470 | fHslider0 = FAUSTFLOAT(0.5);
471 | for (int i1 = 0; (i1 < 2); i1 = (i1 + 1)) {
472 | fRec0[i1] = 0.f;
473 |
474 | }
475 | fConst3 = (1760.f / float(iConst0));
476 | fConst4 = (1.f / float(iConst0));
477 | fConst5 = float(iConst0);
478 | fConst6 = (1.f / fConst5);
479 | fHslider1 = FAUSTFLOAT(20.);
480 | for (int i2 = 0; (i2 < 2); i2 = (i2 + 1)) {
481 | fRec2[i2] = 0.f;
482 |
483 | }
484 | for (int i3 = 0; (i3 < 2); i3 = (i3 + 1)) {
485 | fRec1[i3] = 0.f;
486 |
487 | }
488 | fConst7 = expf((0.f - (100.f / float(iConst0))));
489 | fConst8 = (1.f - fConst7);
490 | fHslider2 = FAUSTFLOAT(60.);
491 | for (int i4 = 0; (i4 < 2); i4 = (i4 + 1)) {
492 | fRec5[i4] = 0.f;
493 |
494 | }
495 | fHslider3 = FAUSTFLOAT(24.);
496 | for (int i5 = 0; (i5 < 2); i5 = (i5 + 1)) {
497 | fRec6[i5] = 0.f;
498 |
499 | }
500 | for (int i6 = 0; (i6 < 2); i6 = (i6 + 1)) {
501 | fRec4[i6] = 0.f;
502 |
503 | }
504 | for (int i7 = 0; (i7 < 2); i7 = (i7 + 1)) {
505 | fVec1[i7] = 0.f;
506 |
507 | }
508 | IOTA = 0;
509 | for (int i8 = 0; (i8 < 4096); i8 = (i8 + 1)) {
510 | fVec2[i8] = 0.f;
511 |
512 | }
513 | fConst9 = (0.5f * fConst5);
514 | for (int i9 = 0; (i9 < 2); i9 = (i9 + 1)) {
515 | fRec3[i9] = 0.f;
516 |
517 | }
518 |
519 | }
520 |
521 | virtual void init(int samplingFreq) {
522 | classInit(samplingFreq);
523 | instanceInit(samplingFreq);
524 | }
525 |
526 | virtual void buildUserInterface(UI* interface) {
527 | interface->openVerticalBox("0x00");
528 | interface->declare(&fHslider2, "OWL", "PARAMETER_A");
529 | interface->declare(&fHslider2, "unit", "semitones");
530 | interface->addHorizontalSlider("BasePitch", &fHslider2, 60.f, 24.f, 96.f, 0.1f);
531 | interface->declare(&fHslider0, "OWL", "PARAMETER_D");
532 | interface->addHorizontalSlider("Mix", &fHslider0, 0.5f, 0.f, 1.f, 0.01f);
533 | interface->declare(&fHslider3, "OWL", "PARAMETER_B");
534 | interface->declare(&fHslider3, "unit", "semitones");
535 | interface->addHorizontalSlider("PitchMod", &fHslider3, 24.f, -64.f, 64.f, 1.f);
536 | interface->declare(&fHslider1, "OWL", "PARAMETER_C");
537 | interface->declare(&fHslider1, "unit", "ms");
538 | interface->addHorizontalSlider("Release", &fHslider1, 20.f, 2.f, 100.f, 1.f);
539 | interface->closeBox();
540 |
541 | }
542 |
543 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
544 | FAUSTFLOAT* input0 = inputs[0];
545 | FAUSTFLOAT* input1 = inputs[1];
546 | FAUSTFLOAT* output0 = outputs[0];
547 | FAUSTFLOAT* output1 = outputs[1];
548 | float fSlow0 = (fConst2 * float(fHslider0));
549 | float fSlow1 = expf((0.f - (fConst4 / max(fConst6, (0.001f * float(fHslider1))))));
550 | float fSlow2 = (1.f - fSlow1);
551 | float fSlow3 = (fConst8 * float(fHslider2));
552 | float fSlow4 = (fConst2 * float(fHslider3));
553 | for (int i = 0; (i < count); i = (i + 1)) {
554 | float fTemp0 = float(input0[i]);
555 | float fTemp1 = float(input1[i]);
556 | iVec0[0] = 1;
557 | fRec0[0] = ((fConst1 * fRec0[1]) + fSlow0);
558 | float fTemp2 = (1.f - fRec0[0]);
559 | float fTemp3 = fabsf((fTemp0 + fTemp1));
560 | fRec2[0] = max(fTemp3, ((fSlow1 * fRec2[1]) + (fSlow2 * fTemp3)));
561 | fRec1[0] = ((fConst1 * fRec1[1]) + (fConst2 * fRec2[0]));
562 | fRec5[0] = ((fConst7 * fRec5[1]) + fSlow3);
563 | fRec6[0] = ((fConst1 * fRec6[1]) + fSlow4);
564 | float fTemp4 = powf(2.f, (0.0833333f * ((fRec5[0] + (fRec6[0] * fRec1[0])) - 69.f)));
565 | float fTemp5 = max((440.f * fTemp4), 23.4489f);
566 | fRec4[0] = fmodf((fRec4[1] + (fConst6 * fTemp5)), 1.f);
567 | float fTemp6 = faustpower2_f(((2.f * fRec4[0]) - 1.f));
568 | fVec1[0] = fTemp6;
569 | float fTemp7 = ((float(iVec0[1]) * (fTemp6 - fVec1[1])) / fTemp5);
570 | fVec2[(IOTA & 4095)] = fTemp7;
571 | float fTemp8 = max(0.f, min(2047.f, (fConst9 / fTemp5)));
572 | int iTemp9 = int(fTemp8);
573 | int iTemp10 = (1 + iTemp9);
574 | fRec3[0] = ((0.999f * fRec3[1]) + (fConst5 * (((0.25f * fTemp7) - (0.25f * (fVec2[((IOTA - iTemp9) & 4095)] * (float(iTemp10) - fTemp8)))) - (0.25f * ((fTemp8 - float(iTemp9)) * fVec2[((IOTA - iTemp10) & 4095)])))));
575 | float fTemp11 = (fConst3 * (((fRec0[0] * fRec1[0]) * fRec3[0]) * fTemp4));
576 | output0[i] = FAUSTFLOAT(((fTemp0 * fTemp2) + fTemp11));
577 | output1[i] = FAUSTFLOAT(((fTemp1 * fTemp2) + fTemp11));
578 | iVec0[1] = iVec0[0];
579 | fRec0[1] = fRec0[0];
580 | fRec2[1] = fRec2[0];
581 | fRec1[1] = fRec1[0];
582 | fRec5[1] = fRec5[0];
583 | fRec6[1] = fRec6[0];
584 | fRec4[1] = fRec4[0];
585 | fVec1[1] = fVec1[0];
586 | IOTA = (IOTA + 1);
587 | fRec3[1] = fRec3[0];
588 |
589 | }
590 |
591 | }
592 |
593 |
594 | };
595 |
596 |
597 | /***************************END USER SECTION ***************************/
598 |
599 | /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
600 |
601 |
602 |
603 | /**************************************************************************************
604 |
605 | BlipperPatch : an OWL patch that calls Faust generated DSP code
606 |
607 | ***************************************************************************************/
608 |
609 | class BlipperPatch : public Patch
610 | {
611 | Blipper fDSP;
612 | OwlUI fUI;
613 |
614 | public:
615 |
616 | BlipperPatch() : fUI(this)
617 | {
618 | fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
619 | fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
620 | }
621 |
622 | void processAudio(AudioBuffer &buffer)
623 | {
624 | // Reasonably assume we will not have more than 32 channels
625 | float* ins[32];
626 | float* outs[32];
627 | int n = buffer.getChannels();
628 |
629 | if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
630 |
631 | // create the table of input channels
632 | for(int ch=0; ch
52 |
53 | */
54 |
55 | #define DB_CLIP(a,lo, hi) ( (a)>(lo)?( (a)<(hi)?(a):(hi) ):(lo) )
56 |
57 |
58 | class DroneBoxPatch : public Patch
59 | {
60 | private:
61 | static const unsigned int BUF_SIZE;
62 | static const unsigned int BUF_MASK;
63 | static const float MAX_FBK;
64 | static const float MIN_DT_SAMPLES;
65 | static const int NUM_COMBS;
66 | static const float MIN_PITCH;
67 | static const float MAX_PITCH;
68 | static const float PITCH_RANGE;
69 | static const float MIN_DECAY;
70 | static const float MAX_DECAY;
71 | static const float DECAY_RANGE;
72 | static const float FREQ_RATIOS[4];
73 |
74 | inline float midi2CPS(float pitch, float tune = 440.f)
75 | {
76 | return tune * powf(2.f, (pitch - 69.f) / 12.f);
77 | }
78 |
79 | class PSmooth
80 | {
81 | private:
82 | float mA, mB;
83 | float mOutM1;
84 |
85 | public:
86 | PSmooth(float coeff = 0.99f, float initalValue = 0.f)
87 | : mA(coeff)
88 | , mB(1.f - mA)
89 | , mOutM1(initalValue)
90 | {
91 | }
92 |
93 | inline float process(float input)
94 | {
95 | mOutM1 = (input * mB) + (mOutM1 * mA);
96 | return mOutM1;
97 | }
98 | };
99 |
100 | class DCBlocker
101 | {
102 | private:
103 | float mInM1, mOutM1;
104 | float mSampleRate;
105 | float mC;
106 | public:
107 | DCBlocker()
108 | : mInM1(0.f)
109 | , mOutM1(0.f)
110 | , mSampleRate(48000.f)
111 | , mC(1.f - ( 126.f / mSampleRate))
112 | {
113 | }
114 |
115 | inline float process(float input)
116 | {
117 | mOutM1 = input - mInM1 + mC * mOutM1;
118 | mInM1 = input;
119 | return mOutM1;
120 | }
121 |
122 | void setSampleRate(float sr)
123 | {
124 | mSampleRate = sr;
125 | mC = 1.f - ( 126.f / mSampleRate);
126 | }
127 | };
128 |
129 | class DBCombFilter
130 | {
131 | class DBLPF
132 | {
133 | private:
134 | float mInM1, mInM2, mInM3;
135 | const float mCoeffA;
136 | const float mCoeffB;
137 |
138 | public:
139 | DBLPF(float dampCoeff)
140 | : mInM1(0.f)
141 | , mInM2(0.f)
142 | , mInM3(0.f)
143 | , mCoeffA(0.5f * (1.f + dampCoeff))
144 | , mCoeffB(0.25f * (1.f - dampCoeff))
145 | {
146 | }
147 |
148 | inline float process(float input)
149 | {
150 | mInM1 = input;
151 | float output = ((mCoeffB * (mInM1 + mInM3)) + (mCoeffA * mInM2));
152 | mInM3 = mInM2;
153 | mInM2 = mInM1;
154 | return output;
155 | }
156 | };
157 |
158 | inline float wrap(float x, const float lo = 0.f, const float hi = 1.f)
159 | {
160 | while (x >= hi) x -= hi;
161 | while (x < lo) x += hi - lo;
162 |
163 | return x;
164 | }
165 |
166 | private:
167 | int mDTSamples;
168 | float mFbkScalar;
169 | int mWriteAddr;
170 | float mSampleRate;
171 | DBLPF mDampingFilterL, mDampingFilterR;
172 | float* mBufferL; // left input
173 | float* mBufferR; // right input
174 | public:
175 | DBCombFilter()
176 | : mDTSamples(0)
177 | , mFbkScalar(0.5f)
178 | , mWriteAddr(0)
179 | , mSampleRate(48000.f)
180 | , mDampingFilterL(0.3f)
181 | , mDampingFilterR(0.35f)
182 | , mBufferL(NULL)
183 | , mBufferR(NULL)
184 | {
185 | setFreqCPS(440.f);
186 | setDecayTimeMs(10.f);
187 | }
188 |
189 | void setBuffer(float* bufferL, float* bufferR)
190 | {
191 | mBufferL = bufferL;
192 | mBufferR = bufferR;
193 | }
194 |
195 | void clearBuffer()
196 | {
197 | memset(mBufferL, 0.f, BUF_SIZE*sizeof(float));
198 | memset(mBufferR, 0.f, BUF_SIZE*sizeof(float));
199 | }
200 |
201 | void setFreqCPS(float freqCPS)
202 | {
203 | mDTSamples = DB_CLIP(mSampleRate/freqCPS, MIN_DT_SAMPLES, BUF_SIZE);
204 | }
205 |
206 | // call after setting the frequency
207 | void setDecayTimeMs(float decayTimeMs)
208 | {
209 | float fbk = powf(10.f, ((-60.f / ( ( fabsf(decayTimeMs) * (mSampleRate / 1000.f) ) / mDTSamples)) / 20.f));
210 | mFbkScalar = DB_CLIP(fbk, 0.f, MAX_FBK);
211 | }
212 |
213 | void setSampleRate(float sr)
214 | {
215 | mSampleRate = sr;
216 | }
217 |
218 | inline void process(float inputL, float inputR, float* acccumOutputL, float* acccumOutputR)
219 | {
220 | float readAddrF = ( (float) mWriteAddr ) - mDTSamples;
221 | readAddrF = wrap(readAddrF, 0.f, (float) BUF_SIZE);
222 |
223 | // Linear interpolation
224 | const int intPart = (int) readAddrF;
225 | const float fracPart = readAddrF-intPart;
226 | const int wrappedIntPart = intPart & BUF_MASK;
227 | const int wrappedIntPartPlusOne = (intPart+1) & BUF_MASK;
228 |
229 | float a = mBufferL[wrappedIntPart];
230 | float b = mBufferL[wrappedIntPartPlusOne];
231 | const float outputL = a + (b - a) * fracPart;
232 |
233 | a = mBufferR[wrappedIntPart];
234 | b = mBufferR[wrappedIntPartPlusOne];
235 | const float outputR = a + (b - a) * fracPart;
236 |
237 | mBufferL[mWriteAddr] = inputL + (mDampingFilterL.process(outputL) * mFbkScalar);
238 | mBufferR[mWriteAddr] = inputR + (mDampingFilterR.process(outputR) * mFbkScalar);
239 | mWriteAddr++;
240 | mWriteAddr &= BUF_MASK;
241 |
242 | *acccumOutputL += outputL;
243 | *acccumOutputR += outputR;
244 | }
245 | };
246 |
247 | private:
248 | DBCombFilter mCombs[4];
249 | PSmooth mMixSmoother;
250 | DCBlocker mDCBlockerL, mDCBlockerR;
251 | float mOldValues[4];
252 | float mRamp;
253 | float mPrevCoarsePitch;
254 | float mPrevFinePitch;
255 | float mPrevDecay;
256 |
257 | inline float getRampedParameterValue(PatchParameterId id)
258 | {
259 | float val = getParameterValue(id);
260 | float result = val * mRamp + mOldValues[id] * (1.f-mRamp);
261 | mOldValues[id] = val;
262 | return result;
263 | }
264 |
265 | public:
266 | DroneBoxPatch()
267 | : mRamp(0.1)
268 | , mPrevCoarsePitch(-1.)
269 | , mPrevFinePitch(-1.)
270 | , mPrevDecay(-1.)
271 | {
272 | registerParameter(PARAMETER_A, "Coarse Pitch", "Coarse Pitch");
273 | registerParameter(PARAMETER_B, "Fine Pitch", "Fine Pitch");
274 | registerParameter(PARAMETER_C, "Decay", "Decay");
275 | registerParameter(PARAMETER_D, "Mix", "Mix");
276 |
277 | mOldValues[0] = 0.f;
278 | mOldValues[1] = 0.f;
279 | mOldValues[2] = 0.f;
280 | mOldValues[3] = 0.f;
281 |
282 | for (int c=0;cgetSamples(0), buffer->getSamples(1));
286 | mCombs[c].setSampleRate(getSampleRate());
287 | mCombs[c].clearBuffer();
288 | }
289 |
290 | mDCBlockerL.setSampleRate(getSampleRate());
291 | mDCBlockerR.setSampleRate(getSampleRate());
292 | }
293 |
294 | void processAudio(AudioBuffer &buffer)
295 | {
296 | const int size = buffer.getSize();
297 | const float coarsePitch = getRampedParameterValue(PARAMETER_A);
298 | const float finePitch = getRampedParameterValue(PARAMETER_B);
299 | const float decay = getRampedParameterValue(PARAMETER_C);
300 | const float mix = getRampedParameterValue(PARAMETER_D);
301 |
302 | if (coarsePitch != mPrevCoarsePitch || finePitch != mPrevFinePitch || decay != mPrevDecay)
303 | {
304 | const float freq = midi2CPS(MIN_PITCH + floorf(mPrevCoarsePitch * PITCH_RANGE) + finePitch);
305 |
306 | for (int c = 0; c < NUM_COMBS; c++)
307 | {
308 | mCombs[c].setFreqCPS(freq * FREQ_RATIOS[c]);
309 | mCombs[c].setDecayTimeMs(MIN_DECAY + (decay * DECAY_RANGE));
310 | }
311 |
312 | mPrevCoarsePitch = coarsePitch;
313 | mPrevFinePitch = finePitch;
314 | mPrevDecay = decay;
315 | }
316 |
317 | float* bufL = buffer.getSamples(0);
318 | float* bufR = buffer.getSamples(1);
319 |
320 | for(int i = 0; i < size; i++)
321 | {
322 | float ipsL = bufL[i];
323 | float ipsR = bufR[i];
324 | float opsL = 0.f;
325 | float opsR = 0.f;
326 |
327 | const float smoothMix = mMixSmoother.process(mix);
328 | const float invSmoothMix = 1.f-smoothMix;
329 |
330 | for (int c = 0; c < NUM_COMBS; c++)
331 | {
332 | mCombs[c].process(ipsL, ipsR, &opsL, &opsR);
333 | }
334 |
335 | bufL[i] = mDCBlockerL.process( ((opsL * 0.1f) * smoothMix) + (ipsL * invSmoothMix) );
336 | bufR[i] = mDCBlockerR.process( ((opsR * 0.1f) * smoothMix) + (ipsR * invSmoothMix) );
337 | }
338 | }
339 | };
340 |
341 | const unsigned int DroneBoxPatch::BUF_SIZE = 1024; // = 4096 bytes per comb
342 | const unsigned int DroneBoxPatch::BUF_MASK = 1023;
343 | const float DroneBoxPatch::MAX_FBK = 0.999999f;
344 | const float DroneBoxPatch::MIN_DT_SAMPLES = 2.5f;
345 | const int DroneBoxPatch::NUM_COMBS = 4;
346 | const float DroneBoxPatch::MIN_PITCH = 36.f; // MIDI notenumber
347 | const float DroneBoxPatch::MAX_PITCH = 60.f; // MIDI notenumber
348 | const float DroneBoxPatch::PITCH_RANGE = MAX_PITCH - MIN_PITCH; // semitones
349 | const float DroneBoxPatch::MIN_DECAY = 200.f; // milliseconds
350 | const float DroneBoxPatch::MAX_DECAY = 30000.f; // milliseconds
351 | const float DroneBoxPatch::DECAY_RANGE = MAX_DECAY - MIN_DECAY;
352 | const float DroneBoxPatch::FREQ_RATIOS[NUM_COMBS] = {1.f, 1.5f, 2.f, 3.f};
353 | //const float DroneBoxPatch::FREQ_RATIOS[NUM_COMBS] = {1., 1.01, 1.02, 1.03};
354 |
355 | #endif // __DroneBox_hpp__
356 |
--------------------------------------------------------------------------------
/DualFreqShifter.dsp:
--------------------------------------------------------------------------------
1 | declare name "Dual Frequency Shifter";
2 | declare description "Dual Channel Frequency Shifter";
3 | declare author "Oli Larkin (contact@olilarkin.co.uk)";
4 | declare copyright "Oliver Larkin";
5 | declare version "0.1";
6 | declare licence "GPL";
7 |
8 | import("stdfaust.lib");
9 |
10 | import("FrequencyShifter.lib");
11 |
12 | shiftL = hslider("Shift L [unit:hz] [OWL:PARAMETER_A]", 0., -1., 1, 0.001);
13 | shiftR = hslider("Shift R [unit:hz] [OWL:PARAMETER_B]", 0., -1., 1, 0.001);
14 | shift_scalar = hslider("Shift Scalar [OWL:PARAMETER_C]", 1., 1., 100, 0.1);
15 | mix = hslider("Mix [OWL:PARAMETER_D]",0.5,0,1,0.01) : si.smooth(ba.tau2pole(0.005));
16 |
17 | process(l,r) = l,r <: *(1-mix), *(1-mix), ssb(shiftL*shift_scalar,l)*mix, ssb(shiftR*shift_scalar,r)*mix :> _,_;
18 |
--------------------------------------------------------------------------------
/DualFreqShifterPatch.hpp:
--------------------------------------------------------------------------------
1 | /* ------------------------------------------------------------
2 | author: "Oli Larkin (contact@olilarkin.co.uk)"
3 | copyright: "Oliver Larkin"
4 | name: "Dual Frequency Shifter"
5 | version: "0.1"
6 | Code generated with Faust 2.0.a41 (http://faust.grame.fr)
7 | ------------------------------------------------------------ */
8 |
9 | #ifndef __DualFreqShifter_H__
10 | #define __DualFreqShifter_H__
11 | /************************************************************************
12 |
13 | IMPORTANT NOTE : this file contains two clearly delimited sections :
14 | the ARCHITECTURE section (in two parts) and the USER section. Each section
15 | is governed by its own copyright and license. Please check individually
16 | each section for license and copyright information.
17 | *************************************************************************/
18 |
19 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
20 |
21 | /************************************************************************
22 | FAUST Architecture File
23 | Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
24 | ---------------------------------------------------------------------
25 | This Architecture section is free software; you can redistribute it
26 | and/or modify it under the terms of the GNU General Public License
27 | as published by the Free Software Foundation; either version 3 of
28 | the License, or (at your option) any later version.
29 |
30 | This program is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with this program; If not, see .
37 |
38 | EXCEPTION : As a special exception, you may create a larger work
39 | that contains this FAUST architecture section and distribute
40 | that work under terms of your choice, so long as this FAUST
41 | architecture section is not modified.
42 |
43 |
44 | ************************************************************************
45 | ************************************************************************/
46 |
47 | #ifndef __DualFreqShifterPatch_h__
48 | #define __DualFreqShifterPatch_h__
49 |
50 | #include "StompBox.h"
51 | #include
52 | #include
53 | #include
54 |
55 |
56 | #ifndef __FaustCommonInfrastructure__
57 | #define __FaustCommonInfrastructure__
58 |
59 |
60 | /************************************************************************
61 | IMPORTANT NOTE : this file contains two clearly delimited sections :
62 | the ARCHITECTURE section (in two parts) and the USER section. Each section
63 | is governed by its own copyright and license. Please check individually
64 | each section for license and copyright information.
65 | *************************************************************************/
66 |
67 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
68 |
69 | /************************************************************************
70 | FAUST Architecture File
71 | Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
72 | ---------------------------------------------------------------------
73 | This Architecture section is free software; you can redistribute it
74 | and/or modify it under the terms of the GNU General Public License
75 | as published by the Free Software Foundation; either version 3 of
76 | the License, or (at your option) any later version.
77 |
78 | This program is distributed in the hope that it will be useful,
79 | but WITHOUT ANY WARRANTY; without even the implied warranty of
80 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 | GNU General Public License for more details.
82 |
83 | You should have received a copy of the GNU General Public License
84 | along with this program; If not, see .
85 |
86 | EXCEPTION : As a special exception, you may create a larger work
87 | that contains this FAUST architecture section and distribute
88 | that work under terms of your choice, so long as this FAUST
89 | architecture section is not modified.
90 |
91 |
92 | ************************************************************************
93 | ************************************************************************/
94 |
95 | /******************************************************************************
96 | *******************************************************************************
97 |
98 | FAUST DSP
99 |
100 | *******************************************************************************
101 | *******************************************************************************/
102 |
103 | #ifndef __dsp__
104 | #define __dsp__
105 |
106 | #ifndef FAUSTFLOAT
107 | #define FAUSTFLOAT float
108 | #endif
109 |
110 | class UI;
111 |
112 | //----------------------------------------------------------------
113 | // Signal processor definition
114 | //----------------------------------------------------------------
115 |
116 | class dsp {
117 |
118 | protected:
119 | int fSamplingFreq;
120 |
121 | public:
122 | dsp() {}
123 | virtual ~dsp() {}
124 |
125 | virtual int getNumInputs() = 0;
126 | virtual int getNumOutputs() = 0;
127 | virtual void buildUserInterface(UI* ui_interface) = 0;
128 | virtual void init(int samplingRate) = 0;
129 | virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
130 | };
131 |
132 | // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
133 | // flags to avoid costly denormals
134 | #ifdef __SSE__
135 | #include
136 | #ifdef __SSE2__
137 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
138 | #else
139 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
140 | #endif
141 | #else
142 | #define AVOIDDENORMALS
143 | #endif
144 |
145 | #endif
146 | #ifndef FAUST_UI_H
147 | #define FAUST_UI_H
148 |
149 | #ifndef FAUSTFLOAT
150 | #define FAUSTFLOAT float
151 | #endif
152 |
153 | /*******************************************************************************
154 | * UI : Faust User Interface
155 | * This abstract class contains only the method that the faust compiler can
156 | * generate to describe a DSP interface.
157 | ******************************************************************************/
158 |
159 | class UI
160 | {
161 |
162 | public:
163 |
164 | UI() {}
165 |
166 | virtual ~UI() {}
167 |
168 | // -- widget's layouts
169 |
170 | virtual void openTabBox(const char* label) = 0;
171 | virtual void openHorizontalBox(const char* label) = 0;
172 | virtual void openVerticalBox(const char* label) = 0;
173 | virtual void closeBox() = 0;
174 |
175 | // -- active widgets
176 |
177 | virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
178 | virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
179 | virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
180 | virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
181 | virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
182 |
183 | // -- passive widgets
184 |
185 | virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
186 | virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
187 |
188 | // -- metadata declarations
189 |
190 | virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val) {}
191 | };
192 |
193 | #endif
194 |
195 |
196 |
197 | struct Meta
198 | {
199 | virtual void declare(const char* key, const char* value) = 0;
200 | };
201 |
202 |
203 |
204 | /**************************************************************************************
205 |
206 | OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
207 | and a faust widget
208 |
209 | ***************************************************************************************/
210 |
211 | class OwlWidget
212 | {
213 | protected:
214 | Patch* fPatch; // needed to register and read owl parameters
215 | PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
216 | FAUSTFLOAT* fZone; // Faust widget zone
217 | const char* fLabel; // Faust widget label
218 | float fMin; // Faust widget minimal value
219 | float fSpan; // Faust widget value span (max-min)
220 |
221 | public:
222 | OwlWidget() :
223 | fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
224 | OwlWidget(const OwlWidget& w) :
225 | fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
226 | OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
227 | fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
228 | void bind() { fPatch->registerParameter(fParameter, fLabel); }
229 | void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
230 |
231 | };
232 |
233 |
234 | /**************************************************************************************
235 |
236 | OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
237 | the mapping between owl parameters and faust widgets. It relies on specific
238 | metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
239 | faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
240 | (the second knob).
241 |
242 | ***************************************************************************************/
243 |
244 | // The maximun number of mappings between owl parameters and faust widgets
245 | #define MAXOWLWIDGETS 8
246 |
247 | class OwlUI : public UI
248 | {
249 | Patch* fPatch;
250 | PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
251 | int fIndex; // number of OwlWidgets collected so far
252 | OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
253 |
254 | // check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
255 | void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
256 | if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
257 | fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
258 | fTable[fIndex].bind();
259 | fIndex++;
260 | }
261 | fParameter = PARAMETER_F; // clear current parameter ID
262 | }
263 |
264 | // we dont want to create a widget by-ut we clear the current parameter ID just in case
265 | void skip() {
266 | fParameter = PARAMETER_F; // clear current parameter ID
267 | }
268 |
269 | public:
270 |
271 | OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
272 |
273 | virtual ~OwlUI() {}
274 |
275 | // should be called before compute() to update widget's zones registered as Owl parameters
276 | void update() {
277 | for (int i=0; i
325 |
326 |
327 | #ifndef FAUSTCLASS
328 | #define FAUSTCLASS DualFreqShifter
329 | #endif
330 |
331 | class DualFreqShifter : public dsp {
332 |
333 | private:
334 |
335 | float fRec2[3];
336 | float fRec1[3];
337 | float fRec5[3];
338 | float fRec4[3];
339 | float fRec7[3];
340 | float fRec6[3];
341 | float fRec10[3];
342 | float fRec9[3];
343 | float fRec0[2];
344 | float fRec3[2];
345 | float fRec8[2];
346 | int fSamplingFreq;
347 | int iConst0;
348 | float fConst1;
349 | float fConst2;
350 | FAUSTFLOAT fHslider0;
351 | float fConst3;
352 | FAUSTFLOAT fHslider1;
353 | FAUSTFLOAT fHslider2;
354 | FAUSTFLOAT fHslider3;
355 |
356 | public:
357 |
358 | void static metadata(Meta* m) {
359 | m->declare("author", "Oli Larkin (contact@olilarkin.co.uk)");
360 | m->declare("copyright", "Oliver Larkin");
361 | m->declare("description", "Dual Channel Frequency Shifter");
362 | m->declare("effect.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
363 | m->declare("effect.lib/copyright", "Julius O. Smith III");
364 | m->declare("effect.lib/exciter_author", "Priyanka Shekar (pshekar@ccrma.stanford.edu)");
365 | m->declare("effect.lib/exciter_copyright", "Copyright (c) 2013 Priyanka Shekar");
366 | m->declare("effect.lib/exciter_license", "MIT License (MIT)");
367 | m->declare("effect.lib/exciter_name", "Harmonic Exciter");
368 | m->declare("effect.lib/exciter_version", "1.0");
369 | m->declare("effect.lib/license", "STK-4.3");
370 | m->declare("effect.lib/name", "Faust Audio Effect Library");
371 | m->declare("effect.lib/version", "1.33");
372 | m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
373 | m->declare("filter.lib/copyright", "Julius O. Smith III");
374 | m->declare("filter.lib/license", "STK-4.3");
375 | m->declare("filter.lib/name", "Faust Filter Library");
376 | m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/");
377 | m->declare("filter.lib/version", "1.29");
378 | m->declare("licence", "GPL");
379 | m->declare("math.lib/author", "GRAME");
380 | m->declare("math.lib/copyright", "GRAME");
381 | m->declare("math.lib/license", "LGPL with exception");
382 | m->declare("math.lib/name", "Math Library");
383 | m->declare("math.lib/version", "1.0");
384 | m->declare("music.lib/author", "GRAME");
385 | m->declare("music.lib/copyright", "GRAME");
386 | m->declare("music.lib/license", "LGPL with exception");
387 | m->declare("music.lib/name", "Music Library");
388 | m->declare("music.lib/version", "1.0");
389 | m->declare("name", "Dual Frequency Shifter");
390 | m->declare("version", "0.1");
391 | }
392 |
393 | virtual int getNumInputs() {
394 | return 2;
395 |
396 | }
397 | virtual int getNumOutputs() {
398 | return 2;
399 |
400 | }
401 | virtual int getInputRate(int channel) {
402 | int rate;
403 | switch (channel) {
404 | case 0: {
405 | rate = 1;
406 | break;
407 | }
408 | case 1: {
409 | rate = 1;
410 | break;
411 | }
412 | default: {
413 | rate = -1;
414 | break;
415 | }
416 |
417 | }
418 | return rate;
419 |
420 | }
421 | virtual int getOutputRate(int channel) {
422 | int rate;
423 | switch (channel) {
424 | case 0: {
425 | rate = 1;
426 | break;
427 | }
428 | case 1: {
429 | rate = 1;
430 | break;
431 | }
432 | default: {
433 | rate = -1;
434 | break;
435 | }
436 |
437 | }
438 | return rate;
439 |
440 | }
441 |
442 | static void classInit(int samplingFreq) {
443 |
444 | }
445 |
446 | virtual void instanceInit(int samplingFreq) {
447 | fSamplingFreq = samplingFreq;
448 | iConst0 = min(192000, max(1, fSamplingFreq));
449 | fConst1 = expf((0.f - (200.f / float(iConst0))));
450 | fConst2 = (1.f - fConst1);
451 | fHslider0 = FAUSTFLOAT(0.5);
452 | for (int i0 = 0; (i0 < 2); i0 = (i0 + 1)) {
453 | fRec0[i0] = 0.f;
454 |
455 | }
456 | for (int i1 = 0; (i1 < 3); i1 = (i1 + 1)) {
457 | fRec2[i1] = 0.f;
458 |
459 | }
460 | for (int i2 = 0; (i2 < 3); i2 = (i2 + 1)) {
461 | fRec1[i2] = 0.f;
462 |
463 | }
464 | fConst3 = (1.f / float(iConst0));
465 | fHslider1 = FAUSTFLOAT(0.);
466 | fHslider2 = FAUSTFLOAT(1.);
467 | for (int i3 = 0; (i3 < 2); i3 = (i3 + 1)) {
468 | fRec3[i3] = 0.f;
469 |
470 | }
471 | for (int i4 = 0; (i4 < 3); i4 = (i4 + 1)) {
472 | fRec5[i4] = 0.f;
473 |
474 | }
475 | for (int i5 = 0; (i5 < 3); i5 = (i5 + 1)) {
476 | fRec4[i5] = 0.f;
477 |
478 | }
479 | for (int i6 = 0; (i6 < 3); i6 = (i6 + 1)) {
480 | fRec7[i6] = 0.f;
481 |
482 | }
483 | for (int i7 = 0; (i7 < 3); i7 = (i7 + 1)) {
484 | fRec6[i7] = 0.f;
485 |
486 | }
487 | fHslider3 = FAUSTFLOAT(0.);
488 | for (int i8 = 0; (i8 < 2); i8 = (i8 + 1)) {
489 | fRec8[i8] = 0.f;
490 |
491 | }
492 | for (int i9 = 0; (i9 < 3); i9 = (i9 + 1)) {
493 | fRec10[i9] = 0.f;
494 |
495 | }
496 | for (int i10 = 0; (i10 < 3); i10 = (i10 + 1)) {
497 | fRec9[i10] = 0.f;
498 |
499 | }
500 |
501 | }
502 |
503 | virtual void init(int samplingFreq) {
504 | classInit(samplingFreq);
505 | instanceInit(samplingFreq);
506 | }
507 |
508 | virtual void buildUserInterface(UI* interface) {
509 | interface->openVerticalBox("0x00");
510 | interface->declare(&fHslider0, "OWL", "PARAMETER_D");
511 | interface->addHorizontalSlider("Mix", &fHslider0, 0.5f, 0.f, 1.f, 0.01f);
512 | interface->declare(&fHslider1, "OWL", "PARAMETER_A");
513 | interface->declare(&fHslider1, "unit", "hz");
514 | interface->addHorizontalSlider("Shift L", &fHslider1, 0.f, -1.f, 1.f, 0.001f);
515 | interface->declare(&fHslider3, "OWL", "PARAMETER_B");
516 | interface->declare(&fHslider3, "unit", "hz");
517 | interface->addHorizontalSlider("Shift R", &fHslider3, 0.f, -1.f, 1.f, 0.001f);
518 | interface->declare(&fHslider2, "OWL", "PARAMETER_C");
519 | interface->addHorizontalSlider("Shift Scalar", &fHslider2, 1.f, 1.f, 100.f, 0.1f);
520 | interface->closeBox();
521 |
522 | }
523 |
524 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
525 | FAUSTFLOAT* input0 = inputs[0];
526 | FAUSTFLOAT* input1 = inputs[1];
527 | FAUSTFLOAT* output0 = outputs[0];
528 | FAUSTFLOAT* output1 = outputs[1];
529 | float fSlow0 = (fConst2 * float(fHslider0));
530 | float fSlow1 = float(fHslider2);
531 | float fSlow2 = (fConst3 * (float(fHslider1) * fSlow1));
532 | float fSlow3 = (fConst3 * (fSlow1 * float(fHslider3)));
533 | for (int i = 0; (i < count); i = (i + 1)) {
534 | float fTemp0 = float(input0[i]);
535 | float fTemp1 = float(input1[i]);
536 | fRec0[0] = ((fConst1 * fRec0[1]) + fSlow0);
537 | float fTemp2 = (1.f - fRec0[0]);
538 | float fTemp3 = (0.02569f * fRec2[1]);
539 | fRec2[0] = ((fTemp0 + (0.260502f * fRec2[2])) - fTemp3);
540 | float fTemp4 = (1.8685f * fRec1[1]);
541 | fRec1[0] = ((fRec2[2] + (fTemp4 + fTemp3)) - ((0.870686f * fRec1[2]) + (0.260502f * fRec2[0])));
542 | float fTemp5 = (fRec3[1] + fSlow2);
543 | fRec3[0] = (fTemp5 - floorf(fTemp5));
544 | float fTemp6 = (6.28319f * fmodf(fRec3[0], 1.f));
545 | float fTemp7 = (1.94632f * fRec5[1]);
546 | fRec5[0] = ((fTemp0 + fTemp7) - (0.94657f * fRec5[2]));
547 | float fTemp8 = (0.83774f * fRec4[1]);
548 | fRec4[0] = ((fRec5[2] + ((0.94657f * fRec5[0]) + fTemp8)) - ((0.06338f * fRec4[2]) + fTemp7));
549 | output0[i] = FAUSTFLOAT(((fTemp0 * fTemp2) + (fRec0[0] * (((((0.870686f * fRec1[0]) + fRec1[2]) - fTemp4) * cosf(fTemp6)) - (sinf(fTemp6) * (((0.06338f * fRec4[0]) + fRec4[2]) - fTemp8))))));
550 | float fTemp9 = (0.02569f * fRec7[1]);
551 | fRec7[0] = ((fTemp1 + (0.260502f * fRec7[2])) - fTemp9);
552 | float fTemp10 = (1.8685f * fRec6[1]);
553 | fRec6[0] = ((fRec7[2] + (fTemp10 + fTemp9)) - ((0.870686f * fRec6[2]) + (0.260502f * fRec7[0])));
554 | float fTemp11 = (fRec8[1] + fSlow3);
555 | fRec8[0] = (fTemp11 - floorf(fTemp11));
556 | float fTemp12 = (6.28319f * fmodf(fRec8[0], 1.f));
557 | float fTemp13 = (1.94632f * fRec10[1]);
558 | fRec10[0] = ((fTemp1 + fTemp13) - (0.94657f * fRec10[2]));
559 | float fTemp14 = (0.83774f * fRec9[1]);
560 | fRec9[0] = ((fRec10[2] + ((0.94657f * fRec10[0]) + fTemp14)) - ((0.06338f * fRec9[2]) + fTemp13));
561 | output1[i] = FAUSTFLOAT(((fTemp1 * fTemp2) + (fRec0[0] * (((((0.870686f * fRec6[0]) + fRec6[2]) - fTemp10) * cosf(fTemp12)) - (sinf(fTemp12) * (((0.06338f * fRec9[0]) + fRec9[2]) - fTemp14))))));
562 | fRec0[1] = fRec0[0];
563 | fRec2[2] = fRec2[1];
564 | fRec2[1] = fRec2[0];
565 | fRec1[2] = fRec1[1];
566 | fRec1[1] = fRec1[0];
567 | fRec3[1] = fRec3[0];
568 | fRec5[2] = fRec5[1];
569 | fRec5[1] = fRec5[0];
570 | fRec4[2] = fRec4[1];
571 | fRec4[1] = fRec4[0];
572 | fRec7[2] = fRec7[1];
573 | fRec7[1] = fRec7[0];
574 | fRec6[2] = fRec6[1];
575 | fRec6[1] = fRec6[0];
576 | fRec8[1] = fRec8[0];
577 | fRec10[2] = fRec10[1];
578 | fRec10[1] = fRec10[0];
579 | fRec9[2] = fRec9[1];
580 | fRec9[1] = fRec9[0];
581 |
582 | }
583 |
584 | }
585 |
586 |
587 | };
588 |
589 |
590 | /***************************END USER SECTION ***************************/
591 |
592 | /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
593 |
594 |
595 |
596 | /**************************************************************************************
597 |
598 | DualFreqShifterPatch : an OWL patch that calls Faust generated DSP code
599 |
600 | ***************************************************************************************/
601 |
602 | class DualFreqShifterPatch : public Patch
603 | {
604 | DualFreqShifter fDSP;
605 | OwlUI fUI;
606 |
607 | public:
608 |
609 | DualFreqShifterPatch() : fUI(this)
610 | {
611 | fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
612 | fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
613 | }
614 |
615 | void processAudio(AudioBuffer &buffer)
616 | {
617 | // Reasonably assume we will not have more than 32 channels
618 | float* ins[32];
619 | float* outs[32];
620 | int n = buffer.getChannels();
621 |
622 | if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
623 |
624 | // create the table of input channels
625 | for(int ch=0; ch _,_;
25 |
--------------------------------------------------------------------------------
/DualPitchShifterPatch.hpp:
--------------------------------------------------------------------------------
1 | /* ------------------------------------------------------------
2 | author: "Oli Larkin (contact@olilarkin.co.uk)"
3 | copyright: "Oliver Larkin"
4 | name: "Dual Pitch Shifter"
5 | version: "0.1"
6 | Code generated with Faust 2.0.a41 (http://faust.grame.fr)
7 | ------------------------------------------------------------ */
8 |
9 | #ifndef __DualPitchShifter_H__
10 | #define __DualPitchShifter_H__
11 | /************************************************************************
12 |
13 | IMPORTANT NOTE : this file contains two clearly delimited sections :
14 | the ARCHITECTURE section (in two parts) and the USER section. Each section
15 | is governed by its own copyright and license. Please check individually
16 | each section for license and copyright information.
17 | *************************************************************************/
18 |
19 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
20 |
21 | /************************************************************************
22 | FAUST Architecture File
23 | Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
24 | ---------------------------------------------------------------------
25 | This Architecture section is free software; you can redistribute it
26 | and/or modify it under the terms of the GNU General Public License
27 | as published by the Free Software Foundation; either version 3 of
28 | the License, or (at your option) any later version.
29 |
30 | This program is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with this program; If not, see .
37 |
38 | EXCEPTION : As a special exception, you may create a larger work
39 | that contains this FAUST architecture section and distribute
40 | that work under terms of your choice, so long as this FAUST
41 | architecture section is not modified.
42 |
43 |
44 | ************************************************************************
45 | ************************************************************************/
46 |
47 | #ifndef __DualPitchShifterPatch_h__
48 | #define __DualPitchShifterPatch_h__
49 |
50 | #include "StompBox.h"
51 | #include
52 | #include
53 | #include
54 |
55 |
56 | #ifndef __FaustCommonInfrastructure__
57 | #define __FaustCommonInfrastructure__
58 |
59 |
60 | /************************************************************************
61 | IMPORTANT NOTE : this file contains two clearly delimited sections :
62 | the ARCHITECTURE section (in two parts) and the USER section. Each section
63 | is governed by its own copyright and license. Please check individually
64 | each section for license and copyright information.
65 | *************************************************************************/
66 |
67 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
68 |
69 | /************************************************************************
70 | FAUST Architecture File
71 | Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
72 | ---------------------------------------------------------------------
73 | This Architecture section is free software; you can redistribute it
74 | and/or modify it under the terms of the GNU General Public License
75 | as published by the Free Software Foundation; either version 3 of
76 | the License, or (at your option) any later version.
77 |
78 | This program is distributed in the hope that it will be useful,
79 | but WITHOUT ANY WARRANTY; without even the implied warranty of
80 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 | GNU General Public License for more details.
82 |
83 | You should have received a copy of the GNU General Public License
84 | along with this program; If not, see .
85 |
86 | EXCEPTION : As a special exception, you may create a larger work
87 | that contains this FAUST architecture section and distribute
88 | that work under terms of your choice, so long as this FAUST
89 | architecture section is not modified.
90 |
91 |
92 | ************************************************************************
93 | ************************************************************************/
94 |
95 | /******************************************************************************
96 | *******************************************************************************
97 |
98 | FAUST DSP
99 |
100 | *******************************************************************************
101 | *******************************************************************************/
102 |
103 | #ifndef __dsp__
104 | #define __dsp__
105 |
106 | #ifndef FAUSTFLOAT
107 | #define FAUSTFLOAT float
108 | #endif
109 |
110 | class UI;
111 |
112 | //----------------------------------------------------------------
113 | // Signal processor definition
114 | //----------------------------------------------------------------
115 |
116 | class dsp {
117 |
118 | protected:
119 | int fSamplingFreq;
120 |
121 | public:
122 | dsp() {}
123 | virtual ~dsp() {}
124 |
125 | virtual int getNumInputs() = 0;
126 | virtual int getNumOutputs() = 0;
127 | virtual void buildUserInterface(UI* ui_interface) = 0;
128 | virtual void init(int samplingRate) = 0;
129 | virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
130 | };
131 |
132 | // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
133 | // flags to avoid costly denormals
134 | #ifdef __SSE__
135 | #include
136 | #ifdef __SSE2__
137 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
138 | #else
139 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
140 | #endif
141 | #else
142 | #define AVOIDDENORMALS
143 | #endif
144 |
145 | #endif
146 | #ifndef FAUST_UI_H
147 | #define FAUST_UI_H
148 |
149 | #ifndef FAUSTFLOAT
150 | #define FAUSTFLOAT float
151 | #endif
152 |
153 | /*******************************************************************************
154 | * UI : Faust User Interface
155 | * This abstract class contains only the method that the faust compiler can
156 | * generate to describe a DSP interface.
157 | ******************************************************************************/
158 |
159 | class UI
160 | {
161 |
162 | public:
163 |
164 | UI() {}
165 |
166 | virtual ~UI() {}
167 |
168 | // -- widget's layouts
169 |
170 | virtual void openTabBox(const char* label) = 0;
171 | virtual void openHorizontalBox(const char* label) = 0;
172 | virtual void openVerticalBox(const char* label) = 0;
173 | virtual void closeBox() = 0;
174 |
175 | // -- active widgets
176 |
177 | virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
178 | virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
179 | virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
180 | virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
181 | virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
182 |
183 | // -- passive widgets
184 |
185 | virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
186 | virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
187 |
188 | // -- metadata declarations
189 |
190 | virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val) {}
191 | };
192 |
193 | #endif
194 |
195 |
196 |
197 | struct Meta
198 | {
199 | virtual void declare(const char* key, const char* value) = 0;
200 | };
201 |
202 |
203 |
204 | /**************************************************************************************
205 |
206 | OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
207 | and a faust widget
208 |
209 | ***************************************************************************************/
210 |
211 | class OwlWidget
212 | {
213 | protected:
214 | Patch* fPatch; // needed to register and read owl parameters
215 | PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
216 | FAUSTFLOAT* fZone; // Faust widget zone
217 | const char* fLabel; // Faust widget label
218 | float fMin; // Faust widget minimal value
219 | float fSpan; // Faust widget value span (max-min)
220 |
221 | public:
222 | OwlWidget() :
223 | fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
224 | OwlWidget(const OwlWidget& w) :
225 | fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
226 | OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
227 | fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
228 | void bind() { fPatch->registerParameter(fParameter, fLabel); }
229 | void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
230 |
231 | };
232 |
233 |
234 | /**************************************************************************************
235 |
236 | OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
237 | the mapping between owl parameters and faust widgets. It relies on specific
238 | metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
239 | faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
240 | (the second knob).
241 |
242 | ***************************************************************************************/
243 |
244 | // The maximun number of mappings between owl parameters and faust widgets
245 | #define MAXOWLWIDGETS 8
246 |
247 | class OwlUI : public UI
248 | {
249 | Patch* fPatch;
250 | PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
251 | int fIndex; // number of OwlWidgets collected so far
252 | OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
253 |
254 | // check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
255 | void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
256 | if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
257 | fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
258 | fTable[fIndex].bind();
259 | fIndex++;
260 | }
261 | fParameter = PARAMETER_F; // clear current parameter ID
262 | }
263 |
264 | // we dont want to create a widget by-ut we clear the current parameter ID just in case
265 | void skip() {
266 | fParameter = PARAMETER_F; // clear current parameter ID
267 | }
268 |
269 | public:
270 |
271 | OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
272 |
273 | virtual ~OwlUI() {}
274 |
275 | // should be called before compute() to update widget's zones registered as Owl parameters
276 | void update() {
277 | for (int i=0; i
325 |
326 |
327 | #ifndef FAUSTCLASS
328 | #define FAUSTCLASS DualPitchShifter
329 | #endif
330 |
331 | class DualPitchShifter : public dsp {
332 |
333 | private:
334 |
335 | float fVec0[65536];
336 | float fVec1[65536];
337 | float fRec0[2];
338 | float fRec2[2];
339 | float fRec1[2];
340 | float fRec3[2];
341 | int IOTA;
342 | int fSamplingFreq;
343 | int iConst0;
344 | float fConst1;
345 | float fConst2;
346 | FAUSTFLOAT fHslider0;
347 | FAUSTFLOAT fHslider1;
348 | float fConst3;
349 | FAUSTFLOAT fHslider2;
350 | float fConst4;
351 | FAUSTFLOAT fHslider3;
352 |
353 | public:
354 |
355 | void static metadata(Meta* m) {
356 | m->declare("author", "Oli Larkin (contact@olilarkin.co.uk)");
357 | m->declare("copyright", "Oliver Larkin");
358 | m->declare("description", "Dual Channel pitch shifter, based on Faust pitch_shifter.dsp by Grame");
359 | m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
360 | m->declare("filter.lib/copyright", "Julius O. Smith III");
361 | m->declare("filter.lib/license", "STK-4.3");
362 | m->declare("filter.lib/name", "Faust Filter Library");
363 | m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/");
364 | m->declare("filter.lib/version", "1.29");
365 | m->declare("licence", "GPL");
366 | m->declare("math.lib/author", "GRAME");
367 | m->declare("math.lib/copyright", "GRAME");
368 | m->declare("math.lib/license", "LGPL with exception");
369 | m->declare("math.lib/name", "Math Library");
370 | m->declare("math.lib/version", "1.0");
371 | m->declare("music.lib/author", "GRAME");
372 | m->declare("music.lib/copyright", "GRAME");
373 | m->declare("music.lib/license", "LGPL with exception");
374 | m->declare("music.lib/name", "Music Library");
375 | m->declare("music.lib/version", "1.0");
376 | m->declare("name", "Dual Pitch Shifter");
377 | m->declare("version", "0.1");
378 | }
379 |
380 | virtual int getNumInputs() {
381 | return 2;
382 |
383 | }
384 | virtual int getNumOutputs() {
385 | return 2;
386 |
387 | }
388 | virtual int getInputRate(int channel) {
389 | int rate;
390 | switch (channel) {
391 | case 0: {
392 | rate = 1;
393 | break;
394 | }
395 | case 1: {
396 | rate = 1;
397 | break;
398 | }
399 | default: {
400 | rate = -1;
401 | break;
402 | }
403 |
404 | }
405 | return rate;
406 |
407 | }
408 | virtual int getOutputRate(int channel) {
409 | int rate;
410 | switch (channel) {
411 | case 0: {
412 | rate = 1;
413 | break;
414 | }
415 | case 1: {
416 | rate = 1;
417 | break;
418 | }
419 | default: {
420 | rate = -1;
421 | break;
422 | }
423 |
424 | }
425 | return rate;
426 |
427 | }
428 |
429 | static void classInit(int samplingFreq) {
430 |
431 | }
432 |
433 | virtual void instanceInit(int samplingFreq) {
434 | fSamplingFreq = samplingFreq;
435 | IOTA = 0;
436 | for (int i0 = 0; (i0 < 65536); i0 = (i0 + 1)) {
437 | fVec0[i0] = 0.f;
438 |
439 | }
440 | for (int i1 = 0; (i1 < 65536); i1 = (i1 + 1)) {
441 | fVec1[i1] = 0.f;
442 |
443 | }
444 | iConst0 = min(192000, max(1, fSamplingFreq));
445 | fConst1 = expf((0.f - (200.f / float(iConst0))));
446 | fConst2 = (1.f - fConst1);
447 | fHslider0 = FAUSTFLOAT(0.5);
448 | for (int i2 = 0; (i2 < 2); i2 = (i2 + 1)) {
449 | fRec0[i2] = 0.f;
450 |
451 | }
452 | fHslider1 = FAUSTFLOAT(0.);
453 | fConst3 = (0.001f * (float(iConst0) * fConst2));
454 | fHslider2 = FAUSTFLOAT(50.);
455 | for (int i3 = 0; (i3 < 2); i3 = (i3 + 1)) {
456 | fRec2[i3] = 0.f;
457 |
458 | }
459 | for (int i4 = 0; (i4 < 2); i4 = (i4 + 1)) {
460 | fRec1[i4] = 0.f;
461 |
462 | }
463 | fConst4 = (50.f / float(iConst0));
464 | fHslider3 = FAUSTFLOAT(0.);
465 | for (int i5 = 0; (i5 < 2); i5 = (i5 + 1)) {
466 | fRec3[i5] = 0.f;
467 |
468 | }
469 |
470 | }
471 |
472 | virtual void init(int samplingFreq) {
473 | classInit(samplingFreq);
474 | instanceInit(samplingFreq);
475 | }
476 |
477 | virtual void buildUserInterface(UI* interface) {
478 | interface->openVerticalBox("0x00");
479 | interface->declare(&fHslider0, "OWL", "PARAMETER_D");
480 | interface->addHorizontalSlider("Mix", &fHslider0, 0.5f, 0.f, 1.f, 0.01f);
481 | interface->declare(&fHslider1, "OWL", "PARAMETER_A");
482 | interface->declare(&fHslider1, "unit", "semitones");
483 | interface->addHorizontalSlider("Shift L", &fHslider1, 0.f, -12.f, 12.f, 0.1f);
484 | interface->declare(&fHslider3, "OWL", "PARAMETER_B");
485 | interface->declare(&fHslider3, "unit", "semitones");
486 | interface->addHorizontalSlider("Shift R", &fHslider3, 0.f, -12.f, 12.f, 0.1f);
487 | interface->declare(&fHslider2, "OWL", "PARAMETER_C");
488 | interface->declare(&fHslider2, "unit", "ms");
489 | interface->addHorizontalSlider("Window Size", &fHslider2, 50.f, 20.f, 1000.f, 1.f);
490 | interface->closeBox();
491 |
492 | }
493 |
494 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
495 | FAUSTFLOAT* input0 = inputs[0];
496 | FAUSTFLOAT* input1 = inputs[1];
497 | FAUSTFLOAT* output0 = outputs[0];
498 | FAUSTFLOAT* output1 = outputs[1];
499 | float fSlow0 = (fConst2 * float(fHslider0));
500 | float fSlow1 = (1.f - powf(2.f, (0.0833333f * float(fHslider1))));
501 | float fSlow2 = (fConst3 * float(fHslider2));
502 | float fSlow3 = (1.f - powf(2.f, (0.0833333f * float(fHslider3))));
503 | for (int i = 0; (i < count); i = (i + 1)) {
504 | float fTemp0 = float(input0[i]);
505 | fVec0[(IOTA & 65535)] = fTemp0;
506 | float fTemp1 = float(input1[i]);
507 | fVec1[(IOTA & 65535)] = fTemp1;
508 | fRec0[0] = ((fConst1 * fRec0[1]) + fSlow0);
509 | float fTemp2 = (1.f - fRec0[0]);
510 | fRec2[0] = (fSlow2 + (fConst1 * fRec2[1]));
511 | fRec1[0] = fmodf((fSlow1 + (fRec2[0] + fRec1[1])), fRec2[0]);
512 | int iTemp3 = int(fRec1[0]);
513 | int iTemp4 = (1 + iTemp3);
514 | float fTemp5 = min((fConst4 * fRec1[0]), 1.f);
515 | float fTemp6 = (fRec2[0] + fRec1[0]);
516 | int iTemp7 = int(fTemp6);
517 | int iTemp8 = (1 + iTemp7);
518 | output0[i] = FAUSTFLOAT(((fTemp0 * fTemp2) + (fRec0[0] * ((((fVec0[((IOTA - (iTemp3 & 65535)) & 65535)] * (float(iTemp4) - fRec1[0])) + ((fRec1[0] - float(iTemp3)) * fVec0[((IOTA - (iTemp4 & 65535)) & 65535)])) * fTemp5) + (((fVec0[((IOTA - (iTemp7 & 65535)) & 65535)] * (0.f - (fTemp6 - float(iTemp8)))) + ((fTemp6 - float(iTemp7)) * fVec0[((IOTA - (iTemp8 & 65535)) & 65535)])) * (1.f - fTemp5))))));
519 | fRec3[0] = fmodf((fSlow3 + (fRec2[0] + fRec3[1])), fRec2[0]);
520 | int iTemp9 = int(fRec3[0]);
521 | int iTemp10 = (1 + iTemp9);
522 | float fTemp11 = min((fConst4 * fRec3[0]), 1.f);
523 | float fTemp12 = (fRec2[0] + fRec3[0]);
524 | int iTemp13 = int(fTemp12);
525 | int iTemp14 = (1 + iTemp13);
526 | output1[i] = FAUSTFLOAT(((fTemp1 * fTemp2) + (fRec0[0] * ((((fVec1[((IOTA - (iTemp9 & 65535)) & 65535)] * (float(iTemp10) - fRec3[0])) + ((fRec3[0] - float(iTemp9)) * fVec1[((IOTA - (iTemp10 & 65535)) & 65535)])) * fTemp11) + (((fVec1[((IOTA - (iTemp13 & 65535)) & 65535)] * (0.f - (fTemp12 - float(iTemp14)))) + ((fTemp12 - float(iTemp13)) * fVec1[((IOTA - (iTemp14 & 65535)) & 65535)])) * (1.f - fTemp11))))));
527 | IOTA = (IOTA + 1);
528 | fRec0[1] = fRec0[0];
529 | fRec2[1] = fRec2[0];
530 | fRec1[1] = fRec1[0];
531 | fRec3[1] = fRec3[0];
532 |
533 | }
534 |
535 | }
536 |
537 |
538 | };
539 |
540 |
541 | /***************************END USER SECTION ***************************/
542 |
543 | /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
544 |
545 |
546 |
547 | /**************************************************************************************
548 |
549 | DualPitchShifterPatch : an OWL patch that calls Faust generated DSP code
550 |
551 | ***************************************************************************************/
552 |
553 | class DualPitchShifterPatch : public Patch
554 | {
555 | DualPitchShifter fDSP;
556 | OwlUI fUI;
557 |
558 | public:
559 |
560 | DualPitchShifterPatch() : fUI(this)
561 | {
562 | fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
563 | fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
564 | }
565 |
566 | void processAudio(AudioBuffer &buffer)
567 | {
568 | // Reasonably assume we will not have more than 32 channels
569 | float* ins[32];
570 | float* outs[32];
571 | int n = buffer.getChannels();
572 |
573 | if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
574 |
575 | // create the table of input channels
576 | for(int ch=0; ch
10 |
11 |
12 |
13 | ## DroneBox OWL
14 | DroneBox OWL is a sympathetic resonance generator: a bank of four virtual tuned strings that resonate in response to the audio input. If the input signal contains energy at the frequency of one of the four strings (or one of their harmonics) it will start the string resonating. The strings are tuned to multiples 1., 1.5, 2. and 3. times the fundamental frequency. It’s a stereo effect and will process stereo signals and works well with many different kinds of audio input. This is a (very) simplified version of my forthcoming plug-in DroneBox v3.
15 |
16 | ### Parameters:
17 | * A) Coarse pitch (stepped in semitones) -- Range C1 (65Hz) to C3 (261Hz)
18 | * B) Fine pitch (cents) -- Range 0 to 100
19 | * C) Decay time (ms) -- Range 200 ms to 30 seconds
20 | * D) Dry/Wet mix
21 |
22 |
23 | ## Dual Frequency Shifter
24 | Dual Frequency Shifter is a twin frequency shifter with independent L-R control of frequency shift. Frequency shifting in small amounts can cause phasing when the dry signal is present. Parameter C is a multiplier which will allow more extreme frequency shifting effects. In order to get subtle phasing effects make sure Parameter C is turned fully left.
25 |
26 | NOTE: Parameter A and B are bi-polar controls so put it in the middle to set the frequency shift for that channel to 0.
27 |
28 | ### Parameters:
29 |
30 | * A) Left frequency shift (Hz) -- Range -1 to 1
31 | * B) Right frequency shift (Hz) -- Range -1 to 1
32 | * C) Shift scalar -- Range 1 to 100
33 | * D) Dry/Wet mix
34 |
35 | ## Stereo Frequency Shifter
36 | Stereo Frequency Shifter is a twin frequency shifter with linked control of frequency shift for each channel, that can be slightly offset for lush stereo phasing. In order to get subtle phasing effects make sure Parameter B is turned fully left.
37 |
38 | NOTE: Parameter A is a bi-polar control so put it in the middle to set the frequency shift to 0.
39 |
40 | ### Parameters:
41 | * A) Frequency shift (Hz) -- Range -1 to 1
42 | * B) Shift scalar -- Range 1 to 100
43 | * C) L-R offset (Hz) -- Range 0 to 1
44 | * D) Dry/Wet mix
45 |
46 | ## XFM Oscillator
47 | XFM Oscillator is a cross coupled FM oscillator, which is ported from Tom Schouten's xfm~ pd object
48 |
49 | ### Parameters:
50 | * A) Oscillator 1 frequency (Hz) -- Range 0 to 1000
51 | * B) Oscillator 2 frequency (Hz) -- Range 0 to 1000
52 | * C) Oscillator 1 cross modulation depth (Hz) -- Range 0 to 1000
53 | * D) Oscillator 2 cross modulation depth (Hz) -- Range 0 to 1000
54 |
55 | ## Thru Zero Flanger
56 | Thru Zero Flanger is a stereo flanger, that can completely cancel left and right channels at a certain point during the LFO’s cycle resulting in some interesting spatial effects, especially with a wide-band noise source as the input signal.
57 |
58 | ### Parameters:
59 | * A) Rate (Hz) -- Range 0 to 1
60 | * B) Delay time (ms) -- Range 0.5 to 20
61 | * C) L-R offset -- Range 0 to 1
62 | * D) Depth (%) -- Range 0 to 100
63 |
64 | ## Dual Pitch Shifter
65 | Dual Pitch Shifter is a dual channel pitch shifter, based on Faust’s pitch_shifter.dsp by Grame. Pitch shifting is (intentionally) extremely basic and introduces significant delay based on window size.
66 |
67 | NOTE: Parameters A and B are bi-polar controls so put them in the middle to set the pitch shift to 0 semitones.
68 |
69 | ### Parameters:
70 | * A) Left shift (semitones) -- Range -12 to +12
71 | * B) Right shift (semitones) -- Range -12 to +12
72 | * C) Window size (ms) — Range 20 to 1000
73 | * D) Dry/Wet mix
74 |
75 | ## Blipper
76 | Blipper is an Envelope Follower which controls the pitch of a triangle oscillator. It is a rough emulation of some of the features of the BOSS PC-2 Percussion Synthesiser. Arthur Russell used something like this to create interesting percussion parts on his records e.g. . It works nicely with drums.
77 |
78 | NOTE: Parameter C (Pitch mod depth) is a bi-polar control so put it in the middle to set the depth to 0.
79 |
80 | ### Parameters:
81 | * A) Base pitch (semitones) -- Range C0 (32Hz) to C6 (2093Hz)
82 | * B) Pitch mod depth (semitones) -- Range -64 to +64 semitones.
83 | * C) Release time (ms) -- Range 2 ms to 100 ms
84 | * D) Dry/Wet mix
85 |
86 | ## Weird Phaser
87 | Weird Phaser is a stereo phase shifter based on SSB (single side band) modulation. Unlike "Stereo Frequency Shifter", Weird Phaser uses a single LFO which has a fixed phase offset for the right hand channel, causing some interesting "between the ears" spatial effects at its maximum settting. Weird Phaser also has feedback for a more pronounced effect.
88 |
89 | ### Parameters:
90 | * A) Rate (Hz) -- Range 0 to 1
91 | * B) Rate scalar -- Range 1 to 40
92 | * C) L-R offset (phase) -- Range 0 to 1
93 | * D) Feedback -- Range 0 to 1
94 |
95 |
96 |
--------------------------------------------------------------------------------
/StereoFreqShifter.dsp:
--------------------------------------------------------------------------------
1 | declare name "Stereo Frequency Shifter";
2 | declare description "Stereo Frequency Shifting";
3 | declare author "Oli Larkin (contact@olilarkin.co.uk)";
4 | declare copyright "Oliver Larkin";
5 | declare version "0.1";
6 | declare licence "GPL";
7 |
8 | import("stdfaust.lib");
9 | import("FrequencyShifter.lib");
10 |
11 | shift = hslider("Shift [unit:hz] [OWL:PARAMETER_A]", 0.0, -1., 1, 0.001);
12 | shift_scalar = hslider("Shift Scalar [OWL:PARAMETER_B]", 1., 1., 100, 0.1);
13 | lr_offset = hslider("L-R Offset [OWL:PARAMETER_C]", 0., 0., 1., 0.00001);
14 | mix = hslider("Mix [OWL:PARAMETER_D]",0.5,0,1,0.01) : si.smooth(ba.tau2pole(0.005));
15 |
16 | shift_amount = shift*shift_scalar;
17 | process(l, r) = l, r <: *(1-mix), *(1-mix), ssb(shift_amount,l)*mix, ssb(shift_amount+lr_offset,r)*mix :> _,_;
--------------------------------------------------------------------------------
/StereoFreqShifterPatch.hpp:
--------------------------------------------------------------------------------
1 | /* ------------------------------------------------------------
2 | author: "Oli Larkin (contact@olilarkin.co.uk)"
3 | copyright: "Oliver Larkin"
4 | name: "Stereo Frequency Shifter"
5 | version: "0.1"
6 | Code generated with Faust 2.0.a41 (http://faust.grame.fr)
7 | ------------------------------------------------------------ */
8 |
9 | #ifndef __StereoFreqShifter_H__
10 | #define __StereoFreqShifter_H__
11 | /************************************************************************
12 |
13 | IMPORTANT NOTE : this file contains two clearly delimited sections :
14 | the ARCHITECTURE section (in two parts) and the USER section. Each section
15 | is governed by its own copyright and license. Please check individually
16 | each section for license and copyright information.
17 | *************************************************************************/
18 |
19 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
20 |
21 | /************************************************************************
22 | FAUST Architecture File
23 | Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
24 | ---------------------------------------------------------------------
25 | This Architecture section is free software; you can redistribute it
26 | and/or modify it under the terms of the GNU General Public License
27 | as published by the Free Software Foundation; either version 3 of
28 | the License, or (at your option) any later version.
29 |
30 | This program is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with this program; If not, see .
37 |
38 | EXCEPTION : As a special exception, you may create a larger work
39 | that contains this FAUST architecture section and distribute
40 | that work under terms of your choice, so long as this FAUST
41 | architecture section is not modified.
42 |
43 |
44 | ************************************************************************
45 | ************************************************************************/
46 |
47 | #ifndef __StereoFreqShifterPatch_h__
48 | #define __StereoFreqShifterPatch_h__
49 |
50 | #include "StompBox.h"
51 | #include
52 | #include
53 | #include
54 |
55 |
56 | #ifndef __FaustCommonInfrastructure__
57 | #define __FaustCommonInfrastructure__
58 |
59 |
60 | /************************************************************************
61 | IMPORTANT NOTE : this file contains two clearly delimited sections :
62 | the ARCHITECTURE section (in two parts) and the USER section. Each section
63 | is governed by its own copyright and license. Please check individually
64 | each section for license and copyright information.
65 | *************************************************************************/
66 |
67 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
68 |
69 | /************************************************************************
70 | FAUST Architecture File
71 | Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
72 | ---------------------------------------------------------------------
73 | This Architecture section is free software; you can redistribute it
74 | and/or modify it under the terms of the GNU General Public License
75 | as published by the Free Software Foundation; either version 3 of
76 | the License, or (at your option) any later version.
77 |
78 | This program is distributed in the hope that it will be useful,
79 | but WITHOUT ANY WARRANTY; without even the implied warranty of
80 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 | GNU General Public License for more details.
82 |
83 | You should have received a copy of the GNU General Public License
84 | along with this program; If not, see .
85 |
86 | EXCEPTION : As a special exception, you may create a larger work
87 | that contains this FAUST architecture section and distribute
88 | that work under terms of your choice, so long as this FAUST
89 | architecture section is not modified.
90 |
91 |
92 | ************************************************************************
93 | ************************************************************************/
94 |
95 | /******************************************************************************
96 | *******************************************************************************
97 |
98 | FAUST DSP
99 |
100 | *******************************************************************************
101 | *******************************************************************************/
102 |
103 | #ifndef __dsp__
104 | #define __dsp__
105 |
106 | #ifndef FAUSTFLOAT
107 | #define FAUSTFLOAT float
108 | #endif
109 |
110 | class UI;
111 |
112 | //----------------------------------------------------------------
113 | // Signal processor definition
114 | //----------------------------------------------------------------
115 |
116 | class dsp {
117 |
118 | protected:
119 | int fSamplingFreq;
120 |
121 | public:
122 | dsp() {}
123 | virtual ~dsp() {}
124 |
125 | virtual int getNumInputs() = 0;
126 | virtual int getNumOutputs() = 0;
127 | virtual void buildUserInterface(UI* ui_interface) = 0;
128 | virtual void init(int samplingRate) = 0;
129 | virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
130 | };
131 |
132 | // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
133 | // flags to avoid costly denormals
134 | #ifdef __SSE__
135 | #include
136 | #ifdef __SSE2__
137 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
138 | #else
139 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
140 | #endif
141 | #else
142 | #define AVOIDDENORMALS
143 | #endif
144 |
145 | #endif
146 | #ifndef FAUST_UI_H
147 | #define FAUST_UI_H
148 |
149 | #ifndef FAUSTFLOAT
150 | #define FAUSTFLOAT float
151 | #endif
152 |
153 | /*******************************************************************************
154 | * UI : Faust User Interface
155 | * This abstract class contains only the method that the faust compiler can
156 | * generate to describe a DSP interface.
157 | ******************************************************************************/
158 |
159 | class UI
160 | {
161 |
162 | public:
163 |
164 | UI() {}
165 |
166 | virtual ~UI() {}
167 |
168 | // -- widget's layouts
169 |
170 | virtual void openTabBox(const char* label) = 0;
171 | virtual void openHorizontalBox(const char* label) = 0;
172 | virtual void openVerticalBox(const char* label) = 0;
173 | virtual void closeBox() = 0;
174 |
175 | // -- active widgets
176 |
177 | virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
178 | virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
179 | virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
180 | virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
181 | virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
182 |
183 | // -- passive widgets
184 |
185 | virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
186 | virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
187 |
188 | // -- metadata declarations
189 |
190 | virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val) {}
191 | };
192 |
193 | #endif
194 |
195 |
196 |
197 | struct Meta
198 | {
199 | virtual void declare(const char* key, const char* value) = 0;
200 | };
201 |
202 |
203 |
204 | /**************************************************************************************
205 |
206 | OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
207 | and a faust widget
208 |
209 | ***************************************************************************************/
210 |
211 | class OwlWidget
212 | {
213 | protected:
214 | Patch* fPatch; // needed to register and read owl parameters
215 | PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
216 | FAUSTFLOAT* fZone; // Faust widget zone
217 | const char* fLabel; // Faust widget label
218 | float fMin; // Faust widget minimal value
219 | float fSpan; // Faust widget value span (max-min)
220 |
221 | public:
222 | OwlWidget() :
223 | fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
224 | OwlWidget(const OwlWidget& w) :
225 | fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
226 | OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
227 | fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
228 | void bind() { fPatch->registerParameter(fParameter, fLabel); }
229 | void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
230 |
231 | };
232 |
233 |
234 | /**************************************************************************************
235 |
236 | OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
237 | the mapping between owl parameters and faust widgets. It relies on specific
238 | metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
239 | faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
240 | (the second knob).
241 |
242 | ***************************************************************************************/
243 |
244 | // The maximun number of mappings between owl parameters and faust widgets
245 | #define MAXOWLWIDGETS 8
246 |
247 | class OwlUI : public UI
248 | {
249 | Patch* fPatch;
250 | PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
251 | int fIndex; // number of OwlWidgets collected so far
252 | OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
253 |
254 | // check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
255 | void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
256 | if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
257 | fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
258 | fTable[fIndex].bind();
259 | fIndex++;
260 | }
261 | fParameter = PARAMETER_F; // clear current parameter ID
262 | }
263 |
264 | // we dont want to create a widget by-ut we clear the current parameter ID just in case
265 | void skip() {
266 | fParameter = PARAMETER_F; // clear current parameter ID
267 | }
268 |
269 | public:
270 |
271 | OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
272 |
273 | virtual ~OwlUI() {}
274 |
275 | // should be called before compute() to update widget's zones registered as Owl parameters
276 | void update() {
277 | for (int i=0; i
325 |
326 |
327 | #ifndef FAUSTCLASS
328 | #define FAUSTCLASS StereoFreqShifter
329 | #endif
330 |
331 | class StereoFreqShifter : public dsp {
332 |
333 | private:
334 |
335 | float fRec2[3];
336 | float fRec1[3];
337 | float fRec5[3];
338 | float fRec4[3];
339 | float fRec7[3];
340 | float fRec6[3];
341 | float fRec10[3];
342 | float fRec9[3];
343 | float fRec0[2];
344 | float fRec3[2];
345 | float fRec8[2];
346 | int fSamplingFreq;
347 | int iConst0;
348 | float fConst1;
349 | float fConst2;
350 | FAUSTFLOAT fHslider0;
351 | float fConst3;
352 | FAUSTFLOAT fHslider1;
353 | FAUSTFLOAT fHslider2;
354 | FAUSTFLOAT fHslider3;
355 |
356 | public:
357 |
358 | void static metadata(Meta* m) {
359 | m->declare("author", "Oli Larkin (contact@olilarkin.co.uk)");
360 | m->declare("copyright", "Oliver Larkin");
361 | m->declare("description", "Stereo Frequency Shifting");
362 | m->declare("effect.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
363 | m->declare("effect.lib/copyright", "Julius O. Smith III");
364 | m->declare("effect.lib/exciter_author", "Priyanka Shekar (pshekar@ccrma.stanford.edu)");
365 | m->declare("effect.lib/exciter_copyright", "Copyright (c) 2013 Priyanka Shekar");
366 | m->declare("effect.lib/exciter_license", "MIT License (MIT)");
367 | m->declare("effect.lib/exciter_name", "Harmonic Exciter");
368 | m->declare("effect.lib/exciter_version", "1.0");
369 | m->declare("effect.lib/license", "STK-4.3");
370 | m->declare("effect.lib/name", "Faust Audio Effect Library");
371 | m->declare("effect.lib/version", "1.33");
372 | m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
373 | m->declare("filter.lib/copyright", "Julius O. Smith III");
374 | m->declare("filter.lib/license", "STK-4.3");
375 | m->declare("filter.lib/name", "Faust Filter Library");
376 | m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/");
377 | m->declare("filter.lib/version", "1.29");
378 | m->declare("licence", "GPL");
379 | m->declare("math.lib/author", "GRAME");
380 | m->declare("math.lib/copyright", "GRAME");
381 | m->declare("math.lib/license", "LGPL with exception");
382 | m->declare("math.lib/name", "Math Library");
383 | m->declare("math.lib/version", "1.0");
384 | m->declare("music.lib/author", "GRAME");
385 | m->declare("music.lib/copyright", "GRAME");
386 | m->declare("music.lib/license", "LGPL with exception");
387 | m->declare("music.lib/name", "Music Library");
388 | m->declare("music.lib/version", "1.0");
389 | m->declare("name", "Stereo Frequency Shifter");
390 | m->declare("version", "0.1");
391 | }
392 |
393 | virtual int getNumInputs() {
394 | return 2;
395 |
396 | }
397 | virtual int getNumOutputs() {
398 | return 2;
399 |
400 | }
401 | virtual int getInputRate(int channel) {
402 | int rate;
403 | switch (channel) {
404 | case 0: {
405 | rate = 1;
406 | break;
407 | }
408 | case 1: {
409 | rate = 1;
410 | break;
411 | }
412 | default: {
413 | rate = -1;
414 | break;
415 | }
416 |
417 | }
418 | return rate;
419 |
420 | }
421 | virtual int getOutputRate(int channel) {
422 | int rate;
423 | switch (channel) {
424 | case 0: {
425 | rate = 1;
426 | break;
427 | }
428 | case 1: {
429 | rate = 1;
430 | break;
431 | }
432 | default: {
433 | rate = -1;
434 | break;
435 | }
436 |
437 | }
438 | return rate;
439 |
440 | }
441 |
442 | static void classInit(int samplingFreq) {
443 |
444 | }
445 |
446 | virtual void instanceInit(int samplingFreq) {
447 | fSamplingFreq = samplingFreq;
448 | iConst0 = min(192000, max(1, fSamplingFreq));
449 | fConst1 = expf((0.f - (200.f / float(iConst0))));
450 | fConst2 = (1.f - fConst1);
451 | fHslider0 = FAUSTFLOAT(0.5);
452 | for (int i0 = 0; (i0 < 2); i0 = (i0 + 1)) {
453 | fRec0[i0] = 0.f;
454 |
455 | }
456 | for (int i1 = 0; (i1 < 3); i1 = (i1 + 1)) {
457 | fRec2[i1] = 0.f;
458 |
459 | }
460 | for (int i2 = 0; (i2 < 3); i2 = (i2 + 1)) {
461 | fRec1[i2] = 0.f;
462 |
463 | }
464 | fConst3 = (1.f / float(iConst0));
465 | fHslider1 = FAUSTFLOAT(0.);
466 | fHslider2 = FAUSTFLOAT(1.);
467 | for (int i3 = 0; (i3 < 2); i3 = (i3 + 1)) {
468 | fRec3[i3] = 0.f;
469 |
470 | }
471 | for (int i4 = 0; (i4 < 3); i4 = (i4 + 1)) {
472 | fRec5[i4] = 0.f;
473 |
474 | }
475 | for (int i5 = 0; (i5 < 3); i5 = (i5 + 1)) {
476 | fRec4[i5] = 0.f;
477 |
478 | }
479 | for (int i6 = 0; (i6 < 3); i6 = (i6 + 1)) {
480 | fRec7[i6] = 0.f;
481 |
482 | }
483 | for (int i7 = 0; (i7 < 3); i7 = (i7 + 1)) {
484 | fRec6[i7] = 0.f;
485 |
486 | }
487 | fHslider3 = FAUSTFLOAT(0.);
488 | for (int i8 = 0; (i8 < 2); i8 = (i8 + 1)) {
489 | fRec8[i8] = 0.f;
490 |
491 | }
492 | for (int i9 = 0; (i9 < 3); i9 = (i9 + 1)) {
493 | fRec10[i9] = 0.f;
494 |
495 | }
496 | for (int i10 = 0; (i10 < 3); i10 = (i10 + 1)) {
497 | fRec9[i10] = 0.f;
498 |
499 | }
500 |
501 | }
502 |
503 | virtual void init(int samplingFreq) {
504 | classInit(samplingFreq);
505 | instanceInit(samplingFreq);
506 | }
507 |
508 | virtual void buildUserInterface(UI* interface) {
509 | interface->openVerticalBox("0x00");
510 | interface->declare(&fHslider3, "OWL", "PARAMETER_C");
511 | interface->addHorizontalSlider("L-R Offset", &fHslider3, 0.f, 0.f, 1.f, 1e-05f);
512 | interface->declare(&fHslider0, "OWL", "PARAMETER_D");
513 | interface->addHorizontalSlider("Mix", &fHslider0, 0.5f, 0.f, 1.f, 0.01f);
514 | interface->declare(&fHslider2, "OWL", "PARAMETER_B");
515 | interface->addHorizontalSlider("Shift Scalar", &fHslider2, 1.f, 1.f, 100.f, 0.1f);
516 | interface->declare(&fHslider1, "OWL", "PARAMETER_A");
517 | interface->declare(&fHslider1, "unit", "hz");
518 | interface->addHorizontalSlider("Shift", &fHslider1, 0.f, -1.f, 1.f, 0.001f);
519 | interface->closeBox();
520 |
521 | }
522 |
523 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
524 | FAUSTFLOAT* input0 = inputs[0];
525 | FAUSTFLOAT* input1 = inputs[1];
526 | FAUSTFLOAT* output0 = outputs[0];
527 | FAUSTFLOAT* output1 = outputs[1];
528 | float fSlow0 = (fConst2 * float(fHslider0));
529 | float fSlow1 = (float(fHslider1) * float(fHslider2));
530 | float fSlow2 = (fConst3 * fSlow1);
531 | float fSlow3 = (fConst3 * (fSlow1 + float(fHslider3)));
532 | for (int i = 0; (i < count); i = (i + 1)) {
533 | float fTemp0 = float(input0[i]);
534 | float fTemp1 = float(input1[i]);
535 | fRec0[0] = ((fConst1 * fRec0[1]) + fSlow0);
536 | float fTemp2 = (1.f - fRec0[0]);
537 | float fTemp3 = (0.02569f * fRec2[1]);
538 | fRec2[0] = ((fTemp0 + (0.260502f * fRec2[2])) - fTemp3);
539 | float fTemp4 = (1.8685f * fRec1[1]);
540 | fRec1[0] = ((fRec2[2] + (fTemp4 + fTemp3)) - ((0.870686f * fRec1[2]) + (0.260502f * fRec2[0])));
541 | float fTemp5 = (fRec3[1] + fSlow2);
542 | fRec3[0] = (fTemp5 - floorf(fTemp5));
543 | float fTemp6 = (6.28319f * fmodf(fRec3[0], 1.f));
544 | float fTemp7 = (1.94632f * fRec5[1]);
545 | fRec5[0] = ((fTemp0 + fTemp7) - (0.94657f * fRec5[2]));
546 | float fTemp8 = (0.83774f * fRec4[1]);
547 | fRec4[0] = ((fRec5[2] + ((0.94657f * fRec5[0]) + fTemp8)) - ((0.06338f * fRec4[2]) + fTemp7));
548 | output0[i] = FAUSTFLOAT(((fTemp0 * fTemp2) + (fRec0[0] * (((((0.870686f * fRec1[0]) + fRec1[2]) - fTemp4) * cosf(fTemp6)) - (sinf(fTemp6) * (((0.06338f * fRec4[0]) + fRec4[2]) - fTemp8))))));
549 | float fTemp9 = (0.02569f * fRec7[1]);
550 | fRec7[0] = ((fTemp1 + (0.260502f * fRec7[2])) - fTemp9);
551 | float fTemp10 = (1.8685f * fRec6[1]);
552 | fRec6[0] = ((fRec7[2] + (fTemp10 + fTemp9)) - ((0.870686f * fRec6[2]) + (0.260502f * fRec7[0])));
553 | float fTemp11 = (fRec8[1] + fSlow3);
554 | fRec8[0] = (fTemp11 - floorf(fTemp11));
555 | float fTemp12 = (6.28319f * fmodf(fRec8[0], 1.f));
556 | float fTemp13 = (1.94632f * fRec10[1]);
557 | fRec10[0] = ((fTemp1 + fTemp13) - (0.94657f * fRec10[2]));
558 | float fTemp14 = (0.83774f * fRec9[1]);
559 | fRec9[0] = ((fRec10[2] + ((0.94657f * fRec10[0]) + fTemp14)) - ((0.06338f * fRec9[2]) + fTemp13));
560 | output1[i] = FAUSTFLOAT(((fTemp1 * fTemp2) + (fRec0[0] * (((((0.870686f * fRec6[0]) + fRec6[2]) - fTemp10) * cosf(fTemp12)) - (sinf(fTemp12) * (((0.06338f * fRec9[0]) + fRec9[2]) - fTemp14))))));
561 | fRec0[1] = fRec0[0];
562 | fRec2[2] = fRec2[1];
563 | fRec2[1] = fRec2[0];
564 | fRec1[2] = fRec1[1];
565 | fRec1[1] = fRec1[0];
566 | fRec3[1] = fRec3[0];
567 | fRec5[2] = fRec5[1];
568 | fRec5[1] = fRec5[0];
569 | fRec4[2] = fRec4[1];
570 | fRec4[1] = fRec4[0];
571 | fRec7[2] = fRec7[1];
572 | fRec7[1] = fRec7[0];
573 | fRec6[2] = fRec6[1];
574 | fRec6[1] = fRec6[0];
575 | fRec8[1] = fRec8[0];
576 | fRec10[2] = fRec10[1];
577 | fRec10[1] = fRec10[0];
578 | fRec9[2] = fRec9[1];
579 | fRec9[1] = fRec9[0];
580 |
581 | }
582 |
583 | }
584 |
585 |
586 | };
587 |
588 |
589 | /***************************END USER SECTION ***************************/
590 |
591 | /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
592 |
593 |
594 |
595 | /**************************************************************************************
596 |
597 | StereoFreqShifterPatch : an OWL patch that calls Faust generated DSP code
598 |
599 | ***************************************************************************************/
600 |
601 | class StereoFreqShifterPatch : public Patch
602 | {
603 | StereoFreqShifter fDSP;
604 | OwlUI fUI;
605 |
606 | public:
607 |
608 | StereoFreqShifterPatch() : fUI(this)
609 | {
610 | fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
611 | fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
612 | }
613 |
614 | void processAudio(AudioBuffer &buffer)
615 | {
616 | // Reasonably assume we will not have more than 32 channels
617 | float* ins[32];
618 | float* outs[32];
619 | int n = buffer.getChannels();
620 |
621 | if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
622 |
623 | // create the table of input channels
624 | for(int ch=0; ch.
37 |
38 | EXCEPTION : As a special exception, you may create a larger work
39 | that contains this FAUST architecture section and distribute
40 | that work under terms of your choice, so long as this FAUST
41 | architecture section is not modified.
42 |
43 |
44 | ************************************************************************
45 | ************************************************************************/
46 |
47 | #ifndef __ThruZeroFlangerPatch_h__
48 | #define __ThruZeroFlangerPatch_h__
49 |
50 | #include "StompBox.h"
51 | #include
52 | #include
53 | #include
54 |
55 |
56 | #ifndef __FaustCommonInfrastructure__
57 | #define __FaustCommonInfrastructure__
58 |
59 |
60 | /************************************************************************
61 | IMPORTANT NOTE : this file contains two clearly delimited sections :
62 | the ARCHITECTURE section (in two parts) and the USER section. Each section
63 | is governed by its own copyright and license. Please check individually
64 | each section for license and copyright information.
65 | *************************************************************************/
66 |
67 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
68 |
69 | /************************************************************************
70 | FAUST Architecture File
71 | Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
72 | ---------------------------------------------------------------------
73 | This Architecture section is free software; you can redistribute it
74 | and/or modify it under the terms of the GNU General Public License
75 | as published by the Free Software Foundation; either version 3 of
76 | the License, or (at your option) any later version.
77 |
78 | This program is distributed in the hope that it will be useful,
79 | but WITHOUT ANY WARRANTY; without even the implied warranty of
80 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 | GNU General Public License for more details.
82 |
83 | You should have received a copy of the GNU General Public License
84 | along with this program; If not, see .
85 |
86 | EXCEPTION : As a special exception, you may create a larger work
87 | that contains this FAUST architecture section and distribute
88 | that work under terms of your choice, so long as this FAUST
89 | architecture section is not modified.
90 |
91 |
92 | ************************************************************************
93 | ************************************************************************/
94 |
95 | /******************************************************************************
96 | *******************************************************************************
97 |
98 | FAUST DSP
99 |
100 | *******************************************************************************
101 | *******************************************************************************/
102 |
103 | #ifndef __dsp__
104 | #define __dsp__
105 |
106 | #ifndef FAUSTFLOAT
107 | #define FAUSTFLOAT float
108 | #endif
109 |
110 | class UI;
111 |
112 | //----------------------------------------------------------------
113 | // Signal processor definition
114 | //----------------------------------------------------------------
115 |
116 | class dsp {
117 |
118 | protected:
119 | int fSamplingFreq;
120 |
121 | public:
122 | dsp() {}
123 | virtual ~dsp() {}
124 |
125 | virtual int getNumInputs() = 0;
126 | virtual int getNumOutputs() = 0;
127 | virtual void buildUserInterface(UI* ui_interface) = 0;
128 | virtual void init(int samplingRate) = 0;
129 | virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
130 | };
131 |
132 | // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
133 | // flags to avoid costly denormals
134 | #ifdef __SSE__
135 | #include
136 | #ifdef __SSE2__
137 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
138 | #else
139 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
140 | #endif
141 | #else
142 | #define AVOIDDENORMALS
143 | #endif
144 |
145 | #endif
146 | #ifndef FAUST_UI_H
147 | #define FAUST_UI_H
148 |
149 | #ifndef FAUSTFLOAT
150 | #define FAUSTFLOAT float
151 | #endif
152 |
153 | /*******************************************************************************
154 | * UI : Faust User Interface
155 | * This abstract class contains only the method that the faust compiler can
156 | * generate to describe a DSP interface.
157 | ******************************************************************************/
158 |
159 | class UI
160 | {
161 |
162 | public:
163 |
164 | UI() {}
165 |
166 | virtual ~UI() {}
167 |
168 | // -- widget's layouts
169 |
170 | virtual void openTabBox(const char* label) = 0;
171 | virtual void openHorizontalBox(const char* label) = 0;
172 | virtual void openVerticalBox(const char* label) = 0;
173 | virtual void closeBox() = 0;
174 |
175 | // -- active widgets
176 |
177 | virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
178 | virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
179 | virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
180 | virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
181 | virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
182 |
183 | // -- passive widgets
184 |
185 | virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
186 | virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
187 |
188 | // -- metadata declarations
189 |
190 | virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val) {}
191 | };
192 |
193 | #endif
194 |
195 |
196 |
197 | struct Meta
198 | {
199 | virtual void declare(const char* key, const char* value) = 0;
200 | };
201 |
202 |
203 |
204 | /**************************************************************************************
205 |
206 | OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
207 | and a faust widget
208 |
209 | ***************************************************************************************/
210 |
211 | class OwlWidget
212 | {
213 | protected:
214 | Patch* fPatch; // needed to register and read owl parameters
215 | PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
216 | FAUSTFLOAT* fZone; // Faust widget zone
217 | const char* fLabel; // Faust widget label
218 | float fMin; // Faust widget minimal value
219 | float fSpan; // Faust widget value span (max-min)
220 |
221 | public:
222 | OwlWidget() :
223 | fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
224 | OwlWidget(const OwlWidget& w) :
225 | fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
226 | OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
227 | fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
228 | void bind() { fPatch->registerParameter(fParameter, fLabel); }
229 | void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
230 |
231 | };
232 |
233 |
234 | /**************************************************************************************
235 |
236 | OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
237 | the mapping between owl parameters and faust widgets. It relies on specific
238 | metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
239 | faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
240 | (the second knob).
241 |
242 | ***************************************************************************************/
243 |
244 | // The maximun number of mappings between owl parameters and faust widgets
245 | #define MAXOWLWIDGETS 8
246 |
247 | class OwlUI : public UI
248 | {
249 | Patch* fPatch;
250 | PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
251 | int fIndex; // number of OwlWidgets collected so far
252 | OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
253 |
254 | // check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
255 | void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
256 | if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
257 | fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
258 | fTable[fIndex].bind();
259 | fIndex++;
260 | }
261 | fParameter = PARAMETER_F; // clear current parameter ID
262 | }
263 |
264 | // we dont want to create a widget by-ut we clear the current parameter ID just in case
265 | void skip() {
266 | fParameter = PARAMETER_F; // clear current parameter ID
267 | }
268 |
269 | public:
270 |
271 | OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
272 |
273 | virtual ~OwlUI() {}
274 |
275 | // should be called before compute() to update widget's zones registered as Owl parameters
276 | void update() {
277 | for (int i=0; i
325 |
326 |
327 | class ThruZeroFlangerSIG0 {
328 |
329 | private:
330 |
331 | int iRec2[2];
332 |
333 | public:
334 |
335 | int getNumInputsThruZeroFlangerSIG0() {
336 | return 0;
337 |
338 | }
339 | int getNumOutputsThruZeroFlangerSIG0() {
340 | return 1;
341 |
342 | }
343 | int getInputRateThruZeroFlangerSIG0(int channel) {
344 | int rate;
345 | switch (channel) {
346 | default: {
347 | rate = -1;
348 | break;
349 | }
350 |
351 | }
352 | return rate;
353 |
354 | }
355 | int getOutputRateThruZeroFlangerSIG0(int channel) {
356 | int rate;
357 | switch (channel) {
358 | case 0: {
359 | rate = 0;
360 | break;
361 | }
362 | default: {
363 | rate = -1;
364 | break;
365 | }
366 |
367 | }
368 | return rate;
369 |
370 | }
371 |
372 | void instanceInitThruZeroFlangerSIG0(int samplingFreq) {
373 | for (int i4 = 0; (i4 < 2); i4 = (i4 + 1)) {
374 | iRec2[i4] = 0;
375 |
376 | }
377 |
378 | }
379 |
380 | void fillThruZeroFlangerSIG0(int count, float* output) {
381 | for (int i = 0; (i < count); i = (i + 1)) {
382 | iRec2[0] = (1 + iRec2[1]);
383 | float fTemp2 = float((iRec2[0] - 1));
384 | float fTemp3 = (0.00195312f * fTemp2);
385 | float fTemp4 = (0.00390625f * fTemp2);
386 | output[i] = (2.f * ((float(((0.f <= fTemp3) & (fTemp3 <= 0.5f))) * (fTemp4 - 0.5f)) + (float(((0.5f < fTemp3) & (fTemp3 <= 1.f))) * (1.5f - fTemp4))));
387 | iRec2[1] = iRec2[0];
388 |
389 | }
390 |
391 | }
392 | };
393 |
394 | ThruZeroFlangerSIG0* newThruZeroFlangerSIG0() {return (ThruZeroFlangerSIG0*) new ThruZeroFlangerSIG0(); }
395 | void deleteThruZeroFlangerSIG0(ThruZeroFlangerSIG0* dsp) {delete dsp; }
396 |
397 | static float ftbl0ThruZeroFlangerSIG0[513];
398 |
399 | #ifndef FAUSTCLASS
400 | #define FAUSTCLASS ThruZeroFlanger
401 | #endif
402 |
403 | class ThruZeroFlanger : public dsp {
404 |
405 | private:
406 |
407 | float fVec0[4096];
408 | float fVec1[4096];
409 | float fRec0[2];
410 | float fRec1[2];
411 | float fRec3[2];
412 | float fRec4[2];
413 | int IOTA;
414 | int fSamplingFreq;
415 | int iConst0;
416 | float fConst1;
417 | float fConst2;
418 | float fConst3;
419 | float fConst4;
420 | FAUSTFLOAT fHslider0;
421 | float fConst5;
422 | FAUSTFLOAT fHslider1;
423 | float fConst6;
424 | FAUSTFLOAT fHslider2;
425 | float fConst7;
426 | FAUSTFLOAT fHslider3;
427 |
428 | public:
429 |
430 | void static metadata(Meta* m) {
431 | m->declare("author", "Oli Larkin (contact@olilarkin.co.uk)");
432 | m->declare("copyright", "Oliver Larkin");
433 | m->declare("description", "Stereo Thru Zero Flanger - warning can ZERO the sound!");
434 | m->declare("effect.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
435 | m->declare("effect.lib/copyright", "Julius O. Smith III");
436 | m->declare("effect.lib/exciter_author", "Priyanka Shekar (pshekar@ccrma.stanford.edu)");
437 | m->declare("effect.lib/exciter_copyright", "Copyright (c) 2013 Priyanka Shekar");
438 | m->declare("effect.lib/exciter_license", "MIT License (MIT)");
439 | m->declare("effect.lib/exciter_name", "Harmonic Exciter");
440 | m->declare("effect.lib/exciter_version", "1.0");
441 | m->declare("effect.lib/license", "STK-4.3");
442 | m->declare("effect.lib/name", "Faust Audio Effect Library");
443 | m->declare("effect.lib/version", "1.33");
444 | m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
445 | m->declare("filter.lib/copyright", "Julius O. Smith III");
446 | m->declare("filter.lib/license", "STK-4.3");
447 | m->declare("filter.lib/name", "Faust Filter Library");
448 | m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/");
449 | m->declare("filter.lib/version", "1.29");
450 | m->declare("licence", "GPL");
451 | m->declare("math.lib/author", "GRAME");
452 | m->declare("math.lib/copyright", "GRAME");
453 | m->declare("math.lib/license", "LGPL with exception");
454 | m->declare("math.lib/name", "Math Library");
455 | m->declare("math.lib/version", "1.0");
456 | m->declare("music.lib/author", "GRAME");
457 | m->declare("music.lib/copyright", "GRAME");
458 | m->declare("music.lib/license", "LGPL with exception");
459 | m->declare("music.lib/name", "Music Library");
460 | m->declare("music.lib/version", "1.0");
461 | m->declare("name", "Thru Zero Flanger");
462 | m->declare("version", "0.1");
463 | }
464 |
465 | virtual int getNumInputs() {
466 | return 2;
467 |
468 | }
469 | virtual int getNumOutputs() {
470 | return 2;
471 |
472 | }
473 | virtual int getInputRate(int channel) {
474 | int rate;
475 | switch (channel) {
476 | case 0: {
477 | rate = 1;
478 | break;
479 | }
480 | case 1: {
481 | rate = 1;
482 | break;
483 | }
484 | default: {
485 | rate = -1;
486 | break;
487 | }
488 |
489 | }
490 | return rate;
491 |
492 | }
493 | virtual int getOutputRate(int channel) {
494 | int rate;
495 | switch (channel) {
496 | case 0: {
497 | rate = 1;
498 | break;
499 | }
500 | case 1: {
501 | rate = 1;
502 | break;
503 | }
504 | default: {
505 | rate = -1;
506 | break;
507 | }
508 |
509 | }
510 | return rate;
511 |
512 | }
513 |
514 | static void classInit(int samplingFreq) {
515 | ThruZeroFlangerSIG0* sig0 = newThruZeroFlangerSIG0();
516 | sig0->instanceInitThruZeroFlangerSIG0(samplingFreq);
517 | sig0->fillThruZeroFlangerSIG0(513, ftbl0ThruZeroFlangerSIG0);
518 | deleteThruZeroFlangerSIG0(sig0);
519 |
520 | }
521 |
522 | virtual void instanceInit(int samplingFreq) {
523 | fSamplingFreq = samplingFreq;
524 | IOTA = 0;
525 | for (int i0 = 0; (i0 < 4096); i0 = (i0 + 1)) {
526 | fVec0[i0] = 0.f;
527 |
528 | }
529 | for (int i1 = 0; (i1 < 4096); i1 = (i1 + 1)) {
530 | fVec1[i1] = 0.f;
531 |
532 | }
533 | iConst0 = min(192000, max(1, fSamplingFreq));
534 | fConst1 = float(iConst0);
535 | fConst2 = (0.001f * fConst1);
536 | fConst3 = expf((0.f - (200.f / float(iConst0))));
537 | fConst4 = (1.f - fConst3);
538 | fHslider0 = FAUSTFLOAT(10.);
539 | for (int i2 = 0; (i2 < 2); i2 = (i2 + 1)) {
540 | fRec0[i2] = 0.f;
541 |
542 | }
543 | fConst5 = (0.01f * fConst4);
544 | fHslider1 = FAUSTFLOAT(20.);
545 | for (int i3 = 0; (i3 < 2); i3 = (i3 + 1)) {
546 | fRec1[i3] = 0.f;
547 |
548 | }
549 | fConst6 = (1.f / fConst1);
550 | fHslider2 = FAUSTFLOAT(0.1);
551 | for (int i5 = 0; (i5 < 2); i5 = (i5 + 1)) {
552 | fRec3[i5] = 0.f;
553 |
554 | }
555 | fConst7 = (0.5f * fConst4);
556 | fHslider3 = FAUSTFLOAT(0.);
557 | for (int i6 = 0; (i6 < 2); i6 = (i6 + 1)) {
558 | fRec4[i6] = 0.f;
559 |
560 | }
561 |
562 | }
563 |
564 | virtual void init(int samplingFreq) {
565 | classInit(samplingFreq);
566 | instanceInit(samplingFreq);
567 | }
568 |
569 | virtual void buildUserInterface(UI* interface) {
570 | interface->openVerticalBox("0x00");
571 | interface->declare(&fHslider0, "OWL", "PARAMETER_B");
572 | interface->declare(&fHslider0, "unit", "ms");
573 | interface->addHorizontalSlider("Delay", &fHslider0, 10.f, 0.5f, 20.f, 0.01f);
574 | interface->declare(&fHslider1, "OWL", "PARAMETER_D");
575 | interface->declare(&fHslider1, "unit", "%");
576 | interface->addHorizontalSlider("Depth", &fHslider1, 20.f, 3.f, 100.f, 1.f);
577 | interface->declare(&fHslider3, "OWL", "PARAMETER_C");
578 | interface->addHorizontalSlider("L-R Offset", &fHslider3, 0.f, 0.f, 1.f, 0.001f);
579 | interface->declare(&fHslider2, "OWL", "PARAMETER_A");
580 | interface->declare(&fHslider2, "unit", "hz");
581 | interface->addHorizontalSlider("Rate", &fHslider2, 0.1f, 0.f, 1.f, 0.001f);
582 | interface->closeBox();
583 |
584 | }
585 |
586 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
587 | FAUSTFLOAT* input0 = inputs[0];
588 | FAUSTFLOAT* input1 = inputs[1];
589 | FAUSTFLOAT* output0 = outputs[0];
590 | FAUSTFLOAT* output1 = outputs[1];
591 | float fSlow0 = (fConst4 * float(fHslider0));
592 | float fSlow1 = (fConst5 * float(fHslider1));
593 | float fSlow2 = (fConst6 * float(fHslider2));
594 | float fSlow3 = (fConst7 * float(fHslider3));
595 | for (int i = 0; (i < count); i = (i + 1)) {
596 | float fTemp0 = float(input0[i]);
597 | fVec0[(IOTA & 4095)] = fTemp0;
598 | float fTemp1 = float(input1[i]);
599 | fVec1[(IOTA & 4095)] = fTemp1;
600 | fRec0[0] = (fSlow0 + (fConst3 * fRec0[1]));
601 | fRec1[0] = (fSlow1 + (fConst3 * fRec1[1]));
602 | float fTemp5 = (fSlow2 + fRec3[1]);
603 | fRec3[0] = (fTemp5 - floorf(fTemp5));
604 | float fTemp6 = (512.f * fmodf(fRec3[0], 1.f));
605 | int iTemp7 = int(fTemp6);
606 | float fTemp8 = (fConst2 * (fRec0[0] * (1.f + (fRec1[0] * (ftbl0ThruZeroFlangerSIG0[iTemp7] + ((fTemp6 - floorf(fTemp6)) * (ftbl0ThruZeroFlangerSIG0[(1 + iTemp7)] - ftbl0ThruZeroFlangerSIG0[iTemp7])))))));
607 | int iTemp9 = int(fTemp8);
608 | int iTemp10 = (1 + iTemp9);
609 | float fTemp11 = (fConst2 * fRec0[0]);
610 | int iTemp12 = int(fTemp11);
611 | int iTemp13 = (iTemp12 & 4095);
612 | int iTemp14 = (1 + iTemp12);
613 | float fTemp15 = (float(iTemp14) - fTemp11);
614 | float fTemp16 = (fTemp11 - float(iTemp12));
615 | int iTemp17 = (iTemp14 & 4095);
616 | output0[i] = FAUSTFLOAT((0.f - (((fVec0[((IOTA - (iTemp9 & 4095)) & 4095)] * (float(iTemp10) - fTemp8)) + ((fTemp8 - float(iTemp9)) * fVec0[((IOTA - (iTemp10 & 4095)) & 4095)])) - ((fVec0[((IOTA - iTemp13) & 4095)] * fTemp15) + (fTemp16 * fVec0[((IOTA - iTemp17) & 4095)])))));
617 | fRec4[0] = (fSlow3 + (fConst3 * fRec4[1]));
618 | float fTemp18 = (512.f * fmodf((fRec3[0] + fRec4[0]), 1.f));
619 | int iTemp19 = int(fTemp18);
620 | float fTemp20 = (fConst2 * (fRec0[0] * (1.f + (fRec1[0] * (ftbl0ThruZeroFlangerSIG0[iTemp19] + ((fTemp18 - floorf(fTemp18)) * (ftbl0ThruZeroFlangerSIG0[(1 + iTemp19)] - ftbl0ThruZeroFlangerSIG0[iTemp19])))))));
621 | int iTemp21 = int(fTemp20);
622 | int iTemp22 = (1 + iTemp21);
623 | output1[i] = FAUSTFLOAT((0.f - (((fVec1[((IOTA - (iTemp21 & 4095)) & 4095)] * (float(iTemp22) - fTemp20)) + ((fTemp20 - float(iTemp21)) * fVec1[((IOTA - (iTemp22 & 4095)) & 4095)])) - ((fTemp15 * fVec1[((IOTA - iTemp13) & 4095)]) + (fTemp16 * fVec1[((IOTA - iTemp17) & 4095)])))));
624 | IOTA = (IOTA + 1);
625 | fRec0[1] = fRec0[0];
626 | fRec1[1] = fRec1[0];
627 | fRec3[1] = fRec3[0];
628 | fRec4[1] = fRec4[0];
629 |
630 | }
631 |
632 | }
633 |
634 |
635 | };
636 |
637 |
638 | /***************************END USER SECTION ***************************/
639 |
640 | /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
641 |
642 |
643 |
644 | /**************************************************************************************
645 |
646 | ThruZeroFlangerPatch : an OWL patch that calls Faust generated DSP code
647 |
648 | ***************************************************************************************/
649 |
650 | class ThruZeroFlangerPatch : public Patch
651 | {
652 | ThruZeroFlanger fDSP;
653 | OwlUI fUI;
654 |
655 | public:
656 |
657 | ThruZeroFlangerPatch() : fUI(this)
658 | {
659 | fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
660 | fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
661 | }
662 |
663 | void processAudio(AudioBuffer &buffer)
664 | {
665 | // Reasonably assume we will not have more than 32 channels
666 | float* ins[32];
667 | float* outs[32];
668 | int n = buffer.getChannels();
669 |
670 | if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
671 |
672 | // create the table of input channels
673 | for(int ch=0; ch _,_;
--------------------------------------------------------------------------------
/WeirdPhaserPatch.hpp:
--------------------------------------------------------------------------------
1 | /* ------------------------------------------------------------
2 | author: "Oli Larkin (contact@olilarkin.co.uk)"
3 | copyright: "Oliver Larkin"
4 | name: "Weird Phaser"
5 | version: "0.1"
6 | Code generated with Faust 2.0.a41 (http://faust.grame.fr)
7 | ------------------------------------------------------------ */
8 |
9 | #ifndef __WeirdPhaser_H__
10 | #define __WeirdPhaser_H__
11 | /************************************************************************
12 |
13 | IMPORTANT NOTE : this file contains two clearly delimited sections :
14 | the ARCHITECTURE section (in two parts) and the USER section. Each section
15 | is governed by its own copyright and license. Please check individually
16 | each section for license and copyright information.
17 | *************************************************************************/
18 |
19 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
20 |
21 | /************************************************************************
22 | FAUST Architecture File
23 | Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
24 | ---------------------------------------------------------------------
25 | This Architecture section is free software; you can redistribute it
26 | and/or modify it under the terms of the GNU General Public License
27 | as published by the Free Software Foundation; either version 3 of
28 | the License, or (at your option) any later version.
29 |
30 | This program is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with this program; If not, see .
37 |
38 | EXCEPTION : As a special exception, you may create a larger work
39 | that contains this FAUST architecture section and distribute
40 | that work under terms of your choice, so long as this FAUST
41 | architecture section is not modified.
42 |
43 |
44 | ************************************************************************
45 | ************************************************************************/
46 |
47 | #ifndef __WeirdPhaserPatch_h__
48 | #define __WeirdPhaserPatch_h__
49 |
50 | #include "StompBox.h"
51 | #include
52 | #include
53 | #include
54 |
55 |
56 | #ifndef __FaustCommonInfrastructure__
57 | #define __FaustCommonInfrastructure__
58 |
59 |
60 | /************************************************************************
61 | IMPORTANT NOTE : this file contains two clearly delimited sections :
62 | the ARCHITECTURE section (in two parts) and the USER section. Each section
63 | is governed by its own copyright and license. Please check individually
64 | each section for license and copyright information.
65 | *************************************************************************/
66 |
67 | /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
68 |
69 | /************************************************************************
70 | FAUST Architecture File
71 | Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
72 | ---------------------------------------------------------------------
73 | This Architecture section is free software; you can redistribute it
74 | and/or modify it under the terms of the GNU General Public License
75 | as published by the Free Software Foundation; either version 3 of
76 | the License, or (at your option) any later version.
77 |
78 | This program is distributed in the hope that it will be useful,
79 | but WITHOUT ANY WARRANTY; without even the implied warranty of
80 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 | GNU General Public License for more details.
82 |
83 | You should have received a copy of the GNU General Public License
84 | along with this program; If not, see .
85 |
86 | EXCEPTION : As a special exception, you may create a larger work
87 | that contains this FAUST architecture section and distribute
88 | that work under terms of your choice, so long as this FAUST
89 | architecture section is not modified.
90 |
91 |
92 | ************************************************************************
93 | ************************************************************************/
94 |
95 | /******************************************************************************
96 | *******************************************************************************
97 |
98 | FAUST DSP
99 |
100 | *******************************************************************************
101 | *******************************************************************************/
102 |
103 | #ifndef __dsp__
104 | #define __dsp__
105 |
106 | #ifndef FAUSTFLOAT
107 | #define FAUSTFLOAT float
108 | #endif
109 |
110 | class UI;
111 |
112 | //----------------------------------------------------------------
113 | // Signal processor definition
114 | //----------------------------------------------------------------
115 |
116 | class dsp {
117 |
118 | protected:
119 | int fSamplingFreq;
120 |
121 | public:
122 | dsp() {}
123 | virtual ~dsp() {}
124 |
125 | virtual int getNumInputs() = 0;
126 | virtual int getNumOutputs() = 0;
127 | virtual void buildUserInterface(UI* ui_interface) = 0;
128 | virtual void init(int samplingRate) = 0;
129 | virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
130 | };
131 |
132 | // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
133 | // flags to avoid costly denormals
134 | #ifdef __SSE__
135 | #include
136 | #ifdef __SSE2__
137 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
138 | #else
139 | #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
140 | #endif
141 | #else
142 | #define AVOIDDENORMALS
143 | #endif
144 |
145 | #endif
146 | #ifndef FAUST_UI_H
147 | #define FAUST_UI_H
148 |
149 | #ifndef FAUSTFLOAT
150 | #define FAUSTFLOAT float
151 | #endif
152 |
153 | /*******************************************************************************
154 | * UI : Faust User Interface
155 | * This abstract class contains only the method that the faust compiler can
156 | * generate to describe a DSP interface.
157 | ******************************************************************************/
158 |
159 | class UI
160 | {
161 |
162 | public:
163 |
164 | UI() {}
165 |
166 | virtual ~UI() {}
167 |
168 | // -- widget's layouts
169 |
170 | virtual void openTabBox(const char* label) = 0;
171 | virtual void openHorizontalBox(const char* label) = 0;
172 | virtual void openVerticalBox(const char* label) = 0;
173 | virtual void closeBox() = 0;
174 |
175 | // -- active widgets
176 |
177 | virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
178 | virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
179 | virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
180 | virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
181 | virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
182 |
183 | // -- passive widgets
184 |
185 | virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
186 | virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0;
187 |
188 | // -- metadata declarations
189 |
190 | virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val) {}
191 | };
192 |
193 | #endif
194 |
195 |
196 |
197 | struct Meta
198 | {
199 | virtual void declare(const char* key, const char* value) = 0;
200 | };
201 |
202 |
203 |
204 | /**************************************************************************************
205 |
206 | OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
207 | and a faust widget
208 |
209 | ***************************************************************************************/
210 |
211 | class OwlWidget
212 | {
213 | protected:
214 | Patch* fPatch; // needed to register and read owl parameters
215 | PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
216 | FAUSTFLOAT* fZone; // Faust widget zone
217 | const char* fLabel; // Faust widget label
218 | float fMin; // Faust widget minimal value
219 | float fSpan; // Faust widget value span (max-min)
220 |
221 | public:
222 | OwlWidget() :
223 | fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
224 | OwlWidget(const OwlWidget& w) :
225 | fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
226 | OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
227 | fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
228 | void bind() { fPatch->registerParameter(fParameter, fLabel); }
229 | void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
230 |
231 | };
232 |
233 |
234 | /**************************************************************************************
235 |
236 | OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
237 | the mapping between owl parameters and faust widgets. It relies on specific
238 | metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
239 | faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
240 | (the second knob).
241 |
242 | ***************************************************************************************/
243 |
244 | // The maximun number of mappings between owl parameters and faust widgets
245 | #define MAXOWLWIDGETS 8
246 |
247 | class OwlUI : public UI
248 | {
249 | Patch* fPatch;
250 | PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
251 | int fIndex; // number of OwlWidgets collected so far
252 | OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
253 |
254 | // check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
255 | void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
256 | if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
257 | fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
258 | fTable[fIndex].bind();
259 | fIndex++;
260 | }
261 | fParameter = PARAMETER_F; // clear current parameter ID
262 | }
263 |
264 | // we dont want to create a widget by-ut we clear the current parameter ID just in case
265 | void skip() {
266 | fParameter = PARAMETER_F; // clear current parameter ID
267 | }
268 |
269 | public:
270 |
271 | OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
272 |
273 | virtual ~OwlUI() {}
274 |
275 | // should be called before compute() to update widget's zones registered as Owl parameters
276 | void update() {
277 | for (int i=0; i
325 |
326 |
327 | #ifndef FAUSTCLASS
328 | #define FAUSTCLASS WeirdPhaser
329 | #endif
330 |
331 | class WeirdPhaser : public dsp {
332 |
333 | private:
334 |
335 | float fRec2[3];
336 | float fRec1[3];
337 | float fRec6[3];
338 | float fRec5[3];
339 | float fRec9[3];
340 | float fRec8[3];
341 | float fRec11[3];
342 | float fRec10[3];
343 | float fRec3[2];
344 | float fRec4[2];
345 | float fRec0[2];
346 | float fRec7[2];
347 | int fSamplingFreq;
348 | int iConst0;
349 | float fConst1;
350 | float fConst2;
351 | FAUSTFLOAT fHslider0;
352 | float fConst3;
353 | FAUSTFLOAT fHslider1;
354 | FAUSTFLOAT fHslider2;
355 | FAUSTFLOAT fHslider3;
356 |
357 | public:
358 |
359 | void static metadata(Meta* m) {
360 | m->declare("author", "Oli Larkin (contact@olilarkin.co.uk)");
361 | m->declare("copyright", "Oliver Larkin");
362 | m->declare("description", "Stereo Phaser based on SSB Modulation");
363 | m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)");
364 | m->declare("filter.lib/copyright", "Julius O. Smith III");
365 | m->declare("filter.lib/license", "STK-4.3");
366 | m->declare("filter.lib/name", "Faust Filter Library");
367 | m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/");
368 | m->declare("filter.lib/version", "1.29");
369 | m->declare("licence", "GPL");
370 | m->declare("math.lib/author", "GRAME");
371 | m->declare("math.lib/copyright", "GRAME");
372 | m->declare("math.lib/license", "LGPL with exception");
373 | m->declare("math.lib/name", "Math Library");
374 | m->declare("math.lib/version", "1.0");
375 | m->declare("music.lib/author", "GRAME");
376 | m->declare("music.lib/copyright", "GRAME");
377 | m->declare("music.lib/license", "LGPL with exception");
378 | m->declare("music.lib/name", "Music Library");
379 | m->declare("music.lib/version", "1.0");
380 | m->declare("name", "Weird Phaser");
381 | m->declare("version", "0.1");
382 | }
383 |
384 | virtual int getNumInputs() {
385 | return 2;
386 |
387 | }
388 | virtual int getNumOutputs() {
389 | return 2;
390 |
391 | }
392 | virtual int getInputRate(int channel) {
393 | int rate;
394 | switch (channel) {
395 | case 0: {
396 | rate = 1;
397 | break;
398 | }
399 | case 1: {
400 | rate = 1;
401 | break;
402 | }
403 | default: {
404 | rate = -1;
405 | break;
406 | }
407 |
408 | }
409 | return rate;
410 |
411 | }
412 | virtual int getOutputRate(int channel) {
413 | int rate;
414 | switch (channel) {
415 | case 0: {
416 | rate = 1;
417 | break;
418 | }
419 | case 1: {
420 | rate = 1;
421 | break;
422 | }
423 | default: {
424 | rate = -1;
425 | break;
426 | }
427 |
428 | }
429 | return rate;
430 |
431 | }
432 |
433 | static void classInit(int samplingFreq) {
434 |
435 | }
436 |
437 | virtual void instanceInit(int samplingFreq) {
438 | fSamplingFreq = samplingFreq;
439 | iConst0 = min(192000, max(1, fSamplingFreq));
440 | fConst1 = expf((0.f - (200.f / float(iConst0))));
441 | fConst2 = (0.7f * (1.f - fConst1));
442 | fHslider0 = FAUSTFLOAT(0.);
443 | for (int i0 = 0; (i0 < 2); i0 = (i0 + 1)) {
444 | fRec3[i0] = 0.f;
445 |
446 | }
447 | for (int i1 = 0; (i1 < 3); i1 = (i1 + 1)) {
448 | fRec2[i1] = 0.f;
449 |
450 | }
451 | for (int i2 = 0; (i2 < 3); i2 = (i2 + 1)) {
452 | fRec1[i2] = 0.f;
453 |
454 | }
455 | fConst3 = (1.f / float(iConst0));
456 | fHslider1 = FAUSTFLOAT(0.);
457 | fHslider2 = FAUSTFLOAT(1.);
458 | for (int i3 = 0; (i3 < 2); i3 = (i3 + 1)) {
459 | fRec4[i3] = 0.f;
460 |
461 | }
462 | for (int i4 = 0; (i4 < 3); i4 = (i4 + 1)) {
463 | fRec6[i4] = 0.f;
464 |
465 | }
466 | for (int i5 = 0; (i5 < 3); i5 = (i5 + 1)) {
467 | fRec5[i5] = 0.f;
468 |
469 | }
470 | for (int i6 = 0; (i6 < 2); i6 = (i6 + 1)) {
471 | fRec0[i6] = 0.f;
472 |
473 | }
474 | for (int i7 = 0; (i7 < 3); i7 = (i7 + 1)) {
475 | fRec9[i7] = 0.f;
476 |
477 | }
478 | for (int i8 = 0; (i8 < 3); i8 = (i8 + 1)) {
479 | fRec8[i8] = 0.f;
480 |
481 | }
482 | fHslider3 = FAUSTFLOAT(0.);
483 | for (int i9 = 0; (i9 < 3); i9 = (i9 + 1)) {
484 | fRec11[i9] = 0.f;
485 |
486 | }
487 | for (int i10 = 0; (i10 < 3); i10 = (i10 + 1)) {
488 | fRec10[i10] = 0.f;
489 |
490 | }
491 | for (int i11 = 0; (i11 < 2); i11 = (i11 + 1)) {
492 | fRec7[i11] = 0.f;
493 |
494 | }
495 |
496 | }
497 |
498 | virtual void init(int samplingFreq) {
499 | classInit(samplingFreq);
500 | instanceInit(samplingFreq);
501 | }
502 |
503 | virtual void buildUserInterface(UI* interface) {
504 | interface->openVerticalBox("0x00");
505 | interface->declare(&fHslider0, "OWL", "PARAMETER_D");
506 | interface->addHorizontalSlider("Feedback", &fHslider0, 0.f, 0.f, 1.f, 0.01f);
507 | interface->declare(&fHslider3, "OWL", "PARAMETER_C");
508 | interface->addHorizontalSlider("L-R Offset", &fHslider3, 0.f, 0.f, 1.f, 0.001f);
509 | interface->declare(&fHslider2, "OWL", "PARAMETER_B");
510 | interface->addHorizontalSlider("Rate Scalar", &fHslider2, 1.f, 1.f, 40.f, 0.001f);
511 | interface->declare(&fHslider1, "OWL", "PARAMETER_A");
512 | interface->declare(&fHslider1, "unit", "hz");
513 | interface->addHorizontalSlider("Rate", &fHslider1, 0.f, 0.f, 1.f, 0.001f);
514 | interface->closeBox();
515 |
516 | }
517 |
518 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
519 | FAUSTFLOAT* input0 = inputs[0];
520 | FAUSTFLOAT* input1 = inputs[1];
521 | FAUSTFLOAT* output0 = outputs[0];
522 | FAUSTFLOAT* output1 = outputs[1];
523 | float fSlow0 = (fConst2 * float(fHslider0));
524 | float fSlow1 = (fConst3 * (float(fHslider1) * float(fHslider2)));
525 | float fSlow2 = (0.5f * float(fHslider3));
526 | for (int i = 0; (i < count); i = (i + 1)) {
527 | float fTemp0 = float(input0[i]);
528 | float fTemp1 = float(input1[i]);
529 | fRec3[0] = ((fConst1 * fRec3[1]) + fSlow0);
530 | float fTemp2 = max(-1.f, min(1.f, (fRec3[0] * fRec0[1])));
531 | float fTemp3 = (0.02569f * fRec2[1]);
532 | fRec2[0] = ((fTemp2 + (fTemp0 + (0.260502f * fRec2[2]))) - fTemp3);
533 | float fTemp4 = (1.8685f * fRec1[1]);
534 | fRec1[0] = ((fRec2[2] + (fTemp4 + fTemp3)) - ((0.870686f * fRec1[2]) + (0.260502f * fRec2[0])));
535 | float fTemp5 = (fRec4[1] + fSlow1);
536 | fRec4[0] = (fTemp5 - floorf(fTemp5));
537 | float fTemp6 = (6.28319f * fmodf(fRec4[0], 1.f));
538 | float fTemp7 = (1.94632f * fRec6[1]);
539 | fRec6[0] = (((fTemp0 + fTemp2) + fTemp7) - (0.94657f * fRec6[2]));
540 | float fTemp8 = (0.83774f * fRec5[1]);
541 | fRec5[0] = ((fRec6[2] + ((0.94657f * fRec6[0]) + fTemp8)) - ((0.06338f * fRec5[2]) + fTemp7));
542 | fRec0[0] = (((((0.870686f * fRec1[0]) + fRec1[2]) - fTemp4) * cosf(fTemp6)) - (sinf(fTemp6) * (((0.06338f * fRec5[0]) + fRec5[2]) - fTemp8)));
543 | output0[i] = FAUSTFLOAT((0.5f * (fTemp0 + fRec0[0])));
544 | float fTemp9 = max(-1.f, min(1.f, (fRec3[0] * fRec7[1])));
545 | float fTemp10 = (0.02569f * fRec9[1]);
546 | fRec9[0] = ((fTemp9 + (fTemp1 + (0.260502f * fRec9[2]))) - fTemp10);
547 | float fTemp11 = (1.8685f * fRec8[1]);
548 | fRec8[0] = ((fRec9[2] + (fTemp11 + fTemp10)) - ((0.870686f * fRec8[2]) + (0.260502f * fRec9[0])));
549 | float fTemp12 = (6.28319f * fmodf((fSlow2 + fRec4[0]), 1.f));
550 | float fTemp13 = (1.94632f * fRec11[1]);
551 | fRec11[0] = (((fTemp1 + fTemp9) + fTemp13) - (0.94657f * fRec11[2]));
552 | float fTemp14 = (0.83774f * fRec10[1]);
553 | fRec10[0] = ((fRec11[2] + ((0.94657f * fRec11[0]) + fTemp14)) - ((0.06338f * fRec10[2]) + fTemp13));
554 | fRec7[0] = (((((0.870686f * fRec8[0]) + fRec8[2]) - fTemp11) * cosf(fTemp12)) - (sinf(fTemp12) * (((0.06338f * fRec10[0]) + fRec10[2]) - fTemp14)));
555 | output1[i] = FAUSTFLOAT((0.5f * (fTemp1 + fRec7[0])));
556 | fRec3[1] = fRec3[0];
557 | fRec2[2] = fRec2[1];
558 | fRec2[1] = fRec2[0];
559 | fRec1[2] = fRec1[1];
560 | fRec1[1] = fRec1[0];
561 | fRec4[1] = fRec4[0];
562 | fRec6[2] = fRec6[1];
563 | fRec6[1] = fRec6[0];
564 | fRec5[2] = fRec5[1];
565 | fRec5[1] = fRec5[0];
566 | fRec0[1] = fRec0[0];
567 | fRec9[2] = fRec9[1];
568 | fRec9[1] = fRec9[0];
569 | fRec8[2] = fRec8[1];
570 | fRec8[1] = fRec8[0];
571 | fRec11[2] = fRec11[1];
572 | fRec11[1] = fRec11[0];
573 | fRec10[2] = fRec10[1];
574 | fRec10[1] = fRec10[0];
575 | fRec7[1] = fRec7[0];
576 |
577 | }
578 |
579 | }
580 |
581 |
582 | };
583 |
584 |
585 | /***************************END USER SECTION ***************************/
586 |
587 | /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
588 |
589 |
590 |
591 | /**************************************************************************************
592 |
593 | WeirdPhaserPatch : an OWL patch that calls Faust generated DSP code
594 |
595 | ***************************************************************************************/
596 |
597 | class WeirdPhaserPatch : public Patch
598 | {
599 | WeirdPhaser fDSP;
600 | OwlUI fUI;
601 |
602 | public:
603 |
604 | WeirdPhaserPatch() : fUI(this)
605 | {
606 | fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
607 | fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
608 | }
609 |
610 | void processAudio(AudioBuffer &buffer)
611 | {
612 | // Reasonably assume we will not have more than 32 channels
613 | float* ins[32];
614 | float* outs[32];
615 | int n = buffer.getChannels();
616 |
617 | if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
618 |
619 | // create the table of input channels
620 | for(int ch=0; ch
37 |
38 | */
39 |
40 | class XFMPatch : public Patch
41 | {
42 | private:
43 |
44 | class PSmooth
45 | {
46 | private:
47 | float mA, mB;
48 | float mOutM1;
49 |
50 | public:
51 | PSmooth(float coeff = 0.99f, float initalValue = 0.f)
52 | : mA(coeff)
53 | , mB(1.f - mA)
54 | , mOutM1(initalValue)
55 | {
56 | }
57 |
58 | inline float process(float input)
59 | {
60 | mOutM1 = (input * mB) + (mOutM1 * mA);
61 | return mOutM1;
62 | }
63 | };
64 |
65 | inline float fastClip(float x, const float lo, const float hi)
66 | {
67 | const float x1 = fabsf(x-lo);
68 | const float x2 = fabsf(x-hi);
69 | return (x1+lo+hi-x2) * 0.5f;
70 | }
71 |
72 | float mFreqA, mFreqB;
73 | float mFbkA, mFbkB;
74 | float mX1, mY1;
75 | float mX2, mY2;
76 | float mScale;
77 |
78 | PSmooth mFbkASmoother;
79 | PSmooth mFbkBSmoother;
80 | PSmooth mFreqASmoother;
81 | PSmooth mFreqBSmoother;
82 |
83 | public:
84 | XFMPatch(float initFreq = 100.f)
85 | : mFreqA(initFreq)
86 | , mFreqB(initFreq)
87 | , mFbkA(initFreq)
88 | , mFbkB(initFreq)
89 | , mX1(1.f)
90 | , mY1(0.f)
91 | , mX2(1.f)
92 | , mY2(0.f)
93 | {
94 | mScale = 6.283185307179586 / getSampleRate();
95 |
96 | registerParameter(PARAMETER_A, "Osc1 Freq", "Osc1 Freq");
97 | registerParameter(PARAMETER_B, "Osc2 Freq", "Osc2 Freq");
98 | registerParameter(PARAMETER_C, "Osc1 Fbk", "Osc1 Fbk");
99 | registerParameter(PARAMETER_D, "Osc2 Fbk", "Osc2 Fbk");
100 | }
101 |
102 | void processAudio(AudioBuffer &buffer)
103 | {
104 | mFreqA = getParameterValue(PARAMETER_A) * 1000.;
105 | mFreqB = getParameterValue(PARAMETER_B) * 1000.;
106 | mFbkA = getParameterValue(PARAMETER_C) * 1000.;
107 | mFbkB = getParameterValue(PARAMETER_D) * 1000.;
108 |
109 | const int size = buffer.getSize();
110 | float z1, dx1, dy1;
111 | float z2, dx2, dy2;
112 |
113 | float* bufL = buffer.getSamples(0);
114 | float* bufR = buffer.getSamples(1);
115 |
116 | for(int i = 0; i < size; i++, bufL++, bufR++)
117 | {
118 | // osc 1
119 | z1 = mScale * (mX2 * mFbkASmoother.process(mFbkA) + mFreqASmoother.process(mFreqA));
120 |
121 | dx1 = mX1 - z1*mY1;
122 | dy1 = mY1 + z1*mX1;
123 |
124 | mX1 = fastClip(dx1, -1., 1.);
125 | mY1 = fastClip(dy1, -1., 1.);
126 |
127 | // osc 2
128 | z2 = mScale * (mX1 * mFbkBSmoother.process(mFbkB) + mFreqBSmoother.process(mFreqB));
129 |
130 | dx2 = mX2 - z2*mY2;
131 | dy2 = mY2 + z2*mX2;
132 |
133 | mX2 = fastClip(dx2, -1., 1.);
134 | mY2 = fastClip(dy2, -1., 1.);
135 |
136 | *bufL = mX1;
137 | *bufR = mX2;
138 | }
139 | }
140 |
141 | };
142 |
143 | #endif // __XFMPatch_hpp__
144 |
--------------------------------------------------------------------------------
/buildVSTVersions.py:
--------------------------------------------------------------------------------
1 | import subprocess, glob, shutil, os.path
2 |
3 | vstdir = "/Library/Audio/Plug-Ins/VST/MyFaust"
4 |
5 | faustFiles = glob.glob("*.dsp")
6 | faustFiles = glob.glob("*.dsp")
7 |
8 | faustFiles.remove("IIRHilbert.dsp")
9 | faustFiles.remove("FrequencyShifter.dsp")
10 |
11 | for file in faustFiles:
12 | command = ["faust2vst", file]
13 | subprocess.call(command)
14 |
15 | vstFiles = glob.glob("*.vst")
16 |
17 | for file in vstFiles:
18 | outputfile = vstdir + "/" + file
19 | if os.path.isdir(outputfile):
20 | shutil.rmtree(outputfile)
21 | shutil.move(file, outputfile)
--------------------------------------------------------------------------------
/updateFaustPatches.py:
--------------------------------------------------------------------------------
1 | import subprocess, glob
2 |
3 | faustFiles = glob.glob("*.dsp")
4 |
5 | faustFiles.remove("IIRHilbert.dsp")
6 | faustFiles.remove("FrequencyShifter.dsp")
7 |
8 | for file in faustFiles:
9 | command = ["faust2owl", file]
10 | subprocess.call(command)
--------------------------------------------------------------------------------