1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #ifndef SPECTMORPH_SAMPLE_EDIT_HH
4 #define SPECTMORPH_SAMPLE_EDIT_HH
5 
6 #include "smsimplejackplayer.hh"
7 #include "smsampleview.hh"
8 #include "smzoomcontroller.hh"
9 
10 #include <QWidget>
11 #include <QApplication>
12 #include <QComboBox>
13 #include <QVBoxLayout>
14 #include <QLabel>
15 #include <QPushButton>
16 #include <QScrollArea>
17 #include <QMainWindow>
18 
19 #include <memory>
20 
21 namespace SpectMorph
22 {
23 
24 class SampleEditMarkers : public SampleView::Markers
25 {
26 public:
27   std::vector<float> positions;
28   std::vector<bool>  m_valid;
29 
30   SampleEditMarkers() :
31     positions (2),
32     m_valid (positions.size())
33   {
34   }
35   size_t
36   count()
37   {
38     return positions.size();
39   }
40   bool
41   valid (size_t m)
42   {
43     return m_valid[m];
44   }
45   float
46   position (size_t m)
47   {
48     g_return_val_if_fail (m >= 0 && m < positions.size(), 0.0);
49 
50     return positions[m];
51   }
52   void
53   set_position (size_t m, float new_pos)
54   {
55     g_return_if_fail (m >= 0 && m < positions.size());
56 
57     positions[m] = new_pos;
58     m_valid[m] = true;
59   }
60   SampleView::EditMarkerType
61   type (size_t m)
62   {
63     if (m == 0)
64       return SampleView::MARKER_CLIP_START;
65     else if (m == 1)
66       return SampleView::MARKER_CLIP_END;
67     else
68       return SampleView::MARKER_NONE;
69   }
70   void
71   clear (size_t m)
72   {
73     g_return_if_fail (m >= 0 && m < positions.size());
74 
75     m_valid[m] = false;
76   }
77   float
78   clip_start (bool& v)
79   {
80     v = m_valid[0];
81     return positions[0];
82   }
83   float
84   clip_end (bool& v)
85   {
86     v = m_valid[1];
87     return positions[1];
88   }
89   void
90   set_clip_start (float pos)
91   {
92     m_valid[0] = true;
93     positions[0] = pos;
94   }
95   void
96   set_clip_end (float pos)
97   {
98     m_valid[1] = true;
99     positions[1] = pos;
100   }
101 };
102 
103 struct Wave
104 {
105   std::string         path;
106   std::string         label;
107   int                 midi_note;
108 
109   SampleEditMarkers   markers;
110 };
111 
112 class MainWidget : public QWidget
113 {
114   Q_OBJECT
115 
116   Audio               audio;
117   Wave               *current_wave;
118 
119   SimpleJackPlayer   *jack_player;
120 
121   SampleView         *sample_view;
122   QScrollArea        *scroll_area;
123   ZoomController     *zoom_controller;
124   QLabel             *time_label;
125   QComboBox          *sample_combobox;
126   QSlider            *volume_slider;
127   QLabel             *volume_label;
128   QPushButton        *edit_clip_start;
129   QPushButton        *edit_clip_end;
130   std::string         marker_filename;
131   std::vector<Wave>   waves;
132 
133   std::unique_ptr<WavData> samples;
134 
135   static std::vector<float> get_clipped_samples (Wave *wave, WavData *samples);
136 public:
137   MainWidget (bool use_jack);
138   ~MainWidget();
139 
140   void load (const std::string& filename, const std::string& clip_markers);
141   void clip (const std::string& export_pattern);
142 
143 public slots:
144   void on_volume_changed (int new_volume);
145   void on_combo_changed();
146   void on_zoom_changed();
147   void on_edit_marker_changed();
148   void on_mouse_time_changed (int time);
149   void on_next_sample();
150 
151   void on_play_clicked();
152   void on_save_clicked();
153 };
154 
155 class MainWindow : public QMainWindow
156 {
157   Q_OBJECT
158 
159   MainWidget *main_widget;
160 
161 public:
162   MainWindow (bool use_jack);
163 
164   void load (const std::string& filename, const std::string& clip_markers);
165   void clip (const std::string& export_pattern);
166 };
167 
168 
169 }
170 
171 #endif
172