Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
math.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2018-2023 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3/*
4 * This file incorporates work covered by the following copyright and
5 * permission notices:
6 *
7 * ---
8 *
9 * Copyright (C) 2017-2019 Robin Gareus <robin@gareus.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 *
25 * ---
26 */
27
37#ifndef __UTILS_MATH_H__
38#define __UTILS_MATH_H__
39
40#include <math.h>
41#include <stdbool.h>
42#include <stdint.h>
43
44#include "utils/types.h"
45
46#include <float.h>
47
59#define MATH_RMS_FRAMES 1
60
63#define MATH_TINY_NUMBER (0.0000001)
64
65#define MATH_MINUS_INFINITY (-HUGE_VAL)
66
72#define math_floats_equal_epsilon(a, b, e) \
73 ((a) > (b) ? (a) - (b) < e : (b) - (a) < e)
74
75#define math_doubles_equal_epsilon math_floats_equal_epsilon
76
80#define math_floats_equal(a, b) \
81 ((a) > (b) ? (a) - (b) < FLT_EPSILON : (b) - (a) < FLT_EPSILON)
82
83#define math_doubles_equal(a, b) \
84 ((a) > (b) ? (a) - (b) < DBL_EPSILON : (b) - (a) < DBL_EPSILON)
85
90#define math_round_double_to_signed_32(x) (lround (x))
91
96#define math_round_double_to_signed_64(x) (llround (x))
97
98#define math_round_double_to_signed_frame_t(x) \
99 math_round_double_to_signed_64 (x)
100
105#define math_round_float_to_signed_32(x) (lroundf (x))
106
111#define math_round_float_to_signed_64(x) (llroundf (x))
112
113#define math_round_float_to_signed_frame_t(x) math_round_float_to_signed_64 (x)
114
121CONST
122static inline float
123math_fast_log2 (float val)
124{
125 union
126 {
127 float f;
128 int i;
129 } t;
130 t.f = val;
131 int * const exp_ptr = &t.i;
132 int x = *exp_ptr;
133 const float log_2 = (float) (((x >> 23) & 255) - 128);
134
135 x &= ~(255 << 23);
136 x += 127 << 23;
137
138 *exp_ptr = x;
139
140 val = ((-1.0f / 3) * t.f + 2) * t.f - 2.0f / 3;
141
142 return (val + log_2);
143}
144
145CONST
146static inline float
147math_fast_log (const float val)
148{
149 return (math_fast_log2 (val) * 0.69314718f);
150}
151
152CONST
153static inline float
154math_fast_log10 (const float val)
155{
156 return math_fast_log2 (val) / 3.312500f;
157}
158
163CONST
164static inline sample_t
165math_get_fader_val_from_amp (sample_t amp)
166{
167 const float fader_coefficient1 =
168 /*192.f * logf (2.f);*/
169 133.084258667509499408f;
170 const float fader_coefficient2 =
171 /*powf (logf (2.f), 8.f) * powf (198.f, 8.f);*/
172 1.25870863180257576e17f;
173
174 /* to prevent weird values when amp is very
175 * small */
176 if (amp <= 0.00001f)
177 {
178 return 1e-20f;
179 }
180 else
181 {
182 if (math_floats_equal (amp, 1.f))
183 {
184 amp = 1.f + 1e-20f;
185 }
186 sample_t fader =
187 powf (
188 /* note: don't use fast_log here - it causes
189 * weirdness in faders */
190 6.f * logf (amp) + fader_coefficient1, 8.f)
191 / fader_coefficient2;
192 return (sample_t) fader;
193 }
194}
195
200CONST
201static inline sample_t
202math_get_amp_val_from_fader (sample_t fader)
203{
204 static const float val1 = 1.f / 6.f;
205 return powf (2.f, (val1) * (-192.f + 198.f * powf (fader, 1.f / 8.f)));
206}
207
211CONST
212static inline sample_t
213math_amp_to_dbfs (sample_t amp)
214{
215 return 20.f * log10f (amp);
216}
217
219math_calculate_rms_amp (sample_t * buf, const nframes_t nframes);
220
229
233CONST
234static inline sample_t
235math_dbfs_to_amp (sample_t dbfs)
236{
237 return powf (10.f, (dbfs / 20.f));
238}
239
243CONST
244static inline sample_t
245math_dbfs_to_fader_val (sample_t dbfs)
246{
247 return math_get_fader_val_from_amp (math_dbfs_to_amp (dbfs));
248}
249
257bool
259
265NONNULL_ARGS (1)
266bool math_is_string_valid_float (const char * str, float * ret);
267
272#endif
NONNULL_ARGS(1) int undo_manager_undo(UndoManager *self
Undo last action.
#define math_floats_equal(a, b)
Checks if 2 doubles are equal.
Definition math.h:80
bool math_is_string_valid_float(const char *str, float *ret)
Returns whether the given string is a valid float.
uint32_t nframes_t
Frame count.
Definition types.h:35
bool math_assert_nonnann(float x)
Asserts that the value is non-nan.
sample_t math_calculate_rms_db(sample_t *buf, const nframes_t nframes)
Calculate db using RMS method.
float sample_t
The sample type.
Definition types.h:47
Math utils.
Custom types.