svcore  1.9
AudioLevel.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version. See the file
12  COPYING included with this distribution for more information.
13 */
14 
15 /*
16  This is a modified version of a source file from the
17  Rosegarden MIDI and audio sequencer and notation editor.
18  This file copyright 2000-2006 Chris Cannam.
19 */
20 
21 #include "AudioLevel.h"
22 #include <cmath>
23 #include <iostream>
24 #include <map>
25 #include <vector>
26 #include <cassert>
27 #include "system/System.h"
28 
29 const float AudioLevel::DB_FLOOR = -1000.f;
30 
32 {
33  FaderDescription(float _minDb, float _maxDb, float _zeroPoint) :
34  minDb(_minDb), maxDb(_maxDb), zeroPoint(_zeroPoint) { }
35 
36  float minDb;
37  float maxDb;
38  float zeroPoint; // as fraction of total throw
39 };
40 
41 static const FaderDescription faderTypes[] = {
42  FaderDescription(-40.f, +6.f, 0.75f), // short
43  FaderDescription(-70.f, +10.f, 0.80f), // long
44  FaderDescription(-70.f, 0.f, 1.00f), // IEC268
45  FaderDescription(-70.f, +10.f, 0.80f), // IEC268 long
46  FaderDescription(-40.f, 0.f, 1.00f), // preview
47 };
48 
49 //typedef std::vector<float> LevelList;
50 //static std::map<int, LevelList> previewLevelCache;
51 //static const LevelList &getPreviewLevelCache(int levels);
52 
53 float
55 {
56  if (multiplier == 0.f) return DB_FLOOR;
57  else if (multiplier < 0.f) return multiplier_to_dB(-multiplier);
58  float dB = 10 * log10f(multiplier);
59  return dB;
60 }
61 
62 float
64 {
65  if (dB == DB_FLOOR) return 0.f;
66  float m = powf(10.f, dB / 10.f);
67  return m;
68 }
69 
70 /* IEC 60-268-18 fader levels. Thanks to Steve Harris. */
71 
72 static float iec_dB_to_fader(float db)
73 {
74  float def = 0.0f; // Meter deflection %age
75 
76  if (db < -70.0f) {
77  def = 0.0f;
78  } else if (db < -60.0f) {
79  def = (db + 70.0f) * 0.25f;
80  } else if (db < -50.0f) {
81  def = (db + 60.0f) * 0.5f + 2.5f; // corrected from 5.0f base, thanks Robin Gareus
82  } else if (db < -40.0f) {
83  def = (db + 50.0f) * 0.75f + 7.5f;
84  } else if (db < -30.0f) {
85  def = (db + 40.0f) * 1.5f + 15.0f;
86  } else if (db < -20.0f) {
87  def = (db + 30.0f) * 2.0f + 30.0f;
88  } else {
89  def = (db + 20.0f) * 2.5f + 50.0f;
90  }
91 
92  return def;
93 }
94 
95 static float iec_fader_to_dB(float def) // Meter deflection %age
96 {
97  float db = 0.0f;
98 
99  if (def >= 50.0f) {
100  db = (def - 50.0f) / 2.5f - 20.0f;
101  } else if (def >= 30.0f) {
102  db = (def - 30.0f) / 2.0f - 30.0f;
103  } else if (def >= 15.0f) {
104  db = (def - 15.0f) / 1.5f - 40.0f;
105  } else if (def >= 7.5f) {
106  db = (def - 7.5f) / 0.75f - 50.0f;
107  } else if (def >= 2.5f) {
108  db = (def - 2.5f) / 0.5f - 60.0f;
109  } else {
110  db = (def / 0.25f) - 70.0f;
111  }
112 
113  return db;
114 }
115 
116 float
117 AudioLevel::fader_to_dB(int level, int maxLevel, FaderType type)
118 {
119  if (level == 0) return DB_FLOOR;
120 
121  if (type == IEC268Meter || type == IEC268LongMeter) {
122 
123  float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb);
124  float percent = float(level) * maxPercent / float(maxLevel);
125  float dB = iec_fader_to_dB(percent);
126  return dB;
127 
128  } else { // scale proportional to sqrt(fabs(dB))
129 
130  int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint);
131 
132  if (level >= zeroLevel) {
133 
134  float value = level - zeroLevel;
135  float scale = float(maxLevel - zeroLevel) /
136  sqrtf(faderTypes[type].maxDb);
137  value /= scale;
138  float dB = powf(value, 2.f);
139  return dB;
140 
141  } else {
142 
143  float value = zeroLevel - level;
144  float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb);
145  value /= scale;
146  float dB = powf(value, 2.f);
147  return 0.f - dB;
148  }
149  }
150 }
151 
152 
153 int
154 AudioLevel::dB_to_fader(float dB, int maxLevel, FaderType type)
155 {
156  if (dB == DB_FLOOR) return 0;
157 
158  if (type == IEC268Meter || type == IEC268LongMeter) {
159 
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
162  // result not as a percentage, but as a scale between 0 and
163  // whatever the "percentage" for our (possibly >0dB) max dB is.
164 
165  float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb);
166  float percent = iec_dB_to_fader(dB);
167  int faderLevel = int((maxLevel * percent) / maxPercent + 0.01f);
168 
169  if (faderLevel < 0) faderLevel = 0;
170  if (faderLevel > maxLevel) faderLevel = maxLevel;
171  return faderLevel;
172 
173  } else {
174 
175  int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint);
176 
177  if (dB >= 0.f) {
178 
179  if (faderTypes[type].maxDb <= 0.f) {
180 
181  return maxLevel;
182 
183  } else {
184 
185  float value = sqrtf(dB);
186  float scale = (maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb);
187  value *= scale;
188  int level = int(value + 0.01f) + zeroLevel;
189  if (level > maxLevel) level = maxLevel;
190  return level;
191  }
192 
193  } else {
194 
195  dB = 0.f - dB;
196  float value = sqrtf(dB);
197  float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb);
198  value *= scale;
199  int level = zeroLevel - int(value + 0.01f);
200  if (level < 0) level = 0;
201  return level;
202  }
203  }
204 }
205 
206 
207 float
208 AudioLevel::fader_to_multiplier(int level, int maxLevel, FaderType type)
209 {
210  if (level == 0) return 0.f;
211  return dB_to_multiplier(fader_to_dB(level, maxLevel, type));
212 }
213 
214 int
215 AudioLevel::multiplier_to_fader(float multiplier, int maxLevel, FaderType type)
216 {
217  if (multiplier == 0.f) return 0;
218  float dB = multiplier_to_dB(multiplier);
219  int fader = dB_to_fader(dB, maxLevel, type);
220  return fader;
221 }
222 
223 /*
224 const LevelList &
225 getPreviewLevelCache(int levels)
226 {
227  LevelList &ll = previewLevelCache[levels];
228  if (ll.empty()) {
229  for (int i = 0; i <= levels; ++i) {
230  float m = AudioLevel::fader_to_multiplier
231  (i + levels/4, levels + levels/4, AudioLevel::PreviewLevel);
232  if (levels == 1) m /= 100; // noise
233  ll.push_back(m);
234  }
235  }
236  return ll;
237 }
238 */
239 
240 int
242 {
243  assert(levels > 0);
244  return multiplier_to_fader(m, levels, PreviewLevel);
245 
246  /* The original multiplier_to_preview which follows is not thread-safe.
247 
248  if (m < 0.f) return -multiplier_to_preview(-m, levels);
249 
250  const LevelList &ll = getPreviewLevelCache(levels);
251  int result = -1;
252 
253  int lo = 0, hi = levels;
254 
255  // binary search
256  int level = -1;
257  while (result < 0) {
258  int newlevel = (lo + hi) / 2;
259  if (newlevel == level ||
260  newlevel == 0 ||
261  newlevel == levels) {
262  result = newlevel;
263  break;
264  }
265  level = newlevel;
266  if (ll[level] >= m) {
267  hi = level;
268  } else if (ll[level+1] >= m) {
269  result = level;
270  } else {
271  lo = level;
272  }
273  }
274 
275  return result;
276 
277  */
278 }
279 
280 float
281 AudioLevel::preview_to_multiplier(int level, int levels)
282 {
283  assert(levels > 0);
284  return fader_to_multiplier(level, levels, PreviewLevel);
285 /*
286  if (level < 0) return -preview_to_multiplier(-level, levels);
287  const LevelList &ll = getPreviewLevelCache(levels);
288  return ll[level];
289 */
290 }
291 
292 
static float multiplier_to_dB(float multiplier)
Definition: AudioLevel.cpp:54
static const float DB_FLOOR
Definition: AudioLevel.h:38
static float fader_to_multiplier(int level, int maxLevel, FaderType type)
Definition: AudioLevel.cpp:208
static float dB_to_multiplier(float dB)
Definition: AudioLevel.cpp:63
static const FaderDescription faderTypes[]
Definition: AudioLevel.cpp:41
static float preview_to_multiplier(int level, int levels)
Definition: AudioLevel.cpp:281
FaderDescription(float _minDb, float _maxDb, float _zeroPoint)
Definition: AudioLevel.cpp:33
static float fader_to_dB(int level, int maxLevel, FaderType type)
Definition: AudioLevel.cpp:117
static float iec_fader_to_dB(float def)
Definition: AudioLevel.cpp:95
static float iec_dB_to_fader(float db)
Definition: AudioLevel.cpp:72
static int multiplier_to_preview(float multiplier, int levels)
Definition: AudioLevel.cpp:241
static int dB_to_fader(float dB, int maxFaderLevel, FaderType type)
Definition: AudioLevel.cpp:154
static int multiplier_to_fader(float multiplier, int maxFaderLevel, FaderType type)
Definition: AudioLevel.cpp:215