20 int getFirstNonZeroSample(
const float* audio_buffer,
int num_samples) {
21 for (
int i = 0; i < num_samples; ++i) {
30 for (
int i = 0; i <
groups_.size(); ++i) {
45 if (index < 0 || index >=
groups_.size() - 1)
52 if (index < 0 || index >=
groups_.size())
55 std::unique_ptr<WavetableGroup> group = std::move(
groups_[index]);
78 float max_value = 0.0f;
79 float min_value = 0.0f;
86 return max_value - min_value;
90 int last_waveframe = 0;
91 bool shepard =
groups_.size() > 0;
94 last_waveframe = std::max(last_waveframe, group->getLastKeyframePosition());
95 shepard = shepard && group->isShepardTone();
100 float max_span = 0.0f;
101 for (
int i = 0; i < last_waveframe + 1; ++i)
102 max_span = std::max(
render(i), max_span);
119 int total_samples = num_frames * frame_size;
120 for (
int i = 0; i < num_frames; ++i) {
131 float* output_buffer = buffer + (i * frame_size);
142 float max_value = 1.0f;
143 for (
int i = 0; i < total_samples; ++i)
144 max_value = std::max(max_value, fabsf(buffer[i]));
146 float scale = 1.0f / max_value;
147 for (
int i = 0; i < total_samples; ++i)
179 for (
int i = 0; i < num_shapes; ++i) {
198 int beginning_sample = getFirstNonZeroSample(audio_buffer, num_samples);
199 int shortened_num_samples = num_samples - beginning_sample;
202 else if (load_style ==
kTtwt)
218 file_source->
loadBuffer(audio_buffer, num_samples, sample_rate);
226 int num_cycles = std::max<int>(1, num_samples / window_size);
234 int last_sample_position = num_samples - window_size;
235 last_sample_position = std::min<int>(file_source->
getKeyframe(1)->
position() * window_size, last_sample_position);
244 int sample_rate,
bool ttwt) {
246 static constexpr float kMaxTTWTPeriod = .02f;
252 file_source->
loadBuffer(audio_buffer, num_samples, sample_rate);
254 file_source->
detectPitch(kMaxTTWTPeriod * sample_rate);
278 file_source->
loadBuffer(audio_buffer, num_samples, sample_rate);
314 if (!data.count(
"version") || !data.count(
"groups") || !data.count(
"name"))
317 json groups_data = data[
"groups"];
318 return groups_data.is_array();
324 std::string version =
"0.0.0";
325 if (data.count(
"version")) {
326 std::string ver = data[
"version"];
332 const std::string kOldOrder[] = {
333 "Wave Source",
"Line Source",
"Audio File Source",
"Phase Shift",
"Wave Window",
334 "Frequency Filter",
"Slew Limiter",
"Wave Folder",
"Wave Warp"
336 json json_groups = data[
"groups"];
338 for (
json json_group : json_groups) {
339 json json_components = json_group[
"components"];
341 for (
json json_component : json_components) {
342 int int_type = json_component[
"type"];
343 json_component[
"type"] = kOldOrder[int_type];
345 new_components.push_back(json_component);
347 json_group[
"components"] = new_components;
348 new_groups.push_back(json_group);
350 data[
"groups"] = new_groups;
355 json json_groups = data[
"groups"];
357 for (
json json_group : json_groups) {
358 json json_components = json_group[
"components"];
360 for (
json json_component : json_components) {
361 std::string type = json_component[
"type"];
362 if (type ==
"Audio File Source")
365 new_components.push_back(json_component);
368 json_group[
"components"] = new_components;
369 new_groups.push_back(json_group);
372 data[
"groups"] = new_groups;
376 data[
"remove_all_dc"] =
false;
380 json json_groups = data[
"groups"];
382 for (
json json_group : json_groups) {
383 json json_components = json_group[
"components"];
385 for (
json json_component : json_components) {
386 std::string type = json_component[
"type"];
387 if (type ==
"Wave Source" || type ==
"Shepard Tone Source") {
388 json old_keyframes = json_component[
"keyframes"];
390 for (
json json_keyframe : old_keyframes) {
392 new_keyframes.push_back(json_keyframe);
395 json_component[
"keyframes"] = new_keyframes;
398 new_components.push_back(json_component);
401 json_group[
"components"] = new_components;
402 new_groups.push_back(json_group);
405 data[
"groups"] = new_groups;
409 data[
"full_normalize"] =
false;
415 json json_groups = data[
"groups"];
417 for (
json json_group : json_groups) {
418 json json_components = json_group[
"components"];
420 for (
json json_component : json_components) {
421 std::string type = json_component[
"type"];
422 if (type ==
"Line Source") {
423 json old_keyframes = json_component[
"keyframes"];
424 int num_points = json_component[
"num_points"];
425 json_component[
"num_points"] = num_points + 2;
429 for (
json json_keyframe : old_keyframes) {
430 json point_data = json_keyframe[
"points"];
431 json power_data = json_keyframe[
"powers"];
432 for (
int i = 0; i < num_points; ++i) {
433 float x = point_data[2 * i];
434 float y = point_data[2 * i + 1];
435 line_converter.
setPoint(i + 1, { x, y * 0.5f + 0.5f });
436 line_converter.
setPower(i + 1, power_data[i]);
438 float start_x = point_data[0];
439 float start_y = point_data[1];
440 float end_x = point_data[2 * (num_points - 1)];
441 float end_y = point_data[2 * (num_points - 1) + 1];
443 float range_x = start_x - end_x + 1.0f;
445 if (range_x < 0.001f)
446 y = 0.5f * (start_y + end_y);
448 float t = (1.0f - end_x) / range_x;
452 line_converter.
setPoint(0, { 0.0f, y * 0.5f + 0.5f });
453 line_converter.
setPoint(num_points + 1, { 1.0f, y * 0.5f + 0.5f });
455 line_converter.
setPower(num_points + 1, 0.0f);
457 json_keyframe[
"line"] = line_converter.
stateToJson();
458 new_keyframes.push_back(json_keyframe);
461 json_component[
"keyframes"] = new_keyframes;
464 new_components.push_back(json_component);
467 json_group[
"components"] = new_components;
468 new_groups.push_back(json_group);
471 data[
"groups"] = new_groups;
481 json_groups.push_back(group->stateToJson());
484 {
"groups", json_groups },
487 {
"version", ProjectInfo::versionString },
506 std::string name =
"";
507 if (data.count(
"name"))
508 name = data[
"name"].get<std::string>();
511 std::string author =
"";
512 if (data.count(
"author"))
513 author = data[
"author"].get<std::string>();
516 if (data.count(
"remove_all_dc"))
518 if (data.count(
"full_normalize"))
523 json json_groups = data[
"groups"];
524 for (
const json& json_group : json_groups) {
int getSamplesNeeded()
Definition file_source.h:117
force_inline void setStartPosition(double start_position)
Definition file_source.h:119
A WavetableComponent that uses an external audio sample as its source.
Definition file_source.h:23
void loadBuffer(const float *buffer, int size, int sample_rate)
Loads audio data into the file source buffer.
Definition file_source.cpp:363
double getWindowSize()
Definition file_source.h:181
void detectPitch(int max_period=vital::WaveFrame::kWaveformSize)
Attempts to detect pitch in the loaded sample to determine window size automatically.
Definition file_source.cpp:376
FadeStyle
Different methods to blend or interpolate the loaded audio window into a wavetable frame.
Definition file_source.h:38
@ kWaveBlend
Blend windowed segments into each other.
Definition file_source.h:39
@ kNoInterpolate
Use a single segment, no blending.
Definition file_source.h:40
void setFadeStyle(FadeStyle fade_style)
Definition file_source.h:178
void setPhaseStyle(PhaseStyle phase_style)
Definition file_source.cpp:337
void detectWaveEditTable()
Detects if the source audio can form a WaveEdit-style wavetable (special format).
Definition file_source.cpp:384
FileSourceKeyframe * getKeyframe(int index)
Definition file_source.cpp:332
@ kNone
Keep phases as-is.
Definition file_source.h:51
@ kVocode
Assign random phases for vocoding-like effect.
Definition file_source.h:53
A class for generating and storing a line shape, defined by a series of points and associated powers.
Definition line_generator.h:20
std::string getName() const
Gets the current name of the line.
Definition line_generator.h:198
force_inline void setPower(int index, float power)
Sets the power for a specific point.
Definition line_generator.h:349
force_inline void setPoint(int index, std::pair< float, float > point)
Sets the position of a specific point.
Definition line_generator.h:337
static bool isValidJson(json data)
Checks if a given JSON object contains valid line data.
Definition line_generator.cpp:116
void jsonToState(json data)
Restores the line state from a given JSON object.
Definition line_generator.cpp:125
force_inline void setNumPoints(int num_points)
Sets the number of points currently in use.
Definition line_generator.h:360
json stateToJson()
Converts the current state of the line into a JSON object.
Definition line_generator.cpp:96
static void convertPcmToFloatBuffer(json &data, const std::string &field)
Converts a PCM buffer field in JSON to a float buffer in base64.
Definition load_save.cpp:61
static int compareVersionStrings(String a, String b)
Compares two version strings.
Definition load_save.cpp:1895
static void convertBufferToPcm(json &data, const std::string &field)
Converts a float buffer field in JSON to PCM format in base64.
Definition load_save.cpp:44
A keyframe class that represents a particular line-based waveform configuration at a given position.
Definition wave_line_source.h:36
const LineGenerator * getLineGenerator() const
Provides const access to the underlying LineGenerator.
Definition wave_line_source.h:134
A WavetableComponent that generates waveforms from a series of line segments.
Definition wave_line_source.h:23
WaveLineSourceKeyframe * getKeyframe(int index)
Retrieves a WaveLineSourceKeyframe by index.
Definition wave_line_source.cpp:116
A WavetableComponent that acts as a direct source of waveforms.
Definition wave_source.h:25
WaveSourceKeyframe * getKeyframe(int index)
Retrieves a WaveSourceKeyframe by index.
Definition wave_source.cpp:51
A keyframe that holds a single WaveFrame and supports various interpolation methods.
Definition wave_source.h:92
vital::WaveFrame * wave_frame()
Provides direct access to the stored WaveFrame.
Definition wave_source.h:107
@ kNone
No interpolation, just jumps between keyframes.
Definition wavetable_component.h:39
WavetableKeyframe * insertNewKeyframe(int position)
Inserts a new keyframe at the given position, creating and sorting it into the array.
Definition wavetable_component.cpp:8
void setInterpolationStyle(InterpolationStyle type)
Sets the global interpolation style.
Definition wavetable_component.h:209
void initPredefinedWaves()
Definition wavetable_creator.cpp:171
void initFromLineGenerator(LineGenerator *line_generator)
Definition wavetable_creator.cpp:292
bool full_normalize_
Definition wavetable_creator.h:159
void removeGroup(int index)
Definition wavetable_creator.cpp:51
json updateJson(json data)
Definition wavetable_creator.cpp:321
static bool isValidJson(json data)
Checks if a given JSON data represents a valid wavetable creator state.
Definition wavetable_creator.cpp:309
vital::WaveFrame compute_frame_combine_
Definition wavetable_creator.h:153
void moveUp(int index)
Definition wavetable_creator.cpp:37
void initFromPitchedAudioFile(const float *audio_buffer, int num_samples, int sample_rate)
Definition wavetable_creator.cpp:271
void addGroup(WavetableGroup *group)
Definition wavetable_creator.h:53
void loadDefaultCreator()
Definition wavetable_creator.cpp:163
void init()
Definition wavetable_creator.cpp:151
void clear()
Definition wavetable_creator.cpp:157
AudioFileLoadStyle
Defines how audio files are interpreted when loading into a wavetable.
Definition wavetable_creator.h:33
@ kTtwt
Similar to vocoded but optimized for TTWT (text-to-wavetable).
Definition wavetable_creator.h:37
@ kVocoded
Apply vocoder-like analysis to extract fundamental cycles.
Definition wavetable_creator.h:36
@ kPitched
Attempts to extract pitch-based cycles from the audio.
Definition wavetable_creator.h:38
json stateToJson()
Definition wavetable_creator.cpp:477
void jsonToState(json data)
Definition wavetable_creator.cpp:493
int getGroupIndex(WavetableGroup *group)
Definition wavetable_creator.cpp:29
void initFromAudioFile(const float *audio_buffer, int num_samples, int sample_rate, AudioFileLoadStyle load_style, FileSource::FadeStyle fade_style)
Definition wavetable_creator.cpp:196
bool remove_all_dc_
Definition wavetable_creator.h:160
vital::Wavetable * wavetable_
Definition wavetable_creator.h:158
void moveDown(int index)
Definition wavetable_creator.cpp:44
void render()
Definition wavetable_creator.cpp:89
void initFromVocodedAudioFile(const float *audio_buffer, int num_samples, int sample_rate, bool ttwt)
Definition wavetable_creator.cpp:243
std::vector< std::unique_ptr< WavetableGroup > > groups_
Definition wavetable_creator.h:155
vital::WaveFrame compute_frame_
Definition wavetable_creator.h:154
void renderToBuffer(float *buffer, int num_frames, int frame_size)
Definition wavetable_creator.cpp:117
void postRender(float max_span)
Definition wavetable_creator.cpp:109
void initFromSplicedAudioFile(const float *audio_buffer, int num_samples, int sample_rate, FileSource::FadeStyle fade_style)
Definition wavetable_creator.cpp:210
A class representing a group of WavetableComponents combined to form part of a wavetable.
Definition wavetable_group.h:24
void jsonToState(json data)
Restores this group's state from a JSON object.
Definition wavetable_group.cpp:121
void addComponent(WavetableComponent *component)
Adds a new WavetableComponent to this group.
Definition wavetable_group.h:44
void loadDefaultGroup()
Loads a default group configuration (e.g., a basic wave source).
Definition wavetable_group.cpp:86
int position() const
Gets the wavetable frame position of this keyframe.
Definition wavetable_keyframe.h:81
static const WaveFrame * getWaveFrame(Shape shape)
Retrieves a pointer to a WaveFrame representing a predefined shape.
Definition wave_frame.h:167
Shape
Supported predefined shapes.
Definition wave_frame.h:146
@ kNumShapes
Definition wave_frame.h:153
void copy(const WaveFrame *other)
Copies another WaveFrame's time and frequency domain data into this one.
Definition wave_frame.cpp:57
float sample_rate
The sample rate associated with this frame.
Definition wave_frame.h:123
void addFrom(WaveFrame *source)
Adds another WaveFrame's data to this one, sample-by-sample, in both time and frequency domains.
Definition wave_frame.cpp:50
float frequency_ratio
The frequency ratio for this frame (e.g., for pitch scaling).
Definition wave_frame.h:122
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
int index
The index of this frame in a wavetable.
Definition wave_frame.h:121
void removedDc()
Removes the DC offset from the waveform.
Definition wave_frame.cpp:90
void multiply(mono_float value)
Multiplies all samples in both time and frequency domains by a given value.
Definition wave_frame.cpp:16
void clear()
Clears the waveform data, resetting it to default states.
Definition wave_frame.cpp:7
void loadWaveFrame(const WaveFrame *wave_frame)
Load a WaveFrame into the wavetable at the frame index specified by the WaveFrame.
Definition wavetable.cpp:89
std::string getAuthor()
Get the author of this wavetable.
Definition wavetable.h:122
force_inline void setShepardTable(bool shepard)
Enable or disable "Shepard" table mode.
Definition wavetable.h:338
std::string getName()
Get the user-defined name of this wavetable.
Definition wavetable.h:115
void setName(const std::string &name)
Set a user-defined name for this wavetable.
Definition wavetable.h:129
void setAuthor(const std::string &author)
Set the author for this wavetable.
Definition wavetable.h:136
void setFrequencyRatio(float frequency_ratio)
Set the frequency ratio for this wavetable.
Definition wavetable.cpp:81
void setSampleRate(float rate)
Set the sample rate associated with this wavetable.
Definition wavetable.cpp:85
void setNumFrames(int num_frames)
Set the number of frames in the wavetable.
Definition wavetable.cpp:27
void postProcess(float max_span)
Post-process the loaded wavetable frames, scaling them based on a maximum span.
Definition wavetable.cpp:102
#define VITAL_ASSERT(x)
Definition common.h:11
nlohmann::json json
Definition line_generator.h:7
force_inline poly_float interpolate(poly_float from, poly_float to, mono_float t)
Performs a linear interpolation between two poly_floats using a scalar t in [0..1].
Definition poly_utils.h:182
constexpr int kNumOscillatorWaveFrames
Number of wave frames in each oscillator’s wavetable.
Definition synth_constants.h:19