mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-16 19:56:31 +01:00
add seeking to sfdb auditioner
This commit is contained in:
parent
10933e2003
commit
b4462b3d22
5 changed files with 116 additions and 7 deletions
|
|
@ -120,7 +120,9 @@ SoundFileBox::SoundFileBox (bool persistent)
|
||||||
length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
|
length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false),
|
||||||
timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
|
timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false),
|
||||||
main_box (false, 6),
|
main_box (false, 6),
|
||||||
autoplay_btn (_("Auto-play"))
|
autoplay_btn (_("Auto-play")),
|
||||||
|
seek_slider(0,1000,1),
|
||||||
|
_seeking(false)
|
||||||
|
|
||||||
{
|
{
|
||||||
set_name (X_("SoundFileBox"));
|
set_name (X_("SoundFileBox"));
|
||||||
|
|
@ -198,9 +200,18 @@ SoundFileBox::SoundFileBox (bool persistent)
|
||||||
bottom_box.pack_start(stop_btn, true, true);
|
bottom_box.pack_start(stop_btn, true, true);
|
||||||
bottom_box.pack_start(autoplay_btn, false, false);
|
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));
|
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.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
|
||||||
|
|
||||||
|
stop_btn.set_sensitive (false);
|
||||||
|
|
||||||
channels_value.set_alignment (0.0f, 0.5f);
|
channels_value.set_alignment (0.0f, 0.5f);
|
||||||
samplerate_value.set_alignment (0.0f, 0.5f);
|
samplerate_value.set_alignment (0.0f, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
@ -216,9 +227,45 @@ SoundFileBox::set_session(Session* s)
|
||||||
if (!_session) {
|
if (!_session) {
|
||||||
play_btn.set_sensitive (false);
|
play_btn.set_sensitive (false);
|
||||||
stop_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
|
bool
|
||||||
SoundFileBox::setup_labels (const string& filename)
|
SoundFileBox::setup_labels (const string& filename)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include <gtkmm/filechooserwidget.h>
|
#include <gtkmm/filechooserwidget.h>
|
||||||
#include <gtkmm/frame.h>
|
#include <gtkmm/frame.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
|
#include <gtkmm/scale.h>
|
||||||
#include <gtkmm/textview.h>
|
#include <gtkmm/textview.h>
|
||||||
#include <gtkmm/table.h>
|
#include <gtkmm/table.h>
|
||||||
#include <gtkmm/liststore.h>
|
#include <gtkmm/liststore.h>
|
||||||
|
|
@ -57,7 +58,7 @@ namespace ARDOUR {
|
||||||
class GainMeter;
|
class GainMeter;
|
||||||
class Mootcher;
|
class Mootcher;
|
||||||
|
|
||||||
class SoundFileBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr
|
class SoundFileBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr, public PBD::ScopedConnectionList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SoundFileBox (bool persistent);
|
SoundFileBox (bool persistent);
|
||||||
|
|
@ -103,11 +104,19 @@ class SoundFileBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr
|
||||||
Gtk::Button stop_btn;
|
Gtk::Button stop_btn;
|
||||||
Gtk::CheckButton autoplay_btn;
|
Gtk::CheckButton autoplay_btn;
|
||||||
Gtk::Button apply_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);
|
bool tags_entry_left (GdkEventFocus* event);
|
||||||
void tags_changed ();
|
void tags_changed ();
|
||||||
void save_tags (const std::vector<std::string>&);
|
void save_tags (const std::vector<std::string>&);
|
||||||
void stop_audition ();
|
void stop_audition ();
|
||||||
|
bool seek_button_press(GdkEventButton*);
|
||||||
|
bool seek_button_release(GdkEventButton*);
|
||||||
|
bool _seeking;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SoundFileBrowser : public ArdourWindow
|
class SoundFileBrowser : public ArdourWindow
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,9 @@ class Auditioner : public AudioTrack
|
||||||
|
|
||||||
void audition_region (boost::shared_ptr<Region>);
|
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 ();
|
ARDOUR::AudioPlaylist& prepare_playlist ();
|
||||||
|
|
||||||
int play_audition (framecnt_t nframes);
|
int play_audition (framecnt_t nframes);
|
||||||
|
|
@ -59,12 +62,19 @@ class Auditioner : public AudioTrack
|
||||||
|
|
||||||
virtual ChanCount input_streams () const;
|
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:
|
private:
|
||||||
boost::shared_ptr<AudioRegion> the_region;
|
boost::shared_ptr<AudioRegion> the_region;
|
||||||
framepos_t current_frame;
|
framepos_t current_frame;
|
||||||
mutable gint _auditioning;
|
mutable gint _auditioning;
|
||||||
Glib::Threads::Mutex lock;
|
Glib::Threads::Mutex lock;
|
||||||
framecnt_t length;
|
framecnt_t length;
|
||||||
|
frameoffset_t _seek_frame;
|
||||||
|
bool _seeking;
|
||||||
|
bool _seek_complete;
|
||||||
bool via_monitor;
|
bool via_monitor;
|
||||||
|
|
||||||
void drop_ports ();
|
void drop_ports ();
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,9 @@ Auditioner::Auditioner (Session& s)
|
||||||
, current_frame (0)
|
, current_frame (0)
|
||||||
, _auditioning (0)
|
, _auditioning (0)
|
||||||
, length (0)
|
, length (0)
|
||||||
|
, _seek_frame (-1)
|
||||||
|
, _seeking (false)
|
||||||
|
, _seek_complete (false)
|
||||||
, via_monitor (false)
|
, via_monitor (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -203,6 +206,8 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
|
||||||
|
|
||||||
_main_outs->reset_panner();
|
_main_outs->reset_panner();
|
||||||
|
|
||||||
|
_seek_frame = -1;
|
||||||
|
_seeking = false;
|
||||||
length = the_region->length();
|
length = the_region->length();
|
||||||
|
|
||||||
int dir;
|
int dir;
|
||||||
|
|
@ -232,6 +237,22 @@ Auditioner::play_audition (framecnt_t nframes)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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);
|
this_nframes = min (nframes, length - current_frame);
|
||||||
|
|
||||||
if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, need_butler)) != 0) {
|
if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, need_butler)) != 0) {
|
||||||
|
|
@ -241,6 +262,20 @@ Auditioner::play_audition (framecnt_t nframes)
|
||||||
|
|
||||||
current_frame += this_nframes;
|
current_frame += this_nframes;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
silence (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) {
|
if (current_frame >= length) {
|
||||||
_session.cancel_audition ();
|
_session.cancel_audition ();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,14 @@ restart:
|
||||||
_session.butler_transport_work ();
|
_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();
|
boost::shared_ptr<RouteList> rl = _session.get_routes();
|
||||||
|
|
||||||
RouteList rl_with_auditioner = *rl;
|
RouteList rl_with_auditioner = *rl;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue