mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 08:28:11 +00:00

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.
95 lines
2.6 KiB
C++
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;
|
|
};
|