AudioCodecPlugin.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibAudio/Loader.h>
  7. #include <LibAudio/Resampler.h>
  8. #include <LibAudio/Sample.h>
  9. #include <LibWeb/Platform/AudioCodecPlugin.h>
  10. namespace Web::Platform {
  11. static AudioCodecPlugin::AudioCodecPluginCreator s_creation_hook;
  12. AudioCodecPlugin::AudioCodecPlugin() = default;
  13. AudioCodecPlugin::~AudioCodecPlugin() = default;
  14. void AudioCodecPlugin::install_creation_hook(AudioCodecPluginCreator creation_hook)
  15. {
  16. VERIFY(!s_creation_hook);
  17. s_creation_hook = move(creation_hook);
  18. }
  19. ErrorOr<NonnullOwnPtr<AudioCodecPlugin>> AudioCodecPlugin::create(NonnullRefPtr<Audio::Loader> loader)
  20. {
  21. VERIFY(s_creation_hook);
  22. return s_creation_hook(move(loader));
  23. }
  24. ErrorOr<FixedArray<Audio::Sample>> AudioCodecPlugin::read_samples_from_loader(Audio::Loader& loader, size_t samples_to_load, size_t device_sample_rate)
  25. {
  26. auto buffer_or_error = loader.get_more_samples(samples_to_load);
  27. if (buffer_or_error.is_error()) {
  28. dbgln("Error while loading samples: {}", buffer_or_error.error().description);
  29. return Error::from_string_literal("Error while loading samples");
  30. }
  31. Audio::ResampleHelper<Audio::Sample> resampler(loader.sample_rate(), device_sample_rate);
  32. return FixedArray<Audio::Sample>::create(resampler.resample(buffer_or_error.release_value()).span());
  33. }
  34. Duration AudioCodecPlugin::set_loader_position(Audio::Loader& loader, double position, Duration duration, size_t device_sample_rate)
  35. {
  36. if (loader.total_samples() == 0)
  37. return current_loader_position(loader, device_sample_rate);
  38. auto duration_value = static_cast<double>(duration.to_milliseconds()) / 1000.0;
  39. position = position / duration_value * static_cast<double>(loader.total_samples() - 1);
  40. loader.seek(static_cast<int>(position)).release_value_but_fixme_should_propagate_errors();
  41. return current_loader_position(loader, device_sample_rate);
  42. }
  43. Duration AudioCodecPlugin::current_loader_position(Audio::Loader const& loader, size_t device_sample_rate)
  44. {
  45. auto samples_played = static_cast<double>(loader.loaded_samples());
  46. auto sample_rate = static_cast<double>(loader.sample_rate());
  47. auto source_to_device_ratio = sample_rate / static_cast<double>(device_sample_rate);
  48. samples_played *= source_to_device_ratio;
  49. return Duration::from_milliseconds(static_cast<i64>(samples_played / sample_rate * 1000.0));
  50. }
  51. }