refactoring to prepare for real-time export
[ardour.git] / libs / ardour / ardour / logcurve.h
1 /*
2     Copyright (C) 2001 Steve Harris & Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __ardour_logcurve_h__
21 #define __ardour_logcurve_h__
22
23 #include "pbd/fastlog.h"
24 #include <glibmm/threads.h>
25
26 namespace ARDOUR {
27
28 class LIBARDOUR_API LogCurve {
29   public:
30         LogCurve (float steepness = 0.2, uint32_t len = 0) {
31                 l = len;
32                 S = steepness;
33                 a = log(S);
34                 b = 1.0f / log(1.0f + (1.0f / S));
35         }
36
37         bool operator== (const LogCurve& other) const {
38                 return S == other.S && l == other.l;
39         }
40
41         bool operator!= (const LogCurve& other) const {
42                 return S != other.S || l != other.l;
43         }
44
45         float value (float frac) const {
46                 return (fast_log(frac + S) - a) * b;
47         }
48
49         float value (uint32_t pos) const {
50                 return (fast_log(((float) pos/l) + S) - a) * b;
51         }
52
53         float invert_value (float frac) const {
54                 return (a - fast_log(frac + S)) * b;
55         }
56
57         float invert_value (uint32_t pos) const {
58                 return (a - fast_log(((float) pos/l) + S)) * b;
59         }
60
61         void fill (float *vec, uint32_t veclen, bool invert) const {
62                 float dx = 1.0f/veclen;
63                 float x;
64                 uint32_t i;
65
66                 if (!invert) {
67
68                         vec[0] = 0.0;
69                         vec[veclen-1] = 1.0;
70
71                         for (i = 1, x = 0; i < veclen - 1; x += dx, i++) {
72                                 vec[i] = value (x);
73                         }
74
75                 } else {
76
77                         vec[0] = 1.0;
78                         vec[veclen-1] = 0.0;
79
80                         for (i = veclen-2, x = 0.0f; i > 0; x += dx, i--) {
81                                 vec[i] = value (x);
82                         }
83                 }
84         }
85
86         float steepness() const { return S; }
87         uint32_t length() const { return l; }
88
89         void set_steepness (float steepness) {
90                 S = steepness;
91                 a = log(S);
92                 b = 1.0f / log(1.0f + (1.0f / S));
93         }
94         void set_length (uint32_t len) { l = len; }
95
96         mutable Glib::Threads::Mutex lock;
97
98   protected:
99         float a;
100         float b;
101         float S;
102         uint32_t l;
103 };
104
105 class LIBARDOUR_API LogCurveIn : public LogCurve
106 {
107   public:
108         LogCurveIn (float steepness = 0.2, uint32_t len = 0)
109                 : LogCurve (steepness, len) {}
110
111         float value (float frac) const {
112                 return (fast_log(frac + S) - a) * b;
113         }
114
115         float value (uint32_t pos) const {
116                 return (fast_log(((float) pos/l) + S) - a) * b;
117         }
118 };
119
120 class LIBARDOUR_API LogCurveOut : public LogCurve
121 {
122   public:
123         LogCurveOut (float steepness = 0.2, uint32_t len = 0)
124                 : LogCurve (steepness, len) {}
125
126 };
127
128 } // namespace ARDOUR
129
130 #endif /* __ardour_logcurve_h__ */
131
132