Ardour  9.0-pre0-1467-gc8540a5ad6
wave_view.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
4  * Copyright (C) 2017 Tim Mayberry <mojofunk@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #ifndef _WAVEVIEW_WAVE_VIEW_H_
22 #define _WAVEVIEW_WAVE_VIEW_H_
23 
24 #include <memory>
25 
26 #include <glibmm/refptr.h>
27 
28 #include "ardour/types.h"
29 #include "canvas/item.h"
30 #include "waveview/visibility.h"
31 
32 namespace ARDOUR {
33  class AudioRegion;
34 }
35 
36 namespace Gdk {
37  class Pixbuf;
38 }
39 
40 namespace ArdourWaveView {
41 
42 class WaveViewCacheGroup;
43 class WaveViewDrawRequest;
44 class WaveViewDrawRequestQueue;
45 class WaveViewImage;
46 class WaveViewProperties;
47 class WaveViewDrawingThread;
48 
49 class LIBWAVEVIEW_API WaveView : public ArdourCanvas::Item, public sigc::trackable
50 {
51 public:
52  enum Shape { Normal, Rectified };
53 
54  std::string debug_name () const;
55 
56  /* Displays a single channel of waveform data for the given Region.
57 
58  x = 0 in the waveview corresponds to the first waveform datum taken
59  from region->start() samples into the source data.
60 
61  x = N in the waveview corresponds to the (N * spp)'th sample
62  measured from region->start() into the source data.
63 
64  when drawing, we will map the zeroth-pixel of the waveview
65  into a window.
66 
67  The waveview itself contains a set of pre-rendered Cairo::ImageSurfaces
68  that cache sections of the display. This is filled on-demand and
69  never cleared until something explicitly marks the cache invalid
70  (such as a change in samples_per_pixel, the log scaling, rectified or
71  other view parameters).
72  */
73 
74  WaveView (ArdourCanvas::Canvas*, std::shared_ptr<ARDOUR::AudioRegion>);
75  WaveView (Item*, std::shared_ptr<ARDOUR::AudioRegion>);
77 
78  void prepare_for_render (ArdourCanvas::Rect const& window_area) const;
79  bool needs_prepare_for_render () const { return true; }
80 
81  void render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context>) const;
82 
83  void compute_bounding_box () const;
84 
85  void set_samples_per_pixel (double);
87  void set_channel (int);
89 
97  void set_start_shift (double pixels);
98 
101 
102  void region_resized ();
103  void gain_changed ();
104 
105  void set_show_zero_line (bool);
106  bool show_zero_line () const;
107 
110  void set_logscaled (bool);
111 
112  void set_gradient_depth (double);
113  double gradient_depth () const;
114 
115  void set_shape (Shape);
116 
118 
119  /* currently missing because we don't need them (yet):
120  * set_shape_independent();
121  * set_logscaled_independent();
122  */
123 
124  static void set_global_gradient_depth (double);
125  static void set_global_logscaled (bool);
126  static void set_global_shape (Shape);
128  static void clear_cache ();
129 
130  static double global_gradient_depth () { return _global_gradient_depth; }
131 
132  static bool global_logscaled () { return _global_logscaled; }
133 
134  static Shape global_shape () { return _global_shape; }
135 
136  void set_amplitude_above_axis (double v);
137 
138  double amplitude_above_axis () const;
139 
140  static void set_clip_level (double dB);
142 
143  static void start_drawing_thread ();
144  static void stop_drawing_thread ();
145 
146  static void set_image_cache_size (uint64_t);
147 
148 private:
149  friend class WaveViewThreadClient;
150  friend class WaveViewThreads;
151 
152  std::shared_ptr<ARDOUR::AudioRegion> _region;
153 
154  const std::unique_ptr<WaveViewProperties> _props;
155 
156  mutable std::shared_ptr<WaveViewImage> _image;
157 
158  mutable std::shared_ptr<WaveViewCacheGroup> _cache_group;
159 
163 
169 
175 
179  bool rendered () const { return _image.get(); }
180 
182 
187 
193 
194  void init();
195 
196  mutable std::shared_ptr<WaveViewDrawRequest> current_request;
197 
199 
200  static double _global_gradient_depth;
201  static bool _global_logscaled;
204  static double _global_clip_level;
205 
207 
210 
211  struct LineTips {
212  double top;
213  double bot;
214  double spread;
215  bool clip_max;
216  bool clip_min;
217 
218  LineTips () : top (0.0), bot (0.0), clip_max (false), clip_min (false) {}
219  };
220 
221  static ArdourCanvas::Coord y_extent (double, Shape const, double const height);
222 
223  static void compute_tips (ARDOUR::PeakData const& peak, LineTips& tips, double const effective_height);
224 
225  static void draw_image (Cairo::RefPtr<Cairo::ImageSurface>&, ARDOUR::PeakData*, int n_peaks,
226  std::shared_ptr<WaveViewDrawRequest>);
227  static void draw_absent_image (Cairo::RefPtr<Cairo::ImageSurface>&, ARDOUR::PeakData*, int);
228 
230 
231  void set_image (std::shared_ptr<WaveViewImage> img) const;
232 
233  // @return true if item area intersects with draw area
235  ArdourCanvas::Rect& item_area,
236  ArdourCanvas::Rect& draw_rect) const;
237 
238  std::shared_ptr<WaveViewDrawRequest> create_draw_request (WaveViewProperties const&) const;
239 
240  void queue_draw_request (std::shared_ptr<WaveViewDrawRequest> const&) const;
241 
242  static void process_draw_request (std::shared_ptr<WaveViewDrawRequest>);
243 
244  std::shared_ptr<WaveViewCacheGroup> get_cache_group () const;
245 
252 };
253 
254 } /* namespace */
255 
256 #endif
WaveView(Item *, std::shared_ptr< ARDOUR::AudioRegion >)
static Shape global_shape()
Definition: wave_view.h:134
static void set_image_cache_size(uint64_t)
static bool global_logscaled()
Definition: wave_view.h:132
void set_amplitude_above_axis(double v)
void set_zero_color(Gtkmm2ext::Color)
ARDOUR::samplecnt_t optimal_image_width_samples() const
static void set_global_gradient_depth(double)
static bool _global_show_waveform_clipping
Definition: wave_view.h:203
static Shape _global_shape
Definition: wave_view.h:202
PBD::ScopedConnectionList invalidation_connection
Definition: wave_view.h:198
bool draw_image_in_gui_thread() const
void compute_bounding_box() const
static PBD::Signal< void()> ClipLevelChanged
Definition: wave_view.h:141
void render(ArdourCanvas::Rect const &area, Cairo::RefPtr< Cairo::Context >) const
static double global_gradient_depth()
Definition: wave_view.h:130
static double _global_clip_level
Definition: wave_view.h:204
static void set_global_logscaled(bool)
void set_outline_color(Gtkmm2ext::Color)
void queue_draw_request(std::shared_ptr< WaveViewDrawRequest > const &) const
static void clear_cache()
std::string debug_name() const
void set_region_start(ARDOUR::sampleoffset_t)
void set_samples_per_pixel(double)
ARDOUR::samplepos_t region_end() const
std::shared_ptr< WaveViewImage > _image
Definition: wave_view.h:156
static void set_clip_level(double dB)
void set_image(std::shared_ptr< WaveViewImage > img) const
static PBD::Signal< void()> VisualPropertiesChanged
Definition: wave_view.h:206
static ArdourCanvas::Coord y_extent(double, Shape const, double const height)
static bool _global_logscaled
Definition: wave_view.h:201
bool get_item_and_draw_rect_in_window_coords(ArdourCanvas::Rect const &canvas_rect, ArdourCanvas::Rect &item_area, ArdourCanvas::Rect &draw_rect) const
static void set_global_shape(Shape)
double amplitude_above_axis() const
void set_fill_color(Gtkmm2ext::Color)
static void stop_drawing_thread()
double gradient_depth() const
ARDOUR::samplecnt_t region_length() const
static void draw_absent_image(Cairo::RefPtr< Cairo::ImageSurface > &, ARDOUR::PeakData *, int)
std::shared_ptr< WaveViewCacheGroup > get_cache_group() const
static void draw_image(Cairo::RefPtr< Cairo::ImageSurface > &, ARDOUR::PeakData *, int n_peaks, std::shared_ptr< WaveViewDrawRequest >)
const std::unique_ptr< WaveViewProperties > _props
Definition: wave_view.h:154
void set_height(ArdourCanvas::Distance)
std::shared_ptr< WaveViewDrawRequest > create_draw_request(WaveViewProperties const &) const
static void set_global_show_waveform_clipping(bool)
static void compute_tips(ARDOUR::PeakData const &peak, LineTips &tips, double const effective_height)
void prepare_for_render(ArdourCanvas::Rect const &window_area) const
static double _global_gradient_depth
Definition: wave_view.h:200
void set_start_shift(double pixels)
bool show_zero_line() const
void set_always_get_image_in_thread(bool yn)
bool needs_prepare_for_render() const
Definition: wave_view.h:79
void set_clip_color(Gtkmm2ext::Color)
void set_gradient_depth(double)
static void start_drawing_thread()
std::shared_ptr< ARDOUR::AudioRegion > _region
Definition: wave_view.h:152
bool _always_draw_image_in_gui_thread
Definition: wave_view.h:192
bool rendered() const
Definition: wave_view.h:179
std::shared_ptr< WaveViewDrawRequest > current_request
Definition: wave_view.h:196
static void process_draw_request(std::shared_ptr< WaveViewDrawRequest >)
std::shared_ptr< WaveViewCacheGroup > _cache_group
Definition: wave_view.h:158
WaveView(ArdourCanvas::Canvas *, std::shared_ptr< ARDOUR::AudioRegion >)
Temporal::samplecnt_t samplecnt_t
Temporal::sampleoffset_t sampleoffset_t
Temporal::samplepos_t samplepos_t
uint32_t Color
Definition: colors.h:33
#define LIBWAVEVIEW_API
gint height
Definition: xcursors.h:1