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#ifndef __COMMON_UTILS_DSP_H__
14#define __COMMON_UTILS_DSP_H__
15
16#include "zrythm-config.h"
17
18#include "utils/math_utils.h"
19
20#include "juce_wrapper.h"
21
22namespace zrythm::utils::float_ranges
23{
24
28[[using gnu: nonnull, hot]] static inline void
29fill (float * buf, float val, size_t size, bool optimized = true)
30{
31 if (optimized)
32 {
33 juce::FloatVectorOperations::fill (buf, val, size);
34 }
35 else
36 {
37 std::fill_n (buf, size, val);
38 }
39}
40
44[[using gnu: nonnull, hot]] static inline void
45clip (float * buf, float minf, float maxf, size_t size, bool optimized = true)
46{
47 if (optimized)
48 {
49 juce::FloatVectorOperations::clip (buf, buf, minf, maxf, size);
50 }
51 else
52 {
53 std::transform (buf, buf + size, buf, [minf, maxf] (float x) {
54 return std::clamp (x, minf, maxf);
55 });
56 }
57}
58
62[[using gnu: nonnull, hot]] static inline void
63copy (float * dest, const float * src, size_t size, bool optimized = true)
64{
65 if (optimized)
66 {
67 juce::FloatVectorOperations::copy (dest, src, size);
68 }
69 else
70 {
71 std::copy_n (src, size, dest);
72 }
73}
74
78[[using gnu: nonnull, hot]] static inline void
79mul_k2 (float * dest, float k, size_t size, bool optimized = true)
80{
81 if (optimized)
82 {
83 juce::FloatVectorOperations::multiply (dest, k, size);
84 }
85 else
86 {
87 std::transform (dest, dest + size, dest, [k] (float x) { return x * k; });
88 }
89}
90
94[[nodiscard]] [[using gnu: nonnull]] static inline float
95abs_max (const float * buf, size_t size, bool optimized = true)
96{
97 if (optimized)
98 {
99 auto min_and_max = juce::FloatVectorOperations::findMinAndMax (buf, size);
100 return std::max (
101 std::abs (min_and_max.getStart ()), std::abs (min_and_max.getEnd ()));
102 }
103
104 return std::abs (*std::max_element (buf, buf + size, [] (float a, float b) {
105 return std::abs (a) < std::abs (b);
106 }));
107}
108
114[[using gnu: nonnull, hot]] static inline bool
115abs_max_with_existing_peak (
116 const float * buf,
117 float * cur_peak,
118 size_t size,
119 bool optimized = true)
120{
121 float new_peak = *cur_peak;
122
123 if (optimized)
124 {
125 new_peak = abs_max (buf, size);
126 }
127 else
128 {
129 for (size_t i = 0; i < size; i++)
130 {
131 float val = fabsf (buf[i]);
132 if (val > new_peak)
133 {
134 new_peak = val;
135 }
136 }
137 }
138
139 bool changed = !utils::math::floats_equal (new_peak, *cur_peak);
140 *cur_peak = new_peak;
141
142 return changed;
143}
144
148[[gnu::nonnull]] static inline float
149min (const float * buf, size_t size, bool optimized = true)
150{
151 if (optimized)
152 {
153 return juce::FloatVectorOperations::findMinimum (buf, size);
154 }
155
156 return *std::min_element (buf, buf + size, [] (float a, float b) {
157 return a < b;
158 });
159}
160
164[[gnu::nonnull]] static inline float
165max (const float * buf, size_t size, bool optimized = true)
166{
167 if (optimized)
168 {
169 return juce::FloatVectorOperations::findMaximum (buf, size);
170 }
171
172 return *std::max_element (buf, buf + size, [] (float a, float b) {
173 return a < b;
174 });
175}
176
180[[using gnu: nonnull, hot]] static inline void
181add2 (float * dest, const float * src, size_t count, bool optimized = true)
182{
183 if (optimized)
184 {
185 juce::FloatVectorOperations::add (dest, src, count);
186 }
187 else
188 {
189 std::transform (dest, dest + count, src, dest, std::plus<> ());
190 }
191}
192
196[[using gnu: nonnull, hot]] static inline void
197product (
198 float * dest,
199 const float * src,
200 float k,
201 size_t size,
202 bool optimized = true)
203{
204 if (optimized)
205 {
206 juce::FloatVectorOperations::copyWithMultiply (dest, src, k, size);
207 }
208 else
209 {
210 std::transform (dest, dest + size, src, dest, [k] (float x, float y) {
211 return y * k;
212 });
213 }
214}
215
219[[using gnu: nonnull, hot]] static inline void
220mix_product (
221 float * dest,
222 const float * src,
223 float k,
224 size_t size,
225 bool optimized = true)
226{
227 if (optimized)
228 {
229 juce::FloatVectorOperations::addWithMultiply (dest, src, k, size);
230 }
231 else
232 {
233 std::transform (dest, dest + size, src, dest, [k] (float x, float y) {
234 return x + y * k;
235 });
236 }
237}
238
242[[using gnu: nonnull, hot]] static inline void
243reverse (float * dest, const float * src, size_t size)
244{
245 std::reverse_copy (src, src + size, dest);
246}
247
252[[using gnu: nonnull, hot]] static inline void
253normalize (float * dest, const float * src, size_t size, bool optimize = true)
254{
255 copy (dest, src, size, optimize);
256 const float abs_peak = abs_max (dest, size, optimize);
257 mul_k2 (dest, 1.f / abs_peak, size, optimize);
258}
259
274[[gnu::nonnull]] void
276 float * dest,
277 int32_t start_offset,
278 int32_t total_frames_to_fade,
279 size_t size,
280 float fade_from_multiplier);
281
293[[gnu::nonnull]] void
295 float * dest,
296 int32_t start_offset,
297 int32_t total_frames_to_fade,
298 size_t size,
299 float fade_to_multiplier);
300
312[[gnu::nonnull]] void
314 float * l,
315 float * r,
316 size_t size,
317 bool equal_power,
318 bool optimize = true);
319
320}; // zrythm::dsp::float_ranges
321
322#endif
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.