comparison base/AudioLevel.cpp @ 1038:cc27f35aa75c cxx11

Introducing the signed 64-bit frame index type, and fixing build failures from inclusion of -Wconversion with -Werror. Not finished yet.
author Chris Cannam
date Tue, 03 Mar 2015 15:18:24 +0000
parents 5bfc4930588d
children 48e9f538e6e9
comparison
equal deleted inserted replaced
1037:bf0e5944289b 1038:cc27f35aa75c
24 #include <map> 24 #include <map>
25 #include <vector> 25 #include <vector>
26 #include <cassert> 26 #include <cassert>
27 #include "system/System.h" 27 #include "system/System.h"
28 28
29 const float AudioLevel::DB_FLOOR = -1000.f; 29 const double AudioLevel::DB_FLOOR = -1000.;
30 30
31 struct FaderDescription 31 struct FaderDescription
32 { 32 {
33 FaderDescription(float _minDb, float _maxDb, float _zeroPoint) : 33 FaderDescription(double _minDb, double _maxDb, double _zeroPoint) :
34 minDb(_minDb), maxDb(_maxDb), zeroPoint(_zeroPoint) { } 34 minDb(_minDb), maxDb(_maxDb), zeroPoint(_zeroPoint) { }
35 35
36 float minDb; 36 double minDb;
37 float maxDb; 37 double maxDb;
38 float zeroPoint; // as fraction of total throw 38 double zeroPoint; // as fraction of total throw
39 }; 39 };
40 40
41 static const FaderDescription faderTypes[] = { 41 static const FaderDescription faderTypes[] = {
42 FaderDescription(-40.f, +6.f, 0.75f), // short 42 FaderDescription(-40., +6., 0.75), // short
43 FaderDescription(-70.f, +10.f, 0.80f), // long 43 FaderDescription(-70., +10., 0.80), // long
44 FaderDescription(-70.f, 0.f, 1.00f), // IEC268 44 FaderDescription(-70., 0., 1.00), // IEC268
45 FaderDescription(-70.f, +10.f, 0.80f), // IEC268 long 45 FaderDescription(-70., +10., 0.80), // IEC268 long
46 FaderDescription(-40.f, 0.f, 1.00f), // preview 46 FaderDescription(-40., 0., 1.00), // preview
47 }; 47 };
48 48
49 //typedef std::vector<float> LevelList; 49 //typedef std::vector<double> LevelList;
50 //static std::map<int, LevelList> previewLevelCache; 50 //static std::map<int, LevelList> previewLevelCache;
51 //static const LevelList &getPreviewLevelCache(int levels); 51 //static const LevelList &getPreviewLevelCache(int levels);
52 52
53 float 53 double
54 AudioLevel::multiplier_to_dB(float multiplier) 54 AudioLevel::multiplier_to_dB(double multiplier)
55 { 55 {
56 if (multiplier == 0.f) return DB_FLOOR; 56 if (multiplier == 0.) return DB_FLOOR;
57 else if (multiplier < 0.f) return multiplier_to_dB(-multiplier); 57 else if (multiplier < 0.) return multiplier_to_dB(-multiplier);
58 float dB = 10 * log10f(multiplier); 58 double dB = 10 * log10(multiplier);
59 return dB; 59 return dB;
60 } 60 }
61 61
62 float 62 double
63 AudioLevel::dB_to_multiplier(float dB) 63 AudioLevel::dB_to_multiplier(double dB)
64 { 64 {
65 if (dB == DB_FLOOR) return 0.f; 65 if (dB == DB_FLOOR) return 0.;
66 float m = powf(10.f, dB / 10.f); 66 double m = pow(10., dB / 10.);
67 return m; 67 return m;
68 } 68 }
69 69
70 /* IEC 60-268-18 fader levels. Thanks to Steve Harris. */ 70 /* IEC 60-268-18 fader levels. Thanks to Steve Harris. */
71 71
72 static float iec_dB_to_fader(float db) 72 static double iec_dB_to_fader(double db)
73 { 73 {
74 float def = 0.0f; // Meter deflection %age 74 double def = 0.0f; // Meter deflection %age
75 75
76 if (db < -70.0f) { 76 if (db < -70.0f) {
77 def = 0.0f; 77 def = 0.0f;
78 } else if (db < -60.0f) { 78 } else if (db < -60.0f) {
79 def = (db + 70.0f) * 0.25f; 79 def = (db + 70.0f) * 0.25f;
90 } 90 }
91 91
92 return def; 92 return def;
93 } 93 }
94 94
95 static float iec_fader_to_dB(float def) // Meter deflection %age 95 static double iec_fader_to_dB(double def) // Meter deflection %age
96 { 96 {
97 float db = 0.0f; 97 double db = 0.0f;
98 98
99 if (def >= 50.0f) { 99 if (def >= 50.0f) {
100 db = (def - 50.0f) / 2.5f - 20.0f; 100 db = (def - 50.0f) / 2.5f - 20.0f;
101 } else if (def >= 30.0f) { 101 } else if (def >= 30.0f) {
102 db = (def - 30.0f) / 2.0f - 30.0f; 102 db = (def - 30.0f) / 2.0f - 30.0f;
111 } 111 }
112 112
113 return db; 113 return db;
114 } 114 }
115 115
116 float 116 double
117 AudioLevel::fader_to_dB(int level, int maxLevel, FaderType type) 117 AudioLevel::fader_to_dB(int level, int maxLevel, FaderType type)
118 { 118 {
119 if (level == 0) return DB_FLOOR; 119 if (level == 0) return DB_FLOOR;
120 120
121 if (type == IEC268Meter || type == IEC268LongMeter) { 121 if (type == IEC268Meter || type == IEC268LongMeter) {
122 122
123 float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb); 123 double maxPercent = iec_dB_to_fader(faderTypes[type].maxDb);
124 float percent = float(level) * maxPercent / float(maxLevel); 124 double percent = double(level) * maxPercent / double(maxLevel);
125 float dB = iec_fader_to_dB(percent); 125 double dB = iec_fader_to_dB(percent);
126 return dB; 126 return dB;
127 127
128 } else { // scale proportional to sqrt(fabs(dB)) 128 } else { // scale proportional to sqrt(fabs(dB))
129 129
130 int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint); 130 int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint);
131 131
132 if (level >= zeroLevel) { 132 if (level >= zeroLevel) {
133 133
134 float value = level - zeroLevel; 134 double value = level - zeroLevel;
135 float scale = float(maxLevel - zeroLevel) / 135 double scale = (maxLevel - zeroLevel) /
136 sqrtf(faderTypes[type].maxDb); 136 sqrt(faderTypes[type].maxDb);
137 value /= scale; 137 value /= scale;
138 float dB = powf(value, 2.f); 138 double dB = pow(value, 2.);
139 return dB; 139 return dB;
140 140
141 } else { 141 } else {
142 142
143 float value = zeroLevel - level; 143 double value = zeroLevel - level;
144 float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb); 144 double scale = zeroLevel / sqrt(0. - faderTypes[type].minDb);
145 value /= scale; 145 value /= scale;
146 float dB = powf(value, 2.f); 146 double dB = pow(value, 2.);
147 return 0.f - dB; 147 return 0. - dB;
148 } 148 }
149 } 149 }
150 } 150 }
151 151
152 152
153 int 153 int
154 AudioLevel::dB_to_fader(float dB, int maxLevel, FaderType type) 154 AudioLevel::dB_to_fader(double dB, int maxLevel, FaderType type)
155 { 155 {
156 if (dB == DB_FLOOR) return 0; 156 if (dB == DB_FLOOR) return 0;
157 157
158 if (type == IEC268Meter || type == IEC268LongMeter) { 158 if (type == IEC268Meter || type == IEC268LongMeter) {
159 159
160 // The IEC scale gives a "percentage travel" for a given dB 160 // The IEC scale gives a "percentage travel" for a given dB
161 // level, but it reaches 100% at 0dB. So we want to treat the 161 // level, but it reaches 100% at 0dB. So we want to treat the
162 // result not as a percentage, but as a scale between 0 and 162 // result not as a percentage, but as a scale between 0 and
163 // whatever the "percentage" for our (possibly >0dB) max dB is. 163 // whatever the "percentage" for our (possibly >0dB) max dB is.
164 164
165 float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb); 165 double maxPercent = iec_dB_to_fader(faderTypes[type].maxDb);
166 float percent = iec_dB_to_fader(dB); 166 double percent = iec_dB_to_fader(dB);
167 int faderLevel = int((maxLevel * percent) / maxPercent + 0.01f); 167 int faderLevel = int((maxLevel * percent) / maxPercent + 0.01f);
168 168
169 if (faderLevel < 0) faderLevel = 0; 169 if (faderLevel < 0) faderLevel = 0;
170 if (faderLevel > maxLevel) faderLevel = maxLevel; 170 if (faderLevel > maxLevel) faderLevel = maxLevel;
171 return faderLevel; 171 return faderLevel;
172 172
173 } else { 173 } else {
174 174
175 int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint); 175 int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint);
176 176
177 if (dB >= 0.f) { 177 if (dB >= 0.) {
178 178
179 if (faderTypes[type].maxDb <= 0.f) { 179 if (faderTypes[type].maxDb <= 0.) {
180 180
181 return maxLevel; 181 return maxLevel;
182 182
183 } else { 183 } else {
184 184
185 float value = sqrtf(dB); 185 double value = sqrt(dB);
186 float scale = (maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb); 186 double scale = (maxLevel - zeroLevel) / sqrt(faderTypes[type].maxDb);
187 value *= scale; 187 value *= scale;
188 int level = int(value + 0.01f) + zeroLevel; 188 int level = int(value + 0.01f) + zeroLevel;
189 if (level > maxLevel) level = maxLevel; 189 if (level > maxLevel) level = maxLevel;
190 return level; 190 return level;
191 } 191 }
192 192
193 } else { 193 } else {
194 194
195 dB = 0.f - dB; 195 dB = 0. - dB;
196 float value = sqrtf(dB); 196 double value = sqrt(dB);
197 float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb); 197 double scale = zeroLevel / sqrt(0. - faderTypes[type].minDb);
198 value *= scale; 198 value *= scale;
199 int level = zeroLevel - int(value + 0.01f); 199 int level = zeroLevel - int(value + 0.01f);
200 if (level < 0) level = 0; 200 if (level < 0) level = 0;
201 return level; 201 return level;
202 } 202 }
203 } 203 }
204 } 204 }
205 205
206 206
207 float 207 double
208 AudioLevel::fader_to_multiplier(int level, int maxLevel, FaderType type) 208 AudioLevel::fader_to_multiplier(int level, int maxLevel, FaderType type)
209 { 209 {
210 if (level == 0) return 0.f; 210 if (level == 0) return 0.;
211 return dB_to_multiplier(fader_to_dB(level, maxLevel, type)); 211 return dB_to_multiplier(fader_to_dB(level, maxLevel, type));
212 } 212 }
213 213
214 int 214 int
215 AudioLevel::multiplier_to_fader(float multiplier, int maxLevel, FaderType type) 215 AudioLevel::multiplier_to_fader(double multiplier, int maxLevel, FaderType type)
216 { 216 {
217 if (multiplier == 0.f) return 0; 217 if (multiplier == 0.) return 0;
218 float dB = multiplier_to_dB(multiplier); 218 double dB = multiplier_to_dB(multiplier);
219 int fader = dB_to_fader(dB, maxLevel, type); 219 int fader = dB_to_fader(dB, maxLevel, type);
220 return fader; 220 return fader;
221 } 221 }
222 222
223 /* 223 /*
225 getPreviewLevelCache(int levels) 225 getPreviewLevelCache(int levels)
226 { 226 {
227 LevelList &ll = previewLevelCache[levels]; 227 LevelList &ll = previewLevelCache[levels];
228 if (ll.empty()) { 228 if (ll.empty()) {
229 for (int i = 0; i <= levels; ++i) { 229 for (int i = 0; i <= levels; ++i) {
230 float m = AudioLevel::fader_to_multiplier 230 double m = AudioLevel::fader_to_multiplier
231 (i + levels/4, levels + levels/4, AudioLevel::PreviewLevel); 231 (i + levels/4, levels + levels/4, AudioLevel::PreviewLevel);
232 if (levels == 1) m /= 100; // noise 232 if (levels == 1) m /= 100; // noise
233 ll.push_back(m); 233 ll.push_back(m);
234 } 234 }
235 } 235 }
236 return ll; 236 return ll;
237 } 237 }
238 */ 238 */
239 239
240 int 240 int
241 AudioLevel::multiplier_to_preview(float m, int levels) 241 AudioLevel::multiplier_to_preview(double m, int levels)
242 { 242 {
243 assert(levels > 0); 243 assert(levels > 0);
244 return multiplier_to_fader(m, levels, PreviewLevel); 244 return multiplier_to_fader(m, levels, PreviewLevel);
245 245
246 /* The original multiplier_to_preview which follows is not thread-safe. 246 /* The original multiplier_to_preview which follows is not thread-safe.
247 247
248 if (m < 0.f) return -multiplier_to_preview(-m, levels); 248 if (m < 0.) return -multiplier_to_preview(-m, levels);
249 249
250 const LevelList &ll = getPreviewLevelCache(levels); 250 const LevelList &ll = getPreviewLevelCache(levels);
251 int result = -1; 251 int result = -1;
252 252
253 int lo = 0, hi = levels; 253 int lo = 0, hi = levels;
275 return result; 275 return result;
276 276
277 */ 277 */
278 } 278 }
279 279
280 float 280 double
281 AudioLevel::preview_to_multiplier(int level, int levels) 281 AudioLevel::preview_to_multiplier(int level, int levels)
282 { 282 {
283 assert(levels > 0); 283 assert(levels > 0);
284 return fader_to_multiplier(level, levels, PreviewLevel); 284 return fader_to_multiplier(level, levels, PreviewLevel);
285 /* 285 /*