1 // prototype of a supercollider-synthdef-based synth prototype
2 // Copyright (C) 2009 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef SC_UGEN_FACTORY_HPP
20 #define SC_UGEN_FACTORY_HPP
22 #include <boost/intrusive/set.hpp>
23 #include <boost/intrusive/unordered_set.hpp>
24 #include <boost/checked_delete.hpp>
26 #include "sc_synthdef.hpp"
27 #include "sc_synth.hpp"
28 #include "sc_plugin_interface.hpp"
30 #include "SC_InterfaceTable.h"
33 #include "utilities/named_hash_entry.hpp"
37 namespace bi
= boost::intrusive
;
39 struct sc_unitcmd_def
:
40 public named_hash_entry
42 const UnitCmdFunc func
;
44 sc_unitcmd_def(const char * cmd_name
, UnitCmdFunc func
):
45 named_hash_entry(cmd_name
), func(func
)
48 void run(Unit
* unit
, struct sc_msg_iter
*args
)
56 public named_hash_entry
59 const size_t alloc_size
;
60 const UnitCtorFunc ctor
;
61 const UnitDtorFunc dtor
;
64 static const std::size_t unitcmd_set_bucket_count
= 4;
65 typedef bi::unordered_set
< sc_unitcmd_def
,
66 bi::constant_time_size
<false>,
67 bi::power_2_buckets
<true>,
71 unitcmd_set_type::bucket_type unitcmd_set_buckets
[unitcmd_set_bucket_count
];
72 unitcmd_set_type unitcmd_set
;
75 sc_ugen_def(const char *inUnitClassName
, size_t inAllocSize
,
76 UnitCtorFunc inCtor
, UnitDtorFunc inDtor
, uint32 inFlags
):
77 named_hash_entry(inUnitClassName
), alloc_size(inAllocSize
), ctor(inCtor
), dtor(inDtor
), flags(inFlags
),
78 unitcmd_set(unitcmd_set_type::bucket_traits(unitcmd_set_buckets
, unitcmd_set_bucket_count
))
81 Unit
* construct(sc_synthdef::unit_spec_t
const & unit_spec
, sc_synth
* s
, World
* world
, char *& chunk
);
83 void initialize(Unit
* unit
)
88 void destruct(Unit
* unit
)
94 bool cant_alias(void) const
96 return flags
& kUnitDef_CantAliasInputsToOutputs
;
99 std::size_t memory_requirement(void) const
104 bool add_command(const char * cmd_name
, UnitCmdFunc func
);
105 void run_unit_command(const char * cmd_name
, Unit
* unit
, struct sc_msg_iter
*args
);
108 struct sc_bufgen_def
:
109 public named_hash_entry
111 const BufGenFunc func
;
113 sc_bufgen_def(const char * name
, BufGenFunc func
):
114 named_hash_entry(name
), func(func
)
117 sample
* run(World
* world
, uint32_t buffer_index
, struct sc_msg_iter
*args
);
120 struct sc_cmdplugin_def
:
121 public named_hash_entry
123 const PlugInCmdFunc func
;
126 sc_cmdplugin_def(const char * name
, PlugInCmdFunc func
, void * user_data
):
127 named_hash_entry(name
), func(func
), user_data(user_data
)
130 void run(World
* world
, struct sc_msg_iter
*args
, void *replyAddr
)
132 (func
)(world
, user_data
, args
, replyAddr
);
136 class sc_plugin_container
138 static const std::size_t ugen_set_bucket_count
= 512;
139 typedef bi::unordered_set
< sc_ugen_def
,
140 bi::constant_time_size
<false>,
141 bi::power_2_buckets
<true>,
145 static const std::size_t bufgen_set_bucket_count
= 64;
146 typedef bi::unordered_set
< sc_bufgen_def
,
147 bi::constant_time_size
<false>,
148 bi::power_2_buckets
<true>,
152 static const std::size_t cmdplugin_set_bucket_count
= 8;
153 typedef bi::unordered_set
< sc_cmdplugin_def
,
154 bi::constant_time_size
<false>,
155 bi::power_2_buckets
<true>,
157 > cmdplugin_set_type
;
159 ugen_set_type::bucket_type ugen_set_buckets
[ugen_set_bucket_count
];
160 ugen_set_type ugen_set
;
162 bufgen_set_type::bucket_type bufgen_set_buckets
[bufgen_set_bucket_count
];
163 bufgen_set_type bufgen_set
;
165 cmdplugin_set_type::bucket_type cmdplugin_set_buckets
[cmdplugin_set_bucket_count
];
166 cmdplugin_set_type cmdplugin_set
;
169 sc_plugin_container (void):
170 ugen_set(ugen_set_type::bucket_traits(ugen_set_buckets
, ugen_set_bucket_count
)),
171 bufgen_set(bufgen_set_type::bucket_traits(bufgen_set_buckets
, bufgen_set_bucket_count
)),
172 cmdplugin_set(cmdplugin_set_type::bucket_traits(cmdplugin_set_buckets
, cmdplugin_set_bucket_count
))
175 ~sc_plugin_container (void)
177 ugen_set
.clear_and_dispose(boost::checked_delete
<sc_ugen_def
>);
178 bufgen_set
.clear_and_dispose(boost::checked_delete
<sc_bufgen_def
>);
179 cmdplugin_set
.clear_and_dispose(boost::checked_delete
<sc_cmdplugin_def
>);
183 void register_ugen(const char *inUnitClassName
, size_t inAllocSize
,
184 UnitCtorFunc inCtor
, UnitDtorFunc inDtor
, uint32 inFlags
);
186 void register_bufgen(const char * name
, BufGenFunc func
);
188 sc_ugen_def
* find_ugen(c_string
const & name
);
190 bool register_ugen_command_function(const char * ugen_name
, const char * cmd_name
, UnitCmdFunc
);
191 bool register_cmd_plugin(const char * cmd_name
, PlugInCmdFunc func
, void * user_data
);
193 sample
* run_bufgen(World
* world
, const char * name
, uint32_t buffer_index
, struct sc_msg_iter
*args
);
194 bool run_cmd_plugin(World
* world
, const char * name
, struct sc_msg_iter
*args
, void *replyAddr
);
197 /** factory class for supercollider ugens
199 * \todo do we need to take care of thread safety? */
200 class sc_ugen_factory
:
201 public sc_plugin_interface
,
202 public sc_plugin_container
205 ~sc_ugen_factory(void)
211 /** ugen count handling */
212 void allocate_ugens(uint32_t count
)
214 ugen_count_
+= count
;
217 void free_ugens(uint32_t count
)
219 ugen_count_
-= count
;
222 uint32_t ugen_count(void) const
228 void load_plugin_folder(boost::filesystem::path
const & path
);
229 void load_plugin(boost::filesystem::path
const & path
);
232 void close_handles(void);
234 uint32_t ugen_count_
;
235 std::vector
<void*> open_handles
;
238 extern sc_ugen_factory
* sc_factory
;
240 } /* namespace nova */
243 #endif /* SC_UGEN_FACTORY_HPP */