Skip to content
This repository was archived by the owner on Feb 27, 2020. It is now read-only.

Commit 33ca572

Browse files
author
Ezra Buchla
committed
add LPF before buffer storage.
doesn't actually help that much. suppresses HF aliasing all right but there are still plenty of imaged artifacts across the spectrum should add pre-recording filter
1 parent bd50862 commit 33ca572

10 files changed

+261
-15
lines changed

faust/LowpassBrickwall-template.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <algorithm>
2+
3+
#include "faust/gui/UI.h"
4+
#include "faust/gui/meta.h"
5+
#include "faust/dsp/dsp.h"
6+
7+
using std::max;
8+
using std::min;
9+
10+
<<includeIntrinsic>>
11+
<<includeclass>>
12+
13+
class LowpassBrickwall {
14+
mydsp dsp_;
15+
public:
16+
void init(int sr) {
17+
mydsp::classInit(sr);
18+
dsp_.instanceConstants(sr);
19+
dsp_.instanceClear();
20+
}
21+
22+
void processSample(float* x) {
23+
dsp_.compute(1, &x, &x);
24+
}
25+
};

faust/LowpassBrickwall.dsp

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare name "BrickwallLowpass";
2+
3+
import("stdfaust.lib");
4+
5+
process = fi.lowpass(6, 16000);

faust/build.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
faust -a LowpassBrickwall-template.h LowpassBrickwall.dsp > ../src/LowpassBrickwall.h

src/LowpassBrickwall.h

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/* ------------------------------------------------------------
2+
name: "BrickwallLowpass"
3+
Code generated with Faust 2.5.30 (https://faust.grame.fr)
4+
Compilation options: cpp, -scal -ftz 0
5+
------------------------------------------------------------ */
6+
7+
#ifndef __mydsp_H__
8+
#define __mydsp_H__
9+
10+
#include <algorithm>
11+
12+
#include "faust/gui/UI.h"
13+
#include "faust/gui/meta.h"
14+
#include "faust/dsp/dsp.h"
15+
16+
using std::max;
17+
using std::min;
18+
19+
#ifndef FAUSTFLOAT
20+
#define FAUSTFLOAT float
21+
#endif
22+
23+
#include <cmath>
24+
#include <math.h>
25+
26+
float mydsp_faustpower2_f(float value) {
27+
return (value * value);
28+
29+
}
30+
31+
#ifndef FAUSTCLASS
32+
#define FAUSTCLASS mydsp
33+
#endif
34+
#ifdef __APPLE__
35+
#define exp10f __exp10f
36+
#define exp10 __exp10
37+
#endif
38+
39+
class mydsp : public dsp {
40+
41+
private:
42+
43+
int fSamplingFreq;
44+
float fConst0;
45+
float fConst1;
46+
float fConst2;
47+
float fConst3;
48+
float fConst4;
49+
float fConst5;
50+
float fConst6;
51+
float fRec2[3];
52+
float fConst7;
53+
float fRec1[3];
54+
float fConst8;
55+
float fRec0[3];
56+
57+
public:
58+
59+
void metadata(Meta* m) {
60+
m->declare("filename", "LowpassBrickwall");
61+
m->declare("filters.lib/name", "Faust Filters Library");
62+
m->declare("filters.lib/version", "0.0");
63+
m->declare("maths.lib/author", "GRAME");
64+
m->declare("maths.lib/copyright", "GRAME");
65+
m->declare("maths.lib/license", "LGPL with exception");
66+
m->declare("maths.lib/name", "Faust Math Library");
67+
m->declare("maths.lib/version", "2.1");
68+
m->declare("name", "BrickwallLowpass");
69+
}
70+
71+
virtual int getNumInputs() {
72+
return 1;
73+
74+
}
75+
virtual int getNumOutputs() {
76+
return 1;
77+
78+
}
79+
virtual int getInputRate(int channel) {
80+
int rate;
81+
switch (channel) {
82+
case 0: {
83+
rate = 1;
84+
break;
85+
}
86+
default: {
87+
rate = -1;
88+
break;
89+
}
90+
91+
}
92+
return rate;
93+
94+
}
95+
virtual int getOutputRate(int channel) {
96+
int rate;
97+
switch (channel) {
98+
case 0: {
99+
rate = 1;
100+
break;
101+
}
102+
default: {
103+
rate = -1;
104+
break;
105+
}
106+
107+
}
108+
return rate;
109+
110+
}
111+
112+
static void classInit(int samplingFreq) {
113+
114+
}
115+
116+
virtual void instanceConstants(int samplingFreq) {
117+
fSamplingFreq = samplingFreq;
118+
fConst0 = tanf((50265.4844f / min(192000.0f, max(1.0f, float(fSamplingFreq)))));
119+
fConst1 = (1.0f / fConst0);
120+
fConst2 = (1.0f / (((fConst1 + 0.517638087f) / fConst0) + 1.0f));
121+
fConst3 = (1.0f / (((fConst1 + 1.41421354f) / fConst0) + 1.0f));
122+
fConst4 = (1.0f / (((fConst1 + 1.93185163f) / fConst0) + 1.0f));
123+
fConst5 = (2.0f * (1.0f - (1.0f / mydsp_faustpower2_f(fConst0))));
124+
fConst6 = (((fConst1 + -1.93185163f) / fConst0) + 1.0f);
125+
fConst7 = (((fConst1 + -1.41421354f) / fConst0) + 1.0f);
126+
fConst8 = (((fConst1 + -0.517638087f) / fConst0) + 1.0f);
127+
128+
}
129+
130+
virtual void instanceResetUserInterface() {
131+
132+
}
133+
134+
virtual void instanceClear() {
135+
for (int l0 = 0; (l0 < 3); l0 = (l0 + 1)) {
136+
fRec2[l0] = 0.0f;
137+
138+
}
139+
for (int l1 = 0; (l1 < 3); l1 = (l1 + 1)) {
140+
fRec1[l1] = 0.0f;
141+
142+
}
143+
for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) {
144+
fRec0[l2] = 0.0f;
145+
146+
}
147+
148+
}
149+
150+
virtual void init(int samplingFreq) {
151+
classInit(samplingFreq);
152+
instanceInit(samplingFreq);
153+
}
154+
virtual void instanceInit(int samplingFreq) {
155+
instanceConstants(samplingFreq);
156+
instanceResetUserInterface();
157+
instanceClear();
158+
}
159+
160+
virtual mydsp* clone() {
161+
return new mydsp();
162+
}
163+
virtual int getSampleRate() {
164+
return fSamplingFreq;
165+
166+
}
167+
168+
virtual void buildUserInterface(UI* ui_interface) {
169+
ui_interface->openVerticalBox("BrickwallLowpass");
170+
ui_interface->closeBox();
171+
172+
}
173+
174+
virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
175+
FAUSTFLOAT* input0 = inputs[0];
176+
FAUSTFLOAT* output0 = outputs[0];
177+
for (int i = 0; (i < count); i = (i + 1)) {
178+
fRec2[0] = (float(input0[i]) - (fConst4 * ((fConst5 * fRec2[1]) + (fConst6 * fRec2[2]))));
179+
fRec1[0] = ((fConst4 * (fRec2[2] + (fRec2[0] + (2.0f * fRec2[1])))) - (fConst3 * ((fConst5 * fRec1[1]) + (fConst7 * fRec1[2]))));
180+
fRec0[0] = ((fConst3 * (fRec1[2] + (fRec1[0] + (2.0f * fRec1[1])))) - (fConst2 * ((fConst5 * fRec0[1]) + (fConst8 * fRec0[2]))));
181+
output0[i] = FAUSTFLOAT((fConst2 * (fRec0[2] + (fRec0[0] + (2.0f * fRec0[1])))));
182+
fRec2[2] = fRec2[1];
183+
fRec2[1] = fRec2[0];
184+
fRec1[2] = fRec1[1];
185+
fRec1[1] = fRec1[0];
186+
fRec0[2] = fRec0[1];
187+
fRec0[1] = fRec0[0];
188+
189+
}
190+
191+
}
192+
193+
194+
};
195+
196+
class LowpassBrickwall {
197+
mydsp dsp_;
198+
public:
199+
void init(int sr) {
200+
mydsp::classInit(sr);
201+
dsp_.instanceConstants(sr);
202+
dsp_.instanceClear();
203+
}
204+
205+
void processSample(float* x) {
206+
dsp_.compute(1, &x, &x);
207+
}
208+
};
209+
210+
#endif

src/Resampler.h

-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ namespace softcut {
6262
// @param f in [0, 1]
6363
float interpolate(float f);
6464

65-
// apply lowpass filtering to sample
66-
float applyLowpass(float x);
67-
6865
// write, upsampling
6966
// return frames written (>= 1)
7067
// assumptions: input has been pushed. rate_ > 1.0

src/SoftCutHeadLogic.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ void SoftCutHeadLogic::setLoopFlag(bool val) {
132132

133133
void SoftCutHeadLogic::setSampleRate(float sr_) {
134134
sr = sr_;
135+
head[0].setSampleRate(sr);
136+
head[1].setSampleRate(sr);
135137
}
136138

137139
float SoftCutHeadLogic::mixFade(float x, float y, float a, float b) {

src/SoftCutHeadLogic.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ namespace softcut{
3636
/// FIXME: this method accepts samples and doesn't wrap.
3737
/// should add something like cutToPos(seconds)
3838
void cutToPhase(float newPhase); // fade in to new position (given in samples)
39-
float getActivePhase();
40-
float getTrig();
41-
void resetTrig();
42-
39+
40+
float getActivePhase();
41+
float getTrig();
42+
void resetTrig();
43+
4344
private:
4445
void takeAction(Action act, int id);
4546
float mixFade(float x, float y, float a, float b); // mix two inputs with phases
@@ -48,6 +49,7 @@ namespace softcut{
4849
typedef enum {
4950
FADE_LIN, FADE_EQ, FADE_EXP
5051
} fade_t;
52+
5153
private:
5254
SubHead head[2];
5355

@@ -66,7 +68,7 @@ namespace softcut{
6668
float fadePre; // pre-level modulated by xfade
6769
float fadeRec; // record level modulated by xfade
6870
bool recRun;
69-
bool playRun;
71+
bool playRun;
7072

7173
// FIXME: not using this right now...
7274
double recPhaseOffset;

src/SubHead.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
using namespace softcut;
1212

13-
1413
SubHead::SubHead() {
1514
this->init();
1615
}
@@ -104,12 +103,12 @@ void SubHead::poke(float in, float pre, float rec, float fadePre, float fadeRec)
104103
int inc = rate_ > 0.f ? 1 : -1;
105104
int nframes = resamp_.processFrame(in);
106105

107-
// assert(phase_ > 0.0);
108-
109106
idx = wrapBufIndex(static_cast<int>(phase_));
107+
110108
const float* src = resamp_.output();
111109
for(int i=0; i<nframes; ++i) {
112110
y = *src++;
111+
lpf_.processSample(&y);
113112
buf_[idx] *= preFade;
114113
buf_[idx] += y * recFade;
115114
idx = wrapBufIndex(idx + inc);
@@ -139,4 +138,8 @@ unsigned int SubHead::wrapBufIndex(int x) {
139138
x += bufFrames_;
140139
assert(x >= 0);
141140
return x & bufMask_;
141+
}
142+
143+
void SubHead::setSampleRate(float sr) {
144+
lpf_.init(static_cast<int>(sr));
142145
}

src/SubHead.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define SOFTCUTHEAD_SUBHEAD_H
1111

1212
#include "Resampler.h"
13+
#include "LowpassBrickwall.h"
1314

1415
namespace softcut {
1516

@@ -22,7 +23,7 @@ namespace softcut {
2223
public:
2324
SubHead();
2425
void init();
25-
26+
void setSampleRate(float sr);
2627
private:
2728
float peek4(double phase);
2829
unsigned int wrapBufIndex(int x);
@@ -70,6 +71,7 @@ namespace softcut {
7071
unsigned int bufFrames_;
7172
unsigned int bufMask_;
7273
Resampler resamp_;
74+
LowpassBrickwall lpf_;
7375
State state_;
7476
double rate_;
7577
double phase_;

test-osc.scd

+2-3
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,17 @@ n.sendMsg("/set/rate", 5/8);
2929
n.sendMsg("/set/rate", 8/5);
3030
n.sendMsg("/set/rate", -1);
3131

32-
33-
3432
n.sendMsg("/set/rate", -6);
3533
n.sendMsg("/set/rate", 3/2);
34+
n.sendMsg("/set/rate", 1/8);
3635

3736

3837
// short loop
3938
n.sendMsg("/set/loopEnd", 1.2);
4039
n.sendMsg("/set/fadeTime", 0.1);
4140

4241

43-
n.sendMsg("/set/recLevel", 0.8);
42+
n.sendMsg("/set/recLevel", 1.0);
4443
n.sendMsg("/set/preLevel", 0.9);
4544

4645
n.sendMsg("/set/recFlag", 0);

0 commit comments

Comments
 (0)