summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mainsbridge <beatroute@iprimus.com.au>2007-10-26 13:32:24 +0000
committerNick Mainsbridge <beatroute@iprimus.com.au>2007-10-26 13:32:24 +0000
commitcc862d31bd8c9005964dca94a9942f1b42847252 (patch)
tree66b2ee6c0201b2b9f6929aa6f5190b5a4c05e22d
parent0c3f01e54074a9b47dcab9b3ec0ed8a9729dbc87 (diff)
use filechooser widget in export dialog, selected files set format combos, hide progress bar until use in export dialog, speed up 'separate regions in range' operation on larger sessions, ruler scale now calculated separately to mark generation, fix for non-stacked layering regression, try not to generate 'buried' crossfades, use playlist->freeze() to speed up copying/moving regions on large playlists (not done for undo), width dependent items now reset on regionview init, get rid of jack_port_ensure_monitor check, remove audiosourse _length (only source has a length.. i think), make overlapend differ to overlapexternal where start points coincide.
git-svn-id: svn://localhost/ardour2/trunk@2576 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_region_view.cc2
-rw-r--r--gtk2_ardour/audio_streamview.cc52
-rw-r--r--gtk2_ardour/editor.cc22
-rw-r--r--gtk2_ardour/editor.h57
-rw-r--r--gtk2_ardour/editor_canvas.cc2
-rw-r--r--gtk2_ardour/editor_export_audio.cc6
-rw-r--r--gtk2_ardour/editor_mouse.cc168
-rw-r--r--gtk2_ardour/editor_ops.cc24
-rw-r--r--gtk2_ardour/editor_rulers.cc1057
-rw-r--r--gtk2_ardour/editor_tempodisplay.cc71
-rw-r--r--gtk2_ardour/export_dialog.cc250
-rw-r--r--gtk2_ardour/export_dialog.h5
-rw-r--r--gtk2_ardour/region_view.cc7
-rw-r--r--gtk2_ardour/streamview.cc21
-rw-r--r--libs/ardour/SConscript29
-rw-r--r--libs/ardour/ardour/audiosource.h5
-rw-r--r--libs/ardour/ardour/jack_port.h6
-rw-r--r--libs/ardour/ardour/types.h4
-rw-r--r--libs/ardour/audio_playlist.cc67
-rw-r--r--libs/ardour/globals.cc2
-rw-r--r--libs/ardour/playlist.cc53
-rw-r--r--libs/ardour/sndfile_helpers.cc10
22 files changed, 1269 insertions, 651 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 4bc10e93ec..0ad6b8af5b 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -202,6 +202,8 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
fade_in_active_changed ();
fade_out_active_changed ();
+ reset_width_dependent_items (_pixel_width);
+
fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this));
fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this));
fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this));
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index 22f8fa6239..c571cb1a7c 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -311,6 +311,7 @@ AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade == crossfade) {
+
if (!crossfades_visible || layer_display == Stacked) {
(*i)->hide();
} else {
@@ -340,10 +341,9 @@ AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
_samples_per_unit,
region_color,
*lview, *rview);
-
+ cv->set_valid (true);
crossfade->Invalidated.connect (mem_fun (*this, &AudioStreamView::remove_crossfade));
crossfade_views.push_back (cv);
-
if (!Config->get_xfades_visible() || !crossfades_visible || layer_display == Stacked) {
cv->hide ();
}
@@ -390,6 +390,8 @@ AudioStreamView::redisplay_diskstream ()
apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
}
+ RegionViewList copy;
+
for (i = region_views.begin(); i != region_views.end(); ) {
tmp = i;
tmp++;
@@ -397,11 +399,47 @@ AudioStreamView::redisplay_diskstream ()
if (!(*i)->is_valid()) {
delete *i;
region_views.erase (i);
+ i = tmp;
+ continue;
} else {
(*i)->enable_display(true);
}
+ /*
+ sort regionviews by layer so that when we call region_layered ()
+ the canvas layering works out (in non-stacked mode).
+ */
+
+ if (copy.size() == 0) {
+ copy.push_front((*i));
+ i = tmp;
+ continue;
+ }
+
+ RegionViewList::iterator k = copy.begin();
+ RegionViewList::iterator l = copy.end();
+ l--;
+
+ if ((*i)->region()->layer() <= (*k)->region()->layer()) {
+ copy.push_front((*i));
+ i = tmp;
+ continue;
+ } else if ((*i)->region()->layer() >= (*l)->region()->layer()) {
+ copy.push_back((*i));
+ i = tmp;
+ continue;
+ }
+
+ for (RegionViewList::iterator j = copy.begin(); j != copy.end(); ++j) {
+
+ if ((*j)->region()->layer() >= (*i)->region()->layer()) {
+ copy.insert(j, (*i));
+ break;
+ }
+ }
+
i = tmp;
+
}
for (xi = crossfade_views.begin(); xi != crossfade_views.end();) {
@@ -416,10 +454,12 @@ AudioStreamView::redisplay_diskstream ()
xi = tmpx;
}
- /* now fix layering */
-
- for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- region_layered (*i);
+ /* now fix canvas layering */
+
+ for (RegionViewList::iterator j = copy.begin(); j != copy.end(); ++j) {
+ (*j)->enable_display(true);
+ (*j)->set_y_position_and_height(0, height);
+ region_layered (*j);
}
}
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index da74ea96cc..1e726277d2 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -348,7 +348,8 @@ Editor::Editor ()
range_marker_drag_rect = 0;
marker_drag_line = 0;
-
+ tempo_map_change_idle_handler_id = -1;
+ canvas_hroizontally_scrolled_handler_id = -1;
set_midi_edit_mode (MidiEditPencil, true);
set_mouse_mode (MouseObject, true);
@@ -1983,7 +1984,9 @@ Editor::set_snap_to (SnapType st)
case SnapToAEighthBeat:
case SnapToAQuarterBeat:
case SnapToAThirdBeat:
+ compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes_t)(canvas_width * frames_per_unit));
update_tempo_based_rulers ();
+ break;
default:
/* relax */
break;
@@ -2638,7 +2641,7 @@ Editor::setup_toolbar ()
/* Zoom */
zoom_box.set_spacing (1);
- zoom_box.set_border_width (2);
+ zoom_box.set_border_width (0);
zoom_in_button.set_name ("EditorTimeButton");
zoom_in_button.set_size_request(-1,16);
@@ -3918,10 +3921,6 @@ Editor::set_frames_per_unit (double fpu)
frames_per_unit = fpu;
- if (frames != zoom_range_clock.current_duration()) {
- zoom_range_clock.set (frames);
- }
-
if (mouse_mode == MouseRange && selection->time.start () != selection->time.end_frame ()) {
if (!selection->tracks.empty()) {
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
@@ -3963,8 +3962,9 @@ Editor::queue_visual_change (double fpu)
pending_visual_change.frames_per_unit = fpu;
if (pending_visual_change.idle_handler_id < 0) {
- pending_visual_change.idle_handler_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, _idle_visual_changer, this, 0);
+ pending_visual_change.idle_handler_id = g_idle_add ( _idle_visual_changer, this);
}
+
}
int
@@ -3979,12 +3979,15 @@ Editor::idle_visual_changer ()
VisualChange::Type p = pending_visual_change.pending;
pending_visual_change.pending = (VisualChange::Type) 0;
- pending_visual_change.idle_handler_id = -1;
if (p & VisualChange::ZoomLevel) {
set_frames_per_unit (pending_visual_change.frames_per_unit);
- }
+ compute_fixed_ruler_scale ();
+ compute_current_bbt_points(pending_visual_change.time_origin, pending_visual_change.time_origin + (nframes_t)(canvas_width * pending_visual_change.frames_per_unit));
+ compute_bbt_ruler_scale (pending_visual_change.time_origin, pending_visual_change.time_origin + (nframes_t)(canvas_width * pending_visual_change.frames_per_unit));
+ update_tempo_based_rulers ();
+ }
if (p & VisualChange::TimeOrigin) {
if (pending_visual_change.time_origin != leftmost_frame) {
horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit);
@@ -3994,6 +3997,7 @@ Editor::idle_visual_changer ()
redisplay_tempo (true);
}
}
+ pending_visual_change.idle_handler_id = -1;
return 0; /* this is always a one-shot call */
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 7e96f9c9c5..4fc2bd0d18 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -476,6 +476,7 @@ class Editor : public PublicEditor
void set_selected_regionview_from_region_list (boost::shared_ptr<ARDOUR::Region> region, Selection::Operation op = Selection::Set);
void collect_new_region_view (RegionView *);
+ void collect_and_select_new_region_view (RegionView *);
Gtk::MenuItem* region_edit_menu_split_item;
Gtk::MenuItem* region_edit_menu_split_multichannel_item;
@@ -559,6 +560,7 @@ class Editor : public PublicEditor
void initialize_rulers ();
void update_just_smpte ();
+ void compute_fixed_ruler_scale (); //calculates the RulerScale of the fixed rulers
void update_fixed_rulers ();
void update_tempo_based_rulers ();
void popup_ruler_menu (nframes_t where = 0, ItemType type = RegionItem);
@@ -573,6 +575,55 @@ class Editor : public PublicEditor
static gint _metric_get_frames (GtkCustomRulerMark **, gdouble, gdouble, gint);
static gint _metric_get_minsec (GtkCustomRulerMark **, gdouble, gdouble, gint);
+ enum MinsecRulerScale {
+ minsec_show_seconds,
+ minsec_show_minutes,
+ minsec_show_hours,
+ minsec_show_frames
+ };
+
+ MinsecRulerScale minsec_ruler_scale;
+
+ nframes_t minsec_mark_interval;
+ gint minsec_mark_modulo;
+ gint minsec_nmarks;
+ void set_minsec_ruler_scale (gdouble lower, gdouble upper);
+
+ enum SMPTERulerScale {
+ smpte_show_bits,
+ smpte_show_frames,
+ smpte_show_seconds,
+ smpte_show_minutes,
+ smpte_show_hours
+ };
+
+ SMPTERulerScale smpte_ruler_scale;
+
+ nframes_t smpte_mark_interval;
+ gint smpte_mark_modulo;
+ gint smpte_nmarks;
+ void set_smpte_ruler_scale (gdouble lower, gdouble upper);
+
+ enum BBTRulerScale {
+ bbt_over,
+ bbt_show_64,
+ bbt_show_16,
+ bbt_show_4,
+ bbt_show_1,
+ bbt_show_beats,
+ bbt_show_ticks,
+ bbt_show_ticks_detail,
+ bbt_show_ticks_super_detail
+ };
+
+ BBTRulerScale bbt_ruler_scale;
+
+ uint32_t bbt_bars;
+ gint bbt_nmarks;
+ uint32_t bbt_bar_helper_on;
+ uint32_t bbt_accent_modulo;
+ void compute_bbt_ruler_scale (nframes_t lower, nframes_t upper);
+
gint metric_get_smpte (GtkCustomRulerMark **, gdouble, gdouble, gint);
gint metric_get_bbt (GtkCustomRulerMark **, gdouble, gdouble, gint);
gint metric_get_frames (GtkCustomRulerMark **, gdouble, gdouble, gint);
@@ -696,6 +747,8 @@ class Editor : public PublicEditor
void tie_vertical_scrolling ();
void canvas_horizontally_scrolled ();
+ static int _idle_canvas_horizontally_scrolled (void *arg);
+ bool idle_canvas_horizontally_scrolled ();
struct VisualChange {
enum Type {
@@ -1261,6 +1314,8 @@ class Editor : public PublicEditor
void handle_new_duration ();
void initialize_canvas ();
+ int canvas_hroizontally_scrolled_handler_id;
+ void reset_horizontally_scrolling_region (Gtk::Allocation* alloc = 0);
void reset_scrolling_region (Gtk::Allocation* alloc = 0);
/* display control */
@@ -1341,6 +1396,8 @@ class Editor : public PublicEditor
void remove_metric_marks ();
void draw_metric_marks (const ARDOUR::Metrics& metrics);
+ void compute_current_bbt_points (nframes_t left, nframes_t right);
+ int tempo_map_change_idle_handler_id;
void tempo_map_changed (ARDOUR::Change);
void redisplay_tempo (bool immediate_redraw);
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 86beec387e..fbd4f13f02 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -360,7 +360,7 @@ Editor::track_canvas_size_allocated ()
transport_punchout_line->property_y1() = 0.0;
transport_punchout_line->property_y2() = canvas_height;
}
-
+ compute_fixed_ruler_scale ();
update_fixed_rulers();
redisplay_tempo (true);
diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc
index 9b0a7c7cb5..3ab2012588 100644
--- a/gtk2_ardour/editor_export_audio.cc
+++ b/gtk2_ardour/editor_export_audio.cc
@@ -82,9 +82,9 @@ Editor::export_range (nframes_t start, nframes_t end)
if (session) {
if (export_dialog == 0) {
export_dialog = new ExportSessionDialog (*this);
+ export_dialog->connect_to_session (session);
}
- export_dialog->connect_to_session (session);
export_dialog->set_range (start, end);
export_dialog->start_export();
}
@@ -121,9 +121,9 @@ Editor::export_range_markers ()
if (export_range_markers_dialog == 0) {
export_range_markers_dialog = new ExportRangeMarkersDialog(*this);
+ export_range_markers_dialog->connect_to_session (session);
}
-
- export_range_markers_dialog->connect_to_session (session);
+
export_range_markers_dialog->start_export();
}
}
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index c6bbf5ca5f..0827fc5321 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2898,6 +2898,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
vector<RegionView*> new_regionviews;
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
+
RegionView* rv;
RegionView* nrv;
@@ -2924,7 +2925,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
/* reset selection to new regionviews */
-
+
selection->set (new_regionviews);
/* reset drag_info data to reflect the fact that we are dragging the copies */
@@ -3288,7 +3289,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
tvp2 = trackview_by_y_position (iy1 + y_delta);
temp_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2);
rv->set_y_position_and_height (0, temp_rtv->height);
-
+
/* if you un-comment the following, the region colours will follow the track colours whilst dragging,
personally, i think this can confuse things, but never mind.
*/
@@ -3358,7 +3359,7 @@ void
Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
nframes_t where;
- RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data);
+ RegionView* rvdi = reinterpret_cast<RegionView *> (drag_info.data);
pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
bool nocommit = true;
double speed;
@@ -3366,6 +3367,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
bool regionview_y_movement;
bool regionview_x_movement;
vector<RegionView*> copies;
+ list <boost::shared_ptr<Playlist > > used_playlists;
+ list <sigc::connection > used_connections;
+ bool preserve_selection = false;
/* first_move is set to false if the regionview has been moved in the
motion handler.
@@ -3404,8 +3408,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
speed = rtv->get_diskstream()->speed();
}
- regionview_x_movement = (drag_info.last_frame_position != (nframes_t) (rv->region()->position()/speed));
- regionview_y_movement = (drag_info.last_trackview != &rv->get_time_axis_view());
+ regionview_x_movement = (drag_info.last_frame_position != (nframes_t) (rvdi->region()->position()/speed));
+ regionview_y_movement = (drag_info.last_trackview != &rvdi->get_time_axis_view());
//printf ("last_frame: %s position is %lu %g\n", rv->get_time_axis_view().name().c_str(), drag_info.last_frame_position, speed);
//printf ("last_rackview: %s \n", drag_info.last_trackview->name().c_str());
@@ -3432,64 +3436,82 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* moved to a different audio track. */
- vector<RegionView*> new_selection;
-
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) {
- RegionView* rv = (*i);
+ RegionView* rv = (*i);
double ix1, ix2, iy1, iy2;
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_group()->i2w (ix1, iy1);
- TimeAxisView* tvp2 = trackview_by_y_position (iy1);
- RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(tvp2);
- boost::shared_ptr<Playlist> from_playlist = rv->region()->playlist();
+ RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(trackview_by_y_position (iy1));
+
boost::shared_ptr<Playlist> to_playlist = rtv2->playlist();
+ if (! to_playlist->frozen()) {
+ /*
+ we haven't seen this playlist before.
+ we want to freeze it because we don't want to relayer per-region.
+ its much better to do that just once if the playlist is large.
+ */
+
+ /*
+ connect so the selection is changed when the new regionview finally appears (after thaw).
+ keep track of it so we can disconnect later.
+ */
+
+ sigc::connection c = rtv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_and_select_new_region_view));
+ used_connections.push_back (c);
+
+ /* undo */
+ session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
+
+ /* remember used playlists so we can thaw them later */
+ used_playlists.push_back(to_playlist);
+ to_playlist->freeze();
+ }
+
where = (nframes_t) (unit_to_frame (ix1) * speed);
boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region()));
- /* undo the previous hide_dependent_views so that xfades don't
- disappear on copying regions
- */
+ if (!drag_info.copy) {
- rv->get_time_axis_view().reveal_dependent_views (*rv);
- if (!drag_info.copy) {
-
/* the region that used to be in the old playlist is not
moved to the new one - we make a copy of it. as a result,
any existing editor for the region should no longer be
visible.
*/
-
+
+ RouteTimeAxisView* from_playlist_rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_trackview());
+ boost::shared_ptr<Playlist> from_playlist = from_playlist_rtv->playlist();
+
+ if (! from_playlist->frozen()) {
+ from_playlist->freeze();
+ used_playlists.push_back(from_playlist);
+
+ sigc::connection c = rtv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_and_select_new_region_view));
+ used_connections.push_back (c);
+
+ session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
+ }
+
rv->hide_region_editor();
rv->fake_set_opaque (false);
- session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
from_playlist->remove_region ((rv->region()));
- session->add_command (new MementoCommand<Playlist>(*from_playlist, 0, &from_playlist->get_state()));
} else {
/* the regionview we dragged around is a temporary copy, queue it for deletion */
-
+
copies.push_back (rv);
}
latest_regionview = 0;
-
- sigc::connection c = rtv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
- session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
+
to_playlist->add_region (new_region, where);
- session->add_command (new MementoCommand<Playlist>(*to_playlist, 0, &to_playlist->get_state()));
- c.disconnect ();
-
- if (latest_regionview) {
- new_selection.push_back (latest_regionview);
- }
/* OK, this is where it gets tricky. If the playlist was being used by >1 tracks, and the region
was selected in all of them, then removing it from the playlist will have removed all
@@ -3506,6 +3528,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
EXCEPT .... if we are doing a copy drag, then the selection hasn't been modified and
we can just iterate.
+
*/
if (drag_info.copy) {
@@ -3514,12 +3537,15 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
if (selection->regions.empty()) {
break;
} else {
- i = selection->regions.by_layer().begin();
+ /*
+ XXX see above .. but we just froze the playlists.. we have to keep iterating, right?
+ */
+
+ //i = selection->regions.by_layer().begin();
+ ++i;
}
}
- }
-
- selection->set (new_selection);
+ }
} else {
@@ -3527,13 +3553,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
list<RegionView*> regions = selection->regions.by_layer();
- if (drag_info.copy) {
- selection->clear_regions();
- }
-
for (list<RegionView*>::iterator i = regions.begin(); i != regions.end(); ++i) {
- rv = (*i);
+ RegionView* rv = (*i);
+ boost::shared_ptr<Playlist> to_playlist = (*i)->region()->playlist();
+ RouteTimeAxisView* from_rtv = dynamic_cast<RouteTimeAxisView*> (&(rv->get_time_axis_view()));
if (!rv->region()->can_move()) {
continue;
@@ -3541,10 +3565,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
if (regionview_x_movement) {
double ownspeed = 1.0;
- rtv = dynamic_cast<RouteTimeAxisView*> (&(rv->get_time_axis_view()));
- if (rtv && rtv->get_diskstream()) {
- ownspeed = rtv->get_diskstream()->speed();
+ if (from_rtv && from_rtv->get_diskstream()) {
+ ownspeed = from_rtv->get_diskstream()->speed();
}
/* base the new region position on the current position of the regionview.*/
@@ -3560,13 +3583,16 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
where = rv->region()->position();
}
- boost::shared_ptr<Playlist> to_playlist = rv->region()->playlist();
+ if (! to_playlist->frozen()) {
+ sigc::connection c = from_rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_and_select_new_region_view));
+ used_connections.push_back (c);
- assert (to_playlist);
+ /* add the undo */
+ session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
- /* add the undo */
-
- session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
+ used_playlists.push_back(to_playlist);
+ to_playlist->freeze();
+ }
if (drag_info.copy) {
@@ -3582,36 +3608,42 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* add it */
- latest_regionview = 0;
- sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
- to_playlist->add_region (newregion, (nframes_t) (where * rtv->get_diskstream()->speed()));
- c.disconnect ();
-
- if (latest_regionview) {
- rtv->reveal_dependent_views (*latest_regionview);
- selection->add (latest_regionview);
- }
+ to_playlist->add_region (newregion, (nframes_t) (where * from_rtv->get_diskstream()->speed()));
/* if the original region was locked, we don't care for the new one */
- newregion->set_locked (false);
+ newregion->set_locked (false);
+ copies.push_back (rv);
} else {
/* just change the model */
rv->region()->set_position (where, (void*) this);
+ preserve_selection = true;
}
- /* add the redo */
+ }
- session->add_command (new MementoCommand<Playlist>(*to_playlist, 0, &to_playlist->get_state()));
+ }
+ if (! preserve_selection) {
+ //selection->clear_regions();
+ }
+ while (used_playlists.size() > 0) {
- if (drag_info.copy) {
- copies.push_back (rv);
- }
+ list <boost::shared_ptr<Playlist > >::iterator i = used_playlists.begin();
+ (*i)->thaw();
+
+ if (used_connections.size()) {
+ sigc::connection c = used_connections.front();
+ c.disconnect();
+ used_connections.pop_front();
}
+ /* add the redo */
+
+ session->add_command (new MementoCommand<Playlist>(*(*i), 0, &(*i)->get_state()));
+ used_playlists.pop_front();
}
out:
@@ -3839,6 +3871,13 @@ Editor::collect_new_region_view (RegionView* rv)
}
void
+Editor::collect_and_select_new_region_view (RegionView* rv)
+{
+ selection->add(rv);
+ latest_regionview = rv;
+}
+
+void
Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
{
if (clicked_regionview == 0) {
@@ -3892,7 +3931,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
/* we need to deselect all other regionviews, and select this one
i'm ignoring undo stuff, because the region creation will take care of it */
- selection->set (latest_regionview);
+ //selection->set (latest_regionview);
drag_info.item = latest_regionview->get_canvas_group();
drag_info.data = latest_regionview;
@@ -4245,6 +4284,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
+ pl->freeze();
}
}
}
@@ -4434,7 +4474,7 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
for (set<boost::shared_ptr<Playlist> >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
- //(*p)->thaw ();
+ (*p)->thaw ();
session->add_command (new MementoCommand<Playlist>(*(*p).get(), 0, &(*p)->get_state()));
}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index ca2d7039ad..2cc30aee17 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -117,6 +117,8 @@ Editor::split_region_at (nframes_t where)
void
Editor::split_regions_at (nframes_t where, RegionSelection& regions)
{
+ list <boost::shared_ptr<Playlist > > used_playlists;
+
begin_reversible_command (_("split"));
// if splitting a single region, and snap-to is using
@@ -135,15 +137,19 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
snap_to (where);
}
- for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
- RegionSelection::iterator tmp;
-
- tmp = a;
- ++tmp;
+ for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ++a) {
boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
+ if (! pl->frozen()) {
+ /* we haven't seen this playlist before */
+
+ /* remember used playlists so we can thaw them later */
+ used_playlists.push_back(pl);
+ pl->freeze();
+ }
+
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
if (arv)
_new_regionviews_show_envelope = arv->envelope_visible();
@@ -155,9 +161,13 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
}
- a = tmp;
- }
+ }
+ while (used_playlists.size() > 0) {
+ list <boost::shared_ptr<Playlist > >::iterator i = used_playlists.begin();
+ (*i)->thaw();
+ used_playlists.pop_front();
+ }
commit_reversible_command ();
_new_regionviews_show_envelope = false;
}
diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc
index 88ff3a0c1e..72e70955cd 100644
--- a/gtk2_ardour/editor_rulers.cc
+++ b/gtk2_ardour/editor_rulers.cc
@@ -712,13 +712,16 @@ Editor::update_ruler_visibility ()
time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars));
time_canvas_event_box.queue_resize();
-
+ compute_fixed_ruler_scale();
update_fixed_rulers();
- //update_tempo_based_rulers();
- redisplay_tempo (false);
time_canvas_event_box.show_all();
time_button_frame.show_all();
+
+ compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes_t)(canvas_width * frames_per_unit));
+ compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes_t)(canvas_width * frames_per_unit));
+
+ redisplay_tempo (false);
}
void
@@ -739,6 +742,22 @@ Editor::update_just_smpte ()
}
void
+Editor::compute_fixed_ruler_scale ()
+{
+ if (session == 0) {
+ return;
+ }
+
+ if (ruler_shown[ruler_metric_smpte]) {
+ set_smpte_ruler_scale (leftmost_frame, leftmost_frame + (canvas_width * frames_per_unit) );
+ }
+
+ if (ruler_shown[ruler_metric_minsec]) {
+ set_minsec_ruler_scale (leftmost_frame, leftmost_frame + (canvas_width * frames_per_unit) );
+ }
+}
+
+void
Editor::update_fixed_rulers ()
{
nframes_t rightmost_frame;
@@ -781,7 +800,7 @@ Editor::update_tempo_based_rulers ()
}
ruler_metrics[ruler_metric_bbt].units_per_pixel = frames_per_unit;
-
+
if (ruler_shown[ruler_metric_bbt]) {
gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_bbt_ruler), leftmost_frame, leftmost_frame+current_page_frames(),
leftmost_frame, session->current_end_frame());
@@ -814,26 +833,15 @@ Editor::_metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble u
return ruler_editor->metric_get_minsec (marks, lower, upper, maxchars);
}
-gint
-Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
+void
+Editor::set_smpte_ruler_scale (gdouble lower, gdouble upper)
{
nframes_t range;
- nframes_t pos;
nframes_t spacer;
nframes_t fr;
- SMPTE::Time smpte;
- gchar buf[16];
- gint nmarks = 0;
- gint n;
- bool show_bits = false;
- bool show_frames = false;
- bool show_seconds = false;
- bool show_minutes = false;
- bool show_hours = false;
- int mark_modulo;
if (session == 0) {
- return 0;
+ return;
}
fr = session->frame_rate();
@@ -847,93 +855,115 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
range = (nframes_t) floor (upper - lower);
if (range < (2 * session->frames_per_smpte_frame())) { /* 0 - 2 frames */
- show_bits = true;
- mark_modulo = 20;
- nmarks = 1 + (2 * Config->get_subframes_per_frame());
+ smpte_ruler_scale = smpte_show_bits;
+ smpte_mark_modulo = 20;
+ smpte_nmarks = 2 + (2 * Config->get_subframes_per_frame());
} else if (range <= (fr / 4)) { /* 2 frames - 0.250 second */
- show_frames = true;
- mark_modulo = 1;
- nmarks = 1 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_ruler_scale = smpte_show_frames;
+ smpte_mark_modulo = 1;
+ smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
} else if (range <= (fr / 2)) { /* 0.25-0.5 second */
- show_frames = true;
- mark_modulo = 2;
- nmarks = 1 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_ruler_scale = smpte_show_frames;
+ smpte_mark_modulo = 2;
+ smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
} else if (range <= fr) { /* 0.5-1 second */
- show_frames = true;
- mark_modulo = 5;
- nmarks = 1 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_ruler_scale = smpte_show_frames;
+ smpte_mark_modulo = 5;
+ smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
} else if (range <= 2 * fr) { /* 1-2 seconds */
- show_frames = true;
- mark_modulo = 10;
- nmarks = 1 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_ruler_scale = smpte_show_frames;
+ smpte_mark_modulo = 10;
+ smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
} else if (range <= 8 * fr) { /* 2-8 seconds */
- show_seconds = true;
- mark_modulo = 1;
- nmarks = 1 + (range / fr);
+ smpte_ruler_scale = smpte_show_seconds;
+ smpte_mark_modulo = 1;
+ smpte_nmarks = 2 + (range / fr);
} else if (range <= 16 * fr) { /* 8-16 seconds */
- show_seconds = true;
- mark_modulo = 2;
- nmarks = 1 + (range / fr);
+ smpte_ruler_scale = smpte_show_seconds;
+ smpte_mark_modulo = 2;
+ smpte_nmarks = 2 + (range / fr);
} else if (range <= 30 * fr) { /* 16-30 seconds */
- show_seconds = true;
- mark_modulo = 5;
- nmarks = 1 + (range / fr);
+ smpte_ruler_scale = smpte_show_seconds;
+ smpte_mark_modulo = 5;
+ smpte_nmarks = 2 + (range / fr);
} else if (range <= 60 * fr) { /* 30-60 seconds */
- show_seconds = true;
- mark_modulo = 5;
- nmarks = 1 + (range / fr);
+ smpte_ruler_scale = smpte_show_seconds;
+ smpte_mark_modulo = 5;
+ smpte_nmarks = 2 + (range / fr);
} else if (range <= 2 * 60 * fr) { /* 1-2 minutes */
- show_seconds = true;
- mark_modulo = 20;
- nmarks = 1 + (range / fr);
+ smpte_ruler_scale = smpte_show_seconds;
+ smpte_mark_modulo = 15;
+ smpte_nmarks = 2 + (range / fr);
} else if (range <= 4 * 60 * fr) { /* 2-4 minutes */
- show_seconds = true;
- mark_modulo = 30;
- nmarks = 1 + (range / fr);
+ smpte_ruler_scale = smpte_show_seconds;
+ smpte_mark_modulo = 30;
+ smpte_nmarks = 2 + (range / fr);
} else if (range <= 10 * 60 * fr) { /* 4-10 minutes */
- show_minutes = true;
- mark_modulo = 2;
- nmarks = 1 + 10;
+ smpte_ruler_scale = smpte_show_minutes;
+ smpte_mark_modulo = 2;
+ smpte_nmarks = 2 + 10;
} else if (range <= 30 * 60 * fr) { /* 10-30 minutes */
- show_minutes = true;
- mark_modulo = 5;
- nmarks = 1 + 30;
+ smpte_ruler_scale = smpte_show_minutes;
+ smpte_mark_modulo = 5;
+ smpte_nmarks = 2 + 30;
} else if (range <= 60 * 60 * fr) { /* 30 minutes - 1hr */
- show_minutes = true;
- mark_modulo = 10;
- nmarks = 1 + 60;
+ smpte_ruler_scale = smpte_show_minutes;
+ smpte_mark_modulo = 10;
+ smpte_nmarks = 2 + 60;
} else if (range <= 4 * 60 * 60 * fr) { /* 1 - 4 hrs*/
- show_minutes = true;
- mark_modulo = 30;
- nmarks = 1 + (60 * 4);
+ smpte_ruler_scale = smpte_show_minutes;
+ smpte_mark_modulo = 30;
+ smpte_nmarks = 2 + (60 * 4);
} else if (range <= 8 * 60 * 60 * fr) { /* 4 - 8 hrs*/
- show_hours = true;
- mark_modulo = 1;
- nmarks = 1 + 8;
+ smpte_ruler_scale = smpte_show_hours;
+ smpte_mark_modulo = 1;
+ smpte_nmarks = 2 + 8;
} else if (range <= 16 * 60 * 60 * fr) { /* 16-24 hrs*/
- show_hours = true;
- mark_modulo = 1;
- nmarks = 1 + 24;
+ smpte_ruler_scale = smpte_show_hours;
+ smpte_mark_modulo = 1;
+ smpte_nmarks = 2 + 24;
} else {
/* not possible if nframes_t is a 32 bit quantity */
- show_hours = true;
- mark_modulo = 4;
- nmarks = 1 + 24;
+ smpte_ruler_scale = smpte_show_hours;
+ smpte_mark_modulo = 4;
+ smpte_nmarks = 2 + 24;
}
+}
+
+gint
+Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
+{
+ nframes_t pos;
+ nframes_t spacer;
+ SMPTE::Time smpte;
+ gchar buf[16];
+ gint n;
+
+ if (session == 0) {
+ return 0;
+ }
+
+ if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+ lower = lower - spacer;
+ } else {
+ lower = 0;
+ }
+
pos = (nframes_t) floor (lower);
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
-
- if (show_bits) {
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * smpte_nmarks);
+ switch (smpte_ruler_scale) {
+ case smpte_show_bits:
+
// Find smpte time of this sample (pos) with subframe accuracy
session->sample_to_smpte(pos, smpte, true /* use_offset */, true /* use_subframes */ );
- for (n = 0; n < nmarks; n++) {
+ for (n = 0; n < smpte_nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, true /* use_subframes */ );
- if ((smpte.subframes % mark_modulo) == 0) {
+ if ((smpte.subframes % smpte_mark_modulo) == 0) {
if (smpte.subframes == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", smpte.negative ? "-" : "", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
@@ -952,15 +982,16 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
// Increment subframes by one
SMPTE::increment_subframes( smpte );
}
- } else if (show_seconds) {
+ break;
+ case smpte_show_seconds:
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole second down
SMPTE::seconds_floor( smpte );
- for (n = 0; n < nmarks; n++) {
+ for (n = 0; n < smpte_nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
- if ((smpte.seconds % mark_modulo) == 0) {
+ if ((smpte.seconds % smpte_mark_modulo) == 0) {
if (smpte.seconds == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
(*marks)[n].position = pos;
@@ -978,15 +1009,16 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
(*marks)[n].label = g_strdup (buf);
SMPTE::increment_seconds( smpte );
}
- } else if (show_minutes) {
+ break;
+ case smpte_show_minutes:
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole minute down
SMPTE::minutes_floor( smpte );
- for (n = 0; n < nmarks; n++) {
+ for (n = 0; n < smpte_nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
- if ((smpte.minutes % mark_modulo) == 0) {
+ if ((smpte.minutes % smpte_mark_modulo) == 0) {
if (smpte.minutes == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
} else {
@@ -1002,15 +1034,17 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
(*marks)[n].position = pos;
SMPTE::increment_minutes( smpte );
}
- } else if (show_hours) {
+
+ break;
+ case smpte_show_hours:
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole hour down
SMPTE::hours_floor( smpte );
- for (n = 0; n < nmarks; n++) {
+ for (n = 0; n < smpte_nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
- if ((smpte.hours % mark_modulo) == 0) {
+ if ((smpte.hours % smpte_mark_modulo) == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", smpte.negative ? "-" : "", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
} else {
@@ -1023,16 +1057,21 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
SMPTE::increment_hours( smpte );
}
- } else { // show_frames
+ break;
+ case smpte_show_frames:
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole frame down
SMPTE::frames_floor( smpte );
- for (n = 0; n < nmarks; n++) {
+ for (n = 0; n < smpte_nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
- if ((smpte.frames % mark_modulo) == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ if ((smpte.frames % smpte_mark_modulo) == 0) {
+ if (smpte.frames == 0) {
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ }
(*marks)[n].position = pos;
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", smpte.negative ? "-" : "", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
} else {
@@ -1044,40 +1083,34 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
(*marks)[n].label = g_strdup (buf);
SMPTE::increment( smpte );
}
+
+ break;
}
- return nmarks;
+ return smpte_nmarks;
}
-gint
-Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
+void
+Editor::compute_bbt_ruler_scale (nframes_t lower, nframes_t upper)
{
if (session == 0) {
- return 0;
+ return;
}
-
TempoMap::BBTPointList::iterator i;
+ BBT_Time lower_beat, upper_beat; // the beats at each end of the ruler
+ session->bbt_time((jack_nframes_t) lower, lower_beat);
+ session->bbt_time((jack_nframes_t) upper, upper_beat);
uint32_t beats = 0;
- uint32_t bars = 0;
- uint32_t desirable_marks;
- uint32_t magic_accent_number = 1;
- gint nmarks;
- char buf[64];
- gint n = 0;
- nframes_t pos;
- bool bar_helper_on = true;
-
- BBT_Time next_beat;
- nframes_t next_beat_pos;
-
- if ((desirable_marks = maxchars / 7) == 0) {
- return 0;
- }
- /* align the tick marks to whatever we're snapping to... */
+ bbt_accent_modulo = 1;
+ bbt_bar_helper_on = false;
+ bbt_bars = 0;
+ bbt_nmarks = 1;
+ bbt_ruler_scale = bbt_over;
+
switch (snap_type) {
case SnapToAThirdBeat:
bbt_beat_subdivision = 3;
@@ -1087,180 +1120,432 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
break;
case SnapToAEighthBeat:
bbt_beat_subdivision = 8;
- magic_accent_number = 2;
+ bbt_accent_modulo = 2;
break;
case SnapToASixteenthBeat:
bbt_beat_subdivision = 16;
- magic_accent_number = 4;
+ bbt_accent_modulo = 4;
break;
case SnapToAThirtysecondBeat:
bbt_beat_subdivision = 32;
- magic_accent_number = 8;
+ bbt_accent_modulo = 8;
break;
default:
- bbt_beat_subdivision = 4;
+ bbt_beat_subdivision = 4;
break;
}
if (current_bbt_points == 0 || current_bbt_points->empty()) {
- return 0;
+ return;
}
i = current_bbt_points->end();
i--;
- bars = (*i).bar - (*current_bbt_points->begin()).bar;
- beats = current_bbt_points->size() - bars;
+ if ((*i).beat >= (*current_bbt_points->begin()).beat) {
+ bbt_bars = (*i).bar - (*current_bbt_points->begin()).bar;
+ } else {
+ bbt_bars = (*i).bar - (*current_bbt_points->begin()).bar - 1;
+ }
+ beats = current_bbt_points->size() - bbt_bars;
/*Only show the bar helper if there aren't many bars on the screen */
- if (bars > 1) {
- bar_helper_on = false;
+ if ((bbt_bars < 2) || (beats < 5)) {
+ bbt_bar_helper_on = true;
}
- if (desirable_marks > (beats / 4)) {
+ if (bbt_bars > 8192) {
+ bbt_ruler_scale = bbt_over;
+ } else if (bbt_bars > 1024) {
+ bbt_ruler_scale = bbt_show_64;
+ } else if (bbt_bars > 256) {
+ bbt_ruler_scale = bbt_show_16;
+ } else if (bbt_bars > 64) {
+ bbt_ruler_scale = bbt_show_4;
+ } else if (bbt_bars > 10) {
+ bbt_ruler_scale = bbt_show_1;
+ } else if (bbt_bars > 2) {
+ bbt_ruler_scale = bbt_show_beats;
+ } else if (bbt_bars > 0) {
+ bbt_ruler_scale = bbt_show_ticks;
+ } else {
+ bbt_ruler_scale = bbt_show_ticks_detail;
+ }
- /* we're in beat land...*/
+ if ((bbt_ruler_scale == bbt_show_ticks_detail) && (lower_beat.beats == upper_beat.beats) && (upper_beat.ticks - lower_beat.ticks <= Meter::ticks_per_beat / 4)) {
+ bbt_ruler_scale = bbt_show_ticks_super_detail;
+ }
+}
- uint32_t tick = 0;
- uint32_t skip;
- uint32_t t;
- nframes_t frame_skip;
- double frame_skip_error;
- double accumulated_error;
- double position_of_helper;
- bool i_am_accented = false;
- bool we_need_ticks = false;
- bool helper_active = false;
-
- position_of_helper = lower + (30 * Editor::get_current_zoom ());
+gint
+Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
+{
+ if (session == 0) {
+ return 0;
+ }
- if (desirable_marks >= (beats)) {
- nmarks = (beats * bbt_beat_subdivision) + 1;
- we_need_ticks = true;
- } else {
- nmarks = beats + 1;
+ TempoMap::BBTPointList::iterator i;
+
+ char buf[64];
+ gint n = 0;
+ nframes_t pos;
+ BBT_Time next_beat;
+ nframes_t next_beat_pos;
+ uint32_t beats = 0;
+
+ uint32_t tick = 0;
+ uint32_t skip;
+ uint32_t t;
+ nframes_t frame_skip;
+ double frame_skip_error;
+ double bbt_position_of_helper;
+ double accumulated_error;
+ bool i_am_accented = false;
+ bool helper_active = false;
+
+ if (current_bbt_points == 0 || current_bbt_points->empty()) {
+ return 0;
+ }
+
+ switch (bbt_ruler_scale) {
+
+ case bbt_show_beats:
+ beats = current_bbt_points->size();
+ bbt_nmarks = beats + 2;
+
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+
+ (*marks)[0].label = g_strdup(" ");
+ (*marks)[0].position = lower;
+ (*marks)[0].style = GtkCustomRulerMarkMicro;
+
+ for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) {
+ if ((*i).type != TempoMap::Beat) {
+ continue;
+ }
+ if ((*i).frame < lower && (bbt_bar_helper_on)) {
+ snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
+ (*marks)[0].label = g_strdup (buf);
+ helper_active = true;
+ } else {
+
+ if ((*i).beat == 1) {
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+ } else if (((*i).beat % 2 == 1)) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ snprintf (buf, sizeof(buf), " ");
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
+ snprintf (buf, sizeof(buf), " ");
+ }
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
}
+ break;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
+ case bbt_show_ticks:
+
+ beats = current_bbt_points->size();
+ bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
+
+ bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
(*marks)[0].label = g_strdup(" ");
(*marks)[0].position = lower;
(*marks)[0].style = GtkCustomRulerMarkMicro;
- for (n = 1, i = current_bbt_points->begin(); n < nmarks && i != current_bbt_points->end(); ++i) {
+ for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) {
+ if ((*i).type != TempoMap::Beat) {
+ continue;
+ }
+ if ((*i).frame < lower && (bbt_bar_helper_on)) {
+ snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
+ (*marks)[0].label = g_strdup (buf);
+ helper_active = true;
+ } else {
- if ((*i).frame < lower && (bar_helper_on)) {
- snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
- (*marks)[0].label = g_strdup (buf);
- helper_active = true;
+ if ((*i).beat == 1) {
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
+ }
+ if (((*i).frame < bbt_position_of_helper) && helper_active) {
+ snprintf (buf, sizeof(buf), " ");
+ }
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
+
+ /* Add the tick marks */
+
+ /* Find the next beat */
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+ next_beat.ticks = 0;
+
+ if ((*i).meter->beats_per_bar() > (next_beat.beats + 1)) {
+ next_beat.beats += 1;
} else {
+ next_beat.bars += 1;
+ next_beat.beats = 1;
+ }
+
+ next_beat_pos = session->tempo_map().frame_time(next_beat);
+
+ frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+ frame_skip_error -= frame_skip;
+ skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
- if ((*i).type == TempoMap::Bar) {
- if (((*i).frame < position_of_helper) && helper_active) {
- snprintf (buf, sizeof(buf), " ");
- } else {
- snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- }
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- n++;
-
- } else if (((*i).type == TempoMap::Beat) && ((*i).beat > 1)) {
- ((((*i).frame < position_of_helper) && bar_helper_on) || !we_need_ticks) ?
- snprintf (buf, sizeof(buf), " ") : snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
- if (((*i).beat % 2 == 1) || we_need_ticks) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
- }
+ pos = (*i).frame + frame_skip;
+ accumulated_error = frame_skip_error;
+
+ tick = skip;
+
+ for (t = 0; (tick < Meter::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+
+ if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
+ i_am_accented = true;
+ }
+
+ snprintf (buf, sizeof(buf), " ");
+ (*marks)[n].label = g_strdup (buf);
+ /* Error compensation for float to nframes_t*/
+ accumulated_error += frame_skip_error;
+ if (accumulated_error > 1) {
+ pos += 1;
+ accumulated_error -= 1.0f;
+ }
+
+ (*marks)[n].position = pos;
+
+ if ((bbt_beat_subdivision > 4) && i_am_accented) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
+ }
+ i_am_accented = false;
+ n++;
}
+ }
+ break;
- /* Add the tick marks */
+ case bbt_show_ticks_detail:
- if (we_need_ticks && (*i).type == TempoMap::Beat) {
+ beats = current_bbt_points->size();
+ bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
- /* Find the next beat */
+ bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
- next_beat.beats = (*i).beat;
- next_beat.bars = (*i).bar;
+ (*marks)[0].label = g_strdup(" ");
+ (*marks)[0].position = lower;
+ (*marks)[0].style = GtkCustomRulerMarkMicro;
+
+ for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) {
+ if ((*i).type != TempoMap::Beat) {
+ continue;
+ }
+ if ((*i).frame < lower && (bbt_bar_helper_on)) {
+ snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
+ (*marks)[0].label = g_strdup (buf);
+ helper_active = true;
+ } else {
- if ((*i).meter->beats_per_bar() > (next_beat.beats + 1)) {
- next_beat.beats += 1;
+ if ((*i).beat == 1) {
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
} else {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
+ }
+ if (((*i).frame < bbt_position_of_helper) && helper_active) {
+ snprintf (buf, sizeof(buf), " ");
+ }
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
+
+ /* Add the tick marks */
+
+ /* Find the next beat */
+
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+
+ if ((*i).meter->beats_per_bar() > (next_beat.beats + 1)) {
+ next_beat.beats += 1;
+ } else {
next_beat.bars += 1;
next_beat.beats = 1;
- }
+ }
- next_beat_pos = session->tempo_map().frame_time(next_beat);
+ next_beat_pos = session->tempo_map().frame_time(next_beat);
+
+ frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+ frame_skip_error -= frame_skip;
+ skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
- frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
- frame_skip_error -= frame_skip;
- skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
+ pos = (*i).frame + frame_skip;
+ accumulated_error = frame_skip_error;
- pos = (*i).frame + frame_skip;
- accumulated_error = frame_skip_error;
+ tick = skip;
+
+ for (t = 0; (tick < Meter::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
- tick = skip;
-
- for (t = 0; (tick < Meter::ticks_per_beat) && (n < nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+ if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
+ i_am_accented = true;
+ }
- if (t % magic_accent_number == (magic_accent_number - 1)) {
- i_am_accented = true;
- }
- if (Editor::get_current_zoom () > 32) {
- snprintf (buf, sizeof(buf), " ");
- } else if ((Editor::get_current_zoom () > 8) && !i_am_accented) {
- snprintf (buf, sizeof(buf), " ");
- } else if (bar_helper_on && (pos < position_of_helper)) {
- snprintf (buf, sizeof(buf), " ");
- } else {
- snprintf (buf, sizeof(buf), "%" PRIu32, tick);
- }
+ if (i_am_accented && (pos > bbt_position_of_helper)){
+ snprintf (buf, sizeof(buf), "%" PRIu32, tick);
+ } else {
+ snprintf (buf, sizeof(buf), " ");
+ }
- (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].label = g_strdup (buf);
- /* Error compensation for float to nframes_t*/
- accumulated_error += frame_skip_error;
- if (accumulated_error > 1) {
- pos += 1;
- accumulated_error -= 1.0f;
- }
+ /* Error compensation for float to nframes_t*/
+ accumulated_error += frame_skip_error;
+ if (accumulated_error > 1) {
+ pos += 1;
+ accumulated_error -= 1.0f;
+ }
- (*marks)[n].position = pos;
+ (*marks)[n].position = pos;
- if ((bbt_beat_subdivision > 4) && i_am_accented) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
- i_am_accented = false;
- n++;
-
+ if ((bbt_beat_subdivision > 4) && i_am_accented) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
}
+ i_am_accented = false;
+ n++;
}
}
- return n; //return the actual number of marks made, since we might have skipped some fro fractional time signatures
- } else {
+ break;
+
+ case bbt_show_ticks_super_detail:
- /* we're in bar land */
+ beats = current_bbt_points->size();
+ bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
- if (desirable_marks < (bars / 256)) {
- nmarks = 1;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
- snprintf (buf, sizeof(buf), "too many bars... (currently %" PRIu32 ")", bars );
+ bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+
+ (*marks)[0].label = g_strdup(" ");
+ (*marks)[0].position = lower;
+ (*marks)[0].style = GtkCustomRulerMarkMicro;
+
+ for (n = 1, i = current_bbt_points->begin(); n < bbt_nmarks && i != current_bbt_points->end(); ++i) {
+ if ((*i).type != TempoMap::Beat) {
+ continue;
+ }
+ if ((*i).frame < lower && (bbt_bar_helper_on)) {
+ snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
+ (*marks)[0].label = g_strdup (buf);
+ helper_active = true;
+ } else {
+
+ if ((*i).beat == 1) {
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
+ }
+ if (((*i).frame < bbt_position_of_helper) && helper_active) {
+ snprintf (buf, sizeof(buf), " ");
+ }
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
+
+ /* Add the tick marks */
+
+ /* Find the next beat */
+
+ next_beat.beats = (*i).beat;
+ next_beat.bars = (*i).bar;
+
+ if ((*i).meter->beats_per_bar() > (next_beat.beats + 1)) {
+ next_beat.beats += 1;
+ } else {
+ next_beat.bars += 1;
+ next_beat.beats = 1;
+ }
+
+ next_beat_pos = session->tempo_map().frame_time(next_beat);
+
+ frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+ frame_skip_error -= frame_skip;
+ skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
+
+ pos = (*i).frame + frame_skip;
+ accumulated_error = frame_skip_error;
+
+ tick = skip;
+
+ for (t = 0; (tick < Meter::ticks_per_beat) && (n < bbt_nmarks) && (pos < next_beat_pos) ; pos += frame_skip, tick += skip, ++t) {
+
+ if (t % bbt_accent_modulo == (bbt_accent_modulo - 1)) {
+ i_am_accented = true;
+ }
+
+ if (pos > bbt_position_of_helper) {
+ snprintf (buf, sizeof(buf), "%" PRIu32, tick);
+ } else {
+ snprintf (buf, sizeof(buf), " ");
+ }
+
+ (*marks)[n].label = g_strdup (buf);
+
+ /* Error compensation for float to nframes_t*/
+ accumulated_error += frame_skip_error;
+ if (accumulated_error > 1) {
+ pos += 1;
+ accumulated_error -= 1.0f;
+ }
+
+ (*marks)[n].position = pos;
+
+ if ((bbt_beat_subdivision > 4) && i_am_accented) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
+ }
+ i_am_accented = false;
+ n++;
+ }
+ }
+
+ break;
+
+ case bbt_over:
+ bbt_nmarks = 1;
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+ snprintf (buf, sizeof(buf), "cannot handle %" PRIu32 " bars", bbt_bars );
(*marks)[0].style = GtkCustomRulerMarkMajor;
(*marks)[0].label = g_strdup (buf);
(*marks)[0].position = lower;
- } else if (desirable_marks < (uint32_t)(nmarks = (gint) (bars / 64) + 1)) {
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
- for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; i++) {
+ n = 1;
+
+ break;
+
+ case bbt_show_64:
+ bbt_nmarks = (gint) (bbt_bars / 64) + 1;
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+ for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; i++) {
if ((*i).type == TempoMap::Bar) {
if ((*i).bar % 64 == 1) {
if ((*i).bar % 256 == 1) {
@@ -1280,74 +1565,87 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
}
}
}
- } else if (desirable_marks < (uint32_t)(nmarks = (bars / 16) + 1)) {
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
- for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; i++) {
- if ((*i).type == TempoMap::Bar) {
- if ((*i).bar % 16 == 1) {
- if ((*i).bar % 64 == 1) {
- snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- } else {
- snprintf (buf, sizeof(buf), " ");
- if ((*i).bar % 64 == 33) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
- }
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
+ break;
+
+ case bbt_show_16:
+ bbt_nmarks = (bbt_bars / 16) + 1;
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+ for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; i++) {
+ if ((*i).type == TempoMap::Bar) {
+ if ((*i).bar % 16 == 1) {
+ if ((*i).bar % 64 == 1) {
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ } else {
+ snprintf (buf, sizeof(buf), " ");
+ if ((*i).bar % 64 == 33) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
}
}
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
}
- } else if (desirable_marks < (uint32_t)(nmarks = (bars / 4) + 1)){
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
- for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; ++i) {
- if ((*i).type == TempoMap::Bar) {
- if ((*i).bar % 4 == 1) {
- if ((*i).bar % 16 == 1) {
- snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- } else {
- snprintf (buf, sizeof(buf), " ");
- if ((*i).bar % 16 == 9) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
- }
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
+ }
+ break;
+
+ case bbt_show_4:
+ bbt_nmarks = (bbt_bars / 4) + 1;
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+ for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; ++i) {
+ if ((*i).type == TempoMap::Bar) {
+ if ((*i).bar % 4 == 1) {
+ if ((*i).bar % 16 == 1) {
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ } else {
+ snprintf (buf, sizeof(buf), " ");
+ if ((*i).bar % 16 == 9) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
}
}
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
}
- } else {
- nmarks = bars + 1;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks );
- for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; i++) {
- if ((*i).type == TempoMap::Bar) {
- if ((*i).bar % 4 == 1) {
- snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- } else {
- snprintf (buf, sizeof(buf), " ");
- if ((*i).bar % 4 == 3) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
- }
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
- }
- }
- }
- return n;
+ }
+ break;
+
+ case bbt_show_1:
+ // default:
+ bbt_nmarks = bbt_bars + 2;
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks );
+ for (n = 0, i = current_bbt_points->begin(); i != current_bbt_points->end() && n < bbt_nmarks; i++) {
+ if ((*i).type == TempoMap::Bar) {
+ if ((*i).bar % 4 == 1) {
+ snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+ (*marks)[n].style = GtkCustomRulerMarkMajor;
+ } else {
+ snprintf (buf, sizeof(buf), " ");
+ if ((*i).bar % 4 == 3) {
+ (*marks)[n].style = GtkCustomRulerMarkMinor;
+ } else {
+ (*marks)[n].style = GtkCustomRulerMarkMicro;
+ }
+ }
+ (*marks)[n].label = g_strdup (buf);
+ (*marks)[n].position = (*i).frame;
+ n++;
+ }
+ }
+
+ break;
+
}
+
+ return n; //return the actual number of marks made, since we might have skipped some from fractional time signatures
+
}
gint
@@ -1415,117 +1713,132 @@ sample_to_clock_parts ( nframes_t sample,
return;
}
-gint
-Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
+void
+Editor::set_minsec_ruler_scale (gdouble lower, gdouble upper)
{
nframes_t range;
nframes_t fr;
- nframes_t mark_interval;
- nframes_t pos;
nframes_t spacer;
- long hrs, mins, secs, millisecs;
- gchar buf[16];
- gint nmarks;
- gint n;
- gint mark_modulo = 100;
- bool show_seconds = false;
- bool show_minutes = false;
- bool show_hours = false;
- nframes_t ilower = (nframes_t) floor (lower);
- nframes_t iupper = (nframes_t) floor (upper);
if (session == 0) {
- return 0;
+ return;
}
fr = session->frame_rate();
/* to prevent 'flashing' */
if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
- lower = lower - spacer;
+ lower -= spacer;
} else {
lower = 0;
}
- upper = upper + spacer;
- range = iupper - ilower;
+ upper += spacer;
+ range = (nframes_t) (upper - lower);
if (range < (fr / 50)) {
- mark_interval = fr / 100; /* show 1/100 seconds */
- mark_modulo = 10;
+ minsec_mark_interval = fr / 1000; /* show 1/1000 seconds */
+ minsec_ruler_scale = minsec_show_frames;
+ minsec_mark_modulo = 10;
} else if (range <= (fr / 10)) { /* 0-0.1 second */
- mark_interval = fr / 50; /* show 1/50 seconds */
- mark_modulo = 20;
+ minsec_mark_interval = fr / 1000; /* show 1/1000 seconds */
+ minsec_ruler_scale = minsec_show_frames;
+ minsec_mark_modulo = 10;
} else if (range <= (fr / 2)) { /* 0-0.5 second */
- mark_interval = fr / 20; /* show 1/20 seconds */
- mark_modulo = 100;
+ minsec_mark_interval = fr / 100; /* show 1/100 seconds */
+ minsec_ruler_scale = minsec_show_frames;
+ minsec_mark_modulo = 100;
} else if (range <= fr) { /* 0-1 second */
- mark_interval = fr / 10; /* show 1/10 seconds */
- mark_modulo = 200;
+ minsec_mark_interval = fr / 10; /* show 1/10 seconds */
+ minsec_ruler_scale = minsec_show_frames;
+ minsec_mark_modulo = 200;
} else if (range <= 2 * fr) { /* 1-2 seconds */
- mark_interval = fr / 2; /* show 1/2 seconds */
- mark_modulo = 500;
+ minsec_mark_interval = fr / 10; /* show 1/10 seconds */
+ minsec_ruler_scale = minsec_show_frames;
+ minsec_mark_modulo = 500;
} else if (range <= 8 * fr) { /* 2-5 seconds */
- mark_interval = fr / 5; /* show 2 seconds */
- mark_modulo = 1000;
+ minsec_mark_interval = fr / 5; /* show 2 seconds */
+ minsec_ruler_scale = minsec_show_frames;
+ minsec_mark_modulo = 1000;
} else if (range <= 16 * fr) { /* 8-16 seconds */
- mark_interval = fr; /* show 1 seconds */
- show_seconds = true;
- mark_modulo = 5;
+ minsec_mark_interval = fr; /* show 1 seconds */
+ minsec_ruler_scale = minsec_show_seconds;
+ minsec_mark_modulo = 2;
} else if (range <= 30 * fr) { /* 10-30 seconds */
- mark_interval = fr; /* show 10 seconds */
- show_seconds = true;
- mark_modulo = 5;
+ minsec_mark_interval = fr; /* show 1 seconds */
+ minsec_ruler_scale = minsec_show_seconds;
+ minsec_mark_modulo = 5;
} else if (range <= 60 * fr) { /* 30-60 seconds */
- mark_interval = 5 * fr; /* show 5 seconds */
- show_seconds = true;
- mark_modulo = 3;
+ minsec_mark_interval = fr; /* show 1 seconds */
+ minsec_ruler_scale = minsec_show_seconds;
+ minsec_mark_modulo = 5;
} else if (range <= 2 * 60 * fr) { /* 1-2 minutes */
- mark_interval = 5 * fr; /* show 5 seconds */
- show_seconds = true;
- mark_modulo = 3;
+ minsec_mark_interval = 5 * fr; /* show 5 seconds */
+ minsec_ruler_scale = minsec_show_seconds;
+ minsec_mark_modulo = 3;
} else if (range <= 4 * 60 * fr) { /* 4 minutes */
- mark_interval = 10 * fr; /* show 10 seconds */
- show_seconds = true;
- mark_modulo = 30;
+ minsec_mark_interval = 5 * fr; /* show 10 seconds */
+ minsec_ruler_scale = minsec_show_seconds;
+ minsec_mark_modulo = 30;
} else if (range <= 10 * 60 * fr) { /* 10 minutes */
- mark_interval = 30 * fr; /* show 30 seconds */
- show_seconds = true;
- mark_modulo = 60;
+ minsec_mark_interval = 30 * fr; /* show 30 seconds */
+ minsec_ruler_scale = minsec_show_seconds;
+ minsec_mark_modulo = 120;
} else if (range <= 30 * 60 * fr) { /* 10-30 minutes */
- mark_interval = 60 * fr; /* show 1 minute */
- show_minutes = true;
- mark_modulo = 5;
+ minsec_mark_interval = 60 * fr; /* show 1 minute */
+ minsec_ruler_scale = minsec_show_minutes;
+ minsec_mark_modulo = 5;
} else if (range <= 60 * 60 * fr) { /* 30 minutes - 1hr */
- mark_interval = 2 * 60 * fr; /* show 2 minutes */
- show_minutes = true;
- mark_modulo = 10;
+ minsec_mark_interval = 2 * 60 * fr; /* show 2 minutes */
+ minsec_ruler_scale = minsec_show_minutes;
+ minsec_mark_modulo = 10;
} else if (range <= 4 * 60 * 60 * fr) { /* 1 - 4 hrs*/
- mark_interval = 5 * 60 * fr; /* show 10 minutes */
- show_minutes = true;
- mark_modulo = 30;
+ minsec_mark_interval = 5 * 60 * fr; /* show 10 minutes */
+ minsec_ruler_scale = minsec_show_minutes;
+ minsec_mark_modulo = 30;
} else if (range <= 8 * 60 * 60 * fr) { /* 4 - 8 hrs*/
- mark_interval = 20 * 60 * fr; /* show 20 minutes */
- show_minutes = true;
- mark_modulo = 60;
+ minsec_mark_interval = 20 * 60 * fr; /* show 20 minutes */
+ minsec_ruler_scale = minsec_show_minutes;
+ minsec_mark_modulo = 60;
} else if (range <= 16 * 60 * 60 * fr) { /* 16-24 hrs*/
- mark_interval = 60 * 60 * fr; /* show 60 minutes */
- show_hours = true;
- mark_modulo = 2;
+ minsec_mark_interval = 60 * 60 * fr; /* show 60 minutes */
+ minsec_ruler_scale = minsec_show_hours;
+ minsec_mark_modulo = 2;
} else {
/* not possible if nframes_t is a 32 bit quantity */
- mark_interval = 4 * 60 * 60 * fr; /* show 4 hrs */
+ minsec_mark_interval = 4 * 60 * 60 * fr; /* show 4 hrs */
}
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
+}
- nmarks = 1 + (range / mark_interval);
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
- pos = ((ilower + (mark_interval/2))/mark_interval) * mark_interval;
-
- if (show_seconds) {
- for (n = 0; n < nmarks; pos += mark_interval, ++n) {
- sample_to_clock_parts (pos, fr, &hrs, &mins, &secs, &millisecs);
- if (secs % mark_modulo == 0) {
+gint
+Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
+{
+ nframes_t pos;
+ nframes_t spacer;
+ long hrs, mins, secs, millisecs;
+ gchar buf[16];
+ gint n;
+
+ if (session == 0) {
+ return 0;
+ }
+
+ /* to prevent 'flashing' */
+ if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+ lower = lower - spacer;
+ } else {
+ lower = 0;
+ }
+
+ *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * minsec_nmarks);
+ pos = ((((nframes_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
+ switch (minsec_ruler_scale) {
+ case minsec_show_seconds:
+ for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
+ sample_to_clock_parts (pos, session->frame_rate(), &hrs, &mins, &secs, &millisecs);
+ if (secs % minsec_mark_modulo == 0) {
if (secs == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
} else {
@@ -1539,10 +1852,11 @@ Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble up
(*marks)[n].label = g_strdup (buf);
(*marks)[n].position = pos;
}
- } else if (show_minutes) {
- for (n = 0; n < nmarks; pos += mark_interval, ++n) {
- sample_to_clock_parts (pos, fr, &hrs, &mins, &secs, &millisecs);
- if (mins % mark_modulo == 0) {
+ break;
+ case minsec_show_minutes:
+ for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
+ sample_to_clock_parts (pos, session->frame_rate(), &hrs, &mins, &secs, &millisecs);
+ if (mins % minsec_mark_modulo == 0) {
if (mins == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
} else {
@@ -1556,10 +1870,11 @@ Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble up
(*marks)[n].label = g_strdup (buf);
(*marks)[n].position = pos;
}
- } else if (show_hours) {
- for (n = 0; n < nmarks; pos += mark_interval, ++n) {
- sample_to_clock_parts (pos, fr, &hrs, &mins, &secs, &millisecs);
- if (hrs % mark_modulo == 0) {
+ break;
+ case minsec_show_hours:
+ for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
+ sample_to_clock_parts (pos, session->frame_rate(), &hrs, &mins, &secs, &millisecs);
+ if (hrs % minsec_mark_modulo == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld.%03ld", hrs, mins, secs, millisecs);
} else {
@@ -1569,11 +1884,12 @@ Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble up
(*marks)[n].label = g_strdup (buf);
(*marks)[n].position = pos;
}
- } else {
- for (n = 0; n < nmarks; pos += mark_interval, ++n) {
- sample_to_clock_parts (pos, fr, &hrs, &mins, &secs, &millisecs);
- if (millisecs % mark_modulo == 0) {
- if (millisecs == 0) {
+ break;
+ case minsec_show_frames:
+ for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
+ sample_to_clock_parts (pos, session->frame_rate(), &hrs, &mins, &secs, &millisecs);
+ if (millisecs % minsec_mark_modulo == 0) {
+ if (secs == 0) {
(*marks)[n].style = GtkCustomRulerMarkMajor;
} else {
(*marks)[n].style = GtkCustomRulerMarkMinor;
@@ -1586,7 +1902,8 @@ Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble up
(*marks)[n].label = g_strdup (buf);
(*marks)[n].position = pos;
}
+ break;
}
- return nmarks;
+ return minsec_nmarks;
}
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index 09133a8823..831fe3b727 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -99,27 +99,53 @@ Editor::tempo_map_changed (Change ignored)
return;
}
- ENSURE_GUI_THREAD(bind (mem_fun (*this, &Editor::tempo_map_changed), ignored));
-
- redisplay_tempo (false); // redraw rulers and measures
+ ENSURE_GUI_THREAD(bind (mem_fun (*this, &Editor::tempo_map_changed), ignored));
+
+ compute_current_bbt_points(leftmost_frame, leftmost_frame + (nframes_t)(canvas_width * frames_per_unit));
session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers
+ update_tempo_based_rulers ();
+ if (tempo_map_change_idle_handler_id < 0) {
+ tempo_map_change_idle_handler_id = Glib::signal_idle().connect (mem_fun (*this, &Editor::redraw_measures));
+ }
}
-/**
- * This code was originally in tempo_map_changed, but this is called every time the canvas scrolls horizontally.
- * That's why this is moved in here. The new tempo_map_changed is called when the ARDOUR::TempoMap actually changed.
- */
void
Editor::redisplay_tempo (bool immediate_redraw)
{
if (!session) {
return;
}
+
+ compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes_t)(canvas_width * frames_per_unit)); // redraw rulers and measures
+
+ if (immediate_redraw) {
+
+ hide_measures ();
+
+ if (current_bbt_points) {
+ draw_measures ();
+ }
+
+ } else if (tempo_map_change_idle_handler_id < 0) {
+
+ tempo_map_change_idle_handler_id = Glib::signal_idle().connect (mem_fun (*this, &Editor::redraw_measures));
+
+ }
+
+ update_tempo_based_rulers ();
+}
+
+void
+Editor::compute_current_bbt_points (nframes_t leftmost, nframes_t rightmost)
+{
+ if (!session) {
+ return;
+ }
BBT_Time previous_beat, next_beat; // the beats previous to the leftmost frame and after the rightmost frame
- session->bbt_time(leftmost_frame, previous_beat);
- session->bbt_time(leftmost_frame + current_page_frames(), next_beat);
+ session->bbt_time(leftmost, previous_beat);
+ session->bbt_time(rightmost, next_beat);
if (previous_beat.beats > 1) {
previous_beat.beats -= 1;
@@ -129,7 +155,7 @@ Editor::redisplay_tempo (bool immediate_redraw)
}
previous_beat.ticks = 0;
- if (session->tempo_map().meter_at(leftmost_frame + current_page_frames()).beats_per_bar () > next_beat.beats + 1) {
+ if (session->tempo_map().meter_at(rightmost).beats_per_bar () > next_beat.beats + 1) {
next_beat.beats += 1;
} else {
next_beat.bars += 1;
@@ -142,29 +168,7 @@ Editor::redisplay_tempo (bool immediate_redraw)
current_bbt_points = 0;
}
- if (session) {
- current_bbt_points = session->tempo_map().get_points (session->tempo_map().frame_time (previous_beat), session->tempo_map().frame_time (next_beat));
- update_tempo_based_rulers ();
- } else {
- current_bbt_points = 0;
- }
-
- if (immediate_redraw) {
-
- hide_measures ();
-
- if (session && current_bbt_points) {
- draw_measures ();
- }
-
- } else {
-
- if (session && current_bbt_points) {
- Glib::signal_idle().connect (mem_fun (*this, &Editor::redraw_measures));
- } else {
- hide_measures ();
- }
- }
+ current_bbt_points = session->tempo_map().get_points (session->tempo_map().frame_time (previous_beat), session->tempo_map().frame_time (next_beat) + 1);
}
void
@@ -179,6 +183,7 @@ Editor::redraw_measures ()
{
hide_measures ();
draw_measures ();
+ tempo_map_change_idle_handler_id = -1;
return false;
}
diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc
index 2cf96fe02a..cbaee3d6d2 100644
--- a/gtk2_ardour/export_dialog.cc
+++ b/gtk2_ardour/export_dialog.cc
@@ -37,6 +37,7 @@
#include <ardour/audio_track.h>
#include <ardour/audioregion.h>
#include <ardour/audioengine.h>
+#include <ardour/audiofilesource.h>
#include <ardour/gdither.h>
#include <ardour/utils.h>
@@ -86,8 +87,8 @@ static const gchar *dither_types[] = {
};
static const gchar* channel_strings[] = {
- N_("stereo"),
- N_("mono"),
+ N_("Stereo"),
+ N_("Mono"),
0
};
@@ -112,7 +113,7 @@ ExportDialog::ExportDialog(PublicEditor& e)
src_quality_label (_("Conversion Quality"), 1.0, 0.5),
dither_type_label (_("Dither Type"), 1.0, 0.5),
cuefile_only_checkbox (_("Export CD Marker File Only")),
- file_browse_button (_("Browse")),
+ file_chooser (FILE_CHOOSER_ACTION_SAVE),
track_selector_button (_("Specific tracks ..."))
{
guint32 n;
@@ -123,6 +124,7 @@ ExportDialog::ExportDialog(PublicEditor& e)
track_and_master_selection_allowed = true;
channel_count_selection_allowed = true;
export_cd_markers_allowed = true;
+ set_resizable (false);
WindowTitle title(Glib::get_application_name());
title += _("Export");
@@ -134,8 +136,6 @@ ExportDialog::ExportDialog(PublicEditor& e)
spec.running = false;
- file_entry.set_name ("ExportFileNameEntry");
-
master_list = ListStore::create (exp_cols);
master_selector.set_model (master_list);
@@ -176,11 +176,11 @@ ExportDialog::ExportDialog(PublicEditor& e)
track_scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
master_scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- get_vbox()->pack_start (file_frame, false, false);
+ get_vbox()->pack_start (file_frame, PACK_EXPAND_WIDGET);
hpacker.set_spacing (5);
hpacker.set_border_width (5);
- hpacker.pack_start (format_frame, false, false);
+ hpacker.pack_start (format_frame, PACK_SHRINK );
master_scroll.add (master_selector);
track_scroll.add (track_selector);
@@ -195,19 +195,36 @@ ExportDialog::ExportDialog(PublicEditor& e)
hpacker.pack_start (track_vpacker);
- get_vbox()->pack_start (hpacker);
+ get_vbox()->pack_start (hpacker, PACK_SHRINK);
track_selector_button.set_name ("EditorGTKButton");
track_selector_button.signal_clicked().connect (mem_fun(*this, &ExportDialog::track_selector_button_click));
- get_vbox()->pack_start (progress_bar, false, false);
+ Gtk::FileFilter filter_wav;
+ filter_wav.set_name("Wav files");
+ filter_wav.add_mime_type("audio/wav");
+ file_chooser.add_filter(filter_wav);
+
+ Gtk::FileFilter filter_aiff;
+ filter_aiff.set_name("Aiff files");
+ filter_aiff.add_mime_type("audio/aiff");
+ filter_aiff.add_pattern("*.aif");
+ filter_aiff.add_pattern("*.aiff");
+ file_chooser.add_filter(filter_aiff);
+
+ Gtk::FileFilter filter_any;
+ filter_any.set_name("All files");
+ filter_any.add_pattern("*");
+ file_chooser.add_filter(filter_any);
+ file_chooser.set_no_show_all();
- Gtkmm2ext::set_size_request_to_display_given_text (file_entry, X_("Kg/quite/a/reasonable/size/for/files/i/think"), 5, 8);
+ get_vbox()->pack_start (progress_bar, false, false, 5);
+ progress_bar.set_no_show_all();
+ progress_bar.hide();
file_hbox.set_spacing (5);
file_hbox.set_border_width (5);
- file_hbox.pack_start (file_entry, true, true);
- file_hbox.pack_start (file_browse_button, false, false);
+ file_hbox.pack_start (file_chooser, PACK_EXPAND_WIDGET);
file_frame.add (file_hbox);
file_frame.set_border_width (5);
@@ -316,37 +333,35 @@ ExportDialog::ExportDialog(PublicEditor& e)
cuefile_only_checkbox.set_name ("ExportCheckbox");
- format_table.set_homogeneous (false);
+ format_table.set_homogeneous (true);
format_table.set_border_width (5);
format_table.set_col_spacings (5);
format_table.set_row_spacings (5);
- format_table.attach (channel_count_label, 0, 1, 0, 1);
- format_table.attach (channel_count_combo, 1, 2, 0, 1);
+ format_table.attach (channel_count_label, 0, 1, 0, 1, FILL, FILL);
+ format_table.attach (channel_count_combo, 1, 2, 0, 1, FILL, FILL);
- format_table.attach (header_format_label, 0, 1, 1, 2);
- format_table.attach (header_format_combo, 1, 2, 1, 2);
+ format_table.attach (header_format_label, 0, 1, 1, 2, FILL, FILL);
+ format_table.attach (header_format_combo, 1, 2, 1, 2, FILL, FILL);
- format_table.attach (bitdepth_format_label, 0, 1, 2, 3);
- format_table.attach (bitdepth_format_combo, 1, 2, 2, 3);
+ format_table.attach (bitdepth_format_label, 0, 1, 2, 3, FILL, FILL);
+ format_table.attach (bitdepth_format_combo, 1, 2, 2, 3, FILL, FILL);
- format_table.attach (endian_format_label, 0, 1, 3, 4);
- format_table.attach (endian_format_combo, 1, 2, 3, 4);
+ format_table.attach (endian_format_label, 0, 1, 3, 4, FILL, FILL);
+ format_table.attach (endian_format_combo, 1, 2, 3, 4, FILL, FILL);
- format_table.attach (sample_rate_label, 0, 1, 4, 5);
- format_table.attach (sample_rate_combo, 1, 2, 4, 5);
+ format_table.attach (sample_rate_label, 0, 1, 4, 5, FILL, FILL);
+ format_table.attach (sample_rate_combo, 1, 2, 4, 5, FILL, FILL);
- format_table.attach (src_quality_label, 0, 1, 5, 6);
- format_table.attach (src_quality_combo, 1, 2, 5, 6);
+ format_table.attach (src_quality_label, 0, 1, 5, 6, FILL, FILL);
+ format_table.attach (src_quality_combo, 1, 2, 5, 6, FILL, FILL);
- format_table.attach (dither_type_label, 0, 1, 6, 7);
- format_table.attach (dither_type_combo, 1, 2, 6, 7);
+ format_table.attach (dither_type_label, 0, 1, 6, 7, FILL, FILL);
+ format_table.attach (dither_type_combo, 1, 2, 6, 7, FILL, FILL);
- format_table.attach (cue_file_label, 0, 1, 7, 8);
- format_table.attach (cue_file_combo, 1, 2, 7, 8);
- format_table.attach (cuefile_only_checkbox, 0, 2, 8, 9);
-
- file_entry.set_name ("ExportFileDisplay");
+ format_table.attach (cue_file_label, 0, 1, 7, 8, FILL, FILL);
+ format_table.attach (cue_file_combo, 1, 2, 7, 8, FILL, FILL);
+ format_table.attach (cuefile_only_checkbox, 0, 2, 8, 9, FILL, FILL);
signal_delete_event().connect (mem_fun(*this, &ExportDialog::window_closed));
@@ -354,15 +369,14 @@ ExportDialog::ExportDialog(PublicEditor& e)
cancel_button->signal_clicked().connect (mem_fun(*this, &ExportDialog::end_dialog));
ok_button = add_button (_("Export"), RESPONSE_ACCEPT);
ok_button->signal_clicked().connect (mem_fun(*this, &ExportDialog::do_export));
-
- file_browse_button.set_name ("EditorGTKButton");
- file_browse_button.signal_clicked().connect (mem_fun(*this, &ExportDialog::browse));
-
channel_count_combo.signal_changed().connect (mem_fun(*this, &ExportDialog::channels_chosen));
bitdepth_format_combo.signal_changed().connect (mem_fun(*this, &ExportDialog::bitdepth_chosen));
header_format_combo.signal_changed().connect (mem_fun(*this, &ExportDialog::header_chosen));
sample_rate_combo.signal_changed().connect (mem_fun(*this, &ExportDialog::sample_rate_chosen));
cue_file_combo.signal_changed().connect (mem_fun(*this, &ExportDialog::cue_file_type_chosen));
+
+ file_chooser.signal_update_preview().connect (mem_fun(*this, &ExportDialog::file_chooser_selection_changed));
+
}
ExportDialog::~ExportDialog()
@@ -373,24 +387,18 @@ void
ExportDialog::do_not_allow_track_and_master_selection()
{
track_and_master_selection_allowed = false;
- track_vpacker.set_no_show_all();
}
void
ExportDialog::do_not_allow_channel_count_selection()
{
channel_count_selection_allowed = false;
- channel_count_combo.set_no_show_all();
- channel_count_label.set_no_show_all();
}
void
ExportDialog::do_not_allow_export_cd_markers()
{
export_cd_markers_allowed = false;
- cue_file_label.set_no_show_all();
- cue_file_combo.set_no_show_all();
- cuefile_only_checkbox.set_no_show_all();
}
void
@@ -433,7 +441,7 @@ ExportDialog::set_state()
{
XMLNode* node = session->instant_xml(X_("ExportDialog"));
XMLProperty* prop;
-
+ bool fc_location_requested = false;
if (node) {
if ((prop = node->property (X_("sample_rate"))) != 0) {
@@ -458,13 +466,28 @@ ExportDialog::set_state()
endian_format_combo.set_active_text(prop->value());
}
if ((prop = node->property (X_("filename"))) != 0) {
- file_entry.set_text(prop->value());
+ file_chooser.set_filename(prop->value());
+ fc_location_requested = true;
+ file_chooser.set_current_folder(Glib::path_get_basename(prop->value()));
}
+
if ((prop = node->property (X_("cue_file_type"))) != 0) {
cue_file_combo.set_active_text(prop->value());
}
}
+ if (!fc_location_requested) {
+
+ /*
+ If the filename hasn't been set before, use the
+ current session's export directory as a default
+ location for the export.
+ */
+
+ file_chooser.set_current_folder (session->session_directory().export_path().to_string());
+ file_chooser.set_current_name (_("export.wav"));
+ }
+
header_chosen ();
bitdepth_chosen();
channels_chosen();
@@ -488,7 +511,7 @@ ExportDialog::set_state()
if (!master) {
/* default is to use all */
- if (channel_count_combo.get_active_text() == _("mono")) {
+ if (channel_count_combo.get_active_text() == _("Mono")) {
nchns = 1;
} else {
nchns = 2;
@@ -564,7 +587,7 @@ ExportDialog::save_state()
node->add_property(X_("header_format"), header_format_combo.get_active_text());
node->add_property(X_("bitdepth_format"), bitdepth_format_combo.get_active_text());
node->add_property(X_("endian_format"), endian_format_combo.get_active_text());
- node->add_property(X_("filename"), file_entry.get_text());
+ node->add_property(X_("filename"), file_chooser.get_filename());
node->add_property(X_("cue_file_type"), cue_file_combo.get_active_text());
XMLNode* tracks = new XMLNode(X_("Tracks"));
@@ -888,7 +911,7 @@ ExportDialog::do_export_cd_markers (const string& path,const string& cuefile_typ
void
ExportDialog::do_export ()
{
- string filepath = file_entry.get_text();
+ string filepath = file_chooser.get_filename();
if(!is_filepath_valid(filepath)){
return;
@@ -896,7 +919,7 @@ ExportDialog::do_export ()
if (export_cd_markers_allowed) {
if (cue_file_combo.get_active_text () != _("None")) {
- do_export_cd_markers (file_entry.get_text(), cue_file_combo.get_active_text ());
+ do_export_cd_markers (file_chooser.get_filename(), cue_file_combo.get_active_text ());
}
if (cuefile_only_checkbox.get_active()) {
@@ -913,12 +936,15 @@ ExportDialog::do_export ()
// read user input into spec
initSpec(filepath);
+ progress_bar.show();
progress_connection = Glib::signal_timeout().connect (mem_fun(*this, &ExportDialog::progress_timeout), 100);
cancel_label.set_text (_("Stop Export"));
export_audio_data();
progress_connection.disconnect ();
+ session->engine().freewheel (false);
+ progress_bar.hide();
end_dialog ();
}
@@ -937,9 +963,9 @@ ExportDialog::end_dialog ()
}
}
- session->finalize_audio_export ();
+ hide ();
- hide_all ();
+ session->finalize_audio_export ();
set_modal (false);
ok_button->set_sensitive(true);
@@ -967,11 +993,39 @@ ExportDialog::start_export ()
file_entry.set_text (export_file_path.to_string());
}
-
+
progress_bar.set_fraction (0);
+ progress_bar.hide();
+ progress_bar.set_no_show_all();
cancel_label.set_text (_("Cancel"));
- show_all ();
+ show_all();
+
+ if (track_and_master_selection_allowed) {
+ track_vpacker.show();
+ } else {
+ track_vpacker.hide();
+ }
+
+ file_chooser.show();
+
+ if (channel_count_selection_allowed) {
+ channel_count_combo.show();
+ channel_count_label.show();
+ } else {
+ channel_count_combo.hide();
+ channel_count_label.hide();
+ }
+
+ if (export_cd_markers_allowed) {
+ cue_file_label.show();
+ cue_file_combo.show();
+ cuefile_only_checkbox.show();
+ } else {
+ cue_file_label.hide();
+ cue_file_combo.hide();
+ cuefile_only_checkbox.hide();
+ }
if (session->master_out()) {
track_scroll.hide ();
@@ -979,15 +1033,21 @@ ExportDialog::start_export ()
master_scroll.hide ();
track_selector_button.hide ();
}
+
+ track_and_master_selection_allowed = true;
+ channel_count_selection_allowed = true;
+ export_cd_markers_allowed = true;
}
void
ExportDialog::header_chosen ()
{
if (sndfile_header_format_from_string (header_format_combo.get_active_text ()) == SF_FORMAT_WAV) {
+ endian_format_combo.set_active_text (N_("Little-endian (Intel)"));
endian_format_combo.set_sensitive (false);
} else {
endian_format_combo.set_sensitive (true);
+ endian_format_combo.set_active_text (N_("Big-endian (Mac)"));
}
}
@@ -1020,6 +1080,65 @@ ExportDialog::cue_file_type_chosen ()
}
void
+ExportDialog::file_chooser_selection_changed ()
+{
+
+ /*
+ if the user selects an existing file from the 'browse for other folders' tab,
+ change the format settings to match the file.
+ */
+ if (file_chooser.get_filename().length() == 0) {
+ return;
+ }
+ if (Glib::file_test(file_chooser.get_preview_filename(),Glib::FILE_TEST_IS_DIR)){
+ file_chooser.set_current_name (_(""));
+ return;
+ }
+ if (!Glib::file_test(file_chooser.get_preview_filename(),Glib::FILE_TEST_EXISTS)) {
+ return;
+ }
+
+ SoundFileInfo finfo;
+ string error_msg, format_str;
+
+ if (!AudioFileSource::get_soundfile_info (file_chooser.get_preview_filename(), finfo, error_msg)) {
+ error << string_compose(_("Export: cannot open file \"%1\"."), error_msg ) << endmsg;
+ return;
+ }
+
+ if (finfo.samplerate == 22050) {
+ sample_rate_combo.set_active_text (N_("22.05kHz"));
+ } else if (finfo.samplerate == 44100) {
+ sample_rate_combo.set_active_text (N_("44.1kHz"));
+ } else if (finfo.samplerate == 48000) {
+ sample_rate_combo.set_active_text (N_("48kHz"));
+ } else if (finfo.samplerate == 88200) {
+ sample_rate_combo.set_active_text (N_("88.2kHz"));
+ } else if (finfo.samplerate == 96000) {
+ sample_rate_combo.set_active_text (N_("96kHz"));
+ } else if (finfo.samplerate == 192000) {
+ sample_rate_combo.set_active_text (N_("192kHz"));
+ }
+
+ if (finfo.channels == 1) {
+ channel_count_combo.set_active_text(N_("Mono"));
+ } else {
+ channel_count_combo.set_active_text(N_("Stereo"));
+ }
+
+ string::size_type pos;
+
+ pos = finfo.format_name.find_first_of (" ");
+ format_str = finfo.format_name.substr(pos + 1, 255);
+ pos = format_str.find_first_of (" ");
+ header_format_combo.set_active_text(format_str.substr(0, pos));
+
+ format_str = finfo.format_name;
+ pos = format_str.find_first_of (",");
+ bitdepth_format_combo.set_active_text(format_str.substr(pos + 2, 255));
+}
+
+void
ExportDialog::sample_rate_chosen ()
{
string sr_str = sample_rate_combo.get_active_text();
@@ -1053,7 +1172,7 @@ ExportDialog::channels_chosen ()
{
bool mono;
- mono = (channel_count_combo.get_active_text() == _("mono"));
+ mono = (channel_count_combo.get_active_text() == _("Mono"));
if (mono) {
track_selector.get_column(2)->set_visible(false);
@@ -1145,7 +1264,7 @@ ExportDialog::is_filepath_valid(string &filepath)
return false;
}
else {
- string txt = _("File already exists, do you want to overwrite it?");
+ string txt = _("File ") + filepath + _(" already exists, do you want to overwrite it?");
MessageDialog msg (*this, txt, false, MESSAGE_QUESTION, BUTTONS_YES_NO, true);
if ((ResponseType) msg.run() == Gtk::RESPONSE_NO) {
return false;
@@ -1175,7 +1294,7 @@ ExportDialog::initSpec(string &filepath)
spec.stop = false;
spec.port_map.clear();
- if (channel_count_combo.get_active_text() == _("mono")) {
+ if (channel_count_combo.get_active_text() == _("Mono")) {
spec.channels = 1;
} else {
spec.channels = 2;
@@ -1306,27 +1425,6 @@ ExportDialog::window_closed (GdkEventAny *ignored)
}
void
-ExportDialog::browse ()
-{
- FileChooserDialog dialog("Export to file", browse_action());
- dialog.set_transient_for(*this);
- dialog.set_filename (file_entry.get_text());
-
- dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
- dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
-
- int result = dialog.run();
-
- if (result == Gtk::RESPONSE_OK) {
- string filename = dialog.get_filename();
-
- if (filename.length()) {
- file_entry.set_text (filename);
- }
- }
-}
-
-void
ExportDialog::track_selector_button_click ()
{
if (track_scroll.is_visible ()) {
diff --git a/gtk2_ardour/export_dialog.h b/gtk2_ardour/export_dialog.h
index 596467d3e1..d518f5ec8a 100644
--- a/gtk2_ardour/export_dialog.h
+++ b/gtk2_ardour/export_dialog.h
@@ -134,7 +134,7 @@ class ExportDialog : public ArdourDialog
Gtk::Entry file_entry;
Gtk::HBox file_hbox;
- Gtk::Button file_browse_button;
+ Gtk::FileChooserWidget file_chooser;
Gtk::Button* ok_button;
Gtk::Button* cancel_button;
@@ -159,6 +159,7 @@ class ExportDialog : public ArdourDialog
void bitdepth_chosen ();
void sample_rate_chosen ();
void cue_file_type_chosen();
+ void file_chooser_selection_changed();
void fill_lists();
void write_track_and_master_selection_to_spec();
@@ -171,8 +172,6 @@ class ExportDialog : public ArdourDialog
void track_selector_button_click ();
- void browse ();
-
void set_state();
void save_state();
};
diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc
index 699ecdbcfa..cb8e7f235b 100644
--- a/gtk2_ardour/region_view.cc
+++ b/gtk2_ardour/region_view.cc
@@ -141,7 +141,7 @@ RegionView::init (Gdk::Color& basic_color, bool wfd)
sync_mark->property_fill_color_rgba() = fill_color;
sync_mark->hide();
- reset_width_dependent_items ((double) _region->length() / samples_per_unit);
+ //reset_width_dependent_items ((double) _region->length() / samples_per_unit);
if (wfd)
_enable_display = true;
@@ -214,9 +214,14 @@ RegionView::region_changed (Change what_changed)
if (what_changed & Region::SyncOffsetChanged) {
region_sync_changed ();
}
+ /*
+ this should not be needed now that only playlist can change layering
+ */
+ /*
if (what_changed & Region::LayerChanged) {
region_layered ();
}
+ */
if (what_changed & Region::LockChanged) {
region_locked ();
}
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index 1a3fb9a084..f6d6924a76 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -285,17 +285,18 @@ StreamView::apply_color (Gdk::Color& color, ColorTarget target)
void
StreamView::region_layered (RegionView* rv)
{
- rv->get_canvas_group()->lower_to_bottom();
- /* don't ever leave it at the bottom, since then it doesn't
- get events - the parent group does instead ...
- */
-
- /* this used to be + 1, but regions to the left ended up below
- ..something.. and couldn't receive events. why? good question.
- */
- /* and now it's + 3 for midi note separator lines */
- rv->get_canvas_group()->raise (rv->region()->layer() + 3);
+ /*
+ Currently 'layer' has nothing to do with the desired canvas layer.
+ For now, ensure that multiple regionviews passed here in groups are
+ ordered by 'layer' (lowest to highest).
+
+ (see AudioStreamView::redisplay_diskstream ()).
+
+ We move them to the top layer as they arrive.
+ */
+
+ rv->get_canvas_group()->raise_to_top();
}
void
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index af08d4569c..bcbc7c78ac 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -232,33 +232,11 @@ def CheckJackRecomputeLatency(context):
context.Result(result)
return result
-#
-# See if JACK supports jack_port_ensure_monitor_input()
-#
-jack_ensure_monitor_input_test = """
-#include <jack/jack.h>
-int main(int argc, char** argv)
-{
- jack_port_t **port;
-
- jack_port_ensure_monitor (*port, 1);
- return 0;
-
-}
-"""
-
-def CheckJackEnsureMonitorInput(context):
- context.Message('Checking for jack_port_ensure_monitor_input()...')
- result = context.TryLink(jack_ensure_monitor_input_test, '.c')
- context.Result(result)
- return result
-
conf = Configure(ardour, custom_tests = {
'CheckJackClientOpen' : CheckJackClientOpen,
'CheckJackRecomputeLatencies' : CheckJackRecomputeLatencies,
'CheckJackRecomputeLatency' : CheckJackRecomputeLatency,
- 'CheckJackVideoFrameOffset' : CheckJackVideoFrameOffset,
- 'CheckJackEnsureMonitorInput' : CheckJackEnsureMonitorInput
+ 'CheckJackVideoFrameOffset' : CheckJackVideoFrameOffset
})
if conf.CheckJackClientOpen():
@@ -272,11 +250,6 @@ if conf.CheckJackRecomputeLatency():
if conf.CheckJackVideoFrameOffset():
ardour.Append(CXXFLAGS="-DHAVE_JACK_VIDEO_SUPPORT")
-
-if conf.CheckJackEnsureMonitorInput():
- ardour.Append(CXXFLAGS='-DHAVE_JACK_PORT_ENSURE_MONITOR')
-else:
- print '\nWARNING: You need at least svn revision 985 of jack for hardware monitoring to work correctly.\n'
#
# Optional header files
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 7b22528bd1..3865019bc7 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -61,10 +61,6 @@ const nframes_t frames_per_peak = 256;
/* returns the number of items in this `audio_source' */
- virtual nframes_t length() const {
- return _length;
- }
-
virtual nframes_t available_peaks (double zoom) const;
virtual nframes_t read (Sample *dst, nframes_t start, nframes_t cnt) const;
@@ -120,7 +116,6 @@ const nframes_t frames_per_peak = 256;
bool _peaks_built;
mutable Glib::Mutex _lock;
mutable Glib::Mutex _peaks_ready_lock;
- nframes_t _length;
Glib::ustring peakpath;
Glib::ustring _captured_for;
diff --git a/libs/ardour/ardour/jack_port.h b/libs/ardour/ardour/jack_port.h
index c3c31c938d..d973ed2cab 100644
--- a/libs/ardour/ardour/jack_port.h
+++ b/libs/ardour/ardour/jack_port.h
@@ -62,13 +62,7 @@ class JackPort : public virtual Port {
}
void ensure_monitor_input (bool yn) {
-
-#ifdef HAVE_JACK_PORT_ENSURE_MONITOR
jack_port_ensure_monitor (_port, yn);
-#else
- jack_port_request_monitor(_port, yn);
-#endif
-
}
/*XXX completely bloody useless imho*/
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 0c5a8e044f..8dd9ccc211 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -279,7 +279,7 @@ namespace ARDOUR {
enum MonitorModel {
HardwareMonitoring,
SoftwareMonitoring,
- ExternalMonitoring,
+ ExternalMonitoring
};
enum DenormalModel {
@@ -292,7 +292,7 @@ namespace ARDOUR {
enum RemoteModel {
UserOrdered,
MixerOrdered,
- EditorOrdered,
+ EditorOrdered
};
enum CrossfadeModel {
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index f4c10cbc12..0631c9121b 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -337,6 +337,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom;
boost::shared_ptr<Crossfade> xfade;
+ RegionList* touched_regions;
if (in_set_state || in_partition) {
return;
@@ -398,7 +399,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
break;
case OverlapExternal:
-
+
/* [ -------- top ------- ]
* {=========== bottom =============}
*/
@@ -411,11 +412,15 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
*/
xfade_length = min ((nframes_t) 720, top->length());
-
- xfade = boost::shared_ptr<Crossfade> (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn));
- add_crossfade (xfade);
+
+ if (top_region_at (top->first_frame()) == top) {
+
+ xfade = boost::shared_ptr<Crossfade> (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn));
+ add_crossfade (xfade);
+ }
if (top_region_at (top->last_frame() - 1) == top) {
+
/*
only add a fade out if there is no region on top of the end of 'top' (which
would cover it).
@@ -425,9 +430,58 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
add_crossfade (xfade);
}
break;
-
+ case OverlapStart:
+
+ /* { ==== top ============ }
+ * [---- bottom -------------------]
+ */
+
+ if (Config->get_xfade_model() == FullCrossfade) {
+ touched_regions = regions_touched (top->first_frame(), bottom->last_frame());
+ if (touched_regions->size() <= 2) {
+ xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active()));
+ add_crossfade (xfade);
+ }
+ } else {
+
+ touched_regions = regions_touched (top->first_frame(),
+ top->first_frame() + min ((nframes_t)Config->get_short_xfade_seconds() * _session.frame_rate(),
+ top->length()));
+ if (touched_regions->size() <= 2) {
+ xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active()));
+ add_crossfade (xfade);
+ }
+ }
+ break;
+ case OverlapEnd:
+
+
+ /* [---- top ------------------------]
+ * { ==== bottom ============ }
+ */
+
+ if (Config->get_xfade_model() == FullCrossfade) {
+
+ touched_regions = regions_touched (bottom->first_frame(), top->last_frame());
+ if (touched_regions->size() <= 2) {
+ xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other,
+ Config->get_xfade_model(), Config->get_xfades_active()));
+ add_crossfade (xfade);
+ }
+
+ } else {
+ touched_regions = regions_touched (bottom->first_frame(),
+ bottom->first_frame() + min ((nframes_t)Config->get_short_xfade_seconds() * _session.frame_rate(),
+ bottom->length()));
+ if (touched_regions->size() <= 2) {
+ xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active()));
+ add_crossfade (xfade);
+ }
+ }
+ break;
default:
- xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active()));
+ xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other,
+ Config->get_xfade_model(), Config->get_xfades_active()));
add_crossfade (xfade);
}
}
@@ -471,6 +525,7 @@ void AudioPlaylist::notify_crossfade_added (boost::shared_ptr<Crossfade> x)
if (g_atomic_int_get(&block_notifications)) {
_pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
} else {
+
NewCrossfade (x); /* EMIT SIGNAL */
}
}
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index badd13412e..7405077cf3 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -486,7 +486,7 @@ ARDOUR::coverage (nframes_t sa, nframes_t ea,
"B overlaps the end of A"
*/
- if ((sb >= sa) && (sb <= ea)) {
+ if ((sb > sa) && (sb <= ea)) {
return OverlapEnd;
}
/*
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 09b54000d8..8d20d8539d 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -70,6 +70,7 @@ struct RegionSortByLastLayerOp {
}
};
+
Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
: SessionObject(sess, nom)
, _type(type)
@@ -350,7 +351,9 @@ Playlist::notify_region_removed (boost::shared_ptr<Region> r)
/* this might not be true, but we have to act
as though it could be.
*/
+ pending_length = false;
LengthChanged (); /* EMIT SIGNAL */
+ pending_modified = false;
Modified (); /* EMIT SIGNAL */
}
}
@@ -367,7 +370,9 @@ Playlist::notify_region_added (boost::shared_ptr<Region> r)
pending_modified = true;
pending_length = true;
} else {
+ pending_length = false;
LengthChanged (); /* EMIT SIGNAL */
+ pending_modified = false;
Modified (); /* EMIT SIGNAL */
}
}
@@ -378,7 +383,9 @@ Playlist::notify_length_changed ()
if (holding_state ()) {
pending_length = true;
} else {
+ pending_length = false;
LengthChanged(); /* EMIT SIGNAL */
+ pending_modified = false;
Modified (); /* EMIT SIGNAL */
}
}
@@ -437,6 +444,7 @@ Playlist::flush_notifications ()
}
pending_modified = false;
Modified (); /* EMIT SIGNAL */
+
}
for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) {
@@ -458,7 +466,7 @@ void
Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times)
{
RegionLock rlock (this);
-
+ delay_notifications();
times = fabs (times);
int itimes = (int) floor (times);
@@ -494,6 +502,8 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos);
}
+
+ release_notifications ();
}
void
@@ -654,7 +664,6 @@ Playlist::partition (nframes_t start, nframes_t end, bool just_top_level)
void
Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist)
{
- RegionLock rlock (this);
boost::shared_ptr<Region> region;
boost::shared_ptr<Region> current;
string new_name;
@@ -662,14 +671,19 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
OverlapType overlap;
nframes_t pos1, pos2, pos3, pos4;
RegionList new_regions;
+ RegionList copy;
in_partition = true;
+ delay_notifications();
+
/* need to work from a copy, because otherwise the regions we add during the process
get operated on as well.
*/
-
- RegionList copy = regions;
+ {
+ RegionLock rlock (this);
+ copy = regions;
+ }
for (RegionList::iterator i = copy.begin(); i != copy.end(); i = tmp) {
@@ -677,9 +691,10 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
++tmp;
current = *i;
-
+
if (current->first_frame() == start && current->last_frame() == end) {
if (cutting) {
+ RegionLock rlock (this);
remove_region_internal (current);
}
continue;
@@ -688,14 +703,14 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
if ((overlap = current->coverage (start, end)) == OverlapNone) {
continue;
}
-
+
pos1 = current->position();
pos2 = start;
pos3 = end;
pos4 = current->last_frame();
if (overlap == OverlapInternal) {
-
+
/* split: we need 3 new regions, the front, middle and end.
cut: we need 2 regions, the front and end.
*/
@@ -715,9 +730,10 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
/* "middle" ++++++ */
- _session.region_name (new_name, current->name(), false);
+ _session.region_name (new_name, current->name(), false); //takes the session-wide region lock
region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
+ RegionLock rlock (this);
add_region_internal (region, start);
new_regions.push_back (region);
}
@@ -727,10 +743,11 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
-
- add_region_internal (region, end);
- new_regions.push_back (region);
-
+ {
+ RegionLock rlock (this);
+ add_region_internal (region, end);
+ new_regions.push_back (region);
+ }
/* "front" ***** */
current->freeze ();
@@ -755,8 +772,9 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
/* end +++++ */
_session.region_name (new_name, current->name(), false);
- region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
+ region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, regions.size(),
Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
+ RegionLock rlock (this);
add_region_internal (region, start);
new_regions.push_back (region);
}
@@ -791,6 +809,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
+ RegionLock rlock (this);
add_region_internal (region, pos1);
new_regions.push_back (region);
}
@@ -820,6 +839,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
*/
if (cutting) {
+ RegionLock rlock (this);
remove_region_internal (current);
}
new_regions.push_back (current);
@@ -831,6 +851,8 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
for (RegionList::iterator i = new_regions.begin(); i != new_regions.end(); ++i) {
check_dependents (*i, false);
}
+
+ release_notifications ();
}
boost::shared_ptr<Playlist>
@@ -1209,7 +1231,9 @@ Playlist::clear (bool with_signals)
}
if (with_signals) {
+ pending_length = false;
LengthChanged ();
+ pending_modified = false;
Modified ();
}
@@ -1587,7 +1611,7 @@ Playlist::relayer ()
/* don't send multiple Modified notifications
when multiple regions are relayered.
*/
-
+
freeze ();
/* build up a new list of regions on each layer */
@@ -1607,7 +1631,6 @@ Playlist::relayer ()
copy.sort (cmp);
}
-
for (RegionList::iterator i = copy.begin(); i != copy.end(); ++i) {
/* find the lowest layer that this region can go on */
diff --git a/libs/ardour/sndfile_helpers.cc b/libs/ardour/sndfile_helpers.cc
index d47a9b9423..96dc2c7779 100644
--- a/libs/ardour/sndfile_helpers.cc
+++ b/libs/ardour/sndfile_helpers.cc
@@ -63,11 +63,11 @@ int sndfile_header_formats[SNDFILE_HEADER_FORMATS] = {
};
const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1] = {
- N_("16 bit"),
- N_("24 bit"),
- N_("32 bit"),
- N_("8 bit"),
- N_("float"),
+ N_("Signed 16 bit PCM"),
+ N_("Signed 24 bit PCM"),
+ N_("Signed 32 bit PCM"),
+ N_("Signed 8 bit PCM"),
+ N_("32 bit float"),
0
};