diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-01-25 05:35:46 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-01-25 05:35:46 +0000 |
commit | d3f64c28489d2358498b9d7dcfc6fa4228ebd63e (patch) | |
tree | 8195496c9330bb4fb279d282598da6dc5c98a361 /gtk2_ardour | |
parent | 28e6ad009158ddaea80fd5d800befcbf58ce47ee (diff) |
meet rhythm ferret: cute, furry and always on time (ardour build now requires fftw3 & fftw3f, no exceptions, ever)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2959 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/SConscript | 8 | ||||
-rw-r--r-- | gtk2_ardour/ardour.menus | 1 | ||||
-rw-r--r-- | gtk2_ardour/au_pluginui.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 18 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 6 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 82 | ||||
-rw-r--r-- | gtk2_ardour/rhythm_ferret.cc | 376 | ||||
-rw-r--r-- | gtk2_ardour/rhythm_ferret.h | 100 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view.cc | 35 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view.h | 5 |
11 files changed, 633 insertions, 2 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 3ece6ee91c..f8d107a8a9 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -50,6 +50,10 @@ gtkardour.Merge ([ libraries['xml'], libraries['xslt'], libraries['samplerate'], + libraries['vamp'], + libraries['vamphost'], + libraries['fftw3f'], + libraries['fftw3'], libraries['jack'] ]) @@ -75,7 +79,7 @@ if gtkardour['FFT_ANALYSIS']: gtkardour.Append(CCFLAGS='-DFFT_ANALYSIS') if gtkardour['RUBBERBAND']: - gtkardour.Merge ([ libraries['rubberband'], libraries['vamp'], libraries['fftw3f'], libraries['fftw3'] ]) + gtkardour.Merge ([ libraries['rubberband'] ]) else: gtkardour.Merge ([ libraries['soundtouch'] ]) @@ -188,7 +192,6 @@ new_session_dialog.cc option_editor.cc opts.cc pan_automation_time_axis.cc - panner.cc panner2d.cc panner_ui.cc @@ -200,6 +203,7 @@ public_editor.cc redirect_automation_line.cc redirect_automation_time_axis.cc redirect_box.cc +rhythm_ferret.cc audio_region_editor.cc region_gain_line.cc region_selection.cc diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 23a803161b..09d07494dd 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -161,6 +161,7 @@ <menuitem action='select-prev-route'/> </menu> <menu name='Regions' action='Regions'> + <menuitem action='split-region-at-transients'/> <menuitem action='crop'/> <menuitem action='duplicate-region'/> <menuitem action='multi-duplicate-region'/> diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h index 46e4cde12f..5bec967091 100644 --- a/gtk2_ardour/au_pluginui.h +++ b/gtk2_ardour/au_pluginui.h @@ -3,6 +3,7 @@ #include <AppKit/AppKit.h> #include <Carbon/Carbon.h> +#include <AudioUnit/AudioUnitCarbonView.h> #include <AudioUnit/AudioUnit.h> /* fix up stupid apple macros */ diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 9e3cc60466..cb43a987b5 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -79,6 +79,7 @@ #include "actions.h" #include "gui_thread.h" #include "sfdb_ui.h" +#include "rhythm_ferret.h" #ifdef FFT_ANALYSIS #include "analysis_window.h" @@ -328,6 +329,7 @@ Editor::Editor () _dragging_hscrollbar = false; select_new_marker = false; zoomed_to_region = false; + rhythm_ferret = 0; scrubbing_direction = 0; @@ -1161,6 +1163,10 @@ Editor::connect_to_session (Session *t) _playlist_selector->set_session (session); nudge_clock.set_session (session); + if (rhythm_ferret) { + rhythm_ferret->set_session (session); + } + #ifdef FFT_ANALYSIS if (analysis_window != 0) analysis_window->set_session (session); @@ -4359,3 +4365,15 @@ Editor::get_regions_corresponding_to (boost::shared_ptr<Region> region, vector<R } } } + +void +Editor::show_rhythm_ferret () +{ + if (rhythm_ferret == 0) { + rhythm_ferret = new RhythmFerret(*this); + } + + rhythm_ferret->set_session (session); + rhythm_ferret->show (); + rhythm_ferret->present (); +} diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 9e155dc5b9..5ce99636db 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -105,6 +105,7 @@ class StreamView; class AudioStreamView; class ControlPoint; class SoundFileOmega; +class RhythmFerret; #ifdef FFT_ANALYSIS class AnalysisWindow; #endif @@ -361,6 +362,8 @@ class Editor : public PublicEditor void toggle_meter_updating(); + void show_rhythm_ferret(); + protected: void map_transport_state (); void map_position_change (nframes_t); @@ -981,6 +984,7 @@ class Editor : public PublicEditor void normalize_region (); void denormalize_region (); void adjust_region_scale_amplitude (bool up); + void split_region_at_transients (); void use_region_as_bar (); void use_range_as_bar (); @@ -2061,6 +2065,8 @@ class Editor : public PublicEditor void select_next_route (); void select_prev_route (); + + RhythmFerret* rhythm_ferret; }; #endif /* __ardour_editor_h__ */ diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 4bb0d74aeb..ae1b93e919 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -364,6 +364,9 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "set-tempo-from-edit-range", _("Set Tempo from Edit Range=Bar"), mem_fun(*this, &Editor::use_range_as_bar)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "split-region-at-transients", _("Other Temporary Label"), mem_fun(*this, &Editor::split_region_at_transients)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "crop", _("Crop"), mem_fun(*this, &Editor::crop_region_to_selection)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "insert-chunk", _("Insert Chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f)); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index f960f27d0f..0e725aeda2 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -43,10 +43,12 @@ #include <ardour/location.h> #include <ardour/named_selection.h> #include <ardour/audio_track.h> +#include <ardour/audiofilesource.h> #include <ardour/audioplaylist.h> #include <ardour/region_factory.h> #include <ardour/playlist_factory.h> #include <ardour/reverse.h> +#include <ardour/transient_detector.h> #include <ardour/dB.h> #include "ardour_ui.h" @@ -5013,3 +5015,83 @@ Editor::define_one_bar (nframes64_t start, nframes64_t end) session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), &before, &after)); commit_reversible_command (); } + +void +Editor::split_region_at_transients () +{ + list<nframes64_t> transients; + + if (!session) { + return; + } + + ExclusiveRegionSelection esr (*this, entered_regionview); + + if (selection->regions.empty()) { + return; + } + + show_rhythm_ferret (); + return; +#if 0 + + cerr << "selection size is " << selection->regions.size() << endl; + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ) { + + RegionSelection::iterator tmp; + + tmp = i; + ++tmp; + + cerr << "working on " << (*i)->get_item_name() << endl; + + boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> ((*i)->region()); + + if (!ar) { + continue; + } + + boost::shared_ptr<Playlist> pl = ar->playlist(); + + if (!pl) { + continue; + } + + cerr << "getting transients\n"; + + ar->get_transients (transients); + nframes64_t start = ar->start(); + nframes64_t pos = ar->position(); + + pl->freeze (); + pl->remove_region (ar); + + cerr << "creating new regions from " << transients.size() << " transients\n"; + + for (list<nframes64_t>::iterator x = transients.begin(); x != transients.end(); ++x) { + + nframes_t len = (*x) - start; + + string new_name; + + if (session->region_name (new_name, ar->name())) { + continue; + } + + pl->add_region (RegionFactory::create (ar->get_sources(), start, len, new_name), pos); + + start = (*x); + pos += len; + } + + pl->thaw (); + + transients.clear (); + + cerr << "done with that one\n"; + + i = tmp; + } +#endif +} diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc new file mode 100644 index 0000000000..a52980167f --- /dev/null +++ b/gtk2_ardour/rhythm_ferret.cc @@ -0,0 +1,376 @@ +#include <gtkmm/stock.h> +#include <gtkmm2ext/utils.h> + +#include <pbd/memento_command.h> + +#include <ardour/transient_detector.h> +#include <ardour/audiosource.h> +#include <ardour/audioregion.h> +#include <ardour/playlist.h> +#include <ardour/region_factory.h> +#include <ardour/session.h> + +#include "rhythm_ferret.h" +#include "audio_region_view.h" +#include "public_editor.h" + +#include "i18n.h" + +using namespace std; +using namespace Gtk; +using namespace Gdk; +using namespace PBD; +using namespace ARDOUR; + +/* order of these must match the AnalysisMode enums + in rhythm_ferret.h +*/ +static const gchar * _analysis_mode_strings[] = { + N_("Percussive Onset"), + N_("Note Onset"), + 0 +}; + +RhythmFerret::RhythmFerret (PublicEditor& e) + : ArdourDialog (_("Rhythm Ferret")) + , editor (e) + , operation_frame (_("Operation")) + , selection_frame (_("Selection")) + , ferret_frame (_("Analysis")) + , logo (0) + , region_split_button (operation_button_group, _("Split Region")) + , tempo_button (operation_button_group, _("Set Tempo Map")) + , region_conform_button (operation_button_group, _("Conform Region")) + , analysis_mode_label (_("Mode")) + , detection_threshold_adjustment (3, 0, 20, 1, 4) + , detection_threshold_scale (detection_threshold_adjustment) + , detection_threshold_label (_("Threshold")) + , sensitivity_adjustment (40, 0, 100, 1, 10) + , sensitivity_scale (sensitivity_adjustment) + , sensitivity_label (_("Sensitivity")) + , analyze_button (_("Analyze")) + , trigger_gap_adjustment (3, 0, 100, 1, 10) + , trigger_gap_spinner (trigger_gap_adjustment) + , trigger_gap_label (_("Trigger gap (msecs)")) + , action_button (Stock::APPLY) + +{ + upper_hpacker.set_spacing (6); + + upper_hpacker.pack_start (operation_frame, true, true); + upper_hpacker.pack_start (selection_frame, true, true); + upper_hpacker.pack_start (ferret_frame, true, true); + + op_packer.pack_start (region_split_button, false, false); + op_packer.pack_start (tempo_button, false, false); + op_packer.pack_start (region_conform_button, false, false); + + operation_frame.add (op_packer); + + HBox* box; + + ferret_packer.set_spacing (6); + ferret_packer.set_border_width (6); + + vector<string> strings; + + analysis_mode_strings = I18N (_analysis_mode_strings); + Gtkmm2ext::set_popdown_strings (analysis_mode_selector, analysis_mode_strings); + analysis_mode_selector.set_active_text (analysis_mode_strings.front()); + + box = manage (new HBox); + box->set_spacing (6); + box->pack_start (analysis_mode_label, false, false); + box->pack_start (analysis_mode_selector, true, true); + ferret_packer.pack_start (*box, false, false); + + box = manage (new HBox); + box->set_spacing (6); + box->pack_start (detection_threshold_label, false, false); + box->pack_start (detection_threshold_scale, true, true); + ferret_packer.pack_start (*box, false, false); + + box = manage (new HBox); + box->set_spacing (6); + box->pack_start (sensitivity_label, false, false); + box->pack_start (sensitivity_scale, true, true); + ferret_packer.pack_start (*box, false, false); + + box = manage (new HBox); + box->set_spacing (6); + box->pack_start (trigger_gap_label, false, false); + box->pack_start (trigger_gap_spinner, false, false); + ferret_packer.pack_start (*box, false, false); + + ferret_packer.pack_start (analyze_button, false, false); + + analyze_button.signal_clicked().connect (mem_fun (*this, &RhythmFerret::run_analysis)); + + ferret_frame.add (ferret_packer); + + // Glib::RefPtr<Pixbuf> logo_pixbuf ("somefile"); + + if (logo) { + lower_hpacker.pack_start (*logo, false, false); + } + + lower_hpacker.pack_start (operation_clarification_label, false, false); + lower_hpacker.pack_start (action_button, false, false); + + action_button.signal_clicked().connect (mem_fun (*this, &RhythmFerret::do_action)); + + get_vbox()->set_border_width (6); + get_vbox()->set_spacing (6); + get_vbox()->pack_start (upper_hpacker, true, true); + get_vbox()->pack_start (lower_hpacker, false, false); + + show_all (); +} + +RhythmFerret::~RhythmFerret() +{ + if (logo) { + delete logo; + } +} + +RhythmFerret::AnalysisMode +RhythmFerret::get_analysis_mode () const +{ + string str = analysis_mode_selector.get_active_text (); + + if (str == _(_analysis_mode_strings[(int) NoteOnset])) { + return NoteOnset; + } + + return PercussionOnset; +} + +RhythmFerret::Action +RhythmFerret::get_action () const +{ + if (tempo_button.get_active()) { + return DefineTempoMap; + } else if (region_conform_button.get_active()) { + return ConformRegion; + } + + return SplitRegion; +} + +void +RhythmFerret::run_analysis () +{ + if (!session) { + return; + } + + RegionSelection& regions (editor.get_selection().regions); + + current_results.clear (); + + if (regions.empty()) { + return; + } + + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + + boost::shared_ptr<Readable> rd = boost::static_pointer_cast<AudioRegion> ((*i)->region()); + + switch (get_analysis_mode()) { + case PercussionOnset: + run_percussion_onset_analysis (rd, (*i)->region()->position(), current_results); + break; + default: + break; + } + + } + + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + (*i)->get_time_axis_view().show_temporary_lines (current_results); + } + +} + +int +RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readable, nframes64_t offset, vector<nframes64_t>& results) +{ + TransientDetector t (session->frame_rate()); + bool existing_results = !results.empty(); + + for (uint32_t i = 0; i < readable->n_channels(); ++i) { + + vector<nframes64_t> these_results; + + t.reset (); + t.set_threshold (detection_threshold_adjustment.get_value()); + t.set_sensitivity (sensitivity_adjustment.get_value()); + + if (t.run ("", readable, i, these_results)) { + continue; + } + + /* translate all transients to give absolute position */ + + for (vector<nframes64_t>::iterator i = these_results.begin(); i != these_results.end(); ++i) { + (*i) += offset; + } + + /* merge */ + + results.insert (results.end(), these_results.begin(), these_results.end()); + } + + if (!results.empty() && (existing_results || readable->n_channels() > 1)) { + + /* now resort to bring transients from different channels together */ + + sort (results.begin(), results.end()); + + /* remove duplicates or other things that are too close */ + + vector<nframes64_t>::iterator i = results.begin(); + nframes64_t curr = (*i); + nframes64_t gap_frames = (nframes64_t) floor (trigger_gap_adjustment.get_value() * (session->frame_rate() / 1000.0)); + + ++i; + + while (i != results.end()) { + if (((*i) == curr) || (((*i) - curr) < gap_frames)) { + i = results.erase (i); + } else { + ++i; + curr = *i; + } + } + + } + + return 0; +} + +void +RhythmFerret::do_action () +{ + if (!session || current_results.empty()) { + return; + } + + switch (get_action()) { + case SplitRegion: + do_split_action (); + break; + + default: + break; + } +} + +void +RhythmFerret::do_split_action () +{ + /* this can/will change the current selection, so work with a copy */ + + RegionSelection& regions (editor.get_selection().regions); + + if (regions.empty()) { + return; + } + + session->begin_reversible_command (_("split regions (rhythm ferret)")); + + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ) { + + RegionSelection::iterator tmp; + + tmp = i; + ++tmp; + + (*i)->get_time_axis_view().hide_temporary_lines (); + + do_region_split ((*i), current_results); + + /* i is invalid at this point */ + + i = tmp; + } + + session->commit_reversible_command (); +} + +void +RhythmFerret::do_region_split (RegionView* rv, const vector<nframes64_t>& positions) +{ + boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (rv->region()); + + if (!ar) { + return; + } + + boost::shared_ptr<Playlist> pl = ar->playlist(); + + if (!pl) { + return; + } + + vector<nframes64_t>::const_iterator x; + + nframes64_t pos = ar->position(); + + XMLNode& before (pl->get_state()); + + x = positions.begin(); + + while (x != positions.end()) { + if ((*x) > pos) { + break; + } + } + + if (x == positions.end()) { + return; + } + + pl->freeze (); + pl->remove_region (ar); + + do { + + /* file start = original start + how far we from the initial position ? + */ + + nframes64_t file_start = ar->start() + (pos - ar->position()); + + /* length = next position - current position + */ + + nframes64_t len = (*x) - pos; + + string new_name; + + if (session->region_name (new_name, ar->name())) { + continue; + } + + pl->add_region (RegionFactory::create (ar->get_sources(), file_start, len, new_name), pos); + + pos += len; + + ++x; + + } while (x != positions.end() && (*x) < ar->last_frame()); + + pl->thaw (); + + XMLNode& after (pl->get_state()); + + session->add_command (new MementoCommand<Playlist>(*pl, &before, &after)); +} + +void +RhythmFerret::set_session (Session* s) +{ + ArdourDialog::set_session (s); + current_results.clear (); +} diff --git a/gtk2_ardour/rhythm_ferret.h b/gtk2_ardour/rhythm_ferret.h new file mode 100644 index 0000000000..36d4450939 --- /dev/null +++ b/gtk2_ardour/rhythm_ferret.h @@ -0,0 +1,100 @@ +#ifndef __gtk2_ardour_rhythm_ferret_h__ +#define __gtk2_ardour_rhythm_ferret_h__ + +#include <gtkmm/box.h> +#include <gtkmm/scale.h> +#include <gtkmm/spinbutton.h> +#include <gtkmm/radiobutton.h> +#include <gtkmm/radiobuttongroup.h> +#include <gtkmm/frame.h> +#include <gtkmm/image.h> +#include <gtkmm/comboboxtext.h> +#include <gtkmm/button.h> +#include <gtkmm/label.h> + +#include "ardour_dialog.h" + +namespace ARDOUR { + class Readable; +} + +class PublicEditor; +class RegionView; + +class RhythmFerret : public ArdourDialog { + public: + /* order of these enums must match the _analyse_mode_strings + in rhythm_ferret.cc + */ + enum AnalysisMode { + PercussionOnset, + NoteOnset + }; + + enum Action { + SplitRegion, + DefineTempoMap, + ConformRegion + }; + + RhythmFerret (PublicEditor&); + ~RhythmFerret (); + + void set_session (ARDOUR::Session*); + + private: + PublicEditor& editor; + + Gtk::HBox upper_hpacker; + Gtk::HBox lower_hpacker; + + Gtk::Frame operation_frame; + Gtk::Frame selection_frame; + Gtk::Frame ferret_frame; + + Gtk::VBox op_logo_packer; + Gtk::Image* logo; + + /* operation frame */ + + Gtk::VBox op_packer; + Gtk::RadioButtonGroup operation_button_group; + Gtk::RadioButton region_split_button; + Gtk::RadioButton tempo_button; + Gtk::RadioButton region_conform_button; + + /* analysis frame */ + + Gtk::VBox ferret_packer; + Gtk::ComboBoxText analysis_mode_selector; + Gtk::Label analysis_mode_label; + Gtk::Adjustment detection_threshold_adjustment; + Gtk::HScale detection_threshold_scale; + Gtk::Label detection_threshold_label; + Gtk::Adjustment sensitivity_adjustment; + Gtk::HScale sensitivity_scale; + Gtk::Label sensitivity_label; + Gtk::Button analyze_button; + Gtk::Adjustment trigger_gap_adjustment; + Gtk::SpinButton trigger_gap_spinner; + Gtk::Label trigger_gap_label; + + Gtk::Label operation_clarification_label; + Gtk::Button action_button; + + std::vector<std::string> analysis_mode_strings; + + std::vector<nframes64_t> current_results; + + AnalysisMode get_analysis_mode () const; + Action get_action() const; + + void run_analysis (); + int run_percussion_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, nframes64_t offset, std::vector<nframes64_t>& results); + + void do_action (); + void do_split_action (); + void do_region_split (RegionView* rv, const std::vector<nframes64_t>&); +}; + +#endif /* __gtk2_ardour_rhythm_ferret_h__ */ diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index c4f5a558ab..c6dc773dd8 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -43,6 +43,7 @@ #include "public_editor.h" #include "time_axis_view.h" #include "simplerect.h" +#include "simpleline.h" #include "selection.h" #include "keyboard.h" #include "rgb_macros.h" @@ -1099,3 +1100,37 @@ TimeAxisView::covers_y_position (double y) return 0; } + +void +TimeAxisView::show_temporary_lines (const vector<nframes64_t>& pos) +{ + while (temp_lines.size()< pos.size()) { + ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*canvas_display); + l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get(); + l->property_y1() = 0; + l->property_y2() = height; + temp_lines.push_back (l); + } + + while (temp_lines.size() > pos.size()) { + ArdourCanvas::SimpleLine *line = temp_lines.back(); + temp_lines.pop_back (); + delete line; + } + + vector<nframes64_t>::const_iterator i; + list<ArdourCanvas::SimpleLine*>::iterator l; + + for (i = pos.begin(), l = temp_lines.begin(); i != pos.end() && l != temp_lines.end(); ++i, ++l) { + (*l)->property_x1() = editor.frame_to_pixel ((double) *i); + (*l)->property_x2() = editor.frame_to_pixel ((double) *i); + } +} + +void +TimeAxisView::hide_temporary_lines () +{ + for (list<ArdourCanvas::SimpleLine*>::iterator l = temp_lines.begin(); l != temp_lines.end(); ++l) { + (*l)->hide (); + } +} diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index 2c45325679..c98a72c626 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -176,6 +176,9 @@ class TimeAxisView : public virtual AxisView virtual ARDOUR::RouteGroup* edit_group() const { return 0; } virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); } + virtual void show_temporary_lines (const std::vector<nframes64_t>&); + virtual void hide_temporary_lines (); + virtual void set_samples_per_unit (double); virtual void show_selection (TimeSelection&); virtual void hide_selection (); @@ -322,6 +325,8 @@ class TimeAxisView : public virtual AxisView void set_height_pixels (uint32_t h); void color_handler (); + list<ArdourCanvas::SimpleLine*> temp_lines; + }; /* class TimeAxisView */ #endif /* __ardour_gtk_time_axis_h__ */ |