mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 16:45:08 +00:00

With the following change in how we send audio, the old Buffer type is not really needed anymore. However, moving WavLoader to the new system is a bit more involved and out of the scope of this PR. Therefore, we need to keep Buffer around, but to make it clear that it's the old buffer type which will be removed soon, we rename it to LegacyBuffer. Most of the users will be gone after the next commit anyways.
70 lines
2.5 KiB
C++
70 lines
2.5 KiB
C++
/*
|
|
* Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>
|
|
* Copyright (c) 2021, JJ Roberts-White <computerfido@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "AudioPlayerLoop.h"
|
|
|
|
#include "TrackManager.h"
|
|
|
|
// Converts Piano-internal data to an Audio::LegacyBuffer that AudioServer receives
|
|
static NonnullRefPtr<Audio::LegacyBuffer> music_samples_to_buffer(Array<Sample, sample_count> samples)
|
|
{
|
|
Vector<Audio::Sample, sample_count> frames;
|
|
frames.ensure_capacity(sample_count);
|
|
for (auto sample : samples) {
|
|
Audio::Sample frame = { sample.left / (double)NumericLimits<i16>::max(), sample.right / (double)NumericLimits<i16>::max() };
|
|
frames.unchecked_append(frame);
|
|
}
|
|
// FIXME: Handle OOM better.
|
|
return MUST(Audio::LegacyBuffer::create_with_samples(frames));
|
|
}
|
|
|
|
AudioPlayerLoop::AudioPlayerLoop(TrackManager& track_manager, bool& need_to_write_wav, Audio::WavWriter& wav_writer)
|
|
: m_track_manager(track_manager)
|
|
, m_need_to_write_wav(need_to_write_wav)
|
|
, m_wav_writer(wav_writer)
|
|
{
|
|
m_audio_client = Audio::ConnectionFromClient::try_create().release_value_but_fixme_should_propagate_errors();
|
|
m_audio_client->on_finish_playing_buffer = [this](int buffer_id) {
|
|
(void)buffer_id;
|
|
enqueue_audio();
|
|
};
|
|
|
|
auto target_sample_rate = m_audio_client->get_sample_rate();
|
|
if (target_sample_rate == 0)
|
|
target_sample_rate = Music::sample_rate;
|
|
m_resampler = Audio::ResampleHelper<double>(Music::sample_rate, target_sample_rate);
|
|
}
|
|
|
|
void AudioPlayerLoop::enqueue_audio()
|
|
{
|
|
m_track_manager.fill_buffer(m_buffer);
|
|
NonnullRefPtr<Audio::LegacyBuffer> audio_buffer = music_samples_to_buffer(m_buffer);
|
|
// FIXME: Handle OOM better.
|
|
audio_buffer = MUST(Audio::resample_buffer(m_resampler.value(), *audio_buffer));
|
|
m_audio_client->async_enqueue(audio_buffer);
|
|
|
|
// FIXME: This should be done somewhere else.
|
|
if (m_need_to_write_wav) {
|
|
m_need_to_write_wav = false;
|
|
m_track_manager.reset();
|
|
m_track_manager.set_should_loop(false);
|
|
do {
|
|
m_track_manager.fill_buffer(m_buffer);
|
|
m_wav_writer.write_samples(reinterpret_cast<u8*>(m_buffer.data()), buffer_size);
|
|
} while (m_track_manager.time());
|
|
m_track_manager.reset();
|
|
m_track_manager.set_should_loop(true);
|
|
m_wav_writer.finalize();
|
|
}
|
|
}
|
|
|
|
void AudioPlayerLoop::toggle_paused()
|
|
{
|
|
m_should_play_audio = !m_should_play_audio;
|
|
|
|
m_audio_client->set_paused(!m_should_play_audio);
|
|
}
|