Files
ladybird/Userland/Applications/Piano/AudioPlayerLoop.h
kleines Filmröllchen b7eea03103 Piano: Overhaul AudioPlayerLoop and throw out event loops
The audio player loop uses custom IPC plumbing to safely bypass any
event loop shenanigans. There is still work to be done, but this already
improves the realtime capabilities of Piano.
2022-12-15 00:21:00 -07:00

54 lines
1.7 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
*/
#pragma once
#include "Music.h"
#include <LibAudio/ConnectionToServer.h>
#include <LibAudio/Resampler.h>
#include <LibAudio/Sample.h>
#include <LibAudio/WavWriter.h>
#include <LibCore/Event.h>
#include <LibCore/Object.h>
#include <LibDSP/Music.h>
#include <LibThreading/Thread.h>
class TrackManager;
// Wrapper class accepting custom events to advance the track playing and forward audio data to the system.
// This does not run on a separate thread, preventing IPC multithreading madness.
class AudioPlayerLoop final : public Core::Object {
C_OBJECT(AudioPlayerLoop)
public:
virtual ~AudioPlayerLoop() override;
void enqueue_audio();
void toggle_paused();
bool is_playing() const { return m_should_play_audio; }
private:
AudioPlayerLoop(TrackManager& track_manager, Atomic<bool>& need_to_write_wav, Threading::MutexProtected<Audio::WavWriter>& wav_writer);
intptr_t pipeline_thread_main();
ErrorOr<void> send_audio_to_server();
void write_wav_if_needed();
TrackManager& m_track_manager;
FixedArray<DSP::Sample> m_buffer;
Optional<Audio::ResampleHelper<DSP::Sample>> m_resampler;
RefPtr<Audio::ConnectionToServer> m_audio_client;
NonnullRefPtr<Threading::Thread> m_pipeline_thread;
Vector<Audio::Sample, Audio::AUDIO_BUFFER_SIZE> m_remaining_samples {};
Atomic<bool> m_should_play_audio { true };
Atomic<bool> m_exit_requested { false };
Atomic<bool>& m_need_to_write_wav;
Threading::MutexProtected<Audio::WavWriter>& m_wav_writer;
};