Skip to content

Commit fa63d89

Browse files
author
mars
committed
Merge branch 'master' of github.com:pingdynasty/OwlProgram
2 parents 560dd87 + 13adcc3 commit fa63d89

11 files changed

Lines changed: 356 additions & 46 deletions

FaustCode/owl.cpp

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/************************************************************************
2+
3+
IMPORTANT NOTE : this file contains two clearly delimited sections :
4+
the ARCHITECTURE section (in two parts) and the USER section. Each section
5+
is governed by its own copyright and license. Please check individually
6+
each section for license and copyright information.
7+
*************************************************************************/
8+
9+
/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
10+
11+
/************************************************************************
12+
FAUST Architecture File
13+
Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
14+
---------------------------------------------------------------------
15+
This Architecture section is free software; you can redistribute it
16+
and/or modify it under the terms of the GNU General Public License
17+
as published by the Free Software Foundation; either version 3 of
18+
the License, or (at your option) any later version.
19+
20+
This program is distributed in the hope that it will be useful,
21+
but WITHOUT ANY WARRANTY; without even the implied warranty of
22+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23+
GNU General Public License for more details.
24+
25+
You should have received a copy of the GNU General Public License
26+
along with this program; If not, see <http://www.gnu.org/licenses/>.
27+
28+
EXCEPTION : As a special exception, you may create a larger work
29+
that contains this FAUST architecture section and distribute
30+
that work under terms of your choice, so long as this FAUST
31+
architecture section is not modified.
32+
33+
34+
************************************************************************
35+
************************************************************************/
36+
37+
#ifndef __FaustPatch_h__
38+
#define __FaustPatch_h__
39+
40+
#include "StompBox.h"
41+
#include <cstddef>
42+
#include <string.h>
43+
#include <strings.h>
44+
45+
46+
#ifndef __FaustCommonInfrastructure__
47+
#define __FaustCommonInfrastructure__
48+
49+
50+
#include "faust/audio/dsp.h"
51+
#include "faust/gui/UI.h"
52+
53+
54+
55+
struct Meta
56+
{
57+
virtual void declare(const char* key, const char* value) = 0;
58+
};
59+
60+
61+
62+
/**************************************************************************************
63+
64+
OwlWidget : object used by OwlUI to ensures the connection between an owl parameter
65+
and a faust widget
66+
67+
***************************************************************************************/
68+
69+
class OwlWidget
70+
{
71+
protected:
72+
Patch* fPatch; // needed to register and read owl parameters
73+
PatchParameterId fParameter; // OWL parameter code : PARAMETER_A,...
74+
FAUSTFLOAT* fZone; // Faust widget zone
75+
const char* fLabel; // Faust widget label
76+
float fMin; // Faust widget minimal value
77+
float fSpan; // Faust widget value span (max-min)
78+
79+
public:
80+
OwlWidget() :
81+
fPatch(0), fParameter(PARAMETER_A), fZone(0), fLabel(""), fMin(0), fSpan(1) {}
82+
OwlWidget(const OwlWidget& w) :
83+
fPatch(w.fPatch), fParameter(w.fParameter), fZone(w.fZone), fLabel(w.fLabel), fMin(w.fMin), fSpan(w.fSpan) {}
84+
OwlWidget(Patch* pp, PatchParameterId param, FAUSTFLOAT* z, const char* l, float lo, float hi) :
85+
fPatch(pp), fParameter(param), fZone(z), fLabel(l), fMin(lo), fSpan(hi-lo) {}
86+
void bind() { fPatch->registerParameter(fParameter, fLabel); }
87+
void update() { *fZone = fMin + fSpan*fPatch->getParameterValue(fParameter); }
88+
89+
};
90+
91+
92+
/**************************************************************************************
93+
94+
OwlUI : Faust User Interface builder. Passed to buildUserInterface OwlUI ensures
95+
the mapping between owl parameters and faust widgets. It relies on specific
96+
metadata "...[OWL:PARAMETER_X]..." in widget's label for that. For example any
97+
faust widget with metadata [OWL:PARAMETER_B] will be controlled by PARAMETER_B
98+
(the second knob).
99+
100+
***************************************************************************************/
101+
102+
// The maximun number of mappings between owl parameters and faust widgets
103+
#define MAXOWLWIDGETS 8
104+
105+
class OwlUI : public UI
106+
{
107+
Patch* fPatch;
108+
PatchParameterId fParameter; // current parameter ID, value PARAMETER_F means not set
109+
int fIndex; // number of OwlWidgets collected so far
110+
OwlWidget fTable[MAXOWLWIDGETS]; // kind of static list of OwlWidgets
111+
112+
// check if the widget is an Owl parameter and, if so, add the corresponding OwlWidget
113+
void addOwlWidget(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) {
114+
if ((fParameter >= PARAMETER_A) && (fParameter <= PARAMETER_E) && (fIndex < MAXOWLWIDGETS)) {
115+
fTable[fIndex] = OwlWidget(fPatch, fParameter, zone, label, lo, hi);
116+
fTable[fIndex].bind();
117+
fIndex++;
118+
}
119+
fParameter = PARAMETER_F; // clear current parameter ID
120+
}
121+
122+
// we dont want to create a widget by-ut we clear the current parameter ID just in case
123+
void skip() {
124+
fParameter = PARAMETER_F; // clear current parameter ID
125+
}
126+
127+
public:
128+
129+
OwlUI(Patch* pp) : fPatch(pp), fParameter(PARAMETER_F), fIndex(0) {}
130+
131+
virtual ~OwlUI() {}
132+
133+
// should be called before compute() to update widget's zones registered as Owl parameters
134+
void update() {
135+
for (int i=0; i<fIndex; i++) fTable[i].update();
136+
}
137+
138+
//---------------------- virtual methods called by buildUserInterface ----------------
139+
140+
// -- widget's layouts
141+
142+
virtual void openTabBox(const char* label) {}
143+
virtual void openHorizontalBox(const char* label) {}
144+
virtual void openVerticalBox(const char* label) {}
145+
virtual void closeBox() {}
146+
147+
// -- active widgets
148+
149+
virtual void addButton(const char* label, FAUSTFLOAT* zone) { skip(); }
150+
virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { skip(); }
151+
virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) { addOwlWidget(label, zone, lo, hi); }
152+
virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) { addOwlWidget(label, zone, lo, hi); }
153+
virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) { addOwlWidget(label, zone, lo, hi); }
154+
155+
// -- passive widgets
156+
157+
virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) { skip(); }
158+
virtual void addVerticalBargraph (const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) { skip(); }
159+
160+
// -- metadata declarations
161+
162+
virtual void declare(FAUSTFLOAT* z, const char* k, const char* id) {
163+
if (strcasecmp(k,"OWL") == 0) {
164+
if (strcasecmp(id,"PARAMETER_A") == 0) fParameter = PARAMETER_A;
165+
else if (strcasecmp(id,"PARAMETER_B") == 0) fParameter = PARAMETER_B;
166+
else if (strcasecmp(id,"PARAMETER_C") == 0) fParameter = PARAMETER_C;
167+
else if (strcasecmp(id,"PARAMETER_D") == 0) fParameter = PARAMETER_D;
168+
else if (strcasecmp(id,"PARAMETER_E") == 0) fParameter = PARAMETER_E;
169+
}
170+
}
171+
};
172+
173+
#endif // __FaustCommonInfrastructure__
174+
175+
/**************************BEGIN USER SECTION **************************/
176+
177+
<<includeIntrinsic>>
178+
179+
<<includeclass>>
180+
181+
/***************************END USER SECTION ***************************/
182+
183+
/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
184+
185+
186+
187+
/**************************************************************************************
188+
189+
FaustPatch : an OWL patch that calls Faust generated DSP code
190+
191+
***************************************************************************************/
192+
193+
class FaustPatch : public Patch
194+
{
195+
mydsp fDSP;
196+
OwlUI fUI;
197+
198+
public:
199+
200+
FaustPatch() : fUI(this)
201+
{
202+
fDSP.init(int(getSampleRate())); // Init Faust code with the OWL sampling rate
203+
fDSP.buildUserInterface(&fUI); // Maps owl parameters and faust widgets
204+
}
205+
206+
void processAudio(AudioBuffer &buffer)
207+
{
208+
// Reasonably assume we will not have more than 32 channels
209+
float* ins[32];
210+
float* outs[32];
211+
int n = buffer.getChannels();
212+
213+
if ( (fDSP.getNumInputs() < 32) && (fDSP.getNumOutputs() < 32) ) {
214+
215+
// create the table of input channels
216+
for(int ch=0; ch<fDSP.getNumInputs(); ++ch) {
217+
ins[ch] = buffer.getSamples(ch%n);
218+
}
219+
220+
// create the table of output channels
221+
for(int ch=0; ch<fDSP.getNumOutputs(); ++ch) {
222+
outs[ch] = buffer.getSamples(ch%n);
223+
}
224+
225+
// read OWL parameters and updates corresponding Faust Widgets zones
226+
fUI.update();
227+
228+
// Process the audio samples
229+
fDSP.compute(buffer.getSize(), ins, outs);
230+
}
231+
}
232+
233+
};
234+
235+
#endif // __FaustPatch_h__
236+
237+
238+
////////////////////////////////////////////////////////////////////////////////////////////////////

LibSource/ComplexFloatArray.cpp

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ float ComplexFloatArray::mag(const int i){
1313
return result;
1414
}
1515

16-
void ComplexFloatArray::getMagnitudeValues(FloatArray& destination){
16+
void ComplexFloatArray::getMagnitudeValues(FloatArray destination){
1717
/// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a>
1818
#ifdef ARM_CORTEX
1919
arm_cmplx_mag_f32((float*)data, (float*)destination, size);
@@ -37,7 +37,7 @@ float ComplexFloatArray::mag2(const int i){
3737
return result;
3838
}
3939

40-
void ComplexFloatArray::getMagnitudeSquaredValues(FloatArray& destination){
40+
void ComplexFloatArray::getMagnitudeSquaredValues(FloatArray destination){
4141
/// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a>
4242
#ifdef ARM_CORTEX
4343
arm_cmplx_mag_squared_f32((float*)data, (float*)destination, size);
@@ -48,7 +48,7 @@ void ComplexFloatArray::getMagnitudeSquaredValues(FloatArray& destination){
4848
#endif
4949
}
5050

51-
void ComplexFloatArray::complexDotProduct(ComplexFloatArray& operand2, ComplexFloat& result){
51+
void ComplexFloatArray::complexDotProduct(ComplexFloatArray operand2, ComplexFloat& result){
5252
/// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a>
5353
#ifdef ARM_CORTEX
5454
arm_cmplx_dot_prod_f32 ( (float*)data, (float*)operand2, size, &(result.re), &(result.im) );
@@ -66,8 +66,8 @@ void ComplexFloatArray::complexDotProduct(ComplexFloatArray& operand2, ComplexFl
6666
#endif
6767
}
6868

69-
void ComplexFloatArray::complexByComplexMultiplication(ComplexFloatArray& operand2, ComplexFloatArray& result){
70-
ASSERT(size==operand2.getSize(), "Wrong size");
69+
void ComplexFloatArray::complexByComplexMultiplication(ComplexFloatArray operand2, ComplexFloatArray result){
70+
ASSERT(operand2.size == size && result.size >= size, "Arrays size mismatch");
7171
/// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a>
7272
#ifdef ARM_CORTEX
7373
arm_cmplx_mult_cmplx_f32( (float*)data, (float*)operand2, (float*)result, size );
@@ -82,8 +82,40 @@ void ComplexFloatArray::complexByComplexMultiplication(ComplexFloatArray& operan
8282
#endif
8383
}
8484

85-
void ComplexFloatArray::getComplexConjugateValues(ComplexFloatArray& destination){
86-
ASSERT(size==destination.getSize(), "Wrong size");
85+
void ComplexFloatArray::add(ComplexFloatArray operand2, ComplexFloatArray destination){
86+
ASSERT(operand2.size == size && destination.size >= size, "Arrays size mismatch");
87+
#ifdef ARM_CORTEX
88+
arm_add_f32((float*)data, (float*)operand2.data, (float*)destination.data, size*2);
89+
#else
90+
for(int n=0; n<size; n++){
91+
destination[n].re = data[n].re + operand2[n].re;
92+
destination[n].im = data[n].im + operand2[n].im;
93+
}
94+
#endif /* ARM_CORTEX */
95+
}
96+
97+
void ComplexFloatArray::add(ComplexFloatArray operand2){
98+
add(operand2, *this);
99+
}
100+
101+
void ComplexFloatArray::subtract(ComplexFloatArray operand2, ComplexFloatArray destination){
102+
ASSERT(operand2.size == size && destination.size >= size, "Arrays size mismatch");
103+
#ifdef ARM_CORTEX
104+
arm_sub_f32((float*)data, (float*)operand2.data, (float*)destination.data, size*2);
105+
#else
106+
for(int n=0; n<size; n++){
107+
destination[n].re = data[n].re - operand2[n].re;
108+
destination[n].im = data[n].im - operand2[n].im;
109+
}
110+
#endif /* ARM_CORTEX */
111+
}
112+
113+
void ComplexFloatArray::subtract(ComplexFloatArray operand2){
114+
subtract(operand2, *this);
115+
}
116+
117+
void ComplexFloatArray::getComplexConjugateValues(ComplexFloatArray destination){
118+
ASSERT(size==destination.getSize(), "Wrong array size");
87119
/// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a>
88120
#ifdef ARM_CORTEX
89121
arm_cmplx_conj_f32( (float*)data, (float*)destination, size );
@@ -97,7 +129,7 @@ void ComplexFloatArray::getComplexConjugateValues(ComplexFloatArray& destination
97129
#endif
98130
}
99131

100-
void ComplexFloatArray::complexByRealMultiplication(FloatArray& operand2, ComplexFloatArray& result){
132+
void ComplexFloatArray::complexByRealMultiplication(FloatArray operand2, ComplexFloatArray result){
101133
ASSERT(size==operand2.getSize(), "Wrong size");
102134
/// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a>
103135
#ifdef ARM_CORTEX
@@ -106,7 +138,7 @@ void ComplexFloatArray::complexByRealMultiplication(FloatArray& operand2, Comple
106138
float *pSrcCmplx=(float*)data;
107139
float *pSrcReal=(float*)operand2;
108140
float *pCmplxDst=(float*)result;
109-
for(int n=0; n<size; n++) {
141+
for(int n=0; n<size; n++) {
110142
pCmplxDst[(2*n)+0] = pSrcCmplx[(2*n)+0] * pSrcReal[n];
111143
pCmplxDst[(2*n)+1] = pSrcCmplx[(2*n)+1] * pSrcReal[n];
112144
}
@@ -143,13 +175,13 @@ float ComplexFloatArray::getMaxMagnitudeValue(){ //this is probably slower than
143175
return maxMag;
144176
}
145177

146-
void ComplexFloatArray::getRealValues(FloatArray& buf){
178+
void ComplexFloatArray::getRealValues(FloatArray buf){
147179
for(int n=0; n<size; n++){
148180
buf[n]=data[n].re;
149181
}
150182
}
151183

152-
void ComplexFloatArray::getImaginaryValues(FloatArray& buf){
184+
void ComplexFloatArray::getImaginaryValues(FloatArray buf){
153185
for(int n=0; n<size; n++){
154186
buf[n]=data[n].im;
155187
}

0 commit comments

Comments
 (0)