LMMS
Loading...
Searching...
No Matches
multichorus.h
Go to the documentation of this file.
1/* Calf DSP Library
2 * Multitap chorus class.
3 *
4 * Copyright (C) 2001-2007 Krzysztof Foltman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02111-1307, USA.
20 */
21#ifndef __CALF_MULTICHORUS_H
22#define __CALF_MULTICHORUS_H
23
24#include "audio_fx.h"
25
26namespace dsp {
27
29
30template<class T, uint32_t Voices>
32{
33protected:
35
36public:
51public:
53 {
54 phase = dphase = vphase = 0.0;
55 voice_offset = 0;
56 voice_depth = 1U << 31;
57
58 set_voices(Voices);
59 }
60 inline uint32_t get_voices() const
61 {
62 return voices;
63 }
65 {
66 voices = value;
67 // use sqrt, because some phases will cancel each other - so 1 / N is usually too low
68 scale = sqrt(1.0 / voices);
69 }
70 inline void set_overlap(float overlap)
71 {
72 // If we scale the delay amount so that full range of a single LFO is 0..1, all the overlapped LFOs will cover 0..range
73 // How it's calculated:
74 // 1. First voice is assumed to always cover the range of 0..1
75 // 2. Each remaining voice contributes an interval of a width = 1 - overlap, starting from the end of the interval of the previous voice
76 // Coverage = non-overlapped part of the LFO range in the 1st voice
77 float range = 1.f + (1.f - overlap) * (voices - 1);
78 float scaling = 1.f / range;
79 voice_offset = (int)(131072 * (1 - overlap) / range);
80 voice_depth = (unsigned int)((1U << 30) * 1.0 * scaling);
81 }
82
83 inline int get_value(uint32_t voice) const {
84 // find this voice's phase (= phase + voice * 360 degrees / number of voices)
85 chorus_phase voice_phase = phase + vphase * (int)voice;
86 // find table offset
87 unsigned int ipart = voice_phase.ipart();
88 // interpolate (use 14 bits of precision - because the table itself uses 17 bits and the result of multiplication must fit in int32_t)
89 // note, the result is still -65535 .. 65535, it's just interpolated
90 // it is never reaching -65536 - but that's acceptable
91 int intval = voice_phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
92 // apply the voice offset/depth (rescale from -65535..65535 to appropriate voice's "band")
93 return -65535 + voice * voice_offset + ((voice_depth >> (30-13)) * (65536 + intval) >> 13);
94 }
95 inline void step() {
96 phase += dphase;
97 }
98 inline T get_scale() const {
99 return scale;
100 }
101 void reset() {
102 phase = 0.f;
103 }
104};
105
110template<class T, class MultiLfo, class Postprocessor, int MaxDelay=4096>
112{
113protected:
115public:
116 MultiLfo lfo;
117 Postprocessor post;
118public:
120 rate = 0.63f;
121 dry = 0.5f;
122 wet = 0.5f;
123 min_delay = 0.005f;
124 mod_depth = 0.0025f;
125 setup(44100);
126 }
127 void reset() {
128 delay.reset();
129 lfo.reset();
130 }
131 void set_rate(float rate) {
133 lfo.dphase = dphase;
134 }
135 virtual void setup(int sample_rate) {
137 delay.reset();
138 lfo.reset();
141 }
142 template<class OutIter, class InIter>
143 void process(OutIter buf_out, InIter buf_in, int nsamples, bool active, float level_in = 1., float level_out = 1.) {
144 int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536;
145 int mdepth = mod_depth_samples;
146 // 1 sample peak-to-peak = mod_depth_samples of 32 (this scaling stuff is tricky and may - but shouldn't - be wrong)
147 // with 192 kHz sample rate, 1 ms = 192 samples, and the maximum 20 ms = 3840 samples (so, 4096 will be used)
148 // 3840 samples of mod depth = mdepth of 122880 (which multiplied by 65536 doesn't fit in int32_t)
149 // so, it will be right-shifted by 2, which gives it a safe range of 30720
150 // NB: calculation of mod_depth_samples (and multiply-by-32) is in chorus_base::set_mod_depth
151 mdepth = mdepth >> 2;
152 T scale = lfo.get_scale();
153 for (int i=0; i<nsamples; i++) {
154 if (lfo_active)
155 phase += dphase;
156 float in = *buf_in++ * level_in;
157
158 delay.put(in);
159 unsigned int nvoices = lfo.get_voices();
160 T out = 0.f;
161 // add up values from all voices, each voice tell its LFO phase and the buffer value is picked at that location
162 for (unsigned int v = 0; v < nvoices; v++)
163 {
164 int lfo_output = lfo.get_value(v);
165 // 3 = log2(32 >> 2) + 1 because the LFO value is in range of [-65535, 65535] (17 bits)
166 int dv = mds + (mdepth * lfo_output >> (3 + 1));
167 int ifv = dv >> 16;
168 T fd; // signal from delay's output
169 delay.get_interp(fd, ifv, (dv & 0xFFFF)*(1.0/65536.0));
170 out += fd;
171 }
172 // apply the post filter
173 out = post.process(out);
174 T sdry = in * gs_dry.get();
175 T swet = out * gs_wet.get() * scale;
176 *buf_out++ = (sdry + (active ? swet : 0)) * level_out;
177 if (lfo_active)
178 lfo.step();
179 }
180 post.sanitize();
181 }
182 float freq_gain(float freq, float sr) const
183 {
184 typedef std::complex<double> cfloat;
185 freq *= 2.0 * M_PI / sr;
186 cfloat z = 1.0 / exp(cfloat(0.0, freq)); // z^-1
187 cfloat h = 0.0;
188 int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536;
189 int mdepth = mod_depth_samples;
190 mdepth = mdepth >> 2;
191 T scale = lfo.get_scale();
192 unsigned int nvoices = lfo.get_voices();
193 for (unsigned int v = 0; v < nvoices; v++)
194 {
195 int lfo_output = lfo.get_value(v);
196 // 3 = log2(32 >> 2) + 1 because the LFO value is in range of [-65535, 65535] (17 bits)
197 int dv = mds + (mdepth * lfo_output >> (3 + 1));
198 int fldp = dv >> 16;
199 cfloat zn = std::pow(z, fldp); // z^-N
200 h += zn + (zn * z - zn) * cfloat(dv / 65536.0 - fldp);
201 }
202 // apply the post filter
203 h *= post.h_z(z);
204 // mix with dry signal
205 float v = std::abs(cfloat(gs_dry.get_last()) + cfloat(scale * gs_wet.get_last()) * h);
206 return v;
207 }
208};
209
210};
211
212#endif
Definition audio_fx.h:160
float min_delay
Definition audio_fx.h:163
float get_mod_depth() const
Definition audio_fx.h:173
int min_delay_samples
Definition audio_fx.h:162
int mod_depth_samples
Definition audio_fx.h:162
void set_min_delay(float min_delay)
Definition audio_fx.h:169
float mod_depth
Definition audio_fx.h:163
float get_min_delay() const
Definition audio_fx.h:166
void set_mod_depth(float mod_depth)
Definition audio_fx.h:176
Definition fixed_point.h:38
T ipart() const
return integer part
Definition fixed_point.h:174
U lerp_by_fract_int(U v1, U v2) const
Definition fixed_point.h:211
int lfo_active
Definition audio_fx.h:54
float rate
Definition audio_fx.h:55
gain_smoothing gs_dry
Definition audio_fx.h:56
fixed_point< unsigned int, 20 > phase
Definition audio_fx.h:58
fixed_point< unsigned int, 20 > dphase
Definition audio_fx.h:58
void setup(int sample_rate)
Definition audio_fx.h:88
void set_rate(float rate)
Definition audio_fx.h:62
float dry
Definition audio_fx.h:55
float wet
Definition audio_fx.h:55
int sample_rate
Definition audio_fx.h:54
gain_smoothing gs_wet
Definition audio_fx.h:56
simple_delay< MaxDelay, T > delay
Definition multichorus.h:114
MultiLfo lfo
Definition multichorus.h:116
void set_rate(float rate)
Definition multichorus.h:131
float freq_gain(float freq, float sr) const
Definition multichorus.h:182
Postprocessor post
Definition multichorus.h:117
multichorus()
Definition multichorus.h:119
void process(OutIter buf_out, InIter buf_in, int nsamples, bool active, float level_in=1., float level_out=1.)
Definition multichorus.h:143
virtual void setup(int sample_rate)
Definition multichorus.h:135
void reset()
Definition multichorus.h:127
int get_value(uint32_t voice) const
Get LFO value for given voice, returns a values in range of [-65536, 65535] (or close).
Definition multichorus.h:83
void set_voices(uint32_t value)
Definition multichorus.h:64
chorus_phase phase
Current LFO phase.
Definition multichorus.h:38
uint32_t voices
Current number of voices.
Definition multichorus.h:44
T scale
Current scale (output multiplier).
Definition multichorus.h:46
sine_table< int, 4096, 65535 > sine
Definition multichorus.h:34
void step()
Definition multichorus.h:95
sine_multi_lfo()
Definition multichorus.h:52
int32_t voice_offset
Per-voice offset unit (the value that says how much the voices are offset with respect to each other ...
Definition multichorus.h:48
void reset()
Definition multichorus.h:101
uint32_t get_voices() const
Definition multichorus.h:60
T get_scale() const
Definition multichorus.h:98
chorus_phase vphase
LFO phase per-voice increment.
Definition multichorus.h:42
chorus_phase dphase
LFO phase increment.
Definition multichorus.h:40
void set_overlap(float overlap)
Definition multichorus.h:70
uint32_t voice_depth
LFO Range scaling for non-100% overlap.
Definition multichorus.h:50
Definition primitives.h:425
Definition synth.h:105
#define M_PI
Definition compat.h:149
unsigned z
Definition inflate.c:1589
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
static PuglViewHint int value
Definition pugl.h:1708
JHUFF_TBL long freq[]
Definition jchuff.h:50
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
int int32_t
Definition mid.cpp:97
unsigned int uint32_t
Definition mid.cpp:100
Definition audio_fx.h:36
fixed_point< unsigned int, 20 > chorus_phase
Definition multichorus.h:28
Definition delay.h:41
Definition globals.h:33
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
typedef int(UZ_EXP MsgFn)()