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., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, 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;
67 for(std::list
<dsp::voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end(); i
++)
69 if ((*i
)->get_priority() < priority
)
71 priority
= (*i
)->get_priority();
75 if (found
== active_voices
.end())
82 void basic_synth::trim_voices()
84 // count stealable voices
85 unsigned int count
= 0;
86 for(std::list
<dsp::voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end(); i
++)
88 if ((*i
)->get_priority() < 10000)
91 // printf("Count=%d limit=%d\n", count, polyphony_limit);
92 // steal any voices above polyphony limit
93 if (count
> polyphony_limit
) {
94 for (unsigned int i
= 0; i
< count
- polyphony_limit
; i
++)
99 void basic_synth::note_on(int note
, int vel
)
105 bool perc
= check_percussion();
106 dsp::voice
*v
= give_voice();
107 v
->setup(sample_rate
);
109 v
->sostenuto
= false;
111 v
->note_on(note
, vel
);
112 active_voices
.push_back(v
);
114 percussion_note_on(note
, vel
);
118 void basic_synth::note_off(int note
, int vel
)
122 kill_note(note
, vel
, false);
125 #define for_all_voices(iter) for (std::list<dsp::voice *>::iterator iter = active_voices.begin(); iter != active_voices.end(); iter++)
127 void basic_synth::on_pedal_release()
131 int note
= (*i
)->get_current_note();
132 if (note
< 0 || note
> 127)
134 bool still_held
= gate
[note
];
135 // sostenuto pedal released
136 if ((*i
)->sostenuto
&& !sostenuto
)
138 // mark note as non-sostenuto
139 (*i
)->sostenuto
= false;
140 // 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)
141 // if key has been released and hold pedal is not depressed, release the note
142 if (!still_held
&& !hold
)
145 else if (!hold
&& !still_held
&& !(*i
)->released
)
147 (*i
)->released
= true;
153 void basic_synth::control_change(int ctl
, int val
)
155 if (ctl
== 64) { // HOLD controller
158 if (!hold
&& prev
&& !sostenuto
) {
162 if (ctl
== 66) { // SOSTENUTO controller
163 bool prev
= sostenuto
;
164 sostenuto
= (val
>= 64);
165 if (sostenuto
&& !prev
) {
166 // SOSTENUTO was pressed - move all notes onto sustain stack
168 (*i
)->sostenuto
= true;
171 if (!sostenuto
&& prev
) {
172 // SOSTENUTO was released - release all keys which were previously held
176 if (ctl
== 123 || ctl
== 120) { // all notes off, all sounds off
179 if (ctl
== 120) { // for "all sounds off", automatically release hold and sostenuto pedal
180 control_change(66, 0);
181 control_change(64, 0);
189 control_change(1, 0);
190 control_change(7, 100);
191 control_change(10, 64);
192 control_change(11, 127);
193 // release hold..hold2
194 for (int i
= 64; i
<= 69; i
++)
195 control_change(i
, 0);
199 void basic_synth::render_to(float (*output
)[2], int nsamples
)
201 // render voices, eliminate ones that aren't sounding anymore
202 for (list
<dsp::voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end();) {
204 v
->render_to(output
, nsamples
);
205 if (!v
->get_active()) {
206 i
= active_voices
.erase(i
);
207 unused_voices
.push(v
);
214 basic_synth::~basic_synth()
216 while(!unused_voices
.empty()) {
217 delete unused_voices
.top();
220 for (list
<voice
*>::iterator i
= active_voices
.begin(); i
!= active_voices
.end(); i
++)