SpectMorph
|
00001 /* 00002 * Copyright (C) 2011 Stefan Westerfeld 00003 * 00004 * This library is free software; you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License as published by the 00006 * Free Software Foundation; either version 3 of the License, or (at your 00007 * option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 00012 * for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef SPECTMORPH_SAMPLE_VIEW_HH 00019 #define SPECTMORPH_SAMPLE_VIEW_HH 00020 00021 #include <gtkmm.h> 00022 00023 #include "smaudio.hh" 00024 #include <bse/bseblockutils.hh> 00025 00026 namespace SpectMorph { 00027 00028 class SampleView : public Gtk::DrawingArea 00029 { 00030 public: 00031 enum EditMarkerType { 00032 MARKER_NONE, 00033 MARKER_START, 00034 MARKER_LOOP_START, 00035 MARKER_LOOP_END, 00036 MARKER_CLIP_START, 00037 MARKER_CLIP_END 00038 }; 00039 class Markers { 00040 public: 00041 virtual size_t count() = 0; 00042 virtual EditMarkerType type (size_t marker) = 0; 00043 virtual float position (size_t marker) = 0; 00044 virtual bool valid (size_t marker) = 0; 00045 virtual void set_position (size_t marker, float new_position) = 0; 00046 virtual void clear (size_t marker) = 0; 00047 }; 00048 00049 private: 00050 Audio *audio; 00051 Markers *markers; 00052 std::vector<float> signal; 00053 double hzoom; 00054 double vzoom; 00055 double attack_start; 00056 double attack_end; 00057 EditMarkerType m_edit_marker_type; 00058 bool button_1_pressed; 00059 00060 int old_width; 00061 void force_redraw(); 00062 void move_marker (int x); 00063 public: 00064 SampleView(); 00065 00066 sigc::signal<void, int, int> signal_resized; 00067 sigc::signal<void> signal_audio_edit; 00068 sigc::signal<void, int> signal_mouse_time_changed; 00069 00070 void load (GslDataHandle *dhandle, SpectMorph::Audio *audio, Markers *markers = 0); 00071 00072 bool on_expose_event (GdkEventExpose *ev); 00073 bool on_button_press_event (GdkEventButton *event); 00074 bool on_motion_notify_event (GdkEventMotion *event); 00075 bool on_button_release_event (GdkEventButton *event); 00076 00077 void set_zoom (double hzoom, double vzoom); 00078 00079 void set_edit_marker_type (EditMarkerType marker_type); 00080 EditMarkerType edit_marker_type(); 00081 00082 template<class DrawOps> static void 00083 draw_signal (std::vector<float>& signal, DrawOps ops, GdkEventExpose *ev, int height, double vz, double hz) 00084 { 00085 int x = ev->area.x; 00086 int last_i0 = -1; 00087 int last_x = 0; 00088 double last_value = 0; 00089 while (x < ev->area.x + ev->area.width) 00090 { 00091 int i0 = x / hz; 00092 int i1 = (x + 1) / hz + 1; 00093 00094 if (last_i0 != i0) 00095 { 00096 if (i0 < int (signal.size()) && i0 >= 0 && i1 < int (signal.size() + 1) && i1 > 0) 00097 { 00098 ops->move_to (last_x, (height / 2) + last_value * vz); 00099 ops->line_to (x, (height / 2) + signal[i0] * vz); 00100 00101 float min_value, max_value; 00102 Bse::Block::range (i1 - i0, &signal[i0], min_value, max_value); 00103 00104 ops->move_to (x, (height / 2) + min_value * vz); 00105 ops->line_to (x, (height / 2) + max_value * vz); 00106 00107 last_x = x; 00108 last_value = signal[i1 - 1]; 00109 } 00110 last_i0 = i0; 00111 } 00112 x++; 00113 } 00114 } 00115 }; 00116 00117 } 00118 00119 #endif