├── .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) --------------------------------------------------------------------------------