1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 08:28:11 +00:00
serenity/Userland/Applications/SoundPlayer/VisualizationWidget.h
kleines Filmröllchen ab49fcfb7c LibAudio+Userland: Remove Audio::LegacyBuffer
The file is now renamed to Queue.h, and the Resampler APIs with
LegacyBuffer are also removed. These changes look large because nobody
actually needs Buffer.h (or Queue.h). It was mostly transitive
dependencies on the massive list of includes in that header, which are
now almost all gone. Instead, we include common things like Sample.h
directly, which should give faster compile times as very few files
actually need Queue.h.
2022-05-03 23:09:20 +02:00

95 lines
2.6 KiB
C++

/*
* Copyright (c) 2021, Cesar Torres <shortanemoia@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/FixedArray.h>
#include <AK/Forward.h>
#include <AK/TypedTransfer.h>
#include <LibAudio/Sample.h>
#include <LibGUI/Frame.h>
#include <LibGUI/Painter.h>
class VisualizationWidget : public GUI::Frame {
C_OBJECT_ABSTRACT(VisualizationWidget)
public:
virtual void render(GUI::PaintEvent&, FixedArray<double> const& samples) = 0;
void set_buffer(FixedArray<Audio::Sample> const& buffer)
{
if (buffer.is_empty())
return;
if (m_sample_buffer.size() != buffer.size())
m_sample_buffer.resize(buffer.size());
for (size_t i = 0; i < buffer.size(); i++)
m_sample_buffer.data()[i] = (buffer[i].left + buffer[i].right) / 2.;
m_frame_count = 0;
}
virtual void set_samplerate(int samplerate)
{
m_samplerate = samplerate;
}
virtual void paint_event(GUI::PaintEvent& event) override
{
if (m_sample_buffer.size() == 0) {
Frame::paint_event(event);
GUI::Painter painter(*this);
painter.add_clip_rect(event.rect());
painter.fill_rect(frame_inner_rect(), Color::Black);
return;
}
if (m_render_buffer.size() == 0)
return;
size_t buffer_position = (m_frame_count * REFRESH_TIME_MILLISECONDS) * m_samplerate / 1000;
if (buffer_position + m_render_buffer.size() >= m_sample_buffer.size())
buffer_position = m_sample_buffer.size() - m_render_buffer.size();
AK::TypedTransfer<double>::copy(m_render_buffer.data(), m_sample_buffer.span().slice(buffer_position).data(), m_render_buffer.size());
render(event, m_render_buffer);
}
virtual void timer_event(Core::TimerEvent&) override
{
update();
m_frame_count++;
}
size_t frame_count() const { return m_frame_count; }
ErrorOr<void> set_render_sample_count(size_t count)
{
auto new_buffer = TRY(FixedArray<double>::try_create(count));
m_render_buffer.swap(new_buffer);
return {};
}
virtual void start_new_file(StringView) { }
protected:
int m_samplerate;
size_t m_frame_count;
Vector<double> m_sample_buffer;
FixedArray<double> m_render_buffer;
static constexpr size_t REFRESH_TIME_MILLISECONDS = 30;
VisualizationWidget()
: m_samplerate(-1)
, m_frame_count(0)
{
start_timer(REFRESH_TIME_MILLISECONDS);
}
virtual ~VisualizationWidget() = default;
};