bumping version to 3.5-rc1
[supercollider.git] / server / supernova / sc / sc_plugin_interface.hpp
blobfa47f41c54625d73f98a870a742b74d2f3371fd8
1 // interface for supercollider plugins
2 // Copyright (C) 2009 Tim Blechmann
3 //
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.
8 //
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_PLUGIN_INTERFACE_HPP
20 #define SC_PLUGIN_INTERFACE_HPP
22 #include <vector>
24 #include "../server/audio_bus_manager.hpp"
25 #include "../server/node_types.hpp"
26 #include "../server/synth.hpp"
27 #include "../server/memory_pool.hpp"
29 #include "SC_InterfaceTable.h"
30 #include "SC_World.h"
32 #include <boost/scoped_array.hpp>
33 #include <boost/thread/pthread/mutex.hpp>
35 namespace nova
38 int headerFormatFromString(const char *name);
39 int sampleFormatFromString(const char* name);
42 class sc_done_action_handler
44 public:
45 void add_pause_node(server_node * node)
47 spin_lock::scoped_lock lock(cmd_lock);
48 pause_nodes.push_back(node);
51 void add_resume_node(server_node * node)
53 spin_lock::scoped_lock lock(cmd_lock);
54 resume_nodes.push_back(node);
57 void add_done_node(server_node * node)
59 spin_lock::scoped_lock lock(cmd_lock);
60 done_nodes.push_back(node);
63 void add_freeDeep_node(abstract_group * node)
65 spin_lock::scoped_lock lock(cmd_lock);
66 freeDeep_nodes.push_back(node);
69 void add_freeAll_node(abstract_group * node)
71 spin_lock::scoped_lock lock(cmd_lock);
72 freeAll_nodes.push_back(node);
75 void update_nodegraph(void);
77 protected:
78 typedef rt_pool_allocator<server_node*> server_node_alloc;
79 typedef rt_pool_allocator<abstract_group*> abstract_group_alloc;
80 std::vector<server_node*, server_node_alloc> done_nodes, pause_nodes, resume_nodes;
81 std::vector<abstract_group*, abstract_group_alloc> freeAll_nodes, freeDeep_nodes;
83 private:
84 spin_lock cmd_lock; /* multiple synths can be scheduled for removal, so we need to guard this
85 later we can try different approaches like a lockfree stack or bitmask */
88 class sc_plugin_interface:
89 public sc_done_action_handler
91 public:
92 void initialize(class server_arguments const & args, float * control_busses);
93 void reset_sampling_rate(int sr);
95 sc_plugin_interface(void):
96 synths_to_initialize(false)
99 ~sc_plugin_interface(void);
101 InterfaceTable sc_interface;
102 World world;
104 audio_bus_manager audio_busses;
106 int buf_counter(void) const
108 return world.mBufCounter;
111 /* @{ */
112 /* audio buffer handling */
113 SndBuf* allocate_buffer(uint32_t index, uint32_t frames, uint32_t channels);
114 int allocate_buffer(SndBuf * buf, uint32_t frames, uint32_t channels, double samplerate);
115 int buffer_read_alloc(uint32_t index, const char * filename, uint32_t start, uint32_t frames);
116 int buffer_alloc_read_channels(uint32_t index, const char * filename, uint32_t start, uint32_t frames, uint32_t channel_count,
117 const uint32_t * channel_data);
118 int buffer_read(uint32_t index, const char * filename, uint32_t start_file, uint32_t frames, uint32_t start_buffer,
119 bool leave_open);
120 int buffer_read_channel(uint32_t index, const char * filename, uint32_t start_file, uint32_t frames, uint32_t start_buffer,
121 bool leave_open, uint32_t channel_count, const uint32_t * channel_data);
123 sample * get_nrt_mirror_buffer(uint32_t index)
125 return world.mSndBufsNonRealTimeMirror[index].data;
128 sample * get_buffer(uint32_t index)
130 return world.mSndBufs[index].data;
133 SndBuf * get_buffer_struct(uint32_t index)
135 return world.mSndBufs + index;
138 int buffer_write(uint32_t index, const char * filename, const char * header_format, const char * sample_format,
139 uint32_t start, uint32_t frames, bool leave_open);
141 void buffer_zero(uint32_t index);
142 void buffer_close(uint32_t index);
144 sample * buffer_generate(uint32_t index, const char * cmd_name, struct sc_msg_iter & msg);
146 void increment_write_updates(uint32_t index)
148 world.mSndBufUpdates[index].writes++;
151 void free_buffer(uint32_t index);
153 typedef boost::mutex::scoped_lock buffer_lock_t;
155 boost::mutex & buffer_guard(size_t index)
157 return async_buffer_guards[index];
160 private:
161 boost::scoped_array<boost::mutex> async_buffer_guards;
162 /* @} */
164 public:
165 /* copies nrt mirror to rt buffers */
166 void buffer_sync(uint32_t index);
168 /* @{ */
169 /* control bus handling */
171 private:
172 void controlbus_set_unchecked(uint32_t bus, float value)
174 world.mControlBus[bus] = value;
175 world.mControlBusTouched[bus] = world.mBufCounter;
178 public:
179 void controlbus_set(uint32_t bus, float value)
181 if (bus < world.mNumControlBusChannels)
182 controlbus_set_unchecked(bus, value);
185 void controlbus_fill(uint32_t bus, size_t count, float value)
187 if (bus + count >= world.mNumControlBusChannels)
188 count = world.mNumAudioBusChannels - bus;
190 for (size_t i = 0; i != count; ++i)
191 controlbus_set_unchecked(i, value);
194 sample controlbus_get(uint32_t bus)
196 if (bus < world.mNumControlBusChannels)
197 return world.mControlBus[bus];
198 else
199 return 0.f;
202 void controlbus_getn(uint32_t bus, size_t count, size_t * r_count, float * r_values)
204 size_t remain = count;
205 if (bus + count >= world.mNumControlBusChannels)
206 remain = world.mNumAudioBusChannels - bus;
207 *r_count = remain;
209 for (size_t i = 0; i != remain; ++i)
210 r_values[i] = world.mControlBus[i];
212 /* @}*/
214 /* @{ */
215 /** synth initialization. called in the beginning of each dsp tick */
216 void initialize_synths(void)
218 if (likely(!synths_to_initialize))
219 return; // fast-path
221 initialize_synths_perform();
224 void schedule_for_preparation(abstract_synth * synth)
226 synths_to_initialize = true;
227 uninitialized_synths.push_back(synth);
228 synth->add_ref();
231 private:
232 bool synths_to_initialize;
234 void initialize_synths_perform(void);
235 std::vector<abstract_synth*, rt_pool_allocator<abstract_synth*> > uninitialized_synths;
236 /* @} */
239 } /* namespace nova */
241 #endif /* SC_PLUGIN_INTERFACE_HPP */