1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7     See the AUTHORS file for more details.
8 
9     This program is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.  See the file
13     COPYING included with this distribution for more information.
14 */
15 
16 #include "base/AudioLevel.h"
17 #include <cmath>
18 #include <iostream>
19 #include <map>
20 #include <vector>
21 
22 namespace Rosegarden {
23 
24 struct FaderDescription
25 {
FaderDescriptionRosegarden::FaderDescription26     FaderDescription(float i_minDb, float i_maxDb, float i_zeroPoint) :
27         minDb(i_minDb), maxDb(i_maxDb), zeroPoint(i_zeroPoint) { }
28 
29     float minDb;
30     float maxDb;
31     float zeroPoint; // as fraction of total throw
32 };
33 
34 static const FaderDescription faderTypes[] = {
35     FaderDescription(-40.0,  +6.0, 0.75), // short
36     FaderDescription(-70.0, +10.0, 0.80), // long
37     FaderDescription(-70.0,   0.0, 1.00), // IEC268
38     FaderDescription(-70.0, +10.0, 0.80), // IEC268 long
39     FaderDescription(-40.0,   0.0, 1.00), // preview
40 };
41 
42 typedef std::vector<float> LevelList;
43 static std::map<int, LevelList> previewLevelCache;
44 static const LevelList &getPreviewLevelCache(int levels);
45 
46 float
multiplier_to_dB(float multiplier)47 AudioLevel::multiplier_to_dB(float multiplier)
48 {
49     if (multiplier == 0.0) return DB_FLOOR;
50     float dB = 10 * log10f(multiplier);
51     return dB;
52 }
53 
54 float
dB_to_multiplier(float dB)55 AudioLevel::dB_to_multiplier(float dB)
56 {
57     if (dB == DB_FLOOR) return 0.0;
58     float m = powf(10.0, dB / 10.0);
59     return m;
60 }
61 
62 /* IEC 60-268-18 fader levels.  Thanks to Steve Harris. */
63 
iec_dB_to_fader(float db)64 static float iec_dB_to_fader(float db)
65 {
66     float def = 0.0f; // Meter deflection %age
67 
68     if (db < -70.0f) {
69         def = 0.0f;
70     } else if (db < -60.0f) {
71         def = (db + 70.0f) * 0.25f;
72     } else if (db < -50.0f) {
73         def = (db + 60.0f) * 0.5f + 2.5f; // corrected from 5.0f base, thanks Robin Gareus
74     } else if (db < -40.0f) {
75         def = (db + 50.0f) * 0.75f + 7.5f;
76     } else if (db < -30.0f) {
77         def = (db + 40.0f) * 1.5f + 15.0f;
78     } else if (db < -20.0f) {
79         def = (db + 30.0f) * 2.0f + 30.0f;
80     } else {
81         def = (db + 20.0f) * 2.5f + 50.0f;
82     }
83 
84     return def;
85 }
86 
iec_fader_to_dB(float def)87 static float iec_fader_to_dB(float def)  // Meter deflection %age
88 {
89     float db = 0.0f;
90 
91     if (def >= 50.0f) {
92         db = (def - 50.0f) / 2.5f - 20.0f;
93     } else if (def >= 30.0f) {
94         db = (def - 30.0f) / 2.0f - 30.0f;
95     } else if (def >= 15.0f) {
96         db = (def - 15.0f) / 1.5f - 40.0f;
97     } else if (def >= 7.5f) {
98         db = (def - 7.5f) / 0.75f - 50.0f;
99     } else if (def >= 2.5f) {
100         db = (def - 2.5f) / 0.5f - 60.0f;
101     } else {
102         db = (def / 0.25f) - 70.0f;
103     }
104 
105     return db;
106 }
107 
108 float
fader_to_dB(int level,int maxLevel,FaderType type)109 AudioLevel::fader_to_dB(int level, int maxLevel, FaderType type)
110 {
111     if (level == 0) return DB_FLOOR;
112 
113     if (type == IEC268Meter || type == IEC268LongMeter) {
114 
115         float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb);
116         float percent = float(level) * maxPercent / float(maxLevel);
117         float dB = iec_fader_to_dB(percent);
118         return dB;
119 
120     } else { // scale proportional to sqrt(fabs(dB))
121 
122         int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint);
123 
124         if (level >= zeroLevel) {
125 
126             float value = level - zeroLevel;
127             float scale = float(maxLevel - zeroLevel) /
128                 sqrtf(faderTypes[type].maxDb);
129             value /= scale;
130             float dB = powf(value, 2.0);
131             return dB;
132 
133         } else {
134 
135             float value = zeroLevel - level;
136             float scale = zeroLevel / sqrtf(0.0 - faderTypes[type].minDb);
137             value /= scale;
138             float dB = powf(value, 2.0);
139             return 0.0 - dB;
140         }
141     }
142 }
143 
144 
145 int
dB_to_fader(float dB,int maxLevel,FaderType type)146 AudioLevel::dB_to_fader(float dB, int maxLevel, FaderType type)
147 {
148     if (dB == DB_FLOOR) return 0;
149 
150     if (type == IEC268Meter || type == IEC268LongMeter) {
151 
152         // The IEC scale gives a "percentage travel" for a given dB
153         // level, but it reaches 100% at 0dB.  So we want to treat the
154         // result not as a percentage, but as a scale between 0 and
155         // whatever the "percentage" for our (possibly >0dB) max dB is.
156 
157         float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb);
158         float percent = iec_dB_to_fader(dB);
159         int faderLevel = int((maxLevel * percent) / maxPercent + 0.01);
160 
161         if (faderLevel < 0) faderLevel = 0;
162         if (faderLevel > maxLevel) faderLevel = maxLevel;
163         return faderLevel;
164 
165     } else {
166 
167         int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint);
168 
169         if (dB >= 0.0) {
170 
171             float value = sqrtf(dB);
172             float scale = (maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb);
173             value *= scale;
174             int level = int(value + 0.01) + zeroLevel;
175             if (level > maxLevel) level = maxLevel;
176             return level;
177 
178         } else {
179 
180             dB = 0.0 - dB;
181             float value = sqrtf(dB);
182             float scale = zeroLevel / sqrtf(0.0 - faderTypes[type].minDb);
183             value *= scale;
184             int level = zeroLevel - int(value + 0.01);
185             if (level < 0) level = 0;
186             return level;
187         }
188     }
189 }
190 
191 
192 float
fader_to_multiplier(int level,int maxLevel,FaderType type)193 AudioLevel::fader_to_multiplier(int level, int maxLevel, FaderType type)
194 {
195     if (level == 0) return 0.0;
196     return dB_to_multiplier(fader_to_dB(level, maxLevel, type));
197 }
198 
199 int
multiplier_to_fader(float multiplier,int maxLevel,FaderType type)200 AudioLevel::multiplier_to_fader(float multiplier, int maxLevel, FaderType type)
201 {
202     if (multiplier == 0.0) return 0;
203     float dB = multiplier_to_dB(multiplier);
204     int fader = dB_to_fader(dB, maxLevel, type);
205     return fader;
206 }
207 
208 
209 const LevelList &
getPreviewLevelCache(int levels)210 getPreviewLevelCache(int levels)
211 {
212     LevelList &ll = previewLevelCache[levels];
213     if (ll.empty()) {
214         for (int i = 0; i <= levels; ++i) {
215             float m = AudioLevel::fader_to_multiplier
216                 (i, levels, AudioLevel::PreviewLevel);
217             if (levels == 1) m /= 100; // noise
218             ll.push_back(m);
219         }
220     }
221     return ll;
222 }
223 
224 int
multiplier_to_preview(float m,int levels)225 AudioLevel::multiplier_to_preview(float m, int levels)
226 {
227     const LevelList &ll = getPreviewLevelCache(levels);
228     int result = -1;
229 
230     int lo = 0, hi = levels;
231 
232     // binary search
233     int level = -1;
234     while (result < 0) {
235         int newlevel = (lo + hi) / 2;
236         if (newlevel == level ||
237             newlevel == 0 ||
238             newlevel == levels) {
239             result = newlevel;
240             break;
241         }
242         level = newlevel;
243         if (ll[level] >= m) {
244             hi = level;
245         } else if (ll[level+1] >= m) {
246             result = level;
247         } else {
248             lo = level;
249         }
250     }
251 
252     return result;
253 }
254 
255 float
preview_to_multiplier(int level,int levels)256 AudioLevel::preview_to_multiplier(int level, int levels)
257 {
258     const LevelList &ll = getPreviewLevelCache(levels);
259     return ll[level];
260 }
261 
262 int AudioLevel::m_panLaw = 0;
263 
264 float
panGainLeft(float pan)265 AudioLevel::panGainLeft(float pan)  // Apply panning law to left channel
266 {
267     if (m_panLaw == 3) {
268         // -3dB Panning Law (variant)
269         //
270         // This law has the same characteristics as the -3dB law described
271         // below, except that a channel's gain begins at +3dB and decreases to
272         // 0dB as the control is moved through the center position.  This
273         // setting must be used with caution, as the increased edge gains could
274         // introduce clipping.
275         //
276         return sqrtf(fabsf((100.0 - pan) / 100.0));  // -3dB pan law  (variant)
277 
278     } else if (m_panLaw == 2) {
279         // -6dB Panning Law
280         //
281         // A channel's gain begins at 0dB and decreases to -6dB as the control
282         // is moved to the center.  From there on the signal continues to
283         // decrease until it is completely attenuated at the opposite edge.
284         // The 3dB dip in the combined power of both channels when the control
285         // is centered will cause the extremes to sound louder than the center.
286         //
287         return (100.0 - pan) / 200.0;
288 
289     } else if (m_panLaw == 1) {
290         // -3dB Panning Law
291         //
292         // A channel's gain begins at 0dB and decreases to -3dB as the control
293         // is centered.  From there on the signal continues to decrease until
294         // it is completely attenuated at the opposite edge.  The combined
295         // power of both channels remains constant throughout the panning
296         // range, resulting in an apparent constant loudness.
297         //
298         return sqrtf(fabsf((100.0 - pan) / 200.0));
299 
300     } else {
301         // OdB Panning Law (default)
302         //
303         // A channel's gain begins at 0dB and remains at 0dB as the control is
304         // moved to the the center.  From there on the signal decreases
305         // linearly till it is completely attenuated at the opposite edge.
306         // Since both channels have a gain of 0dB at the center, the net
307         // effect is a 3dB boost in apparent loudness when the control is
308         // centered.  This is a basic balance pot.
309         //
310         return (pan > 0.0) ? (100.0 - pan) / 100.0 : 1.0;
311 
312     }
313 }
314 
315 float
panGainRight(float pan)316 AudioLevel::panGainRight(float pan)  // Apply panning law to right channel
317 {
318     if (m_panLaw == 3) {
319         return sqrtf(fabsf((100.0 + pan) / 100.0));  // -3dB pannig law (variant)
320 
321     } else if (m_panLaw == 2) {
322         return (100.0 + pan) / 200.0;  // -6dB pan law
323 
324     } else if (m_panLaw == 1) {
325         return sqrtf(fabsf((100.0 + pan) / 200.0));  // -3dB panning law
326 
327     } else {
328         return (pan < 0.0) ? (100.0 + pan) / 100.0 : 1.0;  // 0dB panning law (default)
329 
330     }
331 }
332 
AudioPanD(MidiByte midiPan)333 double AudioLevel::AudioPanD(MidiByte midiPan)
334 {
335     // Scale 0-64 from 0 to 100.
336     if (midiPan <= 64)
337         return static_cast<double>(midiPan) / 64.0 * 100.0;
338 
339     // Scale 64-127 from 100 to 200.
340     return static_cast<double>(midiPan - 1) / 63.0 * 100.0;
341 }
342 
AudioPanI(MidiByte midiPan)343 int AudioLevel::AudioPanI(MidiByte midiPan)
344 {
345     // ??? A table would be faster.
346 
347     // Scale 0-64 from 0 to 100.
348     if (midiPan <= 64) {
349         // Adding 32 (half of 64) to get proper rounding.
350         return (midiPan * 100 + 32) / 64;
351     }
352 
353     // Scale 64-127 from 100 to 200.
354     // Adding 31 (half of 63 truncated) to get proper rounding.
355     return ((midiPan - 1) * 100 + 31) / 63;
356 }
357 
MIDIPanI(int audioPan)358 MidiByte AudioLevel::MIDIPanI(int audioPan)
359 {
360     // Scale 0-100 to 0-64.  (Add 50 to get proper rounding.)
361     if (audioPan <= 100)
362         return (audioPan * 64 + 50) / 100;
363 
364     // Scale 100-200 to 64-127.  (Add 50 to get proper rounding.)
365     return (audioPan * 63 + 50) / 100 + 1;
366 }
367 
368 
369 }
370