diff options
author | Robin Gareus <robin@gareus.org> | 2014-01-17 00:20:58 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2014-01-17 00:20:58 +0100 |
commit | b4462b3d22f57f3fe7f4e933b2df0e2c89148e78 (patch) | |
tree | 114d4c04b6206b199c1c627900a2cbfe1d31007d | |
parent | 10933e200369ecceb2c8b3a52be41b930955d269 (diff) |
add seeking to sfdb auditioner
-rw-r--r-- | gtk2_ardour/sfdb_ui.cc | 49 | ||||
-rw-r--r-- | gtk2_ardour/sfdb_ui.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/auditioner.h | 10 | ||||
-rw-r--r-- | libs/ardour/auditioner.cc | 43 | ||||
-rw-r--r-- | libs/ardour/butler.cc | 8 |
5 files changed, 115 insertions, 6 deletions
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 9b3d78e86d..54faae5654 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -120,7 +120,9 @@ SoundFileBox::SoundFileBox (bool persistent) length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false), timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false), main_box (false, 6), - autoplay_btn (_("Auto-play")) + autoplay_btn (_("Auto-play")), + seek_slider(0,1000,1), + _seeking(false) { set_name (X_("SoundFileBox")); @@ -198,9 +200,18 @@ SoundFileBox::SoundFileBox (bool persistent) bottom_box.pack_start(stop_btn, true, true); bottom_box.pack_start(autoplay_btn, false, false); + seek_slider.set_draw_value(false); + + seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); + seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false); + seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false); + main_box.pack_start (seek_slider, false, false); + play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition)); stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition)); + stop_btn.set_sensitive (false); + channels_value.set_alignment (0.0f, 0.5f); samplerate_value.set_alignment (0.0f, 0.5f); } @@ -216,10 +227,46 @@ SoundFileBox::set_session(Session* s) if (!_session) { play_btn.set_sensitive (false); stop_btn.set_sensitive (false); + auditioner_connections.drop_connections(); + } else { + auditioner_connections.drop_connections(); + _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context()); + _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context()); + } +} + +void +SoundFileBox::audition_active(bool active) { + stop_btn.set_sensitive (active); + seek_slider.set_sensitive (active); + if (!active) { + seek_slider.set_value(0); + } +} + +void +SoundFileBox::audition_progress(ARDOUR::framecnt_t pos, ARDOUR::framecnt_t len) { + if (!_seeking) { + seek_slider.set_value( 1000.0 * pos / len); + seek_slider.set_sensitive (true); } } bool +SoundFileBox::seek_button_press(GdkEventButton*) { + _seeking = true; + return false; // pass on to slider +} + +bool +SoundFileBox::seek_button_release(GdkEventButton*) { + _seeking = false; + _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0); + seek_slider.set_sensitive (false); + return false; // pass on to slider +} + +bool SoundFileBox::setup_labels (const string& filename) { if (!path.empty()) { diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h index 5d8decddf4..ccfd3799be 100644 --- a/gtk2_ardour/sfdb_ui.h +++ b/gtk2_ardour/sfdb_ui.h @@ -36,6 +36,7 @@ #include <gtkmm/filechooserwidget.h> #include <gtkmm/frame.h> #include <gtkmm/label.h> +#include <gtkmm/scale.h> #include <gtkmm/textview.h> #include <gtkmm/table.h> #include <gtkmm/liststore.h> @@ -57,7 +58,7 @@ namespace ARDOUR { class GainMeter; class Mootcher; -class SoundFileBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr +class SoundFileBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr, public PBD::ScopedConnectionList { public: SoundFileBox (bool persistent); @@ -103,11 +104,19 @@ class SoundFileBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr Gtk::Button stop_btn; Gtk::CheckButton autoplay_btn; Gtk::Button apply_btn; + Gtk::HScale seek_slider; + + PBD::ScopedConnectionList auditioner_connections; + void audition_active(bool); + void audition_progress(ARDOUR::framecnt_t, ARDOUR::framecnt_t); bool tags_entry_left (GdkEventFocus* event); void tags_changed (); void save_tags (const std::vector<std::string>&); void stop_audition (); + bool seek_button_press(GdkEventButton*); + bool seek_button_release(GdkEventButton*); + bool _seeking; }; class SoundFileBrowser : public ArdourWindow diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h index 5ce3ddaddf..7e772fe194 100644 --- a/libs/ardour/ardour/auditioner.h +++ b/libs/ardour/ardour/auditioner.h @@ -44,6 +44,9 @@ class Auditioner : public AudioTrack void audition_region (boost::shared_ptr<Region>); + void seek_to_frame (frameoffset_t pos) { if (_seek_frame < 0 && !_seeking) { _seek_frame = pos; }} + void seek_to_percent (float const pos) { if (_seek_frame < 0 && !_seeking) { _seek_frame = floorf(length * pos / 100.0); }} + ARDOUR::AudioPlaylist& prepare_playlist (); int play_audition (framecnt_t nframes); @@ -59,12 +62,19 @@ class Auditioner : public AudioTrack virtual ChanCount input_streams () const; + frameoffset_t seek_frame() const { return _seeking ? _seek_frame : -1;} + void seek_response(frameoffset_t pos) { _seek_complete = true; if (_seeking) { current_frame = pos; _seek_complete = true;} } + PBD::Signal2<void, ARDOUR::framecnt_t, ARDOUR::framecnt_t> AuditionProgress; + private: boost::shared_ptr<AudioRegion> the_region; framepos_t current_frame; mutable gint _auditioning; Glib::Threads::Mutex lock; framecnt_t length; + frameoffset_t _seek_frame; + bool _seeking; + bool _seek_complete; bool via_monitor; void drop_ports (); diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc index 73670798d8..75a40f142d 100644 --- a/libs/ardour/auditioner.cc +++ b/libs/ardour/auditioner.cc @@ -44,6 +44,9 @@ Auditioner::Auditioner (Session& s) , current_frame (0) , _auditioning (0) , length (0) + , _seek_frame (-1) + , _seeking (false) + , _seek_complete (false) , via_monitor (false) { } @@ -203,6 +206,8 @@ Auditioner::audition_region (boost::shared_ptr<Region> region) _main_outs->reset_panner(); + _seek_frame = -1; + _seeking = false; length = the_region->length(); int dir; @@ -232,14 +237,44 @@ Auditioner::play_audition (framecnt_t nframes) return 0; } - this_nframes = min (nframes, length - current_frame); +#if 0 // TODO + if (_seeking && _seek_complete) { + // set FADE-IN + } else if (_seek_frame >= 0 && _seek_frame < length && !_seeking) { + // set FADE-OUT -- use/override amp? || use region-gain ? + } +#endif + + if (_seeking && _seek_complete) { + _seek_complete = false; + _seeking = false; + _seek_frame = -1; + } + + if(!_seeking) { + /* process audio */ + this_nframes = min (nframes, length - current_frame); + + if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, need_butler)) != 0) { + silence (nframes); + return ret; + } - if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, need_butler)) != 0) { + current_frame += this_nframes; + + } else { silence (nframes); - return ret; } - current_frame += this_nframes; + if (_seek_frame >= 0 && _seek_frame < length && !_seeking) { + _seek_complete = false; + _seeking = true; + need_butler = true; + } + + if (!_seeking) { + AuditionProgress(current_frame, length); /* emit */ + } if (current_frame >= length) { _session.cancel_audition (); diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc index 89b2cc1303..e37734f261 100644 --- a/libs/ardour/butler.cc +++ b/libs/ardour/butler.cc @@ -212,6 +212,14 @@ restart: _session.butler_transport_work (); } + frameoffset_t audition_seek; + if (should_run && _session.is_auditioning() + && (audition_seek = _session.the_auditioner()->seek_frame()) > 0) { + boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (_session.the_auditioner()); + tr->seek(audition_seek); + _session.the_auditioner()->seek_response(audition_seek); + } + boost::shared_ptr<RouteList> rl = _session.get_routes(); RouteList rl_with_auditioner = *rl; |