mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:48:11 +00:00

"Frame" is an MPEG term, which is not only unintuitive but also overloaded with different meaning by other codecs (e.g. FLAC). Therefore, use the standard term Sample for the central audio structure. The class is also extracted to its own file, because it's becoming quite large. Bundling these two changes means not distributing similar modifications (changing names and paths) across commits. Co-authored-by: kleines Filmröllchen <malu.bertsch@gmail.com>
64 lines
2.2 KiB
C++
64 lines
2.2 KiB
C++
/*
|
|
* Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>
|
|
* 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::Buffer that AudioServer receives
|
|
static NonnullRefPtr<Audio::Buffer> 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);
|
|
}
|
|
return Audio::Buffer::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::ClientConnection::construct();
|
|
m_audio_client->on_finish_playing_buffer = [this](int buffer_id) {
|
|
(void)buffer_id;
|
|
enqueue_audio();
|
|
};
|
|
m_resampler = Audio::ResampleHelper<double>(Music::sample_rate, m_audio_client->get_sample_rate());
|
|
}
|
|
|
|
void AudioPlayerLoop::enqueue_audio()
|
|
{
|
|
m_track_manager.fill_buffer(m_buffer);
|
|
NonnullRefPtr<Audio::Buffer> audio_buffer = music_samples_to_buffer(m_buffer);
|
|
audio_buffer = 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);
|
|
}
|