Ardour  8.7-15-gadf511264b
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 <boost/scoped_ptr.hpp>
27 
28 #include <glibmm/refptr.h>
29 
30 #include "ardour/types.h"
31 #include "canvas/item.h"
32 #include "waveview/visibility.h"
33 
34 namespace ARDOUR {
35  class AudioRegion;
36 }
37 
38 namespace Gdk {
39  class Pixbuf;
40 }
41 
42 namespace ArdourWaveView {
43 
44 class WaveViewCacheGroup;
45 class WaveViewDrawRequest;
46 class WaveViewDrawRequestQueue;
47 class WaveViewImage;
48 class WaveViewProperties;
49 class WaveViewDrawingThread;
50 
51 class LIBWAVEVIEW_API WaveView : public ArdourCanvas::Item, public sigc::trackable
52 {
53 public:
54  enum Shape { Normal, Rectified };
55 
56  std::string debug_name () const;
57 
58  /* Displays a single channel of waveform data for the given Region.
59 
60  x = 0 in the waveview corresponds to the first waveform datum taken
61  from region->start() samples into the source data.
62 
63  x = N in the waveview corresponds to the (N * spp)'th sample
64  measured from region->start() into the source data.
65 
66  when drawing, we will map the zeroth-pixel of the waveview
67  into a window.
68 
69  The waveview itself contains a set of pre-rendered Cairo::ImageSurfaces
70  that cache sections of the display. This is filled on-demand and
71  never cleared until something explicitly marks the cache invalid
72  (such as a change in samples_per_pixel, the log scaling, rectified or
73  other view parameters).
74  */
75 
76  WaveView (ArdourCanvas::Canvas*, std::shared_ptr<ARDOUR::AudioRegion>);
77  WaveView (Item*, std::shared_ptr<ARDOUR::AudioRegion>);
79 
80  virtual void prepare_for_render (ArdourCanvas::Rect const& window_area) const;
81 
82  virtual void render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context>) const;
83 
84  void compute_bounding_box () const;
85 
86  void set_samples_per_pixel (double);
88  void set_channel (int);
90 
98  void set_start_shift (double pixels);
99 
102 
103  void region_resized ();
104  void gain_changed ();
105 
106  void set_show_zero_line (bool);
107  bool show_zero_line () const;
108 
111  void set_logscaled (bool);
112 
113  void set_gradient_depth (double);
114  double gradient_depth () const;
115 
116  void set_shape (Shape);
117 
119 
120  /* currently missing because we don't need them (yet):
121  * set_shape_independent();
122  * set_logscaled_independent();
123  */
124 
125  static void set_global_gradient_depth (double);
126  static void set_global_logscaled (bool);
127  static void set_global_shape (Shape);
129  static void clear_cache ();
130 
131  static double global_gradient_depth () { return _global_gradient_depth; }
132 
133  static bool global_logscaled () { return _global_logscaled; }
134 
135  static Shape global_shape () { return _global_shape; }
136 
137  void set_amplitude_above_axis (double v);
138 
139  double amplitude_above_axis () const;
140 
141  static void set_clip_level (double dB);
142  static PBD::Signal0<void> ClipLevelChanged;
143 
144  static void start_drawing_thread ();
145  static void stop_drawing_thread ();
146 
147  static void set_image_cache_size (uint64_t);
148 
149 private:
150  friend class WaveViewThreadClient;
151  friend class WaveViewThreads;
152 
153  std::shared_ptr<ARDOUR::AudioRegion> _region;
154 
155  boost::scoped_ptr<WaveViewProperties> _props;
156 
157  mutable std::shared_ptr<WaveViewImage> _image;
158 
159  mutable std::shared_ptr<WaveViewCacheGroup> _cache_group;
160 
164 
170 
176 
180  bool rendered () const { return _image.get(); }
181 
183 
188 
194 
195  void init();
196 
197  mutable std::shared_ptr<WaveViewDrawRequest> current_request;
198 
200 
201  static double _global_gradient_depth;
202  static bool _global_logscaled;
205  static double _global_clip_level;
206 
207  static PBD::Signal0<void> VisualPropertiesChanged;
208 
211 
212  struct LineTips {
213  double top;
214  double bot;
215  double spread;
216  bool clip_max;
217  bool clip_min;
218 
219  LineTips () : top (0.0), bot (0.0), clip_max (false), clip_min (false) {}
220  };
221 
222  static ArdourCanvas::Coord y_extent (double, Shape const, double const height);
223 
224  static void compute_tips (ARDOUR::PeakData const& peak, LineTips& tips, double const effective_height);
225 
226  static void draw_image (Cairo::RefPtr<Cairo::ImageSurface>&, ARDOUR::PeakData*, int n_peaks,
227  std::shared_ptr<WaveViewDrawRequest>);
228  static void draw_absent_image (Cairo::RefPtr<Cairo::ImageSurface>&, ARDOUR::PeakData*, int);
229 
231 
232  void set_image (std::shared_ptr<WaveViewImage> img) const;
233 
234  // @return true if item area intersects with draw area
236  ArdourCanvas::Rect& item_area,
237  ArdourCanvas::Rect& draw_rect) const;
238 
239  std::shared_ptr<WaveViewDrawRequest> create_draw_request (WaveViewProperties const&) const;
240 
241  void queue_draw_request (std::shared_ptr<WaveViewDrawRequest> const&) const;
242 
243  static void process_draw_request (std::shared_ptr<WaveViewDrawRequest>);
244 
245  std::shared_ptr<WaveViewCacheGroup> get_cache_group () const;
246 
253 };
254 
255 } /* namespace */
256 
257 #endif
WaveView(Item *, std::shared_ptr< ARDOUR::AudioRegion >)
static Shape global_shape()
Definition: wave_view.h:135
static void set_image_cache_size(uint64_t)
static bool global_logscaled()
Definition: wave_view.h:133
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:204
static Shape _global_shape
Definition: wave_view.h:203
PBD::ScopedConnectionList invalidation_connection
Definition: wave_view.h:199
bool draw_image_in_gui_thread() const
void compute_bounding_box() const
static double global_gradient_depth()
Definition: wave_view.h:131
static double _global_clip_level
Definition: wave_view.h:205
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)
static PBD::Signal0< void > VisualPropertiesChanged
Definition: wave_view.h:207
ARDOUR::samplepos_t region_end() const
std::shared_ptr< WaveViewImage > _image
Definition: wave_view.h:157
static void set_clip_level(double dB)
void set_image(std::shared_ptr< WaveViewImage > img) const
static ArdourCanvas::Coord y_extent(double, Shape const, double const height)
static bool _global_logscaled
Definition: wave_view.h:202
static PBD::Signal0< void > ClipLevelChanged
Definition: wave_view.h:142
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 >)
void set_height(ArdourCanvas::Distance)
std::shared_ptr< WaveViewDrawRequest > create_draw_request(WaveViewProperties const &) const
virtual void prepare_for_render(ArdourCanvas::Rect const &window_area) const
static void set_global_show_waveform_clipping(bool)
static void compute_tips(ARDOUR::PeakData const &peak, LineTips &tips, double const effective_height)
static double _global_gradient_depth
Definition: wave_view.h:201
void set_start_shift(double pixels)
bool show_zero_line() const
void set_always_get_image_in_thread(bool yn)
boost::scoped_ptr< WaveViewProperties > _props
Definition: wave_view.h:155
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:153
bool _always_draw_image_in_gui_thread
Definition: wave_view.h:193
bool rendered() const
Definition: wave_view.h:180
virtual void render(ArdourCanvas::Rect const &area, Cairo::RefPtr< Cairo::Context >) const
std::shared_ptr< WaveViewDrawRequest > current_request
Definition: wave_view.h:197
static void process_draw_request(std::shared_ptr< WaveViewDrawRequest >)
std::shared_ptr< WaveViewCacheGroup > _cache_group
Definition: wave_view.h:159
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