Guitarix
Loading...
Searching...
No Matches
gx_modulesequencer.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3 * Copyright (C) 2011 Pete Shorthose
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * --------------------------------------------------------------------------
19 */
20
21#pragma once
22
23namespace gx_engine {
24
25/****************************************************************
26 ** class ModuleSelector
27 */
28
30protected:
32public:
34 : seq(seq_) {}
35 virtual ~ModuleSelector() {}
36 virtual void set_module() = 0;
37};
38
39
40/****************************************************************
41 ** class ProcessingChainBase
42 ** members and methods accessed by the rt thread are marked RT
43 */
44
46public:
48private:
49 sem_t sync_sem; // RT
50 list<Plugin*> to_release;
51 int ramp_value; // RT
52 int ramp_mode; // RT should be RampMode, but gcc 4.5 doesn't accept it for g_atomic_int_compare_and_exchange
53 volatile bool stopped;
54protected:
55 int steps_up; // RT; >= 1
56 int steps_up_dead; // RT; >= 0
57 int steps_down; // RT; >= 1
58 list<Plugin*> modules;
59 inline void set_ramp_value(int n) { gx_system::atomic_set(&ramp_value, n); } // RT
61 void try_set_ramp_mode(RampMode oldmode, RampMode newmode, int oldrv, int newrv); // RT
62public:
66 return static_cast<RampMode>(gx_system::atomic_get(ramp_mode)); // RT
67 }
68 inline int get_ramp_value() { return gx_system::atomic_get(ramp_value); } // RT
69 void set_samplerate(int samplerate);
70 bool set_plugin_list(const list<Plugin*> &p);
72 inline void post_rt_finished() { // RT
73 int val;
74 sem_getvalue(&sync_sem, &val);
75 if (val == 0) {
76 sem_post(&sync_sem);
77 }
78 }
80 void set_latch();
82 void sync() { set_latch(); wait_latch(); }
83 inline bool check_release() { return !to_release.empty(); }
84 void release();
85#ifdef GUITARIX_AS_PLUGIN
86 void process_ramp(int count);
87#endif
92 inline bool is_down_dead() { return get_ramp_mode() == ramp_mode_down_dead; }
93 void set_stopped(bool v);
94 bool is_stopped() { return stopped; }
95#ifndef NDEBUG
96 void print_chain_state(const char *title);
97#endif
98};
99
100
101/****************************************************************
102 ** template class ThreadSafeChainPointer
103 ** members and methods accessed by the rt thread are marked RT
104 */
105
106template <class F>
108private:
109 F *rack_order_ptr[2]; // RT
110 int size[2];
113 void setsize(int n);
114 inline F get_audio(PluginDef *p);
115protected:
118public:
121 inline void empty_chain(ParamMap& pmap) {
122 list<Plugin*> p;
123 if (set_plugin_list(p)) {
124 commit(true, pmap);
125 }
126 }
127 void commit(bool clear, ParamMap& pmap);
128};
129
130typedef void (*monochainorder)(int count, float *output, float *output1,
131 PluginDef *plugin);
132typedef void (*stereochainorder)(int count, float* input, float* input1,
133 float *output, float *output1, PluginDef *plugin);
134
141
148
149template <>
154
155template <>
160
161template <class F>
163 rack_order_ptr(),
164 size(),
165 current_index(0),
166 current_pointer(),
167 processing_pointer() {
168 setsize(1);
169 current_pointer[0].func = 0;
171 current_index = 1;
173}
174
175template <class F>
177 delete[] rack_order_ptr[0];
178 delete[] rack_order_ptr[1];
179}
180
181template <class F>
183{
184 if (n <= size[current_index]) {
185 return;
186 }
187 delete[] rack_order_ptr[current_index];
188 rack_order_ptr[current_index] = new F[n];
189 size[current_index] = n;
190 current_pointer = rack_order_ptr[current_index];
191}
192
193template <class F>
195 setsize(modules.size()+1); // leave one slot for 0 marker
196 int active_counter = 0;
197 for (list<Plugin*>::const_iterator p = modules.begin(); p != modules.end(); p++) {
198 PluginDef* pd = (*p)->get_pdef();
199 if (pd->activate_plugin) {
200 if (pd->activate_plugin(true, pd) != 0) {
201 (*p)->set_on_off(false);
202 continue;
203 }
204 } else if (pd->clear_state && clear) {
205 pd->clear_state(pd);
206 }
207 F f = get_audio(pd);
208 assert(f.func);
209 current_pointer[active_counter++] = f;
210 }
211 current_pointer[active_counter].func = 0;
212 gx_system::atomic_set(&processing_pointer, current_pointer);
213 set_latch();
214 current_index = (current_index+1) % 2;
215 current_pointer = rack_order_ptr[current_index];
216}
217
218/****************************************************************
219 ** class MonoModuleChain, class StereoModuleChain
220 */
221
222class MonoModuleChain: public ThreadSafeChainPointer<monochain_data> {
223public:
225 void process(int count, float *input, float *output);
226 inline void print() { printlist("Mono", modules); }
227};
228
229class StereoModuleChain: public ThreadSafeChainPointer<stereochain_data> {
230public:
232#ifndef GUITARIX_AS_PLUGIN
233 void process(int count, float *input1, float *input2, float *output1, float *output2);
234#else
235 void process(int count, float *input1, float *input2, float *output1, float *output2, bool feed=true);
236#endif
237 inline void print() { printlist("Stereo", modules); }
238};
239
240
241/****************************************************************
242 ** class EngineControl
243 */
244
246protected:
247 list<ModuleSelector*> selectors; // selectors that modify the on/off state of
248 // modules at start of reconfiguration
249 sigc::connection rack_changed; // idle signal for reconfiguration of module chains
251 int policy; // jack realtime policy,
252 int priority; // and priority, for internal modules
253 // signal anyone who needs to be synchronously notified
254 // BE CAREFUL: executed by RT thread (though not concurrent with audio
255 // modules, and timing requirements are relaxed)
256 sigc::signal<void, unsigned int> buffersize_change;
257 sigc::signal<void, unsigned int> samplerate_change;
258 unsigned int buffersize;
259 unsigned int samplerate;
260public:
261 enum OverloadType { // type of overload condition
262 ov_User = 0x1, // idle thread probe starved
263 ov_Convolver = 0x2, // convolver overload
264 ov_XRun = 0x4, // jack audio loop overload
265 ov_NoWarn = 0x8 // disable overlaod warning
266 };
270 void init(unsigned int samplerate, unsigned int buffersize,
271 int policy, int priority);
272 virtual void wait_ramp_down_finished() = 0;
273 virtual bool update_module_lists() = 0;
274 virtual void start_ramp_up() = 0;
275 virtual void start_ramp_down() = 0;
276 virtual void overload(OverloadType tp, const char *reason) = 0; // RT
277 void set_samplerate(unsigned int samplerate_);
278 unsigned int get_samplerate() { return samplerate; }
279 void set_buffersize(unsigned int buffersize_);
280 unsigned int get_buffersize() { return buffersize; }
281 virtual void set_rack_changed() = 0;
284 sigc::signal<void, unsigned int>& signal_buffersize_change() { return buffersize_change; }
285 sigc::signal<void, unsigned int>& signal_samplerate_change() { return samplerate_change; }
288 void get_sched_priority(int &policy, int &priority, int prio_dim = 0);
289 ParamMap& get_param() { return pmap; }
290#ifdef GUITARIX_AS_PLUGIN
291 virtual sigc::signal<bool ()>& signal_timeout()=0;
292#endif
293};
294
295
296/****************************************************************
297 ** class ModuleSequencer
298 */
299
300enum GxEngineState { // engine states set by user (ModuleSequencer set_state/get_state)
301 kEngineOff = 0, // mute, no output (but tuner or something might run)
302 kEngineOn = 1, // normal operation
303 kEngineBypass = 2 // just some balance or level control
305
306
308protected:
309 int audio_mode; // GxEngineState coded as PGN_MODE_XX flags
310 boost::mutex stateflags_mutex;
312 sigc::signal<void, GxEngineState> state_change;
313 Glib::Dispatcher overload_detected;
314 const char *overload_reason; // name of unit which detected overload
315 int ov_disabled; // bitmask of OverloadType
316 static int sporadic_interval; // seconds; overload if at least 2 events in the timespan
317#ifdef GUITARIX_AS_PLUGIN
318 sigc::signal<bool ()> _signal_timeout;
319 sigc::connection clearoverride_conn;
320#endif
321protected:
323public:
324 MonoModuleChain mono_chain; // active modules (amp chain, input to insert output)
325 StereoModuleChain stereo_chain; // active stereo modules (effect chain, after insert input)
326 enum StateFlag { // engine is off if one of these flags is set
327 SF_NO_CONNECTION = 0x01, // no jack connection at amp input
328 SF_JACK_RECONFIG = 0x02, // jack buffersize reconfiguration in progress
329 SF_INITIALIZING = 0x04, // jack or engine not ready
330 SF_OVERLOAD = 0x08, // engine overload
331 };
332public:
339 virtual void set_samplerate(unsigned int samplerate);
340 virtual void start_ramp_up();
341 virtual void start_ramp_down();
353 virtual void set_rack_changed();
354 virtual bool update_module_lists();
356 virtual void overload(OverloadType tp, const char *reason); // RT
357 void set_stateflag(StateFlag flag); // RT
358 void clear_stateflag(StateFlag flag); // RT
361 sigc::signal<void, GxEngineState>& signal_state_change() { return state_change; }
362 static void set_overload_interval(int i) { sporadic_interval = i; }
363#ifdef GUITARIX_AS_PLUGIN
364 sigc::signal<bool ()>& signal_timeout() override { return _signal_timeout; }
365#endif
366#ifndef NDEBUG
368#endif
369};
370
371} /* end of gx_engine namespace */
virtual void overload(OverloadType tp, const char *reason)=0
void get_sched_priority(int &policy, int &priority, int prio_dim=0)
void add_selector(ModuleSelector &sel)
sigc::signal< void, unsigned int > & signal_buffersize_change()
void init(unsigned int samplerate, unsigned int buffersize, int policy, int priority)
list< ModuleSelector * > selectors
sigc::signal< void, unsigned int > & signal_samplerate_change()
void registerParameter(ParameterGroups &groups)
virtual bool update_module_lists()=0
virtual void set_rack_changed()=0
void set_buffersize(unsigned int buffersize_)
virtual void wait_ramp_down_finished()=0
sigc::signal< void, unsigned int > samplerate_change
virtual void start_ramp_down()=0
sigc::signal< void, unsigned int > buffersize_change
void set_samplerate(unsigned int samplerate_)
virtual void start_ramp_up()=0
ModuleSelector(EngineControl &seq_)
virtual void set_module()=0
virtual void overload(OverloadType tp, const char *reason)
sigc::signal< void, GxEngineState > state_change
virtual void set_samplerate(unsigned int samplerate)
virtual void start_ramp_up()
virtual void start_ramp_down()
GxEngineState get_state()
virtual void set_rack_changed()
void set_stateflag(StateFlag flag)
sigc::signal< void, GxEngineState > & signal_state_change()
void set_state(GxEngineState state)
void clear_stateflag(StateFlag flag)
static void set_overload_interval(int i)
virtual void wait_ramp_down_finished()
virtual bool update_module_lists()
void process(int count, float *input, float *output)
void set_samplerate(int samplerate)
void try_set_ramp_mode(RampMode oldmode, RampMode newmode, int oldrv, int newrv)
void print_chain_state(const char *title)
bool set_plugin_list(const list< Plugin * > &p)
void process(int count, float *input1, float *input2, float *output1, float *output2)
void commit(bool clear, ParamMap &pmap)
void printlist(const char *title, const list< Plugin * > &modules, bool header=true)
void(* monochainorder)(int count, float *output, float *output1, PluginDef *plugin)
void(* stereochainorder)(int count, float *input, float *input1, float *output, float *output1, PluginDef *plugin)
int atomic_get(volatile int &p)
Definition gx_system.h:98
void atomic_set(volatile int *p, int v)
Definition gx_system.h:90
clearstatefunc clear_state
Definition gx_plugin.h:216
process_mono_audio mono_audio
Definition gx_plugin.h:209
process_stereo_audio stereo_audio
Definition gx_plugin.h:210
activatefunc activate_plugin
Definition gx_plugin.h:213
monochain_data(monochainorder func_, PluginDef *plugin_)
stereochain_data(stereochainorder func_, PluginDef *plugin_)