2 * Generic polyphonic synthesizer framework.
4 * Copyright (C) 2007 Krzysztof Foltman
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.
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.
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 02110-1301 USA
25 #include <jack/jack.h>
27 #include <calf/giface.h>
28 #include <calf/synth.h>
33 void basic_synth::kill_note(int note
, int vel
, bool just_one
)
35 for (list
<dsp::voice
*>::iterator it
= active_voices
.begin(); it
!= active_voices
.end(); it
++) {
36 // preserve sostenuto notes
37 if ((*it
)->get_current_note() == note
&& !(sostenuto
&& (*it
)->sostenuto
)) {
45 dsp::voice
*basic_synth::give_voice()
47 if (active_voices
.size() >= polyphony_limit
)
49 dsp::voice
*stolen
= steal_voice();
53 if (unused_voices
.empty())
56 dsp::voice
*v
= unused_voices
.top();
63 dsp::voice
*basic_synth::steal_voice()
65 std::list
<dsp::voice
*>::iterator found
= active_voices
.end();
66 float priority
= 10000;
68 for(std::list
<dsp::voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end(); i
++)
70 //printf("Voice %d priority %f at %p\n", idx++, (*i)->get_priority(), *i);
71 if ((*i
)->get_priority() < priority
)
73 priority
= (*i
)->get_priority();
77 //printf("Found: %p\n\n", *found);
78 if (found
== active_voices
.end())
85 void basic_synth::trim_voices()
87 // count stealable voices
88 unsigned int count
= 0;
89 for(std::list
<dsp::voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end(); i
++)
91 if ((*i
)->get_priority() < 10000)
94 // printf("Count=%d limit=%d\n", count, polyphony_limit);
95 // steal any voices above polyphony limit
96 if (count
> polyphony_limit
) {
97 for (unsigned int i
= 0; i
< count
- polyphony_limit
; i
++)
102 void basic_synth::note_on(int note
, int vel
)
108 bool perc
= check_percussion();
109 dsp::voice
*v
= give_voice();
110 v
->setup(sample_rate
);
112 v
->sostenuto
= false;
114 v
->note_on(note
, vel
);
115 active_voices
.push_back(v
);
117 percussion_note_on(note
, vel
);
121 void basic_synth::note_off(int note
, int vel
)
125 kill_note(note
, vel
, false);
128 #define for_all_voices(iter) for (std::list<dsp::voice *>::iterator iter = active_voices.begin(); iter != active_voices.end(); iter++)
130 void basic_synth::on_pedal_release()
134 int note
= (*i
)->get_current_note();
135 if (note
< 0 || note
> 127)
137 bool still_held
= gate
[note
];
138 // sostenuto pedal released
139 if ((*i
)->sostenuto
&& !sostenuto
)
141 // mark note as non-sostenuto
142 (*i
)->sostenuto
= false;
143 // if key still pressed or hold pedal used, hold the note (as non-sostenuto so it can be released later by releasing the key or pedal)
144 // if key has been released and hold pedal is not depressed, release the note
145 if (!still_held
&& !hold
)
148 else if (!hold
&& !still_held
&& !(*i
)->released
)
150 (*i
)->released
= true;
156 void basic_synth::control_change(int ctl
, int val
)
158 if (ctl
== 64) { // HOLD controller
161 if (!hold
&& prev
&& !sostenuto
) {
165 if (ctl
== 66) { // SOSTENUTO controller
166 bool prev
= sostenuto
;
167 sostenuto
= (val
>= 64);
168 if (sostenuto
&& !prev
) {
169 // SOSTENUTO was pressed - move all notes onto sustain stack
171 (*i
)->sostenuto
= true;
174 if (!sostenuto
&& prev
) {
175 // SOSTENUTO was released - release all keys which were previously held
179 if (ctl
== 123 || ctl
== 120) { // all notes off, all sounds off
182 if (ctl
== 120) { // for "all sounds off", automatically release hold and sostenuto pedal
183 control_change(66, 0);
184 control_change(64, 0);
195 control_change(1, 0);
196 control_change(7, 100);
197 control_change(10, 64);
198 control_change(11, 127);
199 // release hold..hold2
200 for (int i
= 64; i
<= 69; i
++)
201 control_change(i
, 0);
205 void basic_synth::render_to(float (*output
)[2], int nsamples
)
207 // render voices, eliminate ones that aren't sounding anymore
208 for (list
<dsp::voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end();) {
210 v
->render_to(output
, nsamples
);
211 if (!v
->get_active()) {
212 i
= active_voices
.erase(i
);
213 unused_voices
.push(v
);
220 basic_synth::~basic_synth()
222 while(!unused_voices
.empty()) {
223 delete unused_voices
.top();
226 for (list
<voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end(); i
++)