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