Beast - Music Synthesizer and Composer  0.11.1+10.g2da35
bsecxxmodule.hh
Go to the documentation of this file.
1  // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
2 #ifndef __BSE_CXX_MODULE_H__
3 #define __BSE_CXX_MODULE_H__
4 
5 #include <bse/bsecxxbase.hh>
6 #include <bse/bseieee754.hh>
7 #include <bse/bseengine.hh>
8 
9 namespace Bse {
10 
11 /* enums/structures mirrored from bseengine.hh */
12 enum ProcessCost {
13  NORMAL,
14  CHEAP,
15  EXPENSIVE
16 };
17 struct JStream {
18  const float **values;
19  uint n_connections;
20  /* private: */
21  uint jcount; /* reserved */
22 };
23 struct IStream {
24  const float *values;
25  gboolean connected;
26 };
27 struct OStream {
28  float *values;
29  gboolean connected;
30 };
31 
32 class Effect;
33 
35  template<class T, typename P> class ClosureP1; /* 1-argument member function closure */
36  BseModule *intern_module;
37 public:
38  explicit SynthesisModule ();
39  virtual ~SynthesisModule () = 0;
40  virtual void reset () = 0;
41  virtual void process (uint n_values) = 0;
42  virtual const ProcessCost cost ();
43  inline const IStream& istream (uint istream_index) const;
44  inline const JStream& jstream (uint jstream_index) const;
45  inline const OStream& ostream (uint ostream_index) const;
46  void ostream_set (uint ostream_index,
47  const float *values);
48  const float* const_values (float value);
49  inline const uint mix_freq () const;
50  inline const uint block_size () const;
51  inline guint64 tick_stamp ();
52  inline BseModule* engine_module ();
53  static inline int dtoi (double d) { return bse_dtoi (d); }
54  static inline int ftoi (float f) { return bse_ftoi (f); }
55  /* member functions and closures */
56  struct Closure {
57  virtual void operator() (SynthesisModule*) = 0;
58  virtual ~Closure () {}
59  };
60  /* create a 1-argument member function closure, where C must be derived from SynthesisModule */
61  template<class D, class C>
62  static Closure* make_closure (void (C::*method) (D*),
63  const D &data);
64  /* internal */
65  void set_module (BseModule *module);
66  /* auto_update() trampoline */
67 public:
68  typedef void (*AutoUpdate) (BseModule*, gpointer);
69  struct AutoUpdateData {
70  guint prop_id;
71  double prop_value;
72  /* required by back propagation */
73  guint64 tick_stamp;
74  GParamSpec *pspec;
75  Effect *effect;
76  };
77  struct NeedAutoUpdateTag {};
78 public:
79  template<class M, class P, class C> struct Trampoline {
80  static void auto_update_accessor (BseModule*, gpointer);
81  };
82  /* partial trampoline specializations */
83  template<class M, class P> struct Trampoline<M,P,NeedAutoUpdateTag> {
84  static void auto_update_accessor (BseModule*, gpointer);
85  };
86  template<class M, class P> struct Trampoline<M,P,void> {
87  static void auto_update_accessor (BseModule*, gpointer);
88  };
89 };
90 
91 #define BSE_TYPE_EFFECT (BSE_CXX_TYPE_GET_REGISTERED (Bse, Effect))
92 class EffectBase : public CxxBase {};
93 class Effect : public EffectBase {
94 private:
95  guint64 last_module_update;
96 public:
97  /* BseObject functionality */
98  explicit Effect ();
99  void set_property (guint prop_id,
100  const Value &value,
101  GParamSpec *pspec);
102  void get_property (guint prop_id,
103  Value &value,
104  GParamSpec *pspec);
105  /* BseSource accessors */
106  bool is_prepared() const { return BSE_SOURCE_PREPARED (gobject()); }
107  guint n_ichannels() const { return BSE_SOURCE_N_ICHANNELS (gobject()); }
108  guint n_joint_ichannels() const { return BSE_SOURCE_N_JOINT_ICHANNELS (gobject()); }
109  guint n_ochannels() const { return BSE_SOURCE_N_OCHANNELS (gobject()); }
110  bool is_joint_ichannel (guint i) const { return BSE_SOURCE_IS_JOINT_ICHANNEL (gobject(), i); }
111  guint ichannels_istream (guint i) const { return BSE_SOURCE_ICHANNEL_ISTREAM (gobject(), i); }
112  guint ichannels_jstream (guint i) const { return BSE_SOURCE_ICHANNEL_JSTREAM (gobject(), i); }
113  guint ochannels_ostream (guint i) const { return BSE_SOURCE_OCHANNEL_OSTREAM (gobject(), i); }
114  const gchar* ichannel_ident (guint i) const { return BSE_SOURCE_ICHANNEL_IDENT (gobject(), i); }
115  const gchar* ichannel_label (guint i) const { return BSE_SOURCE_ICHANNEL_LABEL (gobject(), i); }
116  const gchar* ichannel_blurb (guint i) const { return BSE_SOURCE_ICHANNEL_BLURB (gobject(), i); }
117  const gchar* ochannel_ident (guint i) const { return BSE_SOURCE_OCHANNEL_IDENT (gobject(), i); }
118  const gchar* ochannel_label (guint i) const { return BSE_SOURCE_OCHANNEL_LABEL (gobject(), i); }
119  const gchar* ochannel_blurb (guint i) const { return BSE_SOURCE_OCHANNEL_BLURB (gobject(), i); }
120  virtual SynthesisModule* create_module (uint context_handle,
121  BseTrans *trans) = 0;
122  virtual SynthesisModule::
123  Closure* make_module_config_closure () = 0;
124  virtual SynthesisModule::
125  AutoUpdate get_module_auto_update () = 0;
126  void update_modules (BseTrans *trans = NULL);
127  guint64 module_update_tick_stamp () { return last_module_update; }
128  /* prepare & dismiss pre and post invocation hooks */
129  virtual void prepare1() { /* override this to do something before parent class prepare */ }
130  virtual void prepare2() { /* override this to do something after parent class prepare */ }
131  virtual void reset1() { /* override this to do something before parent class dismiss */ }
132  virtual void reset2() { /* override this to do something after parent class dismiss */ }
133 
134  static void class_init (CxxBaseClass *klass);
135 protected:
136  const BseModuleClass* create_engine_class (SynthesisModule *sample_module,
137  int cost = -1,
138  int n_istreams = -1,
139  int n_jstreams = -1,
140  int n_ostreams = -1);
141  virtual BseModule* integrate_engine_module (uint context_handle,
142  BseTrans *trans);
143  virtual void dismiss_engine_module (BseModule *engine_module,
144  guint context_handle,
145  BseTrans *trans);
146  uint block_size () const;
147  uint max_block_size () const;
148 public: /* FIXME: make this protected as soon as the modules have their own current_musical_tuning() accessor */
149  Bse::MusicalTuning current_musical_tuning () const;
150 };
151 /* implement Bse::Effect and Bse::SynthesisModule methods */
152 #define BSE_EFFECT_INTEGRATE_MODULE(ObjectType,ModuleType,ParamType) \
153 Bse::SynthesisModule* \
154 create_module (uint context_handle, \
155  BseTrans *trans) \
156 { \
157  /* check that 'this' is a ObjectType* */ \
158  (void) const_cast<ObjectType*> (this); \
159  /* create a synthesis module */ \
160  return new ModuleType(); \
161 } \
162 Bse::SynthesisModule::Closure* \
163 make_module_config_closure() \
164 { \
165  return SynthesisModule::make_closure (&ModuleType::config, ParamType (this)); \
166 } \
167 Bse::SynthesisModule::AutoUpdate \
168 get_module_auto_update() \
169 { \
170  return SynthesisModule::Trampoline<ModuleType,ParamType, \
171  ObjectType::AutoUpdateCategory>::auto_update_accessor; \
172 }
173 template<class M, class P>
174 void
176 auto_update_accessor (BseModule *bmodule, /* Engine Thread */
177  gpointer data)
178 {
179  M *m = static_cast<M*> (BSE_MODULE_GET_USER_DATA (bmodule));
180  AutoUpdateData *au = static_cast<AutoUpdateData*> (data);
181  typename P::IDType prop_id = static_cast<typename P::IDType> (au->prop_id);
182  if (0) // check M::auto_update() member and prototype
183  (void) static_cast<void (M::*) (typename P::IDType, double)> (&M::auto_update);
184  m->auto_update (prop_id, au->prop_value);
185 }
186 template<class M, class P>
187 void
189 auto_update_accessor (BseModule *bmodule,
190  gpointer data)
191 {
192 }
193 
194 
195 /* --- implementation details --- */
196 inline BseModule*
197 SynthesisModule::engine_module ()
198 {
199  return intern_module;
200 }
201 inline const uint
202 SynthesisModule::mix_freq () const
203 {
204  return bse_engine_sample_freq();
205 }
206 inline const uint
207 SynthesisModule::block_size () const
208 {
209  return bse_engine_block_size();
210 }
211 inline guint64
212 SynthesisModule::tick_stamp ()
213 {
214  return bse_module_tick_stamp (engine_module());
215 }
216 inline const IStream&
217 SynthesisModule::istream (uint istream_index) const
218 {
219  void *istreams = BSE_MODULE_GET_ISTREAMSP (intern_module);
220  return reinterpret_cast<IStream*> (istreams)[istream_index];
221 }
222 inline const JStream&
223 SynthesisModule::jstream (uint jstream_index) const
224 {
225  void *jstreams = BSE_MODULE_GET_JSTREAMSP (intern_module);
226  return reinterpret_cast<JStream*> (jstreams)[jstream_index];
227 }
228 inline const OStream&
229 SynthesisModule::ostream (uint ostream_index) const
230 {
231  void *ostreams = BSE_MODULE_GET_OSTREAMSP (intern_module);
232  return reinterpret_cast<OStream*> (ostreams)[ostream_index];
233 }
234 template<class T, typename P>
235 class SynthesisModule::ClosureP1 : public SynthesisModule::Closure {
236  typedef void (T::*Member) (P*);
237  Member func;
238  P *data;
239 public:
240  ClosureP1 (void (T::*f) (P*), P *p)
241  : func (f), data (p)
242  {
243  assert_derived_from<T,SynthesisModule>();
244  }
245  void operator() (SynthesisModule *p)
246  {
247  T *t = static_cast<T*> (p);
248  (t->*func) (data);
249  }
250  ~ClosureP1 ()
251  {
252  delete data;
253  }
254 };
255 template<class D, class C> SynthesisModule::Closure*
256 SynthesisModule::make_closure (void (C::*method) (D*),
257  const D &data)
258 {
259  D *d = new D (data);
260  ClosureP1<C,D> *ac = new ClosureP1<C,D> (method, d);
261  return ac;
262 }
263 
264 } // Bse
265 
266 #endif /* __BSE_CXX_MODULE_H__ */
Definition: bsecxxmodule.hh:69
The Bse namespace contains all functions of the synthesis engine.
Definition: bstbseutils.cc:91
Definition: bsecxxmodule.hh:27
Definition: bsecxxmodule.hh:77
Definition: bsecxxvalue.hh:13
Definition: bsecxxmodule.hh:17
Definition: bsecxxmodule.hh:34
Definition: bsecxxmodule.hh:92
Definition: bsecxxbase.hh:43
guint64 bse_module_tick_stamp(BseModule *module)
Definition: bseengine.cc:86
Definition: bsecxxmodule.hh:23
Definition: bsecxxmodule.hh:56
Definition: bsecxxmodule.hh:79
Definition: bsecxxmodule.hh:93
Definition: bsecxxbase.hh:14