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"
36 namespace bi
= boost::intrusive
;
38 struct sc_unitcmd_def
:
39 public named_hash_entry
41 const UnitCmdFunc func
;
43 sc_unitcmd_def(const char * cmd_name
, UnitCmdFunc func
):
44 named_hash_entry(cmd_name
), func(func
)
47 void run(Unit
* unit
, struct sc_msg_iter
*args
)
55 public named_hash_entry
58 const size_t alloc_size
;
59 const UnitCtorFunc ctor
;
60 const UnitDtorFunc dtor
;
63 static const std::size_t unitcmd_set_bucket_count
= 4;
64 typedef bi::unordered_set
< sc_unitcmd_def
,
65 bi::constant_time_size
<false>,
66 bi::power_2_buckets
<true>,
70 unitcmd_set_type::bucket_type unitcmd_set_buckets
[unitcmd_set_bucket_count
];
71 unitcmd_set_type unitcmd_set
;
74 sc_ugen_def(const char *inUnitClassName
, size_t inAllocSize
,
75 UnitCtorFunc inCtor
, UnitDtorFunc inDtor
, uint32 inFlags
):
76 named_hash_entry(inUnitClassName
), alloc_size(inAllocSize
), ctor(inCtor
), dtor(inDtor
), flags(inFlags
),
77 unitcmd_set(unitcmd_set_type::bucket_traits(unitcmd_set_buckets
, unitcmd_set_bucket_count
))
80 Unit
* construct(sc_synthdef::unit_spec_t
const & unit_spec
, sc_synth
* s
, World
* world
, linear_allocator
& allocator
);
82 void initialize(Unit
* unit
)
87 void destruct(Unit
* unit
)
93 bool cant_alias(void) const
95 return flags
& kUnitDef_CantAliasInputsToOutputs
;
98 std::size_t memory_requirement(void) const
103 bool add_command(const char * cmd_name
, UnitCmdFunc func
);
104 void run_unit_command(const char * cmd_name
, Unit
* unit
, struct sc_msg_iter
*args
);
107 struct sc_bufgen_def
:
108 public named_hash_entry
110 const BufGenFunc func
;
112 sc_bufgen_def(const char * name
, BufGenFunc func
):
113 named_hash_entry(name
), func(func
)
116 sample
* run(World
* world
, uint32_t buffer_index
, struct sc_msg_iter
*args
);
119 struct sc_cmdplugin_def
:
120 public named_hash_entry
122 const PlugInCmdFunc func
;
125 sc_cmdplugin_def(const char * name
, PlugInCmdFunc func
, void * user_data
):
126 named_hash_entry(name
), func(func
), user_data(user_data
)
129 void run(World
* world
, struct sc_msg_iter
*args
, void *replyAddr
)
131 (func
)(world
, user_data
, args
, replyAddr
);
135 class sc_plugin_container
137 static const std::size_t ugen_set_bucket_count
= 512;
138 typedef bi::unordered_set
< sc_ugen_def
,
139 bi::constant_time_size
<false>,
140 bi::power_2_buckets
<true>,
144 static const std::size_t bufgen_set_bucket_count
= 64;
145 typedef bi::unordered_set
< sc_bufgen_def
,
146 bi::constant_time_size
<false>,
147 bi::power_2_buckets
<true>,
151 static const std::size_t cmdplugin_set_bucket_count
= 8;
152 typedef bi::unordered_set
< sc_cmdplugin_def
,
153 bi::constant_time_size
<false>,
154 bi::power_2_buckets
<true>,
156 > cmdplugin_set_type
;
158 ugen_set_type::bucket_type ugen_set_buckets
[ugen_set_bucket_count
];
159 ugen_set_type ugen_set
;
161 bufgen_set_type::bucket_type bufgen_set_buckets
[bufgen_set_bucket_count
];
162 bufgen_set_type bufgen_set
;
164 cmdplugin_set_type::bucket_type cmdplugin_set_buckets
[cmdplugin_set_bucket_count
];
165 cmdplugin_set_type cmdplugin_set
;
168 sc_plugin_container (void):
169 ugen_set(ugen_set_type::bucket_traits(ugen_set_buckets
, ugen_set_bucket_count
)),
170 bufgen_set(bufgen_set_type::bucket_traits(bufgen_set_buckets
, bufgen_set_bucket_count
)),
171 cmdplugin_set(cmdplugin_set_type::bucket_traits(cmdplugin_set_buckets
, cmdplugin_set_bucket_count
))
174 ~sc_plugin_container (void)
176 ugen_set
.clear_and_dispose(boost::checked_delete
<sc_ugen_def
>);
177 bufgen_set
.clear_and_dispose(boost::checked_delete
<sc_bufgen_def
>);
178 cmdplugin_set
.clear_and_dispose(boost::checked_delete
<sc_cmdplugin_def
>);
182 void register_ugen(const char *inUnitClassName
, size_t inAllocSize
,
183 UnitCtorFunc inCtor
, UnitDtorFunc inDtor
, uint32 inFlags
);
185 void register_bufgen(const char * name
, BufGenFunc func
);
187 sc_ugen_def
* find_ugen(c_string
const & name
);
189 bool register_ugen_command_function(const char * ugen_name
, const char * cmd_name
, UnitCmdFunc
);
190 bool register_cmd_plugin(const char * cmd_name
, PlugInCmdFunc func
, void * user_data
);
192 sample
* run_bufgen(World
* world
, const char * name
, uint32_t buffer_index
, struct sc_msg_iter
*args
);
193 bool run_cmd_plugin(World
* world
, const char * name
, struct sc_msg_iter
*args
, void *replyAddr
);
196 /** factory class for supercollider ugens
198 * \todo do we need to take care of thread safety? */
199 class sc_ugen_factory
:
200 public sc_plugin_interface
,
201 public sc_plugin_container
204 ~sc_ugen_factory(void)
210 /** ugen count handling */
211 void allocate_ugens(uint32_t count
)
213 ugen_count_
+= count
;
216 void free_ugens(uint32_t count
)
218 ugen_count_
-= count
;
221 uint32_t ugen_count(void) const
227 void load_plugin_folder(boost::filesystem::path
const & path
);
228 void load_plugin(boost::filesystem::path
const & path
);
231 void close_handles(void);
233 uint32_t ugen_count_
;
234 std::vector
<void*> open_handles
;
237 extern sc_ugen_factory
* sc_factory
;
239 } /* namespace nova */
242 #endif /* SC_UGEN_FACTORY_HPP */