Skip to content

Commit c5fea10

Browse files
committed
Many fixes and added internal effects.
1 parent 1ec7455 commit c5fea10

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+4924
-10
lines changed

SConstruct

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ SConscript('globals/SCsub');
9696
SConscript('dsp/SCsub');
9797
SConscript('engine/SCsub');
9898
SConscript('gui/SCsub');
99+
SConscript('effects/SCsub');
99100
SConscript('drivers/SCsub');
100101
SConscript('bin/SCsub');
101102

bin/zytrax.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "drivers/vst2/factory_wrapper_vst2.h"
55
#endif
66

7+
#include "effects/effects.h"
78
#include "engine/song.h"
89
#include "globals/json_file.h"
910
#include "gui/interface.h"
@@ -155,10 +156,11 @@ int main(int argc, char *argv[]) {
155156
}
156157
}
157158
}
158-
159159
SoundDriverManager::init_driver(use_driver_index);
160160
}
161161

162+
register_effects(&effect_factory);
163+
162164
/* make it dark */
163165
if (theme.color_scheme == Theme::COLOR_SCHEME_DARK) {
164166
g_object_set(gtk_settings_get_default(),
@@ -183,7 +185,6 @@ int main(int argc, char *argv[]) {
183185
AudioEffectInfo info;
184186

185187
info.caption.parse_utf8(plugin_node.get("caption").toString().c_str());
186-
info.short_caption.parse_utf8(plugin_node.get("short_caption").toString().c_str());
187188
info.description.parse_utf8(plugin_node.get("description").toString().c_str());
188189
info.author.parse_utf8(plugin_node.get("author").toString().c_str());
189190
info.category.parse_utf8(plugin_node.get("category").toString().c_str());

drivers/vst2/audio_effect_provider_vst2.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ void AudioEffectProviderVST2::scan_effects(AudioEffectFactory *p_factory, ScanCa
9393
name = name.substr(0, name.find("."));
9494
info.caption = name;
9595
printf("plugin name: %s\n", info.caption.utf8().get_data());
96-
info.description = "VST Plugin";
97-
info.long_description = "VST Info:\n Name: " + info.caption + "\n ID: " + String::num(ptrPlug->uniqueID) + "\n Version: " + String(ptrPlug->version);
96+
info.description = "VST Info:\n Name: " + info.caption + "\n ID: " + String::num(ptrPlug->uniqueID) + "\n Version: " + String(ptrPlug->version);
9897
info.unique_ID = "VST_" + String::num(ptrPlug->uniqueID);
9998
info.synth = /*(ptrPlug->dispatcher(ptrPlug,effGetVstVersion,0,0,NULL,0.0f)==2 */ ptrPlug->flags & effFlagsIsSynth;
10099
info.category = info.synth ? "VST Instruments" : "VST Effects";

drivers/vst2/audio_effect_vst2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class AudioEffectVST2 : public AudioEffectMIDI {
4949
bool setting;
5050
bool editing;
5151

52+
virtual Hint get_hint() const { return HINT_RANGE_NORMALIZED; }
53+
5254
virtual String get_name() const { return name; }
5355
virtual String get_identifier() const { return identifier; }
5456
virtual float get_min() const { return 0; }

dsp/filter.cpp

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#include "filter.h"
2+
#include <math.h>
3+
4+
void Filter::set_mode(Mode p_mode) {
5+
6+
mode = p_mode;
7+
}
8+
void Filter::set_cutoff(float p_cutoff) {
9+
10+
cutoff = p_cutoff;
11+
}
12+
void Filter::set_resonance(float p_resonance) {
13+
14+
resonance = p_resonance;
15+
}
16+
17+
void Filter::set_gain(float p_gain) {
18+
19+
gain = p_gain;
20+
}
21+
22+
void Filter::set_sampling_rate(float p_srate) {
23+
24+
sampling_rate = p_srate;
25+
}
26+
27+
void Filter::prepare_coefficients(Coeffs *p_coeffs) {
28+
29+
int sr_limit = (sampling_rate / 2) + 512;
30+
31+
double final_cutoff = (cutoff > sr_limit) ? sr_limit : cutoff;
32+
if (final_cutoff < 1) final_cutoff = 1; //don't allow less than this
33+
34+
double omega = 2.0 * M_PI * final_cutoff / sampling_rate;
35+
36+
double sin_v = sin(omega);
37+
double cos_v = cos(omega);
38+
39+
double Q = resonance;
40+
if (Q <= 0.0) {
41+
Q = 0.0001;
42+
}
43+
44+
if (mode == BANDPASS)
45+
Q *= 2.0;
46+
else if (mode == PEAK)
47+
Q *= 3.0;
48+
49+
double tmpgain = gain;
50+
51+
if (tmpgain < 0.001)
52+
tmpgain = 0.001;
53+
54+
if (stages > 1) {
55+
56+
Q = (Q > 1.0 ? pow(Q, 1.0 / stages) : Q);
57+
tmpgain = pow(tmpgain, 1.0 / (stages + 1));
58+
}
59+
double alpha = sin_v / (2 * Q);
60+
61+
double a0 = 1.0 + alpha;
62+
63+
switch (mode) {
64+
65+
case LOWPASS: {
66+
67+
p_coeffs->b0 = (1.0 - cos_v) / 2.0;
68+
p_coeffs->b1 = 1.0 - cos_v;
69+
p_coeffs->b2 = (1.0 - cos_v) / 2.0;
70+
p_coeffs->a1 = -2.0 * cos_v;
71+
p_coeffs->a2 = 1.0 - alpha;
72+
} break;
73+
74+
case HIGHPASS: {
75+
76+
p_coeffs->b0 = (1.0 + cos_v) / 2.0;
77+
p_coeffs->b1 = -(1.0 + cos_v);
78+
p_coeffs->b2 = (1.0 + cos_v) / 2.0;
79+
p_coeffs->a1 = -2.0 * cos_v;
80+
p_coeffs->a2 = 1.0 - alpha;
81+
} break;
82+
83+
case BANDPASS: {
84+
85+
p_coeffs->b0 = alpha * sqrt(Q + 1);
86+
p_coeffs->b1 = 0.0;
87+
p_coeffs->b2 = -alpha * sqrt(Q + 1);
88+
p_coeffs->a1 = -2.0 * cos_v;
89+
p_coeffs->a2 = 1.0 - alpha;
90+
} break;
91+
92+
case NOTCH: {
93+
94+
p_coeffs->b0 = 1.0;
95+
p_coeffs->b1 = -2.0 * cos_v;
96+
p_coeffs->b2 = 1.0;
97+
p_coeffs->a1 = -2.0 * cos_v;
98+
p_coeffs->a2 = 1.0 - alpha;
99+
} break;
100+
case PEAK: {
101+
p_coeffs->b0 = (1.0 + alpha * tmpgain);
102+
p_coeffs->b1 = (-2.0 * cos_v);
103+
p_coeffs->b2 = (1.0 - alpha * tmpgain);
104+
p_coeffs->a1 = -2 * cos_v;
105+
p_coeffs->a2 = (1 - alpha / tmpgain);
106+
} break;
107+
case BANDLIMIT: {
108+
//this one is extra tricky
109+
double hicutoff = resonance;
110+
double centercutoff = (cutoff + resonance) / 2.0;
111+
double bandwidth = (log(centercutoff) - log(hicutoff)) / log((double)2);
112+
omega = 2.0 * M_PI * centercutoff / sampling_rate;
113+
alpha = sin(omega) * sinh(log((double)2) / 2 * bandwidth * omega / sin(omega));
114+
a0 = 1 + alpha;
115+
116+
p_coeffs->b0 = alpha;
117+
p_coeffs->b1 = 0;
118+
p_coeffs->b2 = -alpha;
119+
p_coeffs->a1 = -2 * cos(omega);
120+
p_coeffs->a2 = 1 - alpha;
121+
122+
} break;
123+
case LOWSHELF: {
124+
125+
double tmpq = sqrt(Q);
126+
if (tmpq <= 0)
127+
tmpq = 0.001;
128+
alpha = sin_v / (2 * tmpq);
129+
double beta = sqrt(tmpgain) / tmpq;
130+
131+
a0 = (tmpgain + 1.0) + (tmpgain - 1.0) * cos_v + beta * sin_v;
132+
p_coeffs->b0 = tmpgain * ((tmpgain + 1.0) - (tmpgain - 1.0) * cos_v + beta * sin_v);
133+
p_coeffs->b1 = 2.0 * tmpgain * ((tmpgain - 1.0) - (tmpgain + 1.0) * cos_v);
134+
p_coeffs->b2 = tmpgain * ((tmpgain + 1.0) - (tmpgain - 1.0) * cos_v - beta * sin_v);
135+
p_coeffs->a1 = -2.0 * ((tmpgain - 1.0) + (tmpgain + 1.0) * cos_v);
136+
p_coeffs->a2 = ((tmpgain + 1.0) + (tmpgain - 1.0) * cos_v - beta * sin_v);
137+
138+
} break;
139+
case HIGHSHELF: {
140+
double tmpq = sqrt(Q);
141+
if (tmpq <= 0)
142+
tmpq = 0.001;
143+
alpha = sin_v / (2 * tmpq);
144+
double beta = sqrt(tmpgain) / tmpq;
145+
146+
a0 = (tmpgain + 1.0) - (tmpgain - 1.0) * cos_v + beta * sin_v;
147+
p_coeffs->b0 = tmpgain * ((tmpgain + 1.0) + (tmpgain - 1.0) * cos_v + beta * sin_v);
148+
p_coeffs->b1 = -2.0 * tmpgain * ((tmpgain - 1.0) + (tmpgain + 1.0) * cos_v);
149+
p_coeffs->b2 = tmpgain * ((tmpgain + 1.0) + (tmpgain - 1.0) * cos_v - beta * sin_v);
150+
p_coeffs->a1 = 2.0 * ((tmpgain - 1.0) - (tmpgain + 1.0) * cos_v);
151+
p_coeffs->a2 = ((tmpgain + 1.0) - (tmpgain - 1.0) * cos_v - beta * sin_v);
152+
153+
} break;
154+
};
155+
156+
p_coeffs->b0 /= a0;
157+
p_coeffs->b1 /= a0;
158+
p_coeffs->b2 /= a0;
159+
p_coeffs->a1 /= 0.0 - a0;
160+
p_coeffs->a2 /= 0.0 - a0;
161+
162+
//undenormalise
163+
/* p_coeffs->b0=undenormalise(p_coeffs->b0);
164+
p_coeffs->b1=undenormalise(p_coeffs->b1);
165+
p_coeffs->b2=undenormalise(p_coeffs->b2);
166+
p_coeffs->a1=undenormalise(p_coeffs->a1);
167+
p_coeffs->a2=undenormalise(p_coeffs->a2);*/
168+
}
169+
170+
void Filter::set_stages(int p_stages) { //adjust for multiple stages
171+
172+
stages = p_stages;
173+
}
174+
175+
/* Fouriertransform kernel to obtain response */
176+
177+
float Filter::get_response(float p_freq, Coeffs *p_coeffs) {
178+
179+
float freq = p_freq / sampling_rate * M_PI * 2.0f;
180+
181+
float cx = p_coeffs->b0, cy = 0.0;
182+
183+
cx += cos(freq) * p_coeffs->b1;
184+
cy -= sin(freq) * p_coeffs->b1;
185+
cx += cos(2 * freq) * p_coeffs->b2;
186+
cy -= sin(2 * freq) * p_coeffs->b2;
187+
188+
float H = cx * cx + cy * cy;
189+
cx = 1.0;
190+
cy = 0.0;
191+
192+
cx -= cos(freq) * p_coeffs->a1;
193+
cy += sin(freq) * p_coeffs->a1;
194+
cx -= cos(2 * freq) * p_coeffs->a2;
195+
cy += sin(2 * freq) * p_coeffs->a2;
196+
197+
H = H / (cx * cx + cy * cy);
198+
return H;
199+
}
200+
201+
Filter::Filter() {
202+
203+
sampling_rate = 44100;
204+
resonance = 0.5;
205+
cutoff = 5000;
206+
gain = 1.0;
207+
mode = LOWPASS;
208+
stages = 1;
209+
}
210+
211+
Filter::Processor::Processor() {
212+
213+
set_filter(NULL);
214+
}
215+
216+
void Filter::Processor::set_filter(Filter *p_filter, bool p_clear_history) {
217+
218+
if (p_clear_history) {
219+
ha1 = ha2 = hb1 = hb2 = 0;
220+
}
221+
filter = p_filter;
222+
}
223+
224+
void Filter::Processor::update_coeffs(int p_interp_buffer_len) {
225+
226+
if (!filter)
227+
return;
228+
229+
if (p_interp_buffer_len) { //interpolate
230+
Coeffs old_coeffs = coeffs;
231+
filter->prepare_coefficients(&coeffs);
232+
incr_coeffs.a1 = (coeffs.a1 - old_coeffs.a1) / p_interp_buffer_len;
233+
incr_coeffs.a2 = (coeffs.a2 - old_coeffs.a2) / p_interp_buffer_len;
234+
incr_coeffs.b0 = (coeffs.b0 - old_coeffs.b0) / p_interp_buffer_len;
235+
incr_coeffs.b1 = (coeffs.b1 - old_coeffs.b1) / p_interp_buffer_len;
236+
incr_coeffs.b2 = (coeffs.b2 - old_coeffs.b2) / p_interp_buffer_len;
237+
coeffs = old_coeffs;
238+
} else {
239+
filter->prepare_coefficients(&coeffs);
240+
}
241+
}
242+
243+
void Filter::Processor::process(float *p_samples, int p_amount, int p_stride, bool p_interpolate) {
244+
245+
if (!filter)
246+
return;
247+
248+
if (p_interpolate) {
249+
for (int i = 0; i < p_amount; i++) {
250+
251+
process_one_interp(*p_samples);
252+
p_samples += p_stride;
253+
}
254+
} else {
255+
for (int i = 0; i < p_amount; i++) {
256+
257+
process_one(*p_samples);
258+
p_samples += p_stride;
259+
}
260+
}
261+
}

0 commit comments

Comments
 (0)