summaryrefslogtreecommitdiff
path: root/libs/audiographer/audiographer/routines.h
blob: d78fa602b6954ac996f9de898816a1297cd64573 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef AUDIOGRAPHER_ROUTINES_H
#define AUDIOGRAPHER_ROUTINES_H

#include "types.h"

#include <cmath>

#include "audiographer/visibility.h"

namespace AudioGrapher
{

/// Allows overriding some routines with more efficient ones.
class LIBAUDIOGRAPHER_API Routines
{
  public:
	typedef uint32_t uint_type;

	typedef float (*compute_peak_t)          (float const *, uint_type, float);
	typedef void  (*apply_gain_to_buffer_t)  (float *, uint_type, float);

	static void override_compute_peak         (compute_peak_t func)         { _compute_peak = func; }
	static void override_apply_gain_to_buffer (apply_gain_to_buffer_t func) { _apply_gain_to_buffer = func; }

	/** Computes peak in float buffer
	  * \n RT safe
	  * \param data buffer from which the peak is computed
	  * \param frames length of the portion of \a buffer that is checked
	  * \param current_peak current peak of buffer, if calculated in several passes
	  * \return maximum of values in [\a data, \a data + \a frames) and \a current_peak
	  */
	static inline float compute_peak (float const * data, uint_type frames, float current_peak)
	{
		return (*_compute_peak) (data, frames, current_peak);
	}

	/** Applies constant gain to buffer
	 * \n RT safe
	 * \param data data to which the gain is applied
	 * \param frames length of data
	 * \param gain gain that is applied
	 */
	static inline void apply_gain_to_buffer (float * data, uint_type frames, float gain)
	{
		(*_apply_gain_to_buffer) (data, frames, gain);
	}

  private:
	static inline float default_compute_peak (float const * data, uint_type frames, float current_peak)
	{
		for (uint_type i = 0; i < frames; ++i) {
			float abs = std::fabs(data[i]);
			if (abs > current_peak) { current_peak = abs; }
		}
		return current_peak;
	}

	static inline void default_apply_gain_to_buffer (float * data, uint_type frames, float gain)
	{
		for (uint_type i = 0; i < frames; ++i) {
			data[i] *= gain;
		}
	}

	static compute_peak_t          _compute_peak;
	static apply_gain_to_buffer_t  _apply_gain_to_buffer;
};

} // namespace

#endif // AUDIOGRAPHER_ROUTINES_H