16 const float *f0,
size_t f0_capacity,
17 const float *gaussian,
size_t gaussian_capacity,
18 float *output,
size_t output_capacity,
19 float *phase_scratch,
size_t scratch_capacity,
20 size_t frames,
size_t upsample,
size_t harmonics,
21 float sample_rate,
float voiced_threshold,
22 float sine_amp,
float noise_std,
int weighted_fma_interpolation) {
23 if (!frames || upsample < 4 || !harmonics || !isfinite(sample_rate) ||
24 !isfinite(voiced_threshold) || !isfinite(sine_amp) ||
25 !isfinite(noise_std) || sample_rate <= 0.0f || sine_amp < 0.0f ||
26 noise_std < 0.0f || frames > SIZE_MAX / upsample)
28 const size_t samples = frames * upsample;
29 if (samples > SIZE_MAX / harmonics ||
30 frames > SIZE_MAX / harmonics)
33 const size_t output_need = samples * harmonics;
34 const size_t phase_need = frames * harmonics;
35 if (phase_need > SIZE_MAX - output_need)
37 const size_t scratch_need = phase_need + output_need;
38 if (f0_capacity < frames || gaussian_capacity < output_need ||
39 output_capacity < output_need || scratch_capacity < scratch_need)
53 for (
size_t harmonic = 0; harmonic < harmonics; ++harmonic) {
57 for (
size_t frame = 0; frame < frames; ++frame) {
58 const float hz = f0[frame] * (float)(harmonic + 1);
59 const float radians = hz / sample_rate;
60 const float fraction = radians - floorf(radians);
63 phase_scratch[frame * harmonics + harmonic] =
64 phase * (float)upsample;
65 if (!isfinite(phase_scratch[frame * harmonics + harmonic]))
69 float *staged = phase_scratch + phase_need;
72 for (
size_t sample = 0; sample < samples; ++sample) {
73 const size_t frame = sample / upsample;
74 const float uv = f0[frame] > voiced_threshold ? 1.0f : 0.0f;
75 const float amplitude = uv * noise_std +
76 (1.0f - uv) * (sine_amp / 3.0f);
79 const float inverse_scale = 1.0f / (float)upsample;
80 float position = inverse_scale * ((float)sample + 0.5f) - 0.5f;
81 if (position < 0.0f) position = 0.0f;
82 if (position > (
float)(frames - 1)) position = (float)(frames - 1);
83 const size_t left = (size_t)position;
85 const float right_weight = position - (float)
left;
86 for (
size_t harmonic = 0; harmonic < harmonics; ++harmonic) {
87 const float a = phase_scratch[
left * harmonics + harmonic];
88 const float b = phase_scratch[
right * harmonics + harmonic];
93 const float phase = weighted_fma_interpolation
94 ? fmaf(a, 1.0f - right_weight, b * right_weight)
95 : a + (b - a) * right_weight;
96 const float value = sinf(phase) * sine_amp * uv +
97 amplitude * gaussian[sample * harmonics + harmonic];
99 staged[sample * harmonics + harmonic] = value;
102 memcpy(output, staged, output_need *
sizeof(
float));
107 const float *f0,
size_t f0_capacity,
108 const float *gaussian,
size_t gaussian_capacity,
109 float *output,
size_t output_capacity,
110 float *phase_scratch,
size_t scratch_capacity,
111 size_t frames,
size_t upsample,
size_t harmonics,
112 float sample_rate,
float voiced_threshold,
113 float sine_amp,
float noise_std) {
115 gaussian_capacity, output, output_capacity, phase_scratch,
116 scratch_capacity, frames, upsample, harmonics, sample_rate,
117 voiced_threshold, sine_amp, noise_std, 0);
121 const float *f0,
size_t f0_capacity,
122 const float *gaussian,
size_t gaussian_capacity,
123 float *output,
size_t output_capacity,
124 float *phase_scratch,
size_t scratch_capacity,
125 size_t frames,
size_t upsample,
size_t harmonics,
126 float sample_rate,
float voiced_threshold,
127 float sine_amp,
float noise_std) {
129 gaussian_capacity, output, output_capacity, phase_scratch,
130 scratch_capacity, frames, upsample, harmonics, sample_rate,
131 voiced_threshold, sine_amp, noise_std, 1);
static int audio_harmonic_source_impl_f32(const float *f0, size_t f0_capacity, const float *gaussian, size_t gaussian_capacity, float *output, size_t output_capacity, float *phase_scratch, size_t scratch_capacity, size_t frames, size_t upsample, size_t harmonics, float sample_rate, float voiced_threshold, float sine_amp, float noise_std, int weighted_fma_interpolation)
int audio_harmonic_source_weighted_fma_checked_f32(const float *f0, size_t f0_capacity, const float *gaussian, size_t gaussian_capacity, float *output, size_t output_capacity, float *phase_scratch, size_t scratch_capacity, size_t frames, size_t upsample, size_t harmonics, float sample_rate, float voiced_threshold, float sine_amp, float noise_std)
int audio_harmonic_source_checked_f32(const float *f0, size_t f0_capacity, const float *gaussian, size_t gaussian_capacity, float *output, size_t output_capacity, float *phase_scratch, size_t scratch_capacity, size_t frames, size_t upsample, size_t harmonics, float sample_rate, float voiced_threshold, float sine_amp, float noise_std)