scide: implement selectionLength for openDocument
[supercollider.git] / server / supernova / sc / sc_synth.hpp
blob68f83d66d7e0b8da05d1a2addc0db1b538329751
1 // synth based on supercollider-style synthdef
2 // Copyright (C) 2009, 2010 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.
20 #ifndef SC_SYNTH_HPP
21 #define SC_SYNTH_HPP
23 #include "SC_Unit.h"
24 #include "SC_Graph.h"
25 #include "SC_Rate.h"
26 #include "SC_RGen.h"
27 #include "SC_Wire.h"
29 #include "sc_synth_prototype.hpp"
31 #include "../server/synth.hpp"
32 #include "../server/memory_pool.hpp"
34 namespace nova
37 class sc_synth:
38 public abstract_synth,
39 public Graph
41 typedef std::vector<struct Unit*, rt_pool_allocator<void*> > unit_vector;
42 typedef sc_synthdef::graph_t graph_t;
44 friend class sc_synth_prototype;
46 public:
47 sc_synth(int node_id, sc_synth_prototype_ptr const & prototype);
49 ~sc_synth(void);
51 /** run ugen constructors and initialize first sample
53 * to be executed after preparing the synth and setting the controls
55 void prepare(void);
57 inline void perform(void)
59 if (likely(trace == 0))
61 size_t count = calc_unit_count;
62 Unit ** units = calc_units;
64 size_t preroll = count & 7;
66 for (size_t i = 0; i != preroll; ++i)
68 Unit * unit = units[i];
69 (unit->mCalcFunc)(unit, unit->mBufLength);
72 size_t unroll = count >> 3;
73 if (unroll == 0)
74 return;
76 units += preroll;
78 for (size_t i = 0; i != unroll; ++i)
80 Unit * unit = units[0];
81 (unit->mCalcFunc)(unit, unit->mBufLength);
82 unit = units[1];
83 (unit->mCalcFunc)(unit, unit->mBufLength);
84 unit = units[2];
85 (unit->mCalcFunc)(unit, unit->mBufLength);
86 unit = units[3];
87 (unit->mCalcFunc)(unit, unit->mBufLength);
88 unit = units[4];
89 (unit->mCalcFunc)(unit, unit->mBufLength);
90 unit = units[5];
91 (unit->mCalcFunc)(unit, unit->mBufLength);
92 unit = units[6];
93 (unit->mCalcFunc)(unit, unit->mBufLength);
94 unit = units[7];
95 (unit->mCalcFunc)(unit, unit->mBufLength);
96 units += 8;
99 else
100 run_traced();
103 void run(void);
105 void set(slot_index_t slot_index, sample val);
106 void set_control_array(slot_index_t slot_index, size_t count, sample * val);
108 sample get(slot_index_t slot_index)
110 return mControls[slot_index];
113 /* @{ */
114 /** control mapping */
115 private:
116 void map_control_bus_control(unsigned int slot_index, int control_bus_index);
117 void map_control_buses_control(unsigned int slot_index, int control_bus_index, int count);
118 void map_control_bus_audio(unsigned int slot_index, int audio_bus_index);
119 void map_control_buses_audio(unsigned int slot_index, int audio_bus_index, int count);
121 public:
122 template <bool ControlBusIsAudio>
123 void map_control_bus(unsigned int slot_index, int bus_index)
125 if (ControlBusIsAudio)
126 map_control_bus_audio(slot_index, bus_index);
127 else
128 map_control_bus_control(slot_index, bus_index);
131 template <bool ControlBusIsAudio>
132 void map_control_buses(unsigned int slot_index, int bus_index, int count)
134 if (ControlBusIsAudio)
135 map_control_buses_audio(slot_index, bus_index, count);
136 else
137 map_control_buses_control(slot_index, bus_index, count);
140 template <bool ControlBusIsAudio>
141 void map_control_bus(const char * slot_name, int bus_index)
143 int slot_index = resolve_slot(slot_name);
144 map_control_bus<ControlBusIsAudio>(slot_index, bus_index);
147 template <bool ControlBusIsAudio>
148 void map_control_buses(const char * slot_name, int bus_index, int count)
150 int slot_index = resolve_slot(slot_name);
151 map_control_buses<ControlBusIsAudio>(slot_index, bus_index, count);
154 template <bool ControlBusIsAudio>
155 void map_control_bus(unsigned int slot_index, size_t arrayed_slot_index, int bus_index)
157 map_control_bus<ControlBusIsAudio>(slot_index + arrayed_slot_index, bus_index);
160 template <bool ControlBusIsAudio>
161 void map_control_bus(const char * slot_name, size_t arrayed_slot_index, int bus_index)
163 size_t slot_index = resolve_slot(slot_name) + arrayed_slot_index;
164 map_control_bus<ControlBusIsAudio>(slot_index, bus_index);
166 /* @} */
168 void enable_tracing(void)
170 trace = 1;
173 void apply_unit_cmd(const char * unit_cmd, unsigned int unit_index, struct sc_msg_iter *args);
175 private:
176 void run_traced(void);
178 sample get_constant(size_t index)
180 return static_cast<sc_synth_prototype*>(class_ptr.get())->constants[index];
183 friend class sc_ugen_def;
185 int_fast8_t trace;
186 Unit ** calc_units;
187 sample * unit_buffers;
188 int32_t calc_unit_count, unit_count;
190 RGen rgen;
192 Unit ** units;
195 } /* namespace nova */
197 #endif /* SC_SYNTH_HPP */