Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / supernova / sc / sc_synth.hpp
blob5528f2bc42add69b4a578cd010248d524060f380
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_definition.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_definition;
46 public:
47 sc_synth(int node_id, sc_synth_definition_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 float get(slot_index_t slot_index) const;
107 void set_control_array(slot_index_t slot_index, size_t count, sample * val);
109 sample get(slot_index_t slot_index)
111 return mControls[slot_index];
114 /* @{ */
115 /** control mapping */
116 private:
117 void map_control_bus_control(unsigned int slot_index, int control_bus_index);
118 void map_control_buses_control(unsigned int slot_index, int control_bus_index, int count);
119 void map_control_bus_audio(unsigned int slot_index, int audio_bus_index);
120 void map_control_buses_audio(unsigned int slot_index, int audio_bus_index, int count);
122 public:
123 template <bool ControlBusIsAudio>
124 void map_control_bus(unsigned int slot_index, int bus_index)
126 if (ControlBusIsAudio)
127 map_control_bus_audio(slot_index, bus_index);
128 else
129 map_control_bus_control(slot_index, bus_index);
132 template <bool ControlBusIsAudio>
133 void map_control_buses(unsigned int slot_index, int bus_index, int count)
135 if (ControlBusIsAudio)
136 map_control_buses_audio(slot_index, bus_index, count);
137 else
138 map_control_buses_control(slot_index, bus_index, count);
141 template <bool ControlBusIsAudio>
142 void map_control_bus(const char * slot_name, int bus_index)
144 int slot_index = resolve_slot(slot_name);
145 map_control_bus<ControlBusIsAudio>(slot_index, bus_index);
148 template <bool ControlBusIsAudio>
149 void map_control_buses(const char * slot_name, int bus_index, int count)
151 int slot_index = resolve_slot(slot_name);
152 map_control_buses<ControlBusIsAudio>(slot_index, bus_index, count);
155 template <bool ControlBusIsAudio>
156 void map_control_bus(unsigned int slot_index, size_t arrayed_slot_index, int bus_index)
158 map_control_bus<ControlBusIsAudio>(slot_index + arrayed_slot_index, bus_index);
161 template <bool ControlBusIsAudio>
162 void map_control_bus(const char * slot_name, size_t arrayed_slot_index, int bus_index)
164 size_t slot_index = resolve_slot(slot_name) + arrayed_slot_index;
165 map_control_bus<ControlBusIsAudio>(slot_index, bus_index);
167 /* @} */
169 void enable_tracing(void)
171 trace = 1;
174 void apply_unit_cmd(const char * unit_cmd, unsigned int unit_index, struct sc_msg_iter *args);
176 private:
177 void run_traced(void);
179 sample get_constant(size_t index)
181 return static_cast<sc_synth_definition*>(class_ptr.get())->constants[index];
184 friend class sc_ugen_def;
186 int_fast8_t trace;
187 Unit ** calc_units;
188 sample * unit_buffers;
189 int32_t calc_unit_count, unit_count;
191 RGen rgen;
193 Unit ** units;
196 } /* namespace nova */
198 #endif /* SC_SYNTH_HPP */