15 static constexpr mono_float kMaxFormantShift = 1.0f;
20 static constexpr mono_float kMaxEvenOddFormantShift = 2.0f;
25 static constexpr mono_float kMaxHarmonicScale = 4.0f;
30 static constexpr mono_float kMaxInharmonicScale = 12.0f;
35 static constexpr int kMaxSplitScale = 2;
40 static constexpr mono_float kMaxSplitShift = 24.0f;
45 static constexpr int kRandomAmplitudeStages = 16;
50 static constexpr mono_float kPhaseDisperseScale = 0.05f;
55 static constexpr mono_float kSkewScale = 16.0f;
72 transform->transformRealInverse(buffer + poly_float::kSize);
74 for (
int i = 0; i < poly_float::kSize; ++i) {
91 static force_inline void transformAndWrapBuffer(FourierTransform* transform, poly_float* buffer) {
92 transformAndWrapBuffer(transform, (
mono_float*)buffer);
109 static void passthroughMorph(
const Wavetable::WavetableData* wavetable_data,
110 int wavetable_index, poly_float* dest, FourierTransform* transform,
111 float shift,
int last_harmonic,
const poly_float* data_buffer) {
112 const poly_float* frequency_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
113 const poly_float* normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
115 poly_float* wave_start = dest + 1;
116 int last_index = 2 * last_harmonic / poly_float::kSize;
118 for (
int i = 0; i <= last_index; ++i)
119 wave_start[i] = frequency_amplitudes[i] * normalized_frequencies[i];
121 for (
int i = last_index + 1; i < kMaxPolyIndex; ++i)
122 wave_start[i] = 0.0f;
124 transformAndWrapBuffer(transform, dest);
141 static void shepardMorph(
const Wavetable::WavetableData* wavetable_data,
142 int wavetable_index, poly_float* dest, FourierTransform* transform,
143 float shift,
int last_harmonic,
const poly_float* data_buffer) {
144 static constexpr float kMinAmplitudeRatio = 2.0f;
145 static constexpr float kMinAmplitudeAdd = 0.001f;
146 const poly_float* poly_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
147 const poly_float* poly_normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
149 poly_float* poly_wave_start = dest + 1;
150 int last_index = 2 * last_harmonic / poly_float::kSize;
152 float regular_amount = 1.0f - shift;
153 for (
int i = 0; i <= last_index; ++i) {
154 poly_float value = poly_amplitudes[i] * poly_normalized_frequencies[i] * regular_amount;
158 for (
int i = last_index + 1; i < kMaxPolyIndex; ++i)
159 poly_wave_start[i] = 0.0f;
161 const mono_float* frequency_amplitudes = (
const mono_float*)wavetable_data->frequency_amplitudes[wavetable_index];
162 const mono_float* normalized = (
const mono_float*)wavetable_data->normalized_frequencies[wavetable_index];
166 for (
int i = 0; i <= last_harmonic; i += 2) {
167 int real_index = 2 * i;
168 int imag_index = real_index + 1;
170 float fundamental_amplitude = frequency_amplitudes[real_index];
171 float shepard_amplitude = frequency_amplitudes[i];
172 float amplitude = fundamental_amplitude + (shepard_amplitude - fundamental_amplitude) * shift;
174 float ratio = (fundamental_amplitude + kMinAmplitudeAdd) / (shepard_amplitude + kMinAmplitudeAdd);
176 if (ratio < kMinAmplitudeRatio && ratio > (1.0f / kMinAmplitudeRatio)) {
177 float fundamental_phase = phases[real_index] * (0.5f /
kPi);
178 float shepard_phase = phases[i] * (0.5f /
kPi);
179 float delta_phase = shepard_phase - fundamental_phase;
180 int wraps = delta_phase;
181 wraps = (wraps + 1) / 2;
182 delta_phase -= 2.0f * wraps;
184 float phase = fundamental_phase + delta_phase * shift;
189 float fundamental_real = normalized[real_index];
190 real = (normalized[i] - fundamental_real) * shift + fundamental_real;
191 float fundamental_imag = normalized[real_index + 1];
192 imag = (normalized[i + 1] - fundamental_imag) * shift + fundamental_imag;
195 wave_start[real_index] = amplitude * real;
196 wave_start[imag_index] = amplitude * imag;
199 transformAndWrapBuffer(transform, dest);
216 static void wavetableSkewMorph(
const Wavetable::WavetableData* wavetable_data,
217 int wavetable_index, poly_float* dest, FourierTransform* transform,
218 float shift,
int last_harmonic,
const poly_float* data_buffer) {
221 int num_frames = wavetable_data->num_frames;
222 if (num_frames <= 1) {
223 passthroughMorph(wavetable_data, wavetable_index, dest, transform, shift, last_harmonic, data_buffer);
227 float dc_amplitude = wavetable_data->frequency_amplitudes[wavetable_index][0][0];
228 float dc_real = wavetable_data->normalized_frequencies[wavetable_index][0][0];
229 float dc_imag = wavetable_data->normalized_frequencies[wavetable_index][0][1];
230 wave_start[0] = dc_amplitude * dc_real;
231 wave_start[1] = dc_amplitude * dc_imag;
234 float base_wavetable_t = wavetable_index / max_frame;
235 for (
int i = 1; i <= last_harmonic; ++i) {
237 poly_float base_value = poly_float(1.0f) -
utils::mod((base_wavetable_t + shift * shift_scale) * 0.5f) * 2.0f;
238 float shifted_index = (1.0f -
poly_float::abs(base_value)[0]) * max_frame;
239 int from_index = std::min<int>(shifted_index, num_frames - 2);
240 float t = std::min(1.0f, shifted_index - from_index);
241 int to_index = from_index + 1;
243 int real_index = 2 * i;
244 int imaginary_index = real_index + 1;
245 const mono_float* from_amplitudes = (
const mono_float*)wavetable_data->frequency_amplitudes[from_index];
246 const mono_float* to_amplitudes = (
const mono_float*)wavetable_data->frequency_amplitudes[to_index];
247 float amplitude =
utils::interpolate(from_amplitudes[real_index], to_amplitudes[real_index], t);
249 const mono_float* from_normalized = (
const mono_float*)wavetable_data->normalized_frequencies[from_index];
250 const mono_float* to_normalized = (
const mono_float*)wavetable_data->normalized_frequencies[to_index];
251 float real =
utils::interpolate(from_normalized[real_index], to_normalized[real_index], t);
252 float imag =
utils::interpolate(from_normalized[imaginary_index], to_normalized[imaginary_index], t);
254 wave_start[real_index] = amplitude * real;
255 wave_start[imaginary_index] = amplitude * imag;
259 wave_start[i] = 0.0f;
261 transformAndWrapBuffer(transform, dest);
277 static void phaseMorph(
const Wavetable::WavetableData* wavetable_data,
278 int wavetable_index, poly_float* dest, FourierTransform* transform,
279 float phase_shift,
int last_harmonic,
const poly_float* data_buffer) {
280 static constexpr float kCenterMorph = 24.0f;
282 const poly_float* frequency_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
283 const poly_float* normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
285 poly_float* wave_start = dest + 1;
286 int last_index = 2 * last_harmonic / poly_float::kSize;
288 float offset = -(kCenterMorph - 1.0f) * (kCenterMorph - 1.0f) * phase_shift;
289 poly_float value_offset(0.0f, 0.0f, 1.0f, 1.0f);
290 poly_float phase_offset(0.25f, 0.0f, 0.25f, 0.0f);
291 poly_float scale = 0.5f /
kPi;
292 for (
int i = 0; i <= last_index; ++i) {
293 poly_float amplitude = frequency_amplitudes[i];
294 poly_float normalized = normalized_frequencies[i];
295 poly_float index = value_offset + 2.0f * i;
297 poly_float delta_center = (index - kCenterMorph) * (index - kCenterMorph) * phase_shift + offset;
298 poly_float phase =
utils::mod(delta_center * scale + phase_offset);
301 poly_float match_mult = normalized * shift;
308 for (
int i = last_index + 1; i < kMaxPolyIndex; ++i)
309 wave_start[i] = 0.0f;
311 transformAndWrapBuffer(transform, dest);
327 static void smearMorph(
const Wavetable::WavetableData* wavetable_data,
328 int wavetable_index, poly_float* dest, FourierTransform* transform,
329 float smear,
int last_harmonic,
const poly_float* data_buffer) {
330 const poly_float* frequency_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
331 const poly_float* normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
333 poly_float* wave_start = dest + 1;
334 int last_index = 2 * last_harmonic / poly_float::kSize;
336 poly_float amplitude = frequency_amplitudes[0] * (1.0f - smear);
337 wave_start[0] = amplitude * normalized_frequencies[0];
339 for (
int i = 1; i <= last_index; ++i) {
340 poly_float original_amplitude = frequency_amplitudes[i];
343 wave_start[i] = amplitude * normalized_frequencies[i];
344 amplitude *= (i + 0.25f) / i;
347 for (
int i = last_index + 1; i < kMaxPolyIndex; ++i)
348 wave_start[i] = 0.0f;
350 transformAndWrapBuffer(transform, dest);
366 static void lowPassMorph(
const Wavetable::WavetableData* wavetable_data,
367 int wavetable_index, poly_float* dest, FourierTransform* transform,
368 float cutoff_t,
int last_harmonic,
const poly_float* data_buffer) {
369 const poly_float* frequency_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
370 const poly_float* normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
372 poly_float* wave_start = dest + 1;
374 int last_index = 2 * last_harmonic / poly_float::kSize;
375 float poly_cutoff = std::min(last_index + 1.0f, 2.0f * cutoff / poly_float::kSize);
376 last_index = std::min<int>(last_index, poly_cutoff);
377 float t = poly_float::kSize * (poly_cutoff - last_index) / 2.0f;
379 for (
int i = 0; i <= last_index; ++i)
380 wave_start[i] = frequency_amplitudes[i] * normalized_frequencies[i];
382 for (
int i = last_index + 1; i <= kMaxPolyIndex; ++i)
383 wave_start[i] = 0.0f;
385 poly_float last_mult = 1.0f;
387 last_mult = poly_float(1.0f, 1.0f, t - 1.0f, t - 1.0f);
389 last_mult = poly_float(t, t, 0.0f, 0.0f);
391 wave_start[last_index] = wave_start[last_index] * last_mult;
393 transformAndWrapBuffer(transform, dest);
409 static void highPassMorph(
const Wavetable::WavetableData* wavetable_data,
410 int wavetable_index, poly_float* dest, FourierTransform* transform,
411 float cutoff_t,
int last_harmonic,
const poly_float* data_buffer) {
412 const poly_float* frequency_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
413 const poly_float* normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
415 poly_float* wave_start = dest + 1;
417 cutoff *= (kNumHarmonics + 1.0f) / kNumHarmonics;
418 int last_index = 2 * last_harmonic / poly_float::kSize;
419 float poly_cutoff = std::min(last_index + 1.0f, 2.0f * cutoff / poly_float::kSize);
420 int start_index = poly_cutoff;
421 float t = poly_float::kSize * (poly_cutoff - start_index) / 2.0f;
423 for (
int i = 0; i < start_index; ++i)
424 wave_start[i] = 0.0f;
426 for (
int i = start_index; i <= last_index; ++i)
427 wave_start[i] = frequency_amplitudes[i] * normalized_frequencies[i];
429 for (
int i = last_index + 1; i <= kMaxPolyIndex; ++i)
430 wave_start[i] = 0.0f;
432 poly_float last_mult = 1.0f;
434 last_mult = poly_float(0.0f, 0.0f, 2.0f - t, 2.0f - t);
436 last_mult = poly_float(1.0f - t, 1.0f - t, 1.0f, 1.0f);
438 wave_start[start_index] = wave_start[start_index] * last_mult;
440 transformAndWrapBuffer(transform, dest);
457 static void evenOddVocodeMorph(
const Wavetable::WavetableData* wavetable_data,
458 int wavetable_index, poly_float* dest, FourierTransform* transform,
459 float shift,
int last_harmonic,
const poly_float* data_buffer) {
463 const mono_float* amplitudes = (
const mono_float*)wavetable_data->frequency_amplitudes[wavetable_index];
464 const mono_float* normalized = (
const mono_float*)wavetable_data->normalized_frequencies[wavetable_index];
466 float dc_amplitude = amplitudes[0];
467 wave_start[0] = dc_amplitude * normalized[0];
468 wave_start[1] = dc_amplitude * normalized[1];
470 for (
int i = 1; i <= last_index; ++i) {
471 float shifted_index = std::max(1.0f, i * shift);
472 int index_start = shifted_index;
473 index_start = index_start - (i + index_start) % 2;
474 VITAL_ASSERT(index_start >= 0 && index_start < kNumHarmonics);
476 float t = (shifted_index - index_start) * 0.5f;
477 int real_index1 = 2 * index_start;
478 int real_index2 = real_index1 + 4;
479 float amplitude_from = amplitudes[real_index1];
480 float amplitude_to = amplitudes[real_index2];
481 float real_from = amplitude_from * normalized[real_index1];
482 float real_to = amplitude_to * normalized[real_index2];
483 float imag_from = amplitude_from * normalized[real_index1 + 1];
484 float imag_to = amplitude_to * normalized[real_index2 + 1];
489 int real_index = 2 * i;
494 wave_start[i] = 0.0f;
496 transformAndWrapBuffer(transform, dest);
512 static void harmonicScaleMorph(
const Wavetable::WavetableData* wavetable_data,
513 int wavetable_index, poly_float* dest, FourierTransform* transform,
514 float shift,
int last_harmonic,
const poly_float* data_buffer) {
517 int harmonics = std::min<int>(kNumHarmonics, (last_harmonic - 1) / shift + 1);
519 const mono_float* amplitudes = (
const mono_float*)wavetable_data->frequency_amplitudes[wavetable_index];
520 const mono_float* normalized = (
const mono_float*)wavetable_data->normalized_frequencies[wavetable_index];
522 float dc_amplitude = amplitudes[0];
523 wave_start[0] = dc_amplitude * normalized[0];
524 wave_start[1] = dc_amplitude * normalized[1];
526 for (
int i = 1; i <= harmonics; ++i) {
527 float shifted_index = std::max(1.0f, (i - 1) * shift + 1);
528 int dest_index = shifted_index;
529 VITAL_ASSERT(dest_index >= 0 && dest_index <= kNumHarmonics);
531 float t = shifted_index - dest_index;
532 float real_amount = normalized[2 * i];
533 float imag_amount = normalized[2 * i + 1];
534 float amplitude = amplitudes[2 * i];
535 float amplitude1 = (1.0f - t) * amplitude;
536 float amplitude2 = t * amplitude;
538 int real_index1 = 2 * dest_index;
539 int imaginary_index1 = real_index1 + 1;
540 wave_start[real_index1] += amplitude1 * real_amount;
541 wave_start[imaginary_index1] += amplitude1 * imag_amount;
543 int real_index2 = imaginary_index1 + 1;
544 int imaginary_index2 = real_index2 + 1;
545 wave_start[real_index2] += amplitude2 * real_amount;
546 wave_start[imaginary_index2] += amplitude2 * imag_amount;
549 transformAndWrapBuffer(transform, dest);
565 static void inharmonicScaleMorph(
const Wavetable::WavetableData* wavetable_data,
566 int wavetable_index, poly_float* dest, FourierTransform* transform,
567 float mult,
int last_harmonic,
const poly_float* data_buffer) {
568 poly_float* poly_data_start = dest + 2 + kMaxPolyIndex;
570 poly_float offset(0.0f, 2.0f, 1.0f, 3.0f);
571 for (
int i = 0; i <= kMaxPolyIndex / 2; ++i) {
572 poly_float index = offset + i * 4;
576 poly_float shifted_index =
utils::max(1.0f, shift * (index - 1.0f) + 1.0f);
577 poly_data_start[2 * i] = shifted_index;
581 const mono_float* amplitudes = (
const mono_float*)wavetable_data->frequency_amplitudes[wavetable_index];
582 const mono_float* normalized = (
const mono_float*)wavetable_data->normalized_frequencies[wavetable_index];
587 float dc_amplitude = amplitudes[0];
588 wave_start[0] = dc_amplitude * normalized[0];
589 wave_start[1] = dc_amplitude * normalized[1];
591 int processed_index = 1;
592 for (; processed_index <= kNumHarmonics; ++processed_index) {
593 int index = 2 * processed_index;
594 float shifted_index = index_data[index];
595 int dest_index = shifted_index;
596 if (dest_index > 2 * last_harmonic)
598 VITAL_ASSERT(dest_index >= 0 && dest_index <= kNumHarmonics * 2);
600 float t = shifted_index - dest_index;
601 float amplitude = amplitudes[index];
602 float real = normalized[index];
603 float imag = normalized[index + 1];
607 int real_index = 2 * dest_index;
608 float value1 = (1.0f - t) * amplitude;
609 wave_start[real_index] += value1 * real;
610 wave_start[real_index + 1] += value1 * imag;
611 float value2 = t * amplitude;
612 wave_start[real_index + 2] += value2 * real;
613 wave_start[real_index + 3] += value2 * imag;
616 transformAndWrapBuffer(transform, dest);
632 static void randomAmplitudeMorph(
const Wavetable::WavetableData* wavetable_data,
633 int wavetable_index, poly_float* dest, FourierTransform* transform,
634 float shift,
int last_harmonic,
const poly_float* data_buffer) {
635 const poly_float* frequency_amplitudes = wavetable_data->frequency_amplitudes[wavetable_index];
636 const poly_float* normalized_frequencies = wavetable_data->normalized_frequencies[wavetable_index];
638 poly_float* wave_start = dest + 1;
639 int last_index = 2 * last_harmonic / poly_float::kSize;
640 int index = std::min<int>(shift, kRandomAmplitudeStages - 2);
641 float amount = shift / kRandomAmplitudeStages;
642 float t = shift - index;
643 poly_float scale = shift;
644 poly_float center = poly_float(1.0f) - scale;
645 poly_float mult = 1.0f + shift;
647 const poly_float* buffer1 = data_buffer + index * kNumHarmonics / poly_float::kSize;
648 const poly_float* buffer2 = data_buffer + (index + 1) * kNumHarmonics / poly_float::kSize;
650 poly_float random_t(amount, 1.0f - amount, amount, 1.0f - amount);
651 for (
int i = 0; i <= last_index; ++i) {
656 poly_float random1 = mult *
utils::max(center - scale * random_value1, 0.0f);
657 poly_float random2 = mult *
utils::max(center - scale * random_value2, 0.0f);
660 wave_start[i] = amplitude * normalized_frequencies[i];
662 for (
int i = last_index + 1; i <= kMaxPolyIndex; ++i)
663 wave_start[i] = 0.0f;
665 transformAndWrapBuffer(transform, dest);
static constexpr int kWaveformSize
The size of the waveform (number of samples per frame).
Definition wave_frame.h:21
static constexpr int kFrequencyBins
Number of frequency bins (equal to number of wave bits in a frame).
Definition wavetable.h:23
static constexpr int kWaveformSize
Size of each waveform frame.
Definition wavetable.h:25
#define VITAL_ASSERT(x)
Definition common.h:11
#define force_inline
Definition common.h:23
Contains faster but less accurate versions of utility math functions, such as exponential,...
const poly_mask kLeftMask
A mask identifying the left channel when comparing to kLeftOne.
Definition synth_constants.h:260
const poly_mask kSecondMask
A mask identifying the second voice slots in a polyphonic vector.
Definition synth_constants.h:269
force_inline mono_float sin(mono_float phase)
Definition futils.h:401
force_inline poly_float log2(poly_float value)
Approximates log2(value) for poly_float values using a polynomial approximation.
Definition futils.h:68
force_inline mono_float sin1(mono_float phase)
Definition futils.h:424
force_inline mono_float pow(mono_float base, mono_float exponent)
Definition futils.h:141
force_inline poly_float mod(poly_float value)
Returns the fractional part of each lane by subtracting the floored value.
Definition poly_utils.h:814
force_inline bool isFinite(poly_float value)
Checks if all lanes in a poly_float are finite.
Definition poly_utils.h:610
force_inline poly_float min(poly_float left, poly_float right)
Returns the minimum of two poly_floats lane-by-lane.
Definition poly_utils.h:334
force_inline poly_float max(poly_float left, poly_float right)
Returns the maximum of two poly_floats lane-by-lane.
Definition poly_utils.h:327
force_inline poly_float maskLoad(poly_float zero_value, poly_float one_value, poly_mask reset_mask)
Selects between two values (zero_value or one_value) based on a mask in each lane.
Definition poly_utils.h:351
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
force_inline poly_float swapStereo(poly_float value)
Swaps the left and right channels of a stereo poly_float.
Definition poly_utils.h:411
Contains classes and functions used within the Vital synthesizer framework.
constexpr mono_float kPi
Pi constant.
Definition common.h:36
constexpr int kNumOscillatorWaveFrames
Number of wave frames in each oscillator’s wavetable.
Definition synth_constants.h:19
float mono_float
Definition common.h:33
static force_inline simd_type vector_call abs(simd_type value)
Computes the absolute value of each element in the SIMD float register.
Definition poly_values.h:935