Apply equal-power (cosine) fade-in then fade-out envelope in-place The cosine taper maintains constant perceived loudness at the crossover point (0 dB centre gain vs −6 dB for a linear taper).
96{
97 if (data.empty())
98 return;
99
100 const size_t n = data.size();
101 const auto in_end = static_cast<size_t>(fade_in_ratio * static_cast<double>(n));
102 const size_t out_start = n - static_cast<size_t>(fade_out_ratio * static_cast<double>(n));
103
104 const double pi = std::numbers::pi;
105
106 if (in_end > 0) {
107 const auto in_len = static_cast<double>(in_end - 1);
108 for (size_t i = 0; i < in_end; ++i) {
109 const double t = (in_len > 0.0)
110 ? static_cast<double>(i) / in_len
111 : 1.0;
112 data[i] *= std::sin(t * pi * 0.5);
113 }
114 }
115
116 if (out_start < n) {
117 const auto out_len = static_cast<double>(n - 1 - out_start);
118 for (size_t i = out_start; i < n; ++i) {
119 const double t = (out_len > 0.0)
120 ? static_cast<double>(i - out_start) / out_len
121 : 1.0;
122 data[i] *= std::cos(t * pi * 0.5);
123 }
124 }
125}