Vital
Loading...
Searching...
No Matches
producers_module.cpp
Go to the documentation of this file.
1#include "producers_module.h"
2
3namespace vital {
4
11 SynthModule(kNumInputs, kNumOutputs), sample_destination_(nullptr),
12 filter1_on_(nullptr), filter2_on_(nullptr) {
13 // Create and configure oscillators.
14 for (int i = 0; i < kNumOscillators; ++i) {
15 std::string number = std::to_string(i + 1);
16 oscillators_[i] = new OscillatorModule("osc_" + number);
19 oscillators_[i]->enable(false);
20 oscillator_destinations_[i] = nullptr;
21 }
22
23 // Create and configure sampler.
24 sampler_ = new SampleModule();
27 sampler_->enable(false);
28 }
29
62
71 void ProducersModule::process(int num_samples) {
72 // Base processing for this module.
73 SynthModule::process(num_samples);
74
75 // Process the sampler.
76 getLocalProcessor(sampler_)->process(num_samples);
77
78 // Track distortion types and processing states of oscillators to handle modulation dependencies.
80 bool processed[kNumOscillators];
81 for (int i = 0; i < kNumOscillators; ++i) {
82 distortion_types[i] = oscillators_[i]->getDistortionType();
83 processed[i] = false;
84 }
85
86 // Process oscillators in an order that respects their modulation dependencies.
87 int num_processed = 0;
88 int index = 0;
89 for (int i = 0; i < kNumOscillators * kNumOscillators && num_processed < kNumOscillators; ++i) {
90 OscillatorModule* module = oscillators_[index];
91 int first_source = getFirstModulationIndex(index);
92 int second_source = getSecondModulationIndex(index);
93 if ((!SynthOscillator::isFirstModulation(distortion_types[index]) || processed[first_source]) &&
94 (!SynthOscillator::isSecondModulation(distortion_types[index]) || processed[second_source]) &&
95 !processed[index]) {
96 num_processed++;
97 processed[index] = true;
98 getLocalProcessor(module)->process(num_samples);
99 }
100 index = (index + 1) % kNumOscillators;
101 }
102
103 // Prepare the output buffers for mixing.
104 poly_float* filter1_output = output(kToFilter1)->buffer;
105 poly_float* filter2_output = output(kToFilter2)->buffer;
106 poly_float* raw_output = output(kRawOut)->buffer;
107 poly_float* direct_output = output(kDirectOut)->buffer;
108 utils::zeroBuffer(filter1_output, num_samples);
109 utils::zeroBuffer(filter2_output, num_samples);
110 utils::zeroBuffer(raw_output, num_samples);
111 utils::zeroBuffer(direct_output, num_samples);
112
113 bool filter1_on = isFilter1On();
114 bool filter2_on = isFilter2On();
115
116 // Mix the oscillator outputs into their destinations based on their assigned routes.
117 for (int i = 0; i < kNumOscillators; ++i) {
119
120 int destination = oscillator_destinations_[i]->value();
121 bool raw = destination == constants::kEffects;
122 bool filter1 = (destination == constants::kFilter1 || destination == constants::kDualFilters);
123 bool filter2 = (destination == constants::kFilter2 || destination == constants::kDualFilters);
124 bool direct_out = (destination == constants::kDirectOut);
125
126 // Handle routing logic based on filter states and destinations.
127 if (raw || (!filter2 && filter1 && !filter1_on) ||
128 (!filter1 && filter2 && !filter2_on) ||
129 (filter1 && filter2 && !filter1_on && !filter2_on)) {
130 utils::addBuffers(raw_output, raw_output, buffer, num_samples);
131 }
132 if (filter1)
133 utils::addBuffers(filter1_output, filter1_output, buffer, num_samples);
134 if (filter2)
135 utils::addBuffers(filter2_output, filter2_output, buffer, num_samples);
136 if (direct_out)
137 utils::addBuffers(direct_output, direct_output, buffer, num_samples);
138 }
139
140 // Add the sampler output according to its destination.
142
143 int sample_destination = sample_destination_->value();
144 bool sample_raw = sample_destination == constants::kEffects;
145 bool filter1_sample = (sample_destination == constants::kFilter1 || sample_destination == constants::kDualFilters);
146 bool filter2_sample = (sample_destination == constants::kFilter2 || sample_destination == constants::kDualFilters);
147 bool sample_direct_out = (sample_destination == constants::kDirectOut);
148
149 // Handle routing logic for the sampler output similar to oscillators.
150 if (sample_raw || (!filter2_sample && filter1_sample && !filter1_on) ||
151 (!filter1_sample && filter2_sample && !filter2_on) ||
152 (filter1_sample && filter2_sample && !filter1_on && !filter2_on)) {
153 utils::addBuffers(raw_output, raw_output, sample, num_samples);
154 }
155 if (filter1_sample)
156 utils::addBuffers(filter1_output, filter1_output, sample, num_samples);
157 if (filter2_sample)
158 utils::addBuffers(filter2_output, filter2_output, sample, num_samples);
159 if (sample_direct_out)
160 utils::addBuffers(direct_output, direct_output, sample, num_samples);
161 }
162
163} // namespace vital
A synthesis module that represents an oscillator within the Vital synthesizer.
Definition oscillator_module.h:16
SynthOscillator::DistortionType getDistortionType()
Gets the currently set distortion type.
Definition oscillator_module.h:94
@ kLevelled
Definition oscillator_module.h:36
@ kRaw
Definition oscillator_module.h:35
force_inline SynthOscillator * oscillator()
Returns a pointer to the internal SynthOscillator.
Definition oscillator_module.h:87
@ kMidi
Definition oscillator_module.h:25
@ kActiveVoices
Definition oscillator_module.h:26
@ kReset
Definition oscillator_module.h:23
@ kRetrigger
Definition oscillator_module.h:24
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 process(int num_samples)=0
Main processing function. Called by the ProcessorRouter.
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
virtual void init()
Called after constructor, used for any additional initialization. Subclasses can override....
Definition processor.h:258
Processor * getLocalProcessor(const Processor *global_processor)
Retrieves the local instance of a globally defined Processor.
Definition processor_router.cpp:376
virtual void addProcessor(Processor *processor)
Adds a Processor to be managed by this router.
Definition processor_router.cpp:121
ProducersModule()
Constructs a ProducersModule.
Definition producers_module.cpp:10
bool isFilter1On()
Checks if Filter 1 is on.
Definition producers_module.h:145
bool isFilter2On()
Checks if Filter 2 is on.
Definition producers_module.h:152
@ kActiveVoices
Definition producers_module.h:27
@ kReset
Definition producers_module.h:24
@ kMidi
Definition producers_module.h:26
@ kNoteCount
Definition producers_module.h:28
@ kRetrigger
Definition producers_module.h:25
static force_inline int getFirstModulationIndex(int index)
Helper function to determine the first modulation index for a given oscillator index.
Definition producers_module.h:50
SampleModule * sampler_
The sampler module that provides sampled audio.
Definition producers_module.h:174
Value * oscillator_destinations_[kNumOscillators]
An array of Values determining the destination for each oscillator.
Definition producers_module.h:164
void init() override
Initializes the module and sets up parameter connections.
Definition producers_module.cpp:35
Value * sample_destination_
A Value determining the output destination for the sample.
Definition producers_module.h:169
@ kRawOut
Definition producers_module.h:39
@ kToFilter1
Definition producers_module.h:37
@ kDirectOut
Definition producers_module.h:40
@ kToFilter2
Definition producers_module.h:38
void process(int num_samples) override
Processes the audio for a given number of samples.
Definition producers_module.cpp:71
OscillatorModule * oscillators_[kNumOscillators]
An array of oscillator modules managed by this ProducersModule.
Definition producers_module.h:157
static force_inline int getSecondModulationIndex(int index)
Helper function to determine the second modulation index for a given oscillator index.
Definition producers_module.h:60
A module that plays back a sample (audio file) as part of the synthesis pipeline.
Definition sample_module.h:16
@ kMidi
Definition sample_module.h:24
@ kReset
Definition sample_module.h:23
@ kNoteCount
Definition sample_module.h:25
@ kLevelled
Definition sample_module.h:35
@ kRaw
Definition sample_module.h:34
A ProcessorRouter that encapsulates a cohesive unit of functionality in the synthesizer.
Definition synth_module.h:129
Value * createBaseControl(std::string name, bool audio_rate=false, bool smooth_value=false)
Creates a simple control processor for a given parameter name.
Definition synth_module.cpp:22
void addSubmodule(SynthModule *module)
Adds a submodule to this SynthModule.
Definition synth_module.h:289
virtual void enable(bool enable) override
Enables or disables this SynthModule and its owned processors.
Definition synth_module.cpp:516
static bool isFirstModulation(int type)
Checks if distortion type uses the first modulation oscillator.
Definition synth_oscillator.h:185
DistortionType
Types of distortion/waveshaping used by the oscillator.
Definition synth_oscillator.h:145
void setSecondOscillatorOutput(Output *oscillator)
Assigns an oscillator Output pointer for FM/RM modulation (second mod oscillator).
Definition synth_oscillator.h:382
void setSampleOutput(Output *sample)
Assigns a sample Output pointer for FM/RM modulation using a sample.
Definition synth_oscillator.h:388
void setFirstOscillatorOutput(Output *oscillator)
Assigns an oscillator Output pointer for FM/RM modulation (first mod oscillator).
Definition synth_oscillator.h:376
static bool isSecondModulation(int type)
Checks if distortion type uses the second modulation oscillator.
Definition synth_oscillator.h:194
force_inline mono_float value() const
Returns the current mono_float value of the first lane.
Definition value.h:60
@ kDualFilters
Route through both filters.
Definition synth_constants.h:118
@ kFilter2
Route through Filter 2.
Definition synth_constants.h:117
@ kEffects
Route directly to the effects chain.
Definition synth_constants.h:119
@ kFilter1
Route through Filter 1.
Definition synth_constants.h:116
@ kDirectOut
Route directly to the output (bypass filters and effects).
Definition synth_constants.h:120
force_inline void addBuffers(poly_float *dest, const poly_float *b1, const poly_float *b2, int size)
Adds two poly_float buffers element-by-element, storing in dest.
Definition poly_utils.h:602
force_inline void zeroBuffer(mono_float *buffer, int size)
Zeros a mono buffer (standard array).
Definition poly_utils.h:570
Contains classes and functions used within the Vital synthesizer framework.
constexpr int kNumOscillators
Number of oscillators available in Vital.
Definition synth_constants.h:16
poly_float * buffer
Pointer to the output buffer.
Definition processor.h:110
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600