LMMS
Loading...
Searching...
No Matches
synth.h
Go to the documentation of this file.
1/* Calf DSP Library
2 * Framework for synthesizer-like plugins. This is based
3 * on my earlier work on Drawbar electric organ emulator.
4 *
5 * Copyright (C) 2007 Krzysztof Foltman
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02111-1307, USA.
21 */
22#ifndef CALF_SYNTH_H
23#define CALF_SYNTH_H
24
25#include <assert.h>
26#include <math.h>
27#include <memory.h>
28#include <stdint.h>
29#include <bitset>
30#include <list>
31#include <stack>
32
33namespace dsp {
34
38class keystack {
39private:
40 int dcount;
43public:
45 memset(states, 0xFF, sizeof(states));
46 dcount = 0;
47 }
48 void clear() {
49 for (int i=0; i<dcount; i++)
50 states[active[i]] = 0xFF;
51 dcount = 0;
52 }
53 bool push(int key) {
54 assert(key >= 0 && key <= 127);
55 if (states[key] != 0xFF) {
56 return true;
57 }
58 states[key] = dcount;
59 active[dcount++] = key;
60 return false;
61 }
62 bool pop(int key) {
63 if (states[key] == 0xFF)
64 return false;
65 int pos = states[key];
66 if (pos != dcount-1) {
67 // reuse the popped item's stack position for stack top
68 int last = active[dcount-1];
69 active[pos] = last;
70 // mark that position's new place on stack
71 states[last] = pos;
72 }
73 states[key] = 0xFF;
74 dcount--;
75 return true;
76 }
77 inline bool has(int key) {
78 return states[key] != 0xFF;
79 }
80 inline int count() {
81 return dcount;
82 }
83 inline bool empty() {
84 return (dcount == 0);
85 }
86 inline int nth(int n) {
87 return active[n];
88 }
89};
90
97inline unsigned int midi_note_to_phase(int note, double cents, int sr) {
98 double incphase = 440*pow(2.0, (note-69)/12.0 + cents/1200.0)/sr;
99 if (incphase >= 1.0) incphase = fmod(incphase, 1.0);
100 incphase *= 65536.0*65536.0;
101 return (unsigned int)incphase;
102}
103
104// Base class for all voice objects
105class voice {
106public:
109
111
113 virtual void setup(int sr) { sample_rate = sr; }
115 virtual void reset()=0;
117 virtual void note_on(int note, int vel)=0;
119 virtual void note_off(int vel)=0;
121 virtual bool get_active()=0;
123 virtual void render_to(float (*buf)[2], int nsamples)=0;
125 virtual void steal()=0;
127 virtual int get_current_note()=0;
128 virtual float get_priority() { return stolen ? 20000 : (released ? 1 : (sostenuto ? 200 : 100)); }
130 virtual ~voice() {}
131};
132
133template<class Base>
135{
136public:
137 enum { BlockSize = Base::BlockSize, MaxSnapshots = (Base::MaxSampleRun + Base::BlockSize - 1) / Base::BlockSize + 1 };
138 unsigned int sample_ctr;
139
140 void fill_snapshots(int nsamples)
141 {
142 int s = 0;
143 make_snapshot(s++);
144 while(sample_ctr + nsamples >= Base::BlockSize)
145 {
146 make_snapshot(s++);
147 nsamples -= (Base::BlockSize - sample_ctr);
148 sample_ctr = 0;
149 }
150 sample_ctr += nsamples;
151 }
152 virtual void make_snapshot(int index) = 0;
153};
154
160template<class Base>
161class block_voice: public Base {
162public:
163 // derived from Base
164 // enum { Channels = 2 };
165 using Base::Channels;
166 // enum { BlockSize = 16 };
167 using Base::BlockSize;
168 // float output_buffer[BlockSize][Channels];
169 using Base::output_buffer;
170 // void render_block();
171 using Base::render_block;
172 unsigned int read_ptr;
173
175 {
176 read_ptr = BlockSize;
177 }
178 virtual void reset()
179 {
180 Base::reset();
181 read_ptr = BlockSize;
182 }
183 virtual void render_to(float (*buf)[2], int nsamples)
184 {
185 int p = 0;
186 int current_snapshot = 0;
187 while(p < nsamples)
188 {
189 if (read_ptr == BlockSize)
190 {
191 render_block(current_snapshot);
192 current_snapshot++;
193 read_ptr = 0;
194 }
195 int ncopy = std::min<int>(BlockSize - read_ptr, nsamples - p);
196 for (int i = 0; i < ncopy; i++)
197 for (int c = 0; c < Channels; c++)
198 buf[p + i][c] += output_buffer[read_ptr + i][c];
199 p += ncopy;
200 read_ptr += ncopy;
201 }
202 }
203};
204
205#define for_all_voices(iter) for (dsp::voice **iter = active_voices.begin(); iter != active_voices.end(); iter++)
206
208template<class T>
210 typedef T *iterator;
211 typedef const T *const_iterator;
213 int count;
215
217 : items()
218 , count()
219 , alloc_size()
220 {}
221
222 void init(int max_count)
223 {
224 assert(!items);
225 assert(!count);
227 items = new T[max_count];
228 alloc_size = max_count;
229 }
230
231 T *begin() { return items; }
232 T *end() { return items + count; }
233 const T *begin() const { return items; }
234 const T *end() const { return items + count; }
235 bool empty() const { return count == 0; }
236 size_t size() const { return count; }
237
238 bool add(T v)
239 {
240 if (count >= alloc_size)
241 return false;
242 items[count++] = v;
243 return true;
244 }
245
247 {
248 erase(iter - begin());
249 return iter;
250 }
251 void erase(int pos)
252 {
253 assert(pos >= 0 && pos < count);
254 if (pos != count - 1)
255 std::swap(items[count - 1], items[pos]);
256 count--;
257 items[count] = T();
258 }
259
260 T pop() {
261 if (count)
262 return items[--count];
263 else
264 return NULL;
265 }
266
268 {
269 delete []items;
270 }
271};
272
279protected:
284 bool hold;
294 std::bitset<128> gate;
296 unsigned int polyphony_limit;
297
298 void init_voices(int count);
299 void kill_note(int note, int vel, bool just_one);
300 virtual dsp::voice *alloc_voice() = 0;
301public:
302 virtual void setup(int sr) {
303 sample_rate = sr;
304 hold = false;
305 sostenuto = false;
306 polyphony_limit = (unsigned)-1;
307 }
308 virtual void trim_voices();
309 virtual dsp::voice *give_voice();
310 virtual void steal_voice();
311 virtual void render_to(float (*output)[2], int nsamples);
312 virtual void note_on(int note, int vel);
313 virtual void percussion_note_on(int note, int vel) {}
314 virtual void control_change(int ctl, int val);
315 virtual void note_off(int note, int vel);
317 virtual void pitch_bend(int amt) {}
318 virtual void on_pedal_release();
319 virtual bool check_percussion() { return active_voices.empty(); }
320 virtual ~basic_synth();
321};
322
323}
324
325#endif
#define NULL
Definition CarlaBridgeFormat.cpp:30
assert(0)
Definition synth.h:135
void fill_snapshots(int nsamples)
Definition synth.h:140
virtual void make_snapshot(int index)=0
unsigned int sample_ctr
Definition synth.h:138
@ MaxSnapshots
Definition synth.h:137
@ BlockSize
Definition synth.h:137
unsigned int read_ptr
Definition synth.h:172
virtual void reset()
Definition synth.h:178
virtual void render_to(float(*buf)[2], int nsamples)
Definition synth.h:183
block_voice()
Definition synth.h:174
int dcount
Definition synth.h:40
keystack()
Definition synth.h:44
bool push(int key)
Definition synth.h:53
bool pop(int key)
Definition synth.h:62
int nth(int n)
Definition synth.h:86
bool empty()
Definition synth.h:83
uint8_t states[128]
Definition synth.h:42
bool has(int key)
Definition synth.h:77
uint8_t active[128]
Definition synth.h:41
void clear()
Definition synth.h:48
int count()
Definition synth.h:80
Definition synth.h:105
virtual bool get_active()=0
check if voice can be removed from active voice list
virtual void render_to(float(*buf)[2], int nsamples)=0
render voice data to buffer
virtual void setup(int sr)
reset voice to default state (used when a voice is to be reused)
Definition synth.h:113
voice()
Definition synth.h:110
bool released
Definition synth.h:108
virtual ~voice()
empty virtual destructor
Definition synth.h:130
virtual void reset()=0
reset voice to default state (used when a voice is to be reused)
int sample_rate
Definition synth.h:107
bool stolen
Definition synth.h:108
virtual void note_on(int note, int vel)=0
a note was pressed
bool sostenuto
Definition synth.h:108
virtual float get_priority()
Definition synth.h:128
virtual int get_current_note()=0
return the note used by this voice
virtual void note_off(int vel)=0
a note was released
virtual void steal()=0
very fast note off
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
int val
Definition jpeglib.h:956
unsigned char uint8_t
Definition mid.cpp:98
Definition audio_fx.h:36
unsigned int midi_note_to_phase(int note, double cents, int sr)
Definition synth.h:97
#define false
Definition ordinals.h:83
A basic preallocated var-array with append and.
Definition synth.h:209
size_t size() const
Definition synth.h:236
void init(int max_count)
Definition synth.h:222
~basic_pool()
Definition synth.h:267
int alloc_size
Definition synth.h:214
bool add(T v)
Definition synth.h:238
const T * const_iterator
Definition synth.h:211
T * iterator
Definition synth.h:210
const T * begin() const
Definition synth.h:233
const T * end() const
Definition synth.h:234
T pop()
Definition synth.h:260
void erase(int pos)
Definition synth.h:251
int count
Definition synth.h:213
iterator erase(iterator iter)
Definition synth.h:246
dsp::voice ** items
Definition synth.h:212
T * end()
Definition synth.h:232
T * begin()
Definition synth.h:231
basic_pool()
Definition synth.h:216
bool empty() const
Definition synth.h:235
Definition synth.h:278
virtual ~basic_synth()
Definition synth.cpp:218
voice_array active_voices
Voices currently playing.
Definition synth.h:290
virtual dsp::voice * give_voice()
Definition synth.cpp:51
int sample_rate
Current sample rate.
Definition synth.h:282
bool sostenuto
Sostenuto pedal state.
Definition synth.h:286
basic_pool< dsp::voice * > voice_array
Definition synth.h:280
virtual void control_change(int ctl, int val)
Definition synth.cpp:156
virtual void steal_voice()
Definition synth.cpp:64
virtual dsp::voice * alloc_voice()=0
virtual void render_to(float(*output)[2], int nsamples)
Definition synth.cpp:203
virtual void trim_voices()
Definition synth.cpp:85
virtual void setup(int sr)
Definition synth.h:302
virtual void note_off(int note, int vel)
Definition synth.cpp:123
void init_voices(int count)
Definition synth.cpp:26
virtual void percussion_note_on(int note, int vel)
Definition synth.h:313
virtual bool check_percussion()
Definition synth.h:319
void kill_note(int note, int vel, bool just_one)
Definition synth.cpp:39
std::bitset< 128 > gate
Gate values for all 128 MIDI notes.
Definition synth.h:294
bool hold
Hold pedal state.
Definition synth.h:284
virtual void note_on(int note, int vel)
Definition synth.cpp:102
virtual void pitch_bend(int amt)
amt = -8192 to 8191
Definition synth.h:317
virtual void on_pedal_release()
Definition synth.cpp:130
unsigned int polyphony_limit
Maximum allocated number of channels.
Definition synth.h:296
voice_array unused_voices
Voices allocated, but not used.
Definition synth.h:292
voice_array allocated_voices
All voices available.
Definition synth.h:288
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
ZCONST char * key
Definition crypt.c:587
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263