int AudioLevel::dB_to_fader(float dB, int maxLevel, FaderType type) { if (dB == DB_FLOOR) return 0; if (type == IEC268Meter || type == IEC268LongMeter) { // The IEC scale gives a "percentage travel" for a given dB // level, but it reaches 100% at 0dB. So we want to treat the // result not as a percentage, but as a scale between 0 and // whatever the "percentage" for our (possibly >0dB) max dB is. float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb); float percent = iec_dB_to_fader(dB); int faderLevel = int((maxLevel * percent) / maxPercent + 0.01f); if (faderLevel < 0) faderLevel = 0; if (faderLevel > maxLevel) faderLevel = maxLevel; return faderLevel; } else { int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint); if (dB >= 0.f) { if (faderTypes[type].maxDb <= 0.f) { return maxLevel; } else { float value = sqrtf(dB); float scale = (maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb); value *= scale; int level = int(value + 0.01f) + zeroLevel; if (level > maxLevel) level = maxLevel; return level; } } else { dB = 0.f - dB; float value = sqrtf(dB); float scale = zeroLevel / sqrtf(0.f - faderTypes[type].minDb); value *= scale; int level = zeroLevel - int(value + 0.01f); if (level < 0) level = 0; return level; } } }
float AudioLevel::fader_to_dB(int level, int maxLevel, FaderType type) { if (level == 0) return DB_FLOOR; if (type == IEC268Meter || type == IEC268LongMeter) { float maxPercent = iec_dB_to_fader(faderTypes[type].maxDb); float percent = float(level) * maxPercent / float(maxLevel); float dB = iec_fader_to_dB(percent); return dB; } else { // scale proportional to sqrt(fabs(dB)) int zeroLevel = int(maxLevel * faderTypes[type].zeroPoint); if (level >= zeroLevel) { float value = level - zeroLevel; float scale = float(maxLevel - zeroLevel) / sqrtf(faderTypes[type].maxDb); value /= scale; float dB = powf(value, 2.0); return dB; } else { float value = zeroLevel - level; float scale = zeroLevel / sqrtf(0.0 - faderTypes[type].minDb); value /= scale; float dB = powf(value, 2.0); return 0.0 - dB; } } }