Mercurial > hg > svcore
comparison base/AudioLevel.cpp @ 240:8133ae938704
* Fix incorrect meter-scaling value for 0dB; some tidying
author | Chris Cannam |
---|---|
date | Wed, 28 Feb 2007 11:20:14 +0000 |
parents | fd331fac5f38 |
children | dc46851837d6 |
comparison
equal
deleted
inserted
replaced
239:71f869dac40b | 240:8133ae938704 |
---|---|
23 #include <iostream> | 23 #include <iostream> |
24 #include <map> | 24 #include <map> |
25 #include <vector> | 25 #include <vector> |
26 #include <cassert> | 26 #include <cassert> |
27 | 27 |
28 const float AudioLevel::DB_FLOOR = -1000.0; | 28 const float AudioLevel::DB_FLOOR = -1000.f; |
29 | 29 |
30 struct FaderDescription | 30 struct FaderDescription |
31 { | 31 { |
32 FaderDescription(float _minDb, float _maxDb, float _zeroPoint) : | 32 FaderDescription(float _minDb, float _maxDb, float _zeroPoint) : |
33 minDb(_minDb), maxDb(_maxDb), zeroPoint(_zeroPoint) { } | 33 minDb(_minDb), maxDb(_maxDb), zeroPoint(_zeroPoint) { } |
36 float maxDb; | 36 float maxDb; |
37 float zeroPoint; // as fraction of total throw | 37 float zeroPoint; // as fraction of total throw |
38 }; | 38 }; |
39 | 39 |
40 static const FaderDescription faderTypes[] = { | 40 static const FaderDescription faderTypes[] = { |
41 FaderDescription(-40.0, +6.0, 0.75), // short | 41 FaderDescription(-40.f, +6.f, 0.75f), // short |
42 FaderDescription(-70.0, +10.0, 0.80), // long | 42 FaderDescription(-70.f, +10.f, 0.80f), // long |
43 FaderDescription(-70.0, 0.0, 1.00), // IEC268 | 43 FaderDescription(-70.f, 0.f, 1.00f), // IEC268 |
44 FaderDescription(-70.0, +10.0, 0.80), // IEC268 long | 44 FaderDescription(-70.f, +10.f, 0.80f), // IEC268 long |
45 FaderDescription(-40.0, 0.0, 1.00), // preview | 45 FaderDescription(-40.f, 0.f, 1.00f), // preview |
46 }; | 46 }; |
47 | 47 |
48 typedef std::vector<float> LevelList; | 48 typedef std::vector<float> LevelList; |
49 static std::map<int, LevelList> previewLevelCache; | 49 static std::map<int, LevelList> previewLevelCache; |
50 static const LevelList &getPreviewLevelCache(int levels); | 50 static const LevelList &getPreviewLevelCache(int levels); |
59 } | 59 } |
60 | 60 |
61 float | 61 float |
62 AudioLevel::dB_to_multiplier(float dB) | 62 AudioLevel::dB_to_multiplier(float dB) |
63 { | 63 { |
64 if (dB == DB_FLOOR) return 0.0; | 64 if (dB == DB_FLOOR) return 0.f; |
65 float m = powf(10.0, dB / 10.0); | 65 float m = powf(10.f, dB / 10.f); |
66 return m; | 66 return m; |
67 } | 67 } |
68 | 68 |
69 /* IEC 60-268-18 fader levels. Thanks to Steve Harris. */ | 69 /* IEC 60-268-18 fader levels. Thanks to Steve Harris. */ |
70 | 70 |
132 | 132 |
133 float value = level - zeroLevel; | 133 float value = level - zeroLevel; |
134 float scale = float(maxLevel - zeroLevel) / | 134 float scale = float(maxLevel - zeroLevel) / |
135 sqrtf(faderTypes[type].maxDb); | 135 sqrtf(faderTypes[type].maxDb); |
136 value /= scale; | 136 value /= scale; |
137 float dB = powf(value, 2.0); | 137 float dB = powf(value, 2.f); |
138 return dB; | 138 return dB; |
139 | 139 |
140 } else { | 140 } else { |
141 | 141 |
142 float value = zeroLevel - level; | 142 float value = zeroLevel - level; |
143 float scale = zeroLevel / sqrtf(0.0 - faderTypes[type].minDb); | 143 float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb); |
144 value /= scale; | 144 value /= scale; |
145 float dB = powf(value, 2.0); | 145 float dB = powf(value, 2.f); |
146 return 0.0 - dB; | 146 return 0.f - dB; |
147 } | 147 } |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 | 151 |
161 // result not as a percentage, but as a scale between 0 and | 161 // result not as a percentage, but as a scale between 0 and |
162 // whatever the "percentage" for our (possibly >0dB) max dB is. | 162 // whatever the "percentage" for our (possibly >0dB) max dB is. |
163 | 163 |
164 float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb); | 164 float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb); |
165 float percent = iec_dB_to_fader(dB); | 165 float percent = iec_dB_to_fader(dB); |
166 int faderLevel = int((maxLevel * percent) / maxPercent + 0.01); | 166 int faderLevel = int((maxLevel * percent) / maxPercent + 0.01f); |
167 | 167 |
168 if (faderLevel < 0) faderLevel = 0; | 168 if (faderLevel < 0) faderLevel = 0; |
169 if (faderLevel > maxLevel) faderLevel = maxLevel; | 169 if (faderLevel > maxLevel) faderLevel = maxLevel; |
170 return faderLevel; | 170 return faderLevel; |
171 | 171 |
172 } else { | 172 } else { |
173 | 173 |
174 int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint); | 174 int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint); |
175 | 175 |
176 if (dB >= 0.0) { | 176 if (dB >= 0.f) { |
177 | 177 |
178 if (faderTypes[type].maxDb <= 0.f) { | |
179 | |
180 return maxLevel; | |
181 | |
182 } else { | |
183 | |
184 float value = sqrtf(dB); | |
185 float scale = (maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb); | |
186 value *= scale; | |
187 int level = int(value + 0.01f) + zeroLevel; | |
188 if (level > maxLevel) level = maxLevel; | |
189 return level; | |
190 } | |
191 | |
192 } else { | |
193 | |
194 dB = 0.f - dB; | |
178 float value = sqrtf(dB); | 195 float value = sqrtf(dB); |
179 float scale = (maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb); | 196 float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb); |
180 value *= scale; | 197 value *= scale; |
181 int level = int(value + 0.01) + zeroLevel; | 198 int level = zeroLevel - int(value + 0.01f); |
182 if (level > maxLevel) level = maxLevel; | |
183 return level; | |
184 | |
185 } else { | |
186 | |
187 dB = 0.0 - dB; | |
188 float value = sqrtf(dB); | |
189 float scale = zeroLevel / sqrtf(0.0 - faderTypes[type].minDb); | |
190 value *= scale; | |
191 int level = zeroLevel - int(value + 0.01); | |
192 if (level < 0) level = 0; | 199 if (level < 0) level = 0; |
193 return level; | 200 return level; |
194 } | 201 } |
195 } | 202 } |
196 } | 203 } |
197 | 204 |
198 | 205 |
199 float | 206 float |
200 AudioLevel::fader_to_multiplier(int level, int maxLevel, FaderType type) | 207 AudioLevel::fader_to_multiplier(int level, int maxLevel, FaderType type) |
201 { | 208 { |
202 if (level == 0) return 0.0; | 209 if (level == 0) return 0.f; |
203 return dB_to_multiplier(fader_to_dB(level, maxLevel, type)); | 210 return dB_to_multiplier(fader_to_dB(level, maxLevel, type)); |
204 } | 211 } |
205 | 212 |
206 int | 213 int |
207 AudioLevel::multiplier_to_fader(float multiplier, int maxLevel, FaderType type) | 214 AudioLevel::multiplier_to_fader(float multiplier, int maxLevel, FaderType type) |
208 { | 215 { |
209 if (multiplier == 0.0) return 0; | 216 if (multiplier == 0.f) return 0; |
210 float dB = multiplier_to_dB(multiplier); | 217 float dB = multiplier_to_dB(multiplier); |
211 int fader = dB_to_fader(dB, maxLevel, type); | 218 int fader = dB_to_fader(dB, maxLevel, type); |
212 return fader; | 219 return fader; |
213 } | 220 } |
214 | 221 |
234 assert(levels > 0); | 241 assert(levels > 0); |
235 return multiplier_to_fader(m, levels, PreviewLevel); | 242 return multiplier_to_fader(m, levels, PreviewLevel); |
236 | 243 |
237 /* The original multiplier_to_preview which follows is not thread-safe. | 244 /* The original multiplier_to_preview which follows is not thread-safe. |
238 | 245 |
239 if (m < 0.0) return -multiplier_to_preview(-m, levels); | 246 if (m < 0.f) return -multiplier_to_preview(-m, levels); |
240 | 247 |
241 const LevelList &ll = getPreviewLevelCache(levels); | 248 const LevelList &ll = getPreviewLevelCache(levels); |
242 int result = -1; | 249 int result = -1; |
243 | 250 |
244 int lo = 0, hi = levels; | 251 int lo = 0, hi = levels; |