Vital
Loading...
Searching...
No Matches
wave_fold_modifier.cpp
Go to the documentation of this file.
1/*
2Summary:
3WaveFoldModifier applies a nonlinear wave-folding effect to a wavetable’s time-domain waveform. By scaling and folding the waveform through sine and arcsine functions, it adds harmonic complexity and can create interesting timbral variations. Adjusting the fold boost parameter in keyframes and interpolating between them allows dynamic control over the amount of wave folding across the wavetable.
4 */
5
7
8#include "utils.h"
9#include "wave_frame.h"
10
12 // Default fold boost set to 1.0 for neutral folding.
13 wave_fold_boost_ = 1.0f;
14}
15
17 const WaveFoldModifierKeyframe* source = dynamic_cast<const WaveFoldModifierKeyframe*>(keyframe);
18 wave_fold_boost_ = source->wave_fold_boost_;
19}
20
22 const WavetableKeyframe* to_keyframe,
23 float t) {
24 const WaveFoldModifierKeyframe* from = dynamic_cast<const WaveFoldModifierKeyframe*>(from_keyframe);
25 const WaveFoldModifierKeyframe* to = dynamic_cast<const WaveFoldModifierKeyframe*>(to_keyframe);
26
27 // Linearly interpolate the fold boost between two keyframes.
28 wave_fold_boost_ = linearTween(from->wave_fold_boost_, to->wave_fold_boost_, t);
29}
30
32 // Wave-folding is achieved by scaling and mapping the waveform’s amplitude through a nonlinear transform.
33 float max_value = std::max(1.0f, wave_frame->getMaxZeroOffset());
34
35 for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
36 // Clamp the waveform's value to [-1, 1] relative to max_value, then map through asin and sin to fold it.
37 float value = vital::utils::clamp(wave_frame->time_domain[i] / max_value, -1.0f, 1.0f);
38 float adjusted_value = max_value * wave_fold_boost_ * asinf(value);
39
40 wave_frame->time_domain[i] = sinf(adjusted_value);
41 }
42 wave_frame->toFrequencyDomain();
43}
44
47 data["fold_boost"] = wave_fold_boost_;
48 return data;
49}
50
53 wave_fold_boost_ = data["fold_boost"];
54}
55
57 // Interpolate the fold boost parameter from the component’s keyframe list at the given position.
59 interpolate(keyframe, position);
60 return keyframe;
61}
62
63void WaveFoldModifier::render(vital::WaveFrame* wave_frame, float position) {
64 // Interpolate parameters for this position and apply the folding transformation.
65 interpolate(&compute_frame_, position);
66 compute_frame_.render(wave_frame);
67}
68
72
74 WavetableKeyframe* wavetable_keyframe = keyframes_[index].get();
75 return dynamic_cast<WaveFoldModifier::WaveFoldModifierKeyframe*>(wavetable_keyframe);
76}
A keyframe class that stores the fold boost parameter for wave-folding at a given position.
Definition wave_fold_modifier.h:28
void render(vital::WaveFrame *wave_frame) override
Renders the waveform of this keyframe into a WaveFrame.
Definition wave_fold_modifier.cpp:31
void copy(const WavetableKeyframe *keyframe) override
Copies the state from another keyframe of the same type.
Definition wave_fold_modifier.cpp:16
json stateToJson() override
Serializes the state of this keyframe to a JSON object.
Definition wave_fold_modifier.cpp:45
WaveFoldModifierKeyframe()
Constructs a keyframe with a default wave fold boost value of 1.0.
Definition wave_fold_modifier.cpp:11
void jsonToState(json data) override
Restores the keyframe's state from a JSON object.
Definition wave_fold_modifier.cpp:51
float wave_fold_boost_
The factor by which the wave is folded.
Definition wave_fold_modifier.h:60
void interpolate(const WavetableKeyframe *from_keyframe, const WavetableKeyframe *to_keyframe, float t) override
Linearly interpolates between two keyframes.
Definition wave_fold_modifier.cpp:21
WaveFoldModifierKeyframe * getKeyframe(int index)
Retrieves a WaveFoldModifierKeyframe at a given index.
Definition wave_fold_modifier.cpp:73
WavetableKeyframe * createKeyframe(int position) override
Creates a new keyframe at a given position.
Definition wave_fold_modifier.cpp:56
WavetableComponentFactory::ComponentType getType() override
Returns the type of this WavetableComponent.
Definition wave_fold_modifier.cpp:69
void render(vital::WaveFrame *wave_frame, float position) override
Renders the waveform at a given position into a WaveFrame.
Definition wave_fold_modifier.cpp:63
WaveFoldModifierKeyframe compute_frame_
A keyframe for intermediate computations.
Definition wave_fold_modifier.h:84
ComponentType
Enumerates all known WavetableComponents, including sources and modifiers.
Definition wavetable_component_factory.h:28
@ kWaveFolder
Modifier that applies wave folding.
Definition wavetable_component_factory.h:40
void interpolate(WavetableKeyframe *dest, float position)
Interpolates a destination keyframe at a given position.
Definition wavetable_component.cpp:68
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
mono_float getMaxZeroOffset() const
Retrieves the maximum absolute amplitude in the time-domain waveform.
Definition wave_frame.cpp:30
nlohmann::json json
Definition line_generator.h:7
force_inline poly_float clamp(poly_float value, mono_float min, mono_float max)
Clamps each lane of a vector to [min, max].
Definition poly_utils.h:306
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...