1 #ifndef AUDIOGRAPHER_ROUTINES_H
2 #define AUDIOGRAPHER_ROUTINES_H
3 
4 #include "types.h"
5 
6 #include <cmath>
7 
8 #include "audiographer/visibility.h"
9 
10 namespace AudioGrapher
11 {
12 
13 /// Allows overriding some routines with more efficient ones.
14 class LIBAUDIOGRAPHER_API Routines
15 {
16   public:
17 	typedef uint32_t uint_type;
18 
19 	typedef float (*compute_peak_t)          (float const *, uint_type, float);
20 	typedef void  (*apply_gain_to_buffer_t)  (float *, uint_type, float);
21 
override_compute_peak(compute_peak_t func)22 	static void override_compute_peak         (compute_peak_t func)         { _compute_peak = func; }
override_apply_gain_to_buffer(apply_gain_to_buffer_t func)23 	static void override_apply_gain_to_buffer (apply_gain_to_buffer_t func) { _apply_gain_to_buffer = func; }
24 
25 	/** Computes peak in float buffer
26 	  * \n RT safe
27 	  * \param data buffer from which the peak is computed
28 	  * \param samples length of the portion of \a buffer that is checked
29 	  * \param current_peak current peak of buffer, if calculated in several passes
30 	  * \return maximum of values in [\a data, \a data + \a samples) and \a current_peak
31 	  */
compute_peak(float const * data,uint_type samples,float current_peak)32 	static inline float compute_peak (float const * data, uint_type samples, float current_peak)
33 	{
34 		return (*_compute_peak) (data, samples, current_peak);
35 	}
36 
37 	/** Applies constant gain to buffer
38 	 * \n RT safe
39 	 * \param data data to which the gain is applied
40 	 * \param samples length of data
41 	 * \param gain gain that is applied
42 	 */
apply_gain_to_buffer(float * data,uint_type samples,float gain)43 	static inline void apply_gain_to_buffer (float * data, uint_type samples, float gain)
44 	{
45 		(*_apply_gain_to_buffer) (data, samples, gain);
46 	}
47 
48   private:
default_compute_peak(float const * data,uint_type samples,float current_peak)49 	static inline float default_compute_peak (float const * data, uint_type samples, float current_peak)
50 	{
51 		for (uint_type i = 0; i < samples; ++i) {
52 			float abs = std::fabs(data[i]);
53 			if (abs > current_peak) { current_peak = abs; }
54 		}
55 		return current_peak;
56 	}
57 
default_apply_gain_to_buffer(float * data,uint_type samples,float gain)58 	static inline void default_apply_gain_to_buffer (float * data, uint_type samples, float gain)
59 	{
60 		for (uint_type i = 0; i < samples; ++i) {
61 			data[i] *= gain;
62 		}
63 	}
64 
65 	static compute_peak_t          _compute_peak;
66 	static apply_gain_to_buffer_t  _apply_gain_to_buffer;
67 };
68 
69 } // namespace
70 
71 #endif // AUDIOGRAPHER_ROUTINES_H
72