Serenity Operating System
at master 71 lines 2.8 kB view raw
1/* 2 * Copyright (c) 2021, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/NumericLimits.h> 8#include <AK/Types.h> 9#include <LibAudio/Loader.h> 10#include <LibCore/ArgsParser.h> 11#include <LibCore/DeprecatedFile.h> 12#include <LibCore/ElapsedTimer.h> 13#include <LibCore/System.h> 14#include <LibMain/Main.h> 15#include <stdio.h> 16 17// The Kernel has problems with large anonymous buffers, so let's limit sample reads ourselves. 18static constexpr size_t MAX_CHUNK_SIZE = 1 * MiB / 2; 19 20ErrorOr<int> serenity_main(Main::Arguments args) 21{ 22 StringView path {}; 23 int sample_count = -1; 24 25 Core::ArgsParser args_parser; 26 args_parser.set_general_help("Benchmark audio loading"); 27 args_parser.add_positional_argument(path, "Path to audio file", "path"); 28 args_parser.add_option(sample_count, "How many samples to load at maximum", "sample-count", 's', "samples"); 29 args_parser.parse(args); 30 31 TRY(Core::System::unveil(Core::DeprecatedFile::absolute_path(path), "r"sv)); 32 TRY(Core::System::unveil(nullptr, nullptr)); 33 TRY(Core::System::pledge("stdio recvfd rpath")); 34 35 auto maybe_loader = Audio::Loader::create(path); 36 if (maybe_loader.is_error()) { 37 warnln("Failed to load audio file: {}", maybe_loader.error().description); 38 return 1; 39 } 40 auto loader = maybe_loader.release_value(); 41 42 Core::ElapsedTimer sample_timer { true }; 43 i64 total_loader_time = 0; 44 int remaining_samples = sample_count > 0 ? sample_count : NumericLimits<int>::max(); 45 unsigned total_loaded_samples = 0; 46 47 for (;;) { 48 if (remaining_samples > 0) { 49 sample_timer = sample_timer.start_new(); 50 auto samples = loader->get_more_samples(min(MAX_CHUNK_SIZE, remaining_samples)); 51 total_loader_time += sample_timer.elapsed(); 52 if (!samples.is_error()) { 53 remaining_samples -= samples.value().size(); 54 total_loaded_samples += samples.value().size(); 55 if (samples.value().size() == 0) 56 break; 57 } else { 58 warnln("Error while loading audio: {}", samples.error().description); 59 return 1; 60 } 61 } else 62 break; 63 } 64 65 auto time_per_sample = static_cast<double>(total_loader_time) / static_cast<double>(total_loaded_samples) * 1000.; 66 auto playback_time_per_sample = (1. / static_cast<double>(loader->sample_rate())) * 1000'000.; 67 68 outln("Loaded {:10d} samples in {:06.3f} s, {:9.3f} µs/sample, {:6.1f}% speed (realtime {:9.3f} µs/sample)", total_loaded_samples, static_cast<double>(total_loader_time) / 1000., time_per_sample, playback_time_per_sample / time_per_sample * 100., playback_time_per_sample); 69 70 return 0; 71}