audio clip editor: restore ruler removed during merge conflict resolution; incrementally improve its behavior
This commit is contained in:
parent
9d4a1f080d
commit
f5049cda74
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "waveview/wave_view.h"
|
#include "waveview/wave_view.h"
|
||||||
|
|
||||||
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/audioregion.h"
|
#include "ardour/audioregion.h"
|
||||||
#include "ardour/location.h"
|
#include "ardour/location.h"
|
||||||
#include "ardour/profile.h"
|
#include "ardour/profile.h"
|
||||||
@ -82,29 +83,41 @@ ClipEditorBox::register_clip_editor_actions (Bindings* clip_editor_bindings)
|
|||||||
// ActionManager::register_action (clip_editor_actions, X_("zoom-in"), _("Zoom In"), sigc::mem_fun (*this, &ClipEditorBox::zoom_out));
|
// ActionManager::register_action (clip_editor_actions, X_("zoom-in"), _("Zoom In"), sigc::mem_fun (*this, &ClipEditorBox::zoom_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClipBBTMetric : public ArdourCanvas::Ruler::Metric
|
void
|
||||||
|
AudioClipEditor::ClipBBTMetric::get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const
|
||||||
{
|
{
|
||||||
public:
|
if (!trigger) {
|
||||||
ClipBBTMetric ()
|
std::cerr << "No trigger\n";
|
||||||
{
|
return;
|
||||||
units_per_pixel = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const
|
ArdourCanvas::Ruler::Mark mark;
|
||||||
{
|
|
||||||
ArdourCanvas::Ruler::Mark mark;
|
|
||||||
|
|
||||||
std::cerr << "get marks between " << lower << " .. " << upper << std::endl;
|
|
||||||
|
|
||||||
for (int64_t n = lower; n < upper; n += 4000) {
|
Temporal::Tempo tempo (trigger->apparent_tempo(), 4); /* XXX don't assume 4 */
|
||||||
|
|
||||||
|
std::cerr << "get marks between " << lower << " .. " << upper << " with tempo " << tempo << " upp = " << units_per_pixel << std::endl;
|
||||||
|
|
||||||
|
samplecnt_t samples_per_beat = tempo.samples_per_note_type (AudioEngine::instance()->sample_rate());
|
||||||
|
int64_t beat_number = (lower + (samples_per_beat/2)) / samples_per_beat;
|
||||||
|
int64_t last = INT64_MIN;
|
||||||
|
const double scale = UIConfiguration::instance ().get_ui_scale ();
|
||||||
|
|
||||||
|
for (int64_t n = beat_number * samples_per_beat; n < upper; n += samples_per_beat) {
|
||||||
|
/* ensure at least a 15 pixel (scaled) gap between marks */
|
||||||
|
if (marks.empty() || (((n - last) / units_per_pixel) > (15. * scale))) {
|
||||||
mark.style = ArdourCanvas::Ruler::Mark::Major;
|
mark.style = ArdourCanvas::Ruler::Mark::Major;
|
||||||
mark.label = string_compose ("%1", n);
|
mark.label = string_compose ("%1", beat_number);
|
||||||
mark.position = n / 100;
|
mark.position = n;
|
||||||
marks.push_back (mark);
|
marks.push_back (mark);
|
||||||
|
beat_number++;
|
||||||
|
last = n;
|
||||||
std::cerr << "mark at " << mark.label << " @ " << mark.position << std::endl;
|
std::cerr << "mark at " << mark.label << " @ " << mark.position << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cerr << n << " - " << last << " = " << (n - last) << " pix " << (n - last) / units_per_pixel << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
AudioClipEditor::AudioClipEditor ()
|
AudioClipEditor::AudioClipEditor ()
|
||||||
: _spp (0)
|
: _spp (0)
|
||||||
@ -119,21 +132,33 @@ AudioClipEditor::AudioClipEditor ()
|
|||||||
frame->set_fill (false);
|
frame->set_fill (false);
|
||||||
frame->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::event_handler));
|
frame->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::event_handler));
|
||||||
|
|
||||||
|
/* Scroll bar does not scroll and it outside the frame */
|
||||||
|
|
||||||
scroll_bar_trough = new Rectangle (root ());
|
scroll_bar_trough = new Rectangle (root ());
|
||||||
scroll_bar_handle = new Rectangle (scroll_bar_trough);
|
scroll_bar_handle = new Rectangle (scroll_bar_trough);
|
||||||
scroll_bar_handle->set_outline (false);
|
scroll_bar_handle->set_outline (false);
|
||||||
scroll_bar_handle->set_corner_radius (5.);
|
scroll_bar_handle->set_corner_radius (5.);
|
||||||
scroll_bar_handle->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::scroll_event_handler));
|
scroll_bar_handle->Event.connect (sigc::mem_fun (*this, &AudioClipEditor::scroll_event_handler));
|
||||||
|
|
||||||
|
/* A scrolling container for our waves and lines etc. */
|
||||||
|
|
||||||
waves_container = new ArdourCanvas::ScrollGroup (frame, ScrollGroup::ScrollsHorizontally);
|
waves_container = new ArdourCanvas::ScrollGroup (frame, ScrollGroup::ScrollsHorizontally);
|
||||||
add_scroller (*waves_container);
|
add_scroller (*waves_container);
|
||||||
|
|
||||||
|
/* A ruler, that scrolls with the waves and is overlapped by our
|
||||||
|
* various vertical lines
|
||||||
|
*/
|
||||||
|
|
||||||
clip_metric = new ClipBBTMetric ();
|
clip_metric = new ClipBBTMetric ();
|
||||||
|
|
||||||
ruler_container = new ArdourCanvas::Container (waves_container);
|
ruler_container = new ArdourCanvas::Container (waves_container);
|
||||||
ruler = new ArdourCanvas::Ruler (ruler_container, *clip_metric);
|
ruler = new ArdourCanvas::Ruler (ruler_container, *clip_metric);
|
||||||
ruler->name = "Clip Editor";
|
ruler->name = "Clip Editor";
|
||||||
ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
|
ruler->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
|
||||||
|
ruler->set_fill_color (UIConfiguration::instance().color (X_("theme:bg1")));
|
||||||
|
ruler->set_outline_color (UIConfiguration::instance().color (X_("theme:contrasting less")));
|
||||||
|
|
||||||
|
/* the lines */
|
||||||
|
|
||||||
line_container = new ArdourCanvas::Container (waves_container);
|
line_container = new ArdourCanvas::Container (waves_container);
|
||||||
|
|
||||||
@ -321,7 +346,10 @@ AudioClipEditor::scroll_changed ()
|
|||||||
scroll_fraction = std::min (1., std::max (0., scroll_fraction));
|
scroll_fraction = std::min (1., std::max (0., scroll_fraction));
|
||||||
const samplepos_t s = llrintf (audio_region->source (0)->length ().samples () * scroll_fraction);
|
const samplepos_t s = llrintf (audio_region->source (0)->length ().samples () * scroll_fraction);
|
||||||
|
|
||||||
|
ruler->set_range (s, s + pixel_to_sample (frame->get().width() - 2.));
|
||||||
|
|
||||||
scroll_to (sample_to_pixel (s), 0);
|
scroll_to (sample_to_pixel (s), 0);
|
||||||
|
|
||||||
queue_draw ();
|
queue_draw ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,11 +401,12 @@ AudioClipEditor::drop_waves ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioClipEditor::set_region (boost::shared_ptr<AudioRegion> r)
|
AudioClipEditor::set_region (boost::shared_ptr<AudioRegion> r, Trigger* t)
|
||||||
{
|
{
|
||||||
drop_waves ();
|
drop_waves ();
|
||||||
|
|
||||||
audio_region = r;
|
audio_region = r;
|
||||||
|
clip_metric->set_trigger (t);
|
||||||
|
|
||||||
uint32_t n_chans = r->n_channels ();
|
uint32_t n_chans = r->n_channels ();
|
||||||
samplecnt_t len;
|
samplecnt_t len;
|
||||||
@ -404,6 +433,8 @@ AudioClipEditor::set_region (boost::shared_ptr<AudioRegion> r)
|
|||||||
waves.push_back (wv);
|
waves.push_back (wv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ruler->set_range (0, pixel_to_sample (frame->get().width() - 2.));
|
||||||
|
|
||||||
set_spp_from_length (len);
|
set_spp_from_length (len);
|
||||||
set_wave_heights ();
|
set_wave_heights ();
|
||||||
set_waveform_colors ();
|
set_waveform_colors ();
|
||||||
@ -420,6 +451,9 @@ AudioClipEditor::on_size_allocate (Gtk::Allocation& alloc)
|
|||||||
ArdourCanvas::Rect r (1, 1, alloc.get_width () - 2, alloc.get_height () - 2);
|
ArdourCanvas::Rect r (1, 1, alloc.get_width () - 2, alloc.get_height () - 2);
|
||||||
frame->set (r);
|
frame->set (r);
|
||||||
|
|
||||||
|
const double ruler_height = 25.;
|
||||||
|
ruler->set (Rect (2, 2, alloc.get_width() - 4, ruler_height));
|
||||||
|
|
||||||
const double scroll_bar_height = 10.;
|
const double scroll_bar_height = 10.;
|
||||||
const double scroll_bar_width = alloc.get_width () - 2;
|
const double scroll_bar_width = alloc.get_width () - 2;
|
||||||
const double scroll_bar_handle_left = scroll_bar_width * scroll_fraction;
|
const double scroll_bar_handle_left = scroll_bar_width * scroll_fraction;
|
||||||
@ -441,7 +475,7 @@ AudioClipEditor::set_spp (double samples_per_pixel)
|
|||||||
{
|
{
|
||||||
_spp = samples_per_pixel;
|
_spp = samples_per_pixel;
|
||||||
|
|
||||||
ruler->set_range (0, 48000);
|
clip_metric->units_per_pixel = _spp;
|
||||||
|
|
||||||
position_lines ();
|
position_lines ();
|
||||||
|
|
||||||
@ -467,7 +501,7 @@ AudioClipEditor::set_wave_heights ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
const Distance w = frame->get ().height () - scroll_bar_trough->get ().height () - 2.;
|
const Distance w = frame->get ().height () - scroll_bar_trough->get ().height () - 2. - ruler->get().height();
|
||||||
Distance ht = w / waves.size ();
|
Distance ht = w / waves.size ();
|
||||||
|
|
||||||
for (auto& wave : waves) {
|
for (auto& wave : waves) {
|
||||||
@ -551,7 +585,7 @@ AudioClipEditorBox::zoom_out_click ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioClipEditorBox::set_region (boost::shared_ptr<Region> r)
|
AudioClipEditorBox::set_region (boost::shared_ptr<Region> r, Trigger* t)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
|
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
|
||||||
|
|
||||||
@ -564,7 +598,7 @@ AudioClipEditorBox::set_region (boost::shared_ptr<Region> r)
|
|||||||
state_connection.disconnect ();
|
state_connection.disconnect ();
|
||||||
|
|
||||||
_region = r;
|
_region = r;
|
||||||
editor->set_region (ar);
|
editor->set_region (ar, t);
|
||||||
|
|
||||||
PBD::PropertyChange interesting_stuff;
|
PBD::PropertyChange interesting_stuff;
|
||||||
region_changed (interesting_stuff);
|
region_changed (interesting_stuff);
|
||||||
|
@ -49,6 +49,7 @@ namespace ARDOUR
|
|||||||
{
|
{
|
||||||
class Session;
|
class Session;
|
||||||
class Location;
|
class Location;
|
||||||
|
class Trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ArdourCanvas
|
namespace ArdourCanvas
|
||||||
@ -68,7 +69,7 @@ public:
|
|||||||
ClipEditorBox () {}
|
ClipEditorBox () {}
|
||||||
~ClipEditorBox () {}
|
~ClipEditorBox () {}
|
||||||
|
|
||||||
virtual void set_region (boost::shared_ptr<ARDOUR::Region>) = 0;
|
virtual void set_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::Trigger*) = 0;
|
||||||
|
|
||||||
static void init ();
|
static void init ();
|
||||||
static void register_clip_editor_actions (Gtkmm2ext::Bindings*);
|
static void register_clip_editor_actions (Gtkmm2ext::Bindings*);
|
||||||
@ -90,7 +91,7 @@ public:
|
|||||||
AudioClipEditor ();
|
AudioClipEditor ();
|
||||||
~AudioClipEditor ();
|
~AudioClipEditor ();
|
||||||
|
|
||||||
void set_region (boost::shared_ptr<ARDOUR::AudioRegion>);
|
void set_region (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::Trigger*);
|
||||||
void on_size_allocate (Gtk::Allocation&);
|
void on_size_allocate (Gtk::Allocation&);
|
||||||
|
|
||||||
double sample_to_pixel (ARDOUR::samplepos_t);
|
double sample_to_pixel (ARDOUR::samplepos_t);
|
||||||
@ -115,7 +116,24 @@ private:
|
|||||||
ArdourCanvas::Rectangle* scroll_bar_handle;
|
ArdourCanvas::Rectangle* scroll_bar_handle;
|
||||||
ArdourCanvas::Container* ruler_container;
|
ArdourCanvas::Container* ruler_container;
|
||||||
ArdourCanvas::Ruler* ruler;
|
ArdourCanvas::Ruler* ruler;
|
||||||
ArdourCanvas::Ruler::Metric* clip_metric;
|
|
||||||
|
class ClipBBTMetric : public ArdourCanvas::Ruler::Metric
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClipBBTMetric() : trigger (0) {
|
||||||
|
units_per_pixel = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_trigger (ARDOUR::Trigger* t) { trigger = t; }
|
||||||
|
|
||||||
|
void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, int64_t lower, int64_t upper, int maxchars) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ARDOUR::Trigger* trigger;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ClipBBTMetric* clip_metric;
|
||||||
std::vector<ArdourWaveView::WaveView*> waves;
|
std::vector<ArdourWaveView::WaveView*> waves;
|
||||||
double non_wave_height;
|
double non_wave_height;
|
||||||
samplepos_t left_origin;
|
samplepos_t left_origin;
|
||||||
@ -184,7 +202,7 @@ public:
|
|||||||
AudioClipEditorBox ();
|
AudioClipEditorBox ();
|
||||||
~AudioClipEditorBox ();
|
~AudioClipEditorBox ();
|
||||||
|
|
||||||
void set_region (boost::shared_ptr<ARDOUR::Region>);
|
void set_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::Trigger*);
|
||||||
void region_changed (const PBD::PropertyChange& what_changed);
|
void region_changed (const PBD::PropertyChange& what_changed);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -113,7 +113,7 @@ MidiClipEditorBox::set_session (Session* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiClipEditorBox::set_region (boost::shared_ptr<Region> r)
|
MidiClipEditorBox::set_region (boost::shared_ptr<Region> r, Trigger* t)
|
||||||
{
|
{
|
||||||
set_session (&r->session ());
|
set_session (&r->session ());
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ public:
|
|||||||
|
|
||||||
void set_session (ARDOUR::Session*);
|
void set_session (ARDOUR::Session*);
|
||||||
|
|
||||||
void set_region (boost::shared_ptr<ARDOUR::Region>);
|
void set_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::Trigger*);
|
||||||
void region_changed (const PBD::PropertyChange& what_changed);
|
void region_changed (const PBD::PropertyChange& what_changed);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -335,14 +335,14 @@ TriggerPage::selection_changed ()
|
|||||||
if (slot->region ()) {
|
if (slot->region ()) {
|
||||||
if (slot->region ()->data_type () == DataType::AUDIO) {
|
if (slot->region ()->data_type () == DataType::AUDIO) {
|
||||||
_audio_prop_box.set_region (slot->region ());
|
_audio_prop_box.set_region (slot->region ());
|
||||||
_audio_trim_box.set_region (slot->region ());
|
_audio_trim_box.set_region (slot->region (), slot);
|
||||||
|
|
||||||
_audio_prop_box.show ();
|
_audio_prop_box.show ();
|
||||||
_audio_trim_box.show ();
|
_audio_trim_box.show ();
|
||||||
_audio_ops_box.show ();
|
_audio_ops_box.show ();
|
||||||
} else {
|
} else {
|
||||||
_midi_prop_box.set_region (slot->region ());
|
_midi_prop_box.set_region (slot->region ());
|
||||||
_midi_trim_box.set_region (slot->region ());
|
_midi_trim_box.set_region (slot->region (), slot);
|
||||||
|
|
||||||
_midi_prop_box.show ();
|
_midi_prop_box.show ();
|
||||||
_midi_trim_box.show ();
|
_midi_trim_box.show ();
|
||||||
|
@ -178,7 +178,7 @@ TriggerUI::TriggerUI () :
|
|||||||
Gtk::Label *label;
|
Gtk::Label *label;
|
||||||
|
|
||||||
label = manage(new Gtk::Label(_("Velocity Sense:"))); label->set_alignment(1.0, 0.5);
|
label = manage(new Gtk::Label(_("Velocity Sense:"))); label->set_alignment(1.0, 0.5);
|
||||||
attach(*label, 0, 1, row, row+1, Gtk::FILL, Gtk::SHRINK );
|
attach(*label, 0, 1, row, row+1, Gtk::FILL, Gtk::SHRINK );
|
||||||
label = manage(new Gtk::Label(_("100%"))); label->set_alignment(0.0, 0.5);
|
label = manage(new Gtk::Label(_("100%"))); label->set_alignment(0.0, 0.5);
|
||||||
attach(*label, 1, 2, row, row+1, Gtk::FILL, Gtk::SHRINK ); row++;
|
attach(*label, 1, 2, row, row+1, Gtk::FILL, Gtk::SHRINK ); row++;
|
||||||
|
|
||||||
@ -407,9 +407,9 @@ TriggerWindow::TriggerWindow (Trigger* slot)
|
|||||||
_ops_box = manage(new MidiRegionOperationsBox ());
|
_ops_box = manage(new MidiRegionOperationsBox ());
|
||||||
_trim_box = manage(new MidiClipEditorBox ());
|
_trim_box = manage(new MidiClipEditorBox ());
|
||||||
}
|
}
|
||||||
|
|
||||||
_prop_box->set_region(slot->region());
|
_prop_box->set_region(slot->region());
|
||||||
_trim_box->set_region(slot->region());
|
_trim_box->set_region(slot->region(), slot);
|
||||||
_ops_box->set_session(&slot->region()->session());
|
_ops_box->set_session(&slot->region()->session());
|
||||||
|
|
||||||
table->attach(*_prop_box, col, col+1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); col++;
|
table->attach(*_prop_box, col, col+1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); col++;
|
||||||
|
Loading…
Reference in New Issue
Block a user