| 44 | const float MinPower = 0.000125f; |
| 45 | |
| 46 | static float calculateNormalizationScale(AudioBus * response) |
| 47 | { |
| 48 | // Normalize by RMS power |
| 49 | size_t numberOfChannels = response->numberOfChannels(); |
| 50 | int length = response->length(); |
| 51 | |
| 52 | float power = 0; |
| 53 | |
| 54 | for (int i = 0; i < numberOfChannels; ++i) |
| 55 | { |
| 56 | float channelPower = 0; |
| 57 | VectorMath::vsvesq(response->channel(i)->data(), 1, &channelPower, length); |
| 58 | power += channelPower; |
| 59 | } |
| 60 | |
| 61 | power = sqrt(power / (numberOfChannels * length)); |
| 62 | |
| 63 | // Protect against accidental overload |
| 64 | if (isinf(power) || isnan(power) || power < MinPower) |
| 65 | power = MinPower; |
| 66 | |
| 67 | float scale = 1 / power; |
| 68 | |
| 69 | scale *= powf(10, GainCalibration * 0.05f); // calibrate to make perceived volume same as unprocessed |
| 70 | |
| 71 | // Scale depends on sample-rate. |
| 72 | if (response->sampleRate()) |
| 73 | scale *= GainCalibrationSampleRate / response->sampleRate(); |
| 74 | |
| 75 | // True-stereo compensation |
| 76 | if (response->numberOfChannels() == Channels::Quad) |
| 77 | scale *= 0.5f; |
| 78 | |
| 79 | return scale; |
| 80 | } |
| 81 | |
| 82 | //------------------------------------------------------------------------------ |
| 83 |
no test coverage detected