AudioCodecPluginLadybird.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "AudioCodecPluginLadybird.h"
  7. #include <AK/Endian.h>
  8. #include <AK/MemoryStream.h>
  9. #include <LibAudio/Sample.h>
  10. #include <QAudioFormat>
  11. #include <QAudioSink>
  12. #include <QBuffer>
  13. #include <QMediaDevices>
  14. namespace Ladybird {
  15. ErrorOr<NonnullOwnPtr<AudioCodecPluginLadybird>> AudioCodecPluginLadybird::create()
  16. {
  17. auto devices = TRY(adopt_nonnull_own_or_enomem(new (nothrow) QMediaDevices()));
  18. auto const& device_info = devices->defaultAudioOutput();
  19. auto format = device_info.preferredFormat();
  20. format.setSampleFormat(QAudioFormat::Int16);
  21. format.setChannelCount(2);
  22. if (!device_info.isFormatSupported(format))
  23. return Error::from_string_literal("Audio device format not supported");
  24. auto audio_output = TRY(adopt_nonnull_own_or_enomem(new (nothrow) QAudioSink(device_info, format)));
  25. return adopt_nonnull_own_or_enomem(new (nothrow) AudioCodecPluginLadybird(move(devices), move(audio_output)));
  26. }
  27. AudioCodecPluginLadybird::AudioCodecPluginLadybird(NonnullOwnPtr<QMediaDevices> devices, NonnullOwnPtr<QAudioSink> audio_output)
  28. : m_devices(move(devices))
  29. , m_audio_output(move(audio_output))
  30. , m_io_device(m_audio_output->start())
  31. {
  32. }
  33. AudioCodecPluginLadybird::~AudioCodecPluginLadybird() = default;
  34. size_t AudioCodecPluginLadybird::device_sample_rate()
  35. {
  36. return m_audio_output->format().sampleRate();
  37. }
  38. void AudioCodecPluginLadybird::enqueue_samples(FixedArray<Audio::Sample> samples)
  39. {
  40. QByteArray buffer;
  41. buffer.resize(samples.size() * 2 * sizeof(u16));
  42. FixedMemoryStream stream { Bytes { buffer.data(), static_cast<size_t>(buffer.size()) } };
  43. for (auto& sample : samples) {
  44. LittleEndian<i16> pcm;
  45. pcm = static_cast<i16>(sample.left * NumericLimits<i16>::max());
  46. MUST(stream.write_value(pcm));
  47. pcm = static_cast<i16>(sample.right * NumericLimits<i16>::max());
  48. MUST(stream.write_value(pcm));
  49. }
  50. m_io_device->write(buffer.data(), buffer.size());
  51. }
  52. size_t AudioCodecPluginLadybird::remaining_samples() const
  53. {
  54. return 0;
  55. }
  56. void AudioCodecPluginLadybird::resume_playback()
  57. {
  58. m_audio_output->resume();
  59. }
  60. void AudioCodecPluginLadybird::pause_playback()
  61. {
  62. m_audio_output->suspend();
  63. }
  64. void AudioCodecPluginLadybird::playback_ended()
  65. {
  66. m_audio_output->suspend();
  67. }
  68. }