84911b0369233361205ba22900a23d3d0890775d
[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     $Id$
19 */
20
21 #ifndef __ardour_logcurve_h__
22 #define __ardour_logcurve_h__
23
24 #include <pbd/fastlog.h>
25 #include <pbd/lockmonitor.h>
26
27 namespace ARDOUR {
28
29 class LogCurve {
30   public:
31         LogCurve (float steepness = 0.2, uint32_t len = 0) {
32                 l = len;
33                 S = steepness;
34                 a = log(S);
35                 b = 1.0f / log(1.0f + (1.0f / S));
36         }
37
38         bool operator== (const LogCurve& other) const {
39                 return S == other.S && l == other.l;
40         }
41
42         bool operator!= (const LogCurve& other) const {
43                 return S != other.S || l != other.l;
44         }
45         
46         float value (float frac) const {
47                 return (fast_log(frac + S) - a) * b;
48         } 
49         
50         float value (uint32_t pos) const {
51                 return (fast_log(((float) pos/l) + S) - a) * b;
52         } 
53
54         float invert_value (float frac) const {
55                 return (a - fast_log(frac + S)) * b;
56         } 
57         
58         float invert_value (uint32_t pos) const {
59                 return (a - fast_log(((float) pos/l) + S)) * b;
60         } 
61
62         void fill (float *vec, uint32_t veclen, bool invert) const {
63                 float dx = 1.0f/veclen;
64                 float x;
65                 uint32_t i;
66
67                 if (!invert) {
68
69                         vec[0] = 0.0;
70                         vec[veclen-1] = 1.0;
71
72                         for (i = 1, x = 0; i < veclen - 1; x += dx, i++) {
73                                 vec[i] = value (x);
74                         }
75
76                 } else {
77
78                         vec[0] = 1.0;
79                         vec[veclen-1] = 0.0;
80
81                         for (i = veclen-2, x = 0.0f; i > 0; x += dx, i--) {
82                                 vec[i] = value (x);
83                         }
84                 }
85         }
86
87         float steepness() const { return S; }
88         uint32_t length() const { return l; }
89         
90         void set_steepness (float steepness) { 
91                 S = steepness; 
92                 a = log(S);             
93                 b = 1.0f / log(1.0f + (1.0f / S));
94         }
95         void set_length (uint32_t len) { l = len; }
96
97         mutable PBD::NonBlockingLock lock;
98
99   protected:
100         float a;
101         float b;
102         float S;
103         uint32_t l;
104 };
105
106 class LogCurveIn : public LogCurve 
107 {
108   public:
109         LogCurveIn (float steepness = 0.2, uint32_t len = 0) 
110                 : LogCurve (steepness, len) {}
111
112         float value (float frac) const {
113                 return (fast_log(frac + S) - a) * b;
114         } 
115         
116         float value (uint32_t pos) const {
117                 return (fast_log(((float) pos/l) + S) - a) * b;
118         } 
119 };
120
121 class LogCurveOut : public LogCurve 
122 {
123   public:
124         LogCurveOut (float steepness = 0.2, uint32_t len = 0) 
125                 : LogCurve (steepness, len) {}
126
127 };
128
129 }; /* namespace ARDOUR */
130
131 #endif /* __ardour_logcurve_h__ */
132
133