1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #ifndef SPECTMORPH_SAMPLE_VIEW_HH
4 #define SPECTMORPH_SAMPLE_VIEW_HH
5 
6 #include "smaudio.hh"
7 #include "smwavdata.hh"
8 #include "smblockutils.hh"
9 
10 #include <QWidget>
11 
12 namespace SpectMorph {
13 
14 class SampleView : public QWidget
15 {
16   Q_OBJECT
17 
18 public:
19   enum EditMarkerType {
20     MARKER_NONE,
21     MARKER_LOOP_START,
22     MARKER_LOOP_END,
23     MARKER_CLIP_START,
24     MARKER_CLIP_END
25   };
26   class Markers {
27   public:
28     virtual size_t          count() = 0;
29     virtual EditMarkerType  type (size_t marker) = 0;
30     virtual float           position (size_t marker) = 0;
31     virtual bool            valid (size_t marker) = 0;
32     virtual void            set_position (size_t marker, float new_position) = 0;
33     virtual void            clear (size_t marker) = 0;
34   };
35 
36 private:
37   std::vector<float> signal;
38   Audio             *audio;
39   Markers           *markers;
40   double             attack_start;
41   double             attack_end;
42   double             hzoom;
43   double             vzoom;
44   EditMarkerType     m_edit_marker_type;
45   bool               button_1_pressed;
46   bool               m_show_tuning = false;
47 
48   void               update_size();
49   void               mousePressEvent (QMouseEvent *event);
50   void               move_marker (int x);
51   void               mouseMoveEvent (QMouseEvent *event);
52   void               mouseReleaseEvent (QMouseEvent *event);
53 
54 public:
55   SampleView();
56   void load (const WavData *wav_data, SpectMorph::Audio *audio, Markers *markers = 0);
57   void set_zoom (double hzoom, double vzoom);
58   void paintEvent (QPaintEvent *event);
59 
60   void set_edit_marker_type (EditMarkerType marker_type);
61   EditMarkerType edit_marker_type();
62 
63   void set_show_tuning (bool show_tuning);
64 
65   template<class Painter> static void
draw_signal(std::vector<float> & signal,Painter & painter,const QRect & rect,int height,double vz,double hz)66   draw_signal (std::vector<float>& signal, Painter& painter, const QRect& rect, int height, double vz, double hz)
67   {
68     int last_i0 = -1;
69     int last_x = 0;
70     double last_value = 0;
71 
72     for (int x = rect.x(); x < rect.x() + rect.width(); x++)
73       {
74         int i0 = x / hz;
75         int i1 = (x + 1) / hz + 1;
76 
77         if (last_i0 != i0)
78           {
79             if (i0 < int (signal.size()) && i0 >= 0 && i1 < int (signal.size() + 1) && i1 > 0)
80               {
81                 painter.drawLine (last_x, (height / 2) + last_value * vz, x, (height / 2) + signal[i0] * vz);
82 
83                 float min_value, max_value;
84                 Block::range (i1 - i0, &signal[i0], min_value, max_value);
85 
86                 painter.drawLine (x, (height / 2) + min_value * vz, x, (height / 2) + max_value * vz);
87 
88                 last_x = x;
89                 last_value = signal[i1 - 1];
90               }
91             last_i0 = i0;
92           }
93       }
94   }
95 signals:
96   void audio_edit();
97   void mouse_time_changed (int pos);
98 };
99 
100 }
101 
102 #endif
103