Vital
Loading...
Searching...
No Matches
processor.cpp
Go to the documentation of this file.
1
7#include "processor.h"
8
9#include "feedback.h"
10#include "processor_router.h"
11
12namespace vital {
13
15
16
25 Processor::Processor(int num_inputs, int num_outputs, bool control_rate, int max_oversample) {
27 state_ = std::make_shared<ProcessorState>();
28 state_->oversample_amount = max_oversample;
29 state_->control_rate = control_rate;
30
31 inputs_ = std::make_shared<std::vector<Input*>>();
32 outputs_ = std::make_shared<std::vector<Output*>>();
33 router_ = nullptr;
34
35 for (int i = 0; i < num_inputs; ++i)
36 addInput();
37
38 for (int i = 0; i < num_outputs; ++i)
39 addOutput(max_oversample);
40 }
41
43 if (input >= inputs_->size())
44 return false;
45
46 if (numOutputs() == 0)
47 return true;
48
49 return inputs_->at(input)->source->buffer_size >= output()->buffer_size;
50 }
51
52 bool Processor::checkInputAndOutputSize(int num_samples) {
53 if (isControlRate())
54 return true;
55
56 int num_outputs = numOutputs();
57 for (int i = 0; i < num_outputs; ++i) {
58 int buffer_size = output(i)->buffer_size;
59 if (buffer_size > 1 && buffer_size < num_samples)
60 return false;
61 }
62
63 int num_inputs = numInputs();
64 for (int i = 0; i < num_inputs; ++i) {
65 int buffer_size = input(i)->source->buffer_size;
66 if (buffer_size > 1 && buffer_size < num_samples)
67 return false;
68 }
69
70 return true;
71 }
72
74 if (router_)
75 return router_->isPolyphonic(this);
76 return false;
77 }
78
79 void Processor::plug(const Output* source) {
80 plug(source, 0);
81 }
82
83 void Processor::plug(const Output* source, unsigned int input_index) {
84 VITAL_ASSERT(input_index < inputs_->size());
85 VITAL_ASSERT(source);
86 VITAL_ASSERT(inputs_->at(input_index));
87
88 inputs_->at(input_index)->source = source;
89
90 if (router_)
91 router_->connect(this, source, input_index);
92
94 }
95
96 void Processor::plug(const Processor* source) {
97 plug(source, 0);
98 }
99
100 void Processor::plug(const Processor* source, unsigned int input_index) {
101 plug(source->output(), input_index);
102 }
103
104 void Processor::plugNext(const Output* source) {
105 int num_inputs = static_cast<int>(inputs_->size());
106 for (int i = plugging_start_; i < num_inputs; ++i) {
107 Input* input = inputs_->at(i);
109 plug(source, i);
110 return;
111 }
112 }
113
114 // If there are no empty inputs, create another.
115 std::shared_ptr<Input> input = std::make_shared<Input>();
116 owned_inputs_.push_back(input);
117 input->source = source;
118 registerInput(input.get());
120 }
121
122 void Processor::plugNext(const Processor* source) {
123 plugNext(source->output());
124 }
125
127 useInput(input, 0);
128 }
129
130 void Processor::useInput(Input* input, int index) {
131 VITAL_ASSERT(index < inputs_->size());
133
134 inputs_->at(index) = input;
136 }
137
139 useOutput(output, 0);
140 }
141
142 void Processor::useOutput(Output* output, int index) {
143 VITAL_ASSERT(index < outputs_->size());
145
146 outputs_->at(index) = output;
147 }
148
150 int count = 0;
151 int num_inputs = static_cast<int>(inputs_->size());
152 for (int i = 0; i < num_inputs; ++i) {
153 Input* input = inputs_->at(i);
155 count++;
156 }
157
158 return count;
159 }
160
161 void Processor::unplugIndex(unsigned int input_index) {
162 if (inputs_->at(input_index))
163 inputs_->at(input_index)->source = &Processor::null_source_;
165 }
166
167 void Processor::unplug(const Output* source) {
168 if (router_)
169 router_->disconnect(this, source);
170
171 for (unsigned int i = 0; i < inputs_->size(); ++i) {
172 if (inputs_->at(i) && inputs_->at(i)->source == source)
173 inputs_->at(i)->source = &Processor::null_source_;
174 }
176 }
177
178 void Processor::unplug(const Processor* source) {
179 if (router_) {
180 for (int i = 0; i < source->numOutputs(); ++i)
181 router_->disconnect(this, source->output(i));
182 }
183 for (unsigned int i = 0; i < inputs_->size(); ++i) {
184 if (inputs_->at(i) && inputs_->at(i)->source->owner == source)
185 inputs_->at(i)->source = &Processor::null_source_;
186 }
188 }
189
191 ProcessorRouter* top_level = nullptr;
192 ProcessorRouter* current_level = router_;
193
194 while (current_level) {
195 top_level = current_level;
196 current_level = current_level->router();
197 }
198 return top_level;
199 }
200
202 inputs_->push_back(input);
203
205 router_->connect(this, input->source, static_cast<int>(inputs_->size()) - 1);
206 }
207
209 outputs_->push_back(output);
210 return output;
211 }
212
213 void Processor::registerInput(Input* input, int index) {
214 while (inputs_->size() <= index)
215 inputs_->push_back(nullptr);
216
217 inputs_->at(index) = input;
218
220 router_->connect(this, input->source, index);
221 }
222
224 while (outputs_->size() <= index)
225 outputs_->push_back(nullptr);
226
227 outputs_->at(index) = output;
228 return output;
229 }
230
231 Output* Processor::addOutput(int oversample) {
232 std::shared_ptr<Output> output;
233 if (isControlRate())
234 output = std::make_shared<cr::Output>();
235 else
236 output = std::make_shared<Output>(kMaxBufferSize, oversample);
237
238 owned_outputs_.push_back(output);
239
240 // All outputs are owned by this Processor.
241 output->owner = this;
242 registerOutput(output.get());
243 return output.get();
244 }
245
247 std::shared_ptr<Input> input = std::make_shared<Input>();
248 owned_inputs_.push_back(input);
249
250 // All inputs start off with null input.
252 registerInput(input.get());
253 return input.get();
254 }
255} // namespace vital
Base class for all signal-processing units in Vital.
Definition processor.h:212
std::shared_ptr< ProcessorState > state_
Shared state (sample rate, oversample, etc.)
Definition processor.h:653
virtual void unplugIndex(unsigned int input_index)
Removes the connection at a specified input index, if any.
Definition processor.cpp:161
Processor(int num_inputs, int num_outputs, bool control_rate=false, int max_oversample=1)
Constructs a Processor with a given number of inputs/outputs and oversampling.
Definition processor.cpp:25
force_inline int numOutputs() const
Returns the total number of Output pointers (owned or otherwise).
Definition processor.h:564
force_inline int numInputs() const
Returns the total number of Input pointers (owned or otherwise).
Definition processor.h:557
virtual void numInputsChanged()
Called when the number of inputs changes (e.g., new connections). Subclasses may override for dynamic...
Definition processor.h:501
virtual Output * registerOutput(Output *output, int index)
Registers a new Output in the output list at a specified index.
Definition processor.cpp:223
void plugNext(const Output *source)
Connects an external Output to the first available (unplugged) input.
Definition processor.cpp:104
Input * addInput()
Creates and registers a new Input, initially connected to null_source_.
Definition processor.cpp:246
int plugging_start_
The index at which plugNext starts searching for an unplugged input.
Definition processor.h:655
void useOutput(Output *output)
Uses an existing Output object as this Processor's first output.
Definition processor.cpp:138
virtual bool isPolyphonic() const
Checks if this Processor is polyphonic by querying its ProcessorRouter.
Definition processor.cpp:73
force_inline Input * input(unsigned int index=0) const
Retrieves the Input pointer at a given index.
Definition processor.h:587
void useInput(Input *input)
Uses an existing Input object as this Processor's first input.
Definition processor.cpp:126
virtual void registerInput(Input *input, int index)
Registers a new input, appending it to the input list.
Definition processor.cpp:213
force_inline bool isControlRate() const
Checks if this Processor is running at control rate (buffer_size == 1).
Definition processor.h:342
bool inputMatchesBufferSize(int input=0)
Checks whether the buffer size of a particular input matches the size needed by this Processor.
Definition processor.cpp:42
static const Output null_source_
A null (dummy) source used for unconnected inputs.
Definition processor.h:665
ProcessorRouter * getTopLevelRouter() const
Gets the topmost (root) ProcessorRouter by traversing parent routers.
Definition processor.cpp:190
std::shared_ptr< std::vector< Input * > > inputs_
All inputs, owned or external.
Definition processor.h:660
bool checkInputAndOutputSize(int num_samples)
Checks if all inputs and outputs have buffers big enough for num_samples.
Definition processor.cpp:52
std::vector< std::shared_ptr< Input > > owned_inputs_
Inputs owned by this Processor.
Definition processor.h:657
void plug(const Output *source)
Connects an external Output to this Processor's first input.
Definition processor.cpp:79
int connectedInputs()
Counts how many inputs are connected to a real source (not null_source_).
Definition processor.cpp:149
Output * addOutput(int oversample=1)
Creates and registers a new Output. Handles control rate vs. audio rate.
Definition processor.cpp:231
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
virtual void unplug(const Output *source)
Removes a connection to a given Output from all inputs.
Definition processor.cpp:167
std::shared_ptr< std::vector< Output * > > outputs_
All outputs, owned or external.
Definition processor.h:661
std::vector< std::shared_ptr< Output > > owned_outputs_
Outputs owned by this Processor.
Definition processor.h:658
ProcessorRouter * router_
The ProcessorRouter that manages this Processor.
Definition processor.h:663
force_inline void router(ProcessorRouter *router)
Sets the ProcessorRouter that owns or manages this Processor.
Definition processor.h:507
A specialized Processor that manages a directed graph of Processors and ensures correct processing or...
Definition processor_router.h:34
void disconnect(const Processor *destination, const Output *source)
Disconnects a source Output from a destination Processor.
Definition processor_router.cpp:182
virtual bool isPolyphonic(const Processor *processor) const
Determines if a given Processor is polyphonic within this router.
Definition processor_router.cpp:257
void connect(Processor *destination, const Output *source, int index)
Connects a source Output to a destination Processor input by index.
Definition processor_router.cpp:168
#define VITAL_ASSERT(x)
Definition common.h:11
Contains classes and functions used within the Vital synthesizer framework.
constexpr int kMaxBufferSize
Maximum buffer size for processing.
Definition common.h:39
constexpr int kMaxOversample
Maximum allowed oversampling factor.
Definition common.h:40
Declares the Processor class and related structures for handling audio processing in a polyphonic con...
Declares the ProcessorRouter class, which manages a graph of Processors and their dependencies.
Represents a connection to an Output from another Processor.
Definition processor.h:128
force_inline poly_float at(int i) const
Returns the sample at index i from the source buffer.
Definition processor.h:141
const Output * source
The output from which this input reads samples.
Definition processor.h:134
Holds and manages a buffer of samples (poly_float) for a Processor's output.
Definition processor.h:35
Processor * owner
Owning processor.
Definition processor.h:112
int buffer_size
Current buffer size in samples.
Definition processor.h:114