1 // interface for supercollider plugins
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_PLUGIN_INTERFACE_HPP
20 #define SC_PLUGIN_INTERFACE_HPP
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"
32 #include <boost/scoped_array.hpp>
33 #include <boost/thread/pthread/mutex.hpp>
38 int headerFormatFromString(const char *name
);
39 int sampleFormatFromString(const char* name
);
42 class sc_done_action_handler
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);
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
;
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
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
;
104 audio_bus_manager audio_busses
;
106 int buf_counter(void) const
108 return world
.mBufCounter
;
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
,
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
];
161 boost::scoped_array
<boost::mutex
> async_buffer_guards
;
165 /* copies nrt mirror to rt buffers */
166 void buffer_sync(uint32_t index
);
169 /* control bus handling */
172 void controlbus_set_unchecked(uint32_t bus
, float value
)
174 world
.mControlBus
[bus
] = value
;
175 world
.mControlBusTouched
[bus
] = world
.mBufCounter
;
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
];
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
;
209 for (size_t i
= 0; i
!= remain
; ++i
)
210 r_values
[i
] = world
.mControlBus
[i
];
215 /** synth initialization. called in the beginning of each dsp tick */
216 void initialize_synths(void)
218 if (likely(!synths_to_initialize
))
221 initialize_synths_perform();
224 void schedule_for_preparation(abstract_synth
* synth
)
226 synths_to_initialize
= true;
227 uninitialized_synths
.push_back(synth
);
232 bool synths_to_initialize
;
234 void initialize_synths_perform(void);
235 std::vector
<abstract_synth
*, rt_pool_allocator
<abstract_synth
*> > uninitialized_synths
;
239 } /* namespace nova */
241 #endif /* SC_PLUGIN_INTERFACE_HPP */