Mercurial > hg > svcore
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 /* |