Zrythm v2.0.0-alpha.1
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
waveform_canvas_renderer.h
1// SPDX-FileCopyrightText: © 2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <functional>
7#include <vector>
8
9#include "dsp/tempo_map.h"
10#include "dsp/tick_types.h"
11
12#include <QColor>
13#include <QtCanvasPainter/qcanvaspainter.h>
14#include <QtCanvasPainter/qcanvaspainteritemrenderer.h>
15
16#include <juce_audio_basics/juce_audio_basics.h>
17
18namespace zrythm::gui::qquick
19{
20
22
25{
26 float min;
27 float max;
28};
29
43std::vector<int64_t>
44compute_frame_mapping (
45 int canvas_width,
46 qreal reference_width,
47 qreal reference_x,
48 std::function<int64_t (double)> content_fraction_to_frame);
49
53std::vector<int64_t>
54compute_linear_frame_mapping (
55 int canvas_width,
56 qreal reference_width,
57 qreal reference_x,
58 int64_t total_frames);
59
70std::vector<int64_t>
71compute_timeline_frame_mapping (
72 int canvas_width,
73 qreal reference_width,
74 qreal reference_x,
75 const dsp::TempoMap &tempo_map,
76 dsp::TimelineTick clip_start_tick,
77 double timeline_tick_duration);
78
95std::vector<std::vector<WaveformPeak>>
96compute_waveform_peaks (
97 const juce::AudioSampleBuffer &buffer,
98 const std::vector<int64_t> &pixel_frames,
99 int canvas_width,
100 int64_t loop_wrap_start,
101 int64_t loop_wrap_length,
102 bool has_loop);
103
110class WaveformCanvasRenderer : public QCanvasPainterItemRenderer
111{
112public:
113 WaveformCanvasRenderer () = default;
114 Q_DISABLE_COPY_MOVE (WaveformCanvasRenderer)
115
116 void synchronize (QCanvasPainterItem * item) override;
117 void paint (QCanvasPainter * painter) override;
118
119private:
120 void compute_peaks ();
121
122 // Cached visual state from the item
123 QColor waveform_color_;
124 QColor outline_color_;
125 float canvas_width_ = 0.0f;
126 float canvas_height_ = 0.0f;
127
128 // Content density decoupling (from ClipCanvasItemBase)
129 qreal reference_width_ = 0;
130 qreal reference_x_ = 0;
131
132 // Loop wrapping (from AudioClipWaveformCanvasItem)
133 bool has_loop_ = false;
134 int64_t loop_wrap_start_ = 0; // where loop region begins in buffer
135 int64_t loop_wrap_length_ = 0; // length of one loop iteration in buffer
136
137 // Cached pointer to the item's serialized audio buffer (owned by the item)
138 const juce::AudioSampleBuffer * audio_buffer_ = nullptr;
139
140 // Precomputed per-pixel frame mapping (size = canvas_width + 1)
141 std::vector<int64_t> pixel_frames_;
142
143 // Cached peak data
144 std::vector<std::vector<WaveformPeak>> peaks_;
145 int num_channels_ = 0;
146
147 // Change detection
148 uint64_t prev_generation_ = 0;
149 float prev_width_ = 0.0f;
150 float prev_height_ = 0.0f;
151 qreal prev_reference_width_ = 0;
152 qreal prev_reference_x_ = 0;
153};
154
155} // namespace zrythm::gui::qquick
Generic base for hardware-accelerated waveform rendering.
A min/max peak pair for one pixel column, normalized to [0, 1].