summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2014-01-17 00:20:58 +0100
committerRobin Gareus <robin@gareus.org>2014-01-17 00:20:58 +0100
commitb4462b3d22f57f3fe7f4e933b2df0e2c89148e78 (patch)
tree114d4c04b6206b199c1c627900a2cbfe1d31007d
parent10933e200369ecceb2c8b3a52be41b930955d269 (diff)
add seeking to sfdb auditioner
-rw-r--r--gtk2_ardour/sfdb_ui.cc49
-rw-r--r--gtk2_ardour/sfdb_ui.h11
-rw-r--r--libs/ardour/ardour/auditioner.h10
-rw-r--r--libs/ardour/auditioner.cc43
-rw-r--r--libs/ardour/butler.cc8
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;