Vital
Loading...
Searching...
No Matches
wave_window_modifier.cpp
Go to the documentation of this file.
1/*
2Summary:
3WaveWindowModifier applies a chosen windowing function to the beginning and end of a waveform, tapering its amplitude based on left_position_ and right_position_. Different window shapes (cosine, half-sine, linear, square, wiggle) produce various slopes and transitions. By interpolating between keyframes, users can animate the window size and shape over the wavetable, influencing how the waveform’s amplitude envelope evolves dynamically.
4 */
5
6#include "wave_frame.h"
7
9
10float WaveWindowModifier::applyWindow(WindowShape window_shape, float t) {
11 // Applies the selected window function at time t.
12 if (window_shape == kCos)
13 return 0.5f - 0.5f * cosf(vital::kPi * t);
14 if (window_shape == kHalfSin)
15 return sinf(vital::kPi * t / 2.0f);
16 if (window_shape == kSquare)
17 return t < 1.0f ? 0.0f : 1.0f;
18 if (window_shape == kWiggle)
19 return t * cosf(vital::kPi * (t * 1.5f + 0.5f));
20 // Default to linear if no shape matches.
21 return t;
22}
23
25 // Default positions leave a portion of the wave fully amplitude-visible.
26 static constexpr float kDefaultOffset = 0.25f;
27 left_position_ = kDefaultOffset;
28 right_position_ = 1.0f - kDefaultOffset;
30}
31
33 const WaveWindowModifierKeyframe* source = dynamic_cast<const WaveWindowModifierKeyframe*>(keyframe);
34
35 left_position_ = source->left_position_;
36 right_position_ = source->right_position_;
37}
38
40 const WavetableKeyframe* to_keyframe,
41 float t) {
42 const WaveWindowModifierKeyframe* from = dynamic_cast<const WaveWindowModifierKeyframe*>(from_keyframe);
43 const WaveWindowModifierKeyframe* to = dynamic_cast<const WaveWindowModifierKeyframe*>(to_keyframe);
44
45 left_position_ = linearTween(from->left_position_, to->left_position_, t);
46 right_position_ = linearTween(from->right_position_, to->right_position_, t);
47}
48
50 // Apply the window shape at the start (up to left_position_) and end (after right_position_) of the wave.
51 for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
52 float t = i / (vital::WaveFrame::kWaveformSize - 1.0f);
53 if (t >= left_position_)
54 break;
55
56 wave_frame->time_domain[i] *= applyWindow(t / left_position_);
57 }
58
59 // Process from the end backwards until we hit right_position_.
60 for (int i = vital::WaveFrame::kWaveformSize; i >= 0; --i) {
61 float t = i / (vital::WaveFrame::kWaveformSize - 1.0f);
62 if (t <= right_position_)
63 break;
64
65 wave_frame->time_domain[i] *= applyWindow((1.0f - t) / (1.0f - right_position_));
66 }
67
68 wave_frame->toFrequencyDomain();
69}
70
73 data["left_position"] = left_position_;
74 data["right_position"] = right_position_;
75 return data;
76}
77
80 left_position_ = data["left_position"];
81 right_position_ = data["right_position"];
82}
83
86 interpolate(keyframe, position);
87 return keyframe;
88}
89
90void WaveWindowModifier::render(vital::WaveFrame* wave_frame, float position) {
91 // Interpolate parameters and apply the chosen window shape before rendering.
92 interpolate(&compute_frame_, position);
94 compute_frame_.render(wave_frame);
95}
96
100
103 data["window_shape"] = window_shape_;
104 return data;
105}
106
109 window_shape_ = data["window_shape"];
110}
111
113 WavetableKeyframe* wavetable_keyframe = keyframes_[index].get();
114 return dynamic_cast<WaveWindowModifier::WaveWindowModifierKeyframe*>(wavetable_keyframe);
115}
A keyframe class that stores the window shape and positions at a given table position.
Definition wave_window_modifier.h:51
json stateToJson() override
Serializes the state of this keyframe to a JSON object.
Definition wave_window_modifier.cpp:71
WaveWindowModifierKeyframe()
Constructs a WaveWindowModifierKeyframe with a default window shape and positions.
Definition wave_window_modifier.cpp:24
void render(vital::WaveFrame *wave_frame) override
Renders the waveform of this keyframe into a WaveFrame.
Definition wave_window_modifier.cpp:49
WindowShape window_shape_
The chosen window shape for this keyframe.
Definition wave_window_modifier.h:116
float right_position_
The right boundary of the windowing region.
Definition wave_window_modifier.h:115
float left_position_
The left boundary of the windowing region.
Definition wave_window_modifier.h:114
void setWindowShape(WindowShape window_shape)
Sets the window shape for this keyframe.
Definition wave_window_modifier.h:103
void jsonToState(json data) override
Restores the keyframe's state from a JSON object.
Definition wave_window_modifier.cpp:78
void interpolate(const WavetableKeyframe *from_keyframe, const WavetableKeyframe *to_keyframe, float t) override
Linearly interpolates between two keyframes.
Definition wave_window_modifier.cpp:39
void copy(const WavetableKeyframe *keyframe) override
Copies the state from another keyframe of the same type.
Definition wave_window_modifier.cpp:32
json stateToJson() override
Serializes the component’s state and all keyframes to a JSON object.
Definition wave_window_modifier.cpp:101
void render(vital::WaveFrame *wave_frame, float position) override
Renders the waveform at a given position into a WaveFrame.
Definition wave_window_modifier.cpp:90
static float applyWindow(WindowShape window_shape, float t)
Applies the chosen window shape to a given normalized position.
Definition wave_window_modifier.cpp:10
WaveWindowModifierKeyframe compute_frame_
A keyframe for intermediate computations.
Definition wave_window_modifier.h:156
WaveWindowModifierKeyframe * getKeyframe(int index)
Retrieves a WaveWindowModifierKeyframe by index.
Definition wave_window_modifier.cpp:112
WindowShape window_shape_
The global window shape used.
Definition wave_window_modifier.h:157
void jsonToState(json data) override
Restores the component’s state from a JSON object.
Definition wave_window_modifier.cpp:107
WavetableComponentFactory::ComponentType getType() override
Returns the type of this WavetableComponent.
Definition wave_window_modifier.cpp:97
WavetableKeyframe * createKeyframe(int position) override
Creates a new keyframe at a given position.
Definition wave_window_modifier.cpp:84
WindowShape
Defines different windowing curves.
Definition wave_window_modifier.h:25
@ kWiggle
A more complex wiggle-based shape.
Definition wave_window_modifier.h:30
@ kCos
A cosine-based window (smooth rise/fall).
Definition wave_window_modifier.h:26
@ kHalfSin
A half-sine window shape.
Definition wave_window_modifier.h:27
@ kSquare
A sudden step (square) window.
Definition wave_window_modifier.h:29
ComponentType
Enumerates all known WavetableComponents, including sources and modifiers.
Definition wavetable_component_factory.h:28
@ kWaveWindow
Modifier that applies window functions to the wave.
Definition wavetable_component_factory.h:37
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
nlohmann::json json
Definition line_generator.h:7
constexpr mono_float kPi
Pi constant.
Definition common.h:36