| 186 | } |
| 187 | |
| 188 | engine::io::json::Value audio_summary_json(const engine::runtime::AudioBuffer & audio) { |
| 189 | if (audio.samples.empty()) { |
| 190 | throw std::runtime_error("Vevo2 warmbench received empty audio output"); |
| 191 | } |
| 192 | double sum = 0.0; |
| 193 | double abs_sum = 0.0; |
| 194 | double sq_sum = 0.0; |
| 195 | float min_value = audio.samples.front(); |
| 196 | float max_value = audio.samples.front(); |
| 197 | for (const float sample : audio.samples) { |
| 198 | sum += static_cast<double>(sample); |
| 199 | abs_sum += std::abs(static_cast<double>(sample)); |
| 200 | sq_sum += static_cast<double>(sample) * static_cast<double>(sample); |
| 201 | min_value = std::min(min_value, sample); |
| 202 | max_value = std::max(max_value, sample); |
| 203 | } |
| 204 | const int64_t channels = std::max<int64_t>(1, audio.channels); |
| 205 | const double count = static_cast<double>(audio.samples.size()); |
| 206 | return engine::io::json::Value::make_object({ |
| 207 | {"sample_rate", number(static_cast<double>(audio.sample_rate))}, |
| 208 | {"channels", number(static_cast<double>(audio.channels))}, |
| 209 | {"samples", number(static_cast<double>(audio.samples.size()))}, |
| 210 | {"frames", number(static_cast<double>(audio.samples.size() / static_cast<size_t>(channels)))}, |
| 211 | {"sum", number(sum)}, |
| 212 | {"mean_abs", number(abs_sum / count)}, |
| 213 | {"rms", number(std::sqrt(sq_sum / count))}, |
| 214 | {"min", number(min_value)}, |
| 215 | {"max", number(max_value)}, |
| 216 | }); |
| 217 | } |
| 218 | |
| 219 | engine::io::json::Value step_json( |
| 220 | const engine::runtime::TaskResult & result, |