Remove all use of nframes_t.
[ardour.git] / libs / audiographer / audiographer / general / normalizer.h
1 #ifndef AUDIOGRAPHER_NORMALIZER_H
2 #define AUDIOGRAPHER_NORMALIZER_H
3
4 #include "audiographer/sink.h"
5 #include "audiographer/routines.h"
6 #include "audiographer/utils/listed_source.h"
7
8 #include <cstring>
9
10 namespace AudioGrapher
11 {
12
13 /// A class for normalizing to a specified target in dB
14 class Normalizer
15   : public ListedSource<float>
16   , public Sink<float>
17   , public Throwing<>
18 {
19   public:
20         /// Constructs a normalizer with a specific target in dB \n RT safe
21         Normalizer (float target_dB)
22           : enabled (false)
23           , buffer (0)
24           , buffer_size (0)
25         {
26                 target = pow (10.0f, target_dB * 0.05f);
27         }
28         
29         ~Normalizer()
30         {
31                 delete [] buffer;
32         }
33
34         /// Sets the peak found in the material to be normalized \see PeakReader \n RT safe
35         void set_peak (float peak)
36         {
37                 if (peak == 0.0f || peak == target) {
38                         /* don't even try */
39                         enabled = false;
40                 } else {
41                         enabled = true;
42                         gain = target / peak;
43                 }
44         }
45
46         /** Allocates a buffer for using with const ProcessContexts
47           * This function does not need to be called if
48           * non-const ProcessContexts are given to \a process() .
49           * \n Not RT safe
50           */
51         void alloc_buffer(framecnt_t frames)
52         {
53                 delete [] buffer;
54                 buffer = new float[frames];
55                 buffer_size = frames;
56         }
57
58         /// Process a const ProcessContext \see alloc_buffer() \n RT safe
59         void process (ProcessContext<float> const & c)
60         {
61                 if (throw_level (ThrowProcess) && c.frames() > buffer_size) {
62                         throw Exception (*this, "Too many frames given to process()");
63                 }
64                 
65                 if (enabled) {
66                         memcpy (buffer, c.data(), c.frames() * sizeof(float));
67                         Routines::apply_gain_to_buffer (buffer, c.frames(), gain);
68                 }
69                 
70                 ProcessContext<float> c_out (c, buffer);
71                 ListedSource<float>::output (c_out);
72         }
73         
74         /// Process a non-const ProcsesContext in-place \n RT safe
75         void process (ProcessContext<float> & c)
76         {
77                 if (enabled) {
78                         Routines::apply_gain_to_buffer (c.data(), c.frames(), gain);
79                 }
80                 ListedSource<float>::output(c);
81         }
82         
83   private:
84         bool      enabled;
85         float     target;
86         float     gain;
87         
88         float *   buffer;
89         framecnt_t buffer_size;
90 };
91
92
93 } // namespace
94
95 #endif // AUDIOGRAPHER_NORMALIZER_H