Vital
Loading...
Searching...
No Matches
wave_line_source.cpp
Go to the documentation of this file.
1/*
2Summary:
3WaveLineSource constructs wavetables using a line generator that defines a waveform through a set of points. By adjusting the points’ positions and power values, and optionally smoothing the line, it produces a custom waveform shape. Keyframes store configurations of these line-based shapes, and interpolation (including nonlinear “pull_power” effects) allows the waveform to evolve smoothly from one shape to another across the wavetable’s dimension.
4 */
5
6#include "wave_line_source.h"
7
8#include "futils.h"
9#include "utils.h"
10#include "poly_utils.h"
11#include "wave_frame.h"
13
15 line_generator_(vital::WaveFrame::kWaveformSize) {
16 pull_power_ = 0.0f;
17}
18
20 const WaveLineSourceKeyframe* source = dynamic_cast<const WaveLineSourceKeyframe*>(keyframe);
21
22 const LineGenerator* source_generator = source->getLineGenerator();
23 line_generator_.setNumPoints(source_generator->getNumPoints());
24 line_generator_.setSmooth(source_generator->smooth());
25 for (int i = 0; i < line_generator_.getNumPoints(); ++i) {
26 line_generator_.setPoint(i, source_generator->getPoint(i));
27 line_generator_.setPower(i, source_generator->getPower(i));
28 }
29}
30
32 const WavetableKeyframe* to_keyframe,
33 float t) {
34 const WaveLineSourceKeyframe* from = dynamic_cast<const WaveLineSourceKeyframe*>(from_keyframe);
35 const WaveLineSourceKeyframe* to = dynamic_cast<const WaveLineSourceKeyframe*>(to_keyframe);
36 VITAL_ASSERT(from->getNumPoints() == to->getNumPoints());
37
38 // Use pull_power_ to nonlinearize interpolation parameter 't'.
39 float relative_power = from->getPullPower() - to->getPullPower();
40 float adjusted_t = vital::futils::powerScale(t, relative_power);
41
42 const LineGenerator* from_generator = from->getLineGenerator();
43 const LineGenerator* to_generator = to->getLineGenerator();
44 int num_points = from_generator->getNumPoints();
45 line_generator_.setNumPoints(num_points);
46 line_generator_.setSmooth(from_generator->smooth());
47
48 // Interpolate each point and power value based on adjusted_t.
49 for (int i = 0; i < num_points; ++i) {
50 std::pair<float, float> from_point = from_generator->getPoint(i);
51 std::pair<float, float> to_point = to_generator->getPoint(i);
52 line_generator_.setPoint(i, {
53 linearTween(from_point.first, to_point.first, adjusted_t),
54 linearTween(from_point.second, to_point.second, adjusted_t),
55 });
56 line_generator_.setPower(i, linearTween(from_generator->getPower(i), to_generator->getPower(i), adjusted_t));
57 }
58}
59
61 // Render the line-based waveform and map it from [0,1] to [-1,1].
62 line_generator_.render();
63 memcpy(wave_frame->time_domain, line_generator_.getBuffer(), vital::WaveFrame::kWaveformSize * sizeof(float));
64 for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i)
65 wave_frame->time_domain[i] = wave_frame->time_domain[i] * 2.0f - 1.0f;
66 wave_frame->toFrequencyDomain();
67}
68
71 data["pull_power"] = pull_power_;
72 data["line"] = line_generator_.stateToJson();
73 return data;
74}
75
78 pull_power_ = 0.0f;
79 if (data.count("pull_power"))
80 pull_power_ = data["pull_power"];
81 if (data.count("line"))
82 line_generator_.jsonToState(data["line"]);
83}
84
87 interpolate(keyframe, position);
88 return keyframe;
89}
90
91void WaveLineSource::render(vital::WaveFrame* wave_frame, float position) {
92 // Interpolate the compute_frame_ and render the final line-based waveform.
93 interpolate(&compute_frame_, position);
94 compute_frame_.render(wave_frame);
95}
96
100
103 data["num_points"] = num_points_;
104 return data;
105}
106
109 setNumPoints(data["num_points"]);
110}
111
112void WaveLineSource::setNumPoints(int num_points) {
113 num_points_ = num_points;
114}
115
117 WavetableKeyframe* wavetable_keyframe = keyframes_[index].get();
118 return dynamic_cast<WaveLineSource::WaveLineSourceKeyframe*>(wavetable_keyframe);
119}
A class for generating and storing a line shape, defined by a series of points and associated powers.
Definition line_generator.h:20
force_inline bool smooth() const
Indicates whether smoothing is enabled.
Definition line_generator.h:280
force_inline int getNumPoints() const
Returns the current number of points defining the line.
Definition line_generator.h:327
force_inline void setNumPoints(int num_points)
Sets the number of points currently in use.
Definition line_generator.h:360
force_inline std::pair< float, float > getPoint(int index) const
Returns a point at the given index.
Definition line_generator.h:306
force_inline float getPower(int index) const
Returns the power at the given index.
Definition line_generator.h:317
A keyframe class that represents a particular line-based waveform configuration at a given position.
Definition wave_line_source.h:36
int getNumPoints() const
Gets the number of points defining the line.
Definition wave_line_source.h:104
void jsonToState(json data) override
Restores the keyframe's state from a JSON object.
Definition wave_line_source.cpp:76
void render(vital::WaveFrame *wave_frame) override
Renders the waveform of this keyframe into a WaveFrame.
Definition wave_line_source.cpp:60
float pull_power_
Controls nonlinear interpolation between keyframes.
Definition wave_line_source.h:145
WaveLineSourceKeyframe()
Constructs a WaveLineSourceKeyframe with default parameters.
Definition wave_line_source.cpp:14
void copy(const WavetableKeyframe *keyframe) override
Copies the state from another keyframe of the same type.
Definition wave_line_source.cpp:19
const LineGenerator * getLineGenerator() const
Provides const access to the underlying LineGenerator.
Definition wave_line_source.h:134
float getPullPower() const
Gets the current pull power value.
Definition wave_line_source.h:127
json stateToJson() override
Serializes the state of this keyframe to a JSON object.
Definition wave_line_source.cpp:69
void interpolate(const WavetableKeyframe *from_keyframe, const WavetableKeyframe *to_keyframe, float t) override
Linearly interpolates between two keyframes.
Definition wave_line_source.cpp:31
WaveLineSourceKeyframe * getKeyframe(int index)
Retrieves a WaveLineSourceKeyframe by index.
Definition wave_line_source.cpp:116
int num_points_
The number of points defining the line-based waveform.
Definition wave_line_source.h:185
WavetableComponentFactory::ComponentType getType() override
Returns the type of this WavetableComponent.
Definition wave_line_source.cpp:97
json stateToJson() override
Serializes the component’s state and all keyframes to a JSON object.
Definition wave_line_source.cpp:101
void jsonToState(json data) override
Restores the component’s state from a JSON object.
Definition wave_line_source.cpp:107
void setNumPoints(int num_points)
Sets the number of points used by the line generator.
Definition wave_line_source.cpp:112
WavetableKeyframe * createKeyframe(int position) override
Creates a new keyframe at a given position.
Definition wave_line_source.cpp:85
WaveLineSourceKeyframe compute_frame_
A keyframe for intermediate computations.
Definition wave_line_source.h:186
void render(vital::WaveFrame *wave_frame, float position) override
Renders the waveform at a given position into a WaveFrame.
Definition wave_line_source.cpp:91
ComponentType
Enumerates all known WavetableComponents, including sources and modifiers.
Definition wavetable_component_factory.h:28
@ kLineSource
A line-based wave source.
Definition wavetable_component_factory.h:30
virtual json stateToJson()
Serializes the component’s state and all keyframes to a JSON object.
Definition wavetable_component.cpp:49
void interpolate(WavetableKeyframe *dest, float position)
Interpolates a destination keyframe at a given position.
Definition wavetable_component.cpp:68
virtual void jsonToState(json data)
Restores the component’s state from a JSON object.
Definition wavetable_component.cpp:37
std::vector< std::unique_ptr< WavetableKeyframe > > keyframes_
The list of keyframes sorted by position.
Definition wavetable_component.h:219
Represents a single state of a waveform at a specific position in a wavetable.
Definition wavetable_keyframe.h:35
virtual json stateToJson()
Serializes the state of this keyframe to a JSON object.
Definition wavetable_keyframe.cpp:37
virtual void jsonToState(json data)
Restores the keyframe's state from a JSON object.
Definition wavetable_keyframe.cpp:41
Represents a single frame of a wavetable, containing both time-domain and frequency-domain data.
Definition wave_frame.h:16
void toFrequencyDomain()
Converts the currently loaded time-domain data into frequency-domain representation.
Definition wave_frame.cpp:64
static constexpr int kWaveformSize
The size of the waveform (number of samples per frame).
Definition wave_frame.h:21
mono_float time_domain[2 *kWaveformSize]
The time-domain data, extended buffer size for FFT alignment.
Definition wave_frame.h:124
#define VITAL_ASSERT(x)
Definition common.h:11
Contains faster but less accurate versions of utility math functions, such as exponential,...
nlohmann::json json
Definition line_generator.h:7
force_inline mono_float powerScale(mono_float value, mono_float power)
A power-scaling function to map a linear range to a curved response.
Definition futils.h:455
Contains classes and functions used within the Vital synthesizer framework.
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...