Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
dsp.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2020-2022, 2024 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
12
13#pragma once
14
15#include <algorithm>
16
17#include "utils/math_utils.h"
18
19#include "juce_wrapper.h"
20
21namespace zrythm::utils::float_ranges
22{
23
27[[using gnu: nonnull, hot]] static inline void
28fill (float * buf, float val, size_t size, bool optimized = true)
29{
30 if (optimized)
31 {
32 juce::FloatVectorOperations::fill (buf, val, size);
33 }
34 else
35 {
36 std::fill_n (buf, size, val);
37 }
38}
39
43[[using gnu: nonnull, hot]] static inline void
44clip (float * buf, float minf, float maxf, size_t size, bool optimized = true)
45{
46 if (optimized)
47 {
48 juce::FloatVectorOperations::clip (buf, buf, minf, maxf, size);
49 }
50 else
51 {
52 std::transform (buf, buf + size, buf, [minf, maxf] (float x) {
53 return std::clamp (x, minf, maxf);
54 });
55 }
56}
57
61[[using gnu: nonnull, hot]] static inline void
62copy (float * dest, const float * src, size_t size, bool optimized = true)
63{
64 if (optimized)
65 {
66 juce::FloatVectorOperations::copy (dest, src, size);
67 }
68 else
69 {
70 std::copy_n (src, size, dest);
71 }
72}
73
77[[using gnu: nonnull, hot]] static inline void
78mul_k2 (float * dest, float k, size_t size, bool optimized = true)
79{
80 if (optimized)
81 {
82 juce::FloatVectorOperations::multiply (dest, k, size);
83 }
84 else
85 {
86 std::transform (dest, dest + size, dest, [k] (float x) { return x * k; });
87 }
88}
89
93[[nodiscard]] [[using gnu: nonnull]] static inline float
94abs_max (const float * buf, size_t size, bool optimized = true)
95{
96 if (optimized)
97 {
98 auto min_and_max = juce::FloatVectorOperations::findMinAndMax (buf, size);
99 return std::max (
100 std::abs (min_and_max.getStart ()), std::abs (min_and_max.getEnd ()));
101 }
102
103 return std::abs (*std::max_element (buf, buf + size, [] (float a, float b) {
104 return std::abs (a) < std::abs (b);
105 }));
106}
107
113[[using gnu: nonnull, hot]] static inline bool
114abs_max_with_existing_peak (
115 const float * buf,
116 float * cur_peak,
117 size_t size,
118 bool optimized = true)
119{
120 float new_peak = *cur_peak;
121
122 if (optimized)
123 {
124 new_peak = abs_max (buf, size);
125 }
126 else
127 {
128 for (size_t i = 0; i < size; i++)
129 {
130 float val = fabsf (buf[i]);
131 new_peak = std::max (val, new_peak);
132 }
133 }
134
135 bool changed = !utils::math::floats_equal (new_peak, *cur_peak);
136 *cur_peak = new_peak;
137
138 return changed;
139}
140
144[[gnu::nonnull]] static inline float
145min (const float * buf, size_t size, bool optimized = true)
146{
147 if (optimized)
148 {
149 return juce::FloatVectorOperations::findMinimum (buf, size);
150 }
151
152 return *std::min_element (buf, buf + size, [] (float a, float b) {
153 return a < b;
154 });
155}
156
160[[gnu::nonnull]] static inline float
161max (const float * buf, size_t size, bool optimized = true)
162{
163 if (optimized)
164 {
165 return juce::FloatVectorOperations::findMaximum (buf, size);
166 }
167
168 return *std::max_element (buf, buf + size, [] (float a, float b) {
169 return a < b;
170 });
171}
172
176[[using gnu: nonnull, hot]] static inline void
177add2 (float * dest, const float * src, size_t count, bool optimized = true)
178{
179 if (optimized)
180 {
181 juce::FloatVectorOperations::add (dest, src, count);
182 }
183 else
184 {
185 std::transform (dest, dest + count, src, dest, std::plus<> ());
186 }
187}
188
192[[using gnu: nonnull, hot]] static inline void
193product (
194 float * dest,
195 const float * src,
196 float k,
197 size_t size,
198 bool optimized = true)
199{
200 if (optimized)
201 {
202 juce::FloatVectorOperations::copyWithMultiply (dest, src, k, size);
203 }
204 else
205 {
206 std::transform (dest, dest + size, src, dest, [k] (float x, float y) {
207 return y * k;
208 });
209 }
210}
211
215[[using gnu: nonnull, hot]] static inline void
216mix_product (
217 float * dest,
218 const float * src,
219 float k,
220 size_t size,
221 bool optimized = true)
222{
223 if (optimized)
224 {
225 juce::FloatVectorOperations::addWithMultiply (dest, src, k, size);
226 }
227 else
228 {
229 std::transform (dest, dest + size, src, dest, [k] (float x, float y) {
230 return x + y * k;
231 });
232 }
233}
234
238[[using gnu: nonnull, hot]] static inline void
239reverse (float * dest, const float * src, size_t size)
240{
241 std::reverse_copy (src, src + size, dest);
242}
243
248[[using gnu: nonnull, hot]] static inline void
249normalize (float * dest, const float * src, size_t size, bool optimize = true)
250{
251 copy (dest, src, size, optimize);
252 const float abs_peak = abs_max (dest, size, optimize);
253 mul_k2 (dest, 1.f / abs_peak, size, optimize);
254}
255
270[[gnu::nonnull]] void
272 float * dest,
273 int32_t start_offset,
274 int32_t total_frames_to_fade,
275 size_t size,
276 float fade_from_multiplier);
277
289[[gnu::nonnull]] void
291 float * dest,
292 int32_t start_offset,
293 int32_t total_frames_to_fade,
294 size_t size,
295 float fade_to_multiplier);
296
308[[gnu::nonnull]] void
310 float * l,
311 float * r,
312 size_t size,
313 bool equal_power,
314 bool optimize = true);
315
316}; // zrythm::dsp::float_ranges
constexpr bool floats_equal(T a, T b)
Checks if 2 floating point numbers are equal.
Definition math_utils.h:75
void make_mono(float *l, float *r, size_t size, bool equal_power, bool optimize=true)
Makes the two signals mono.
void linear_fade_in_from(float *dest, int32_t start_offset, int32_t total_frames_to_fade, size_t size, float fade_from_multiplier)
Calculate linear fade by multiplying from 0 to 1 for.
void linear_fade_out_to(float *dest, int32_t start_offset, int32_t total_frames_to_fade, size_t size, float fade_to_multiplier)
Calculate linear fade by multiplying from 0 to 1 for.