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
This commit is contained in:
Nick Mainsbridge 2007-10-26 13:32:24 +00:00
parent 0c3f01e540
commit cc862d31bd
22 changed files with 1331 additions and 713 deletions

View File

@ -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));

View File

@ -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);
}
}

View File

@ -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 */
}

View File

@ -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);

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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
*/
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 (drag_info.copy) {
copies.push_back (rv);
}
}
}
if (! preserve_selection) {
//selection->clear_regions();
}
while (used_playlists.size() > 0) {
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:
@ -3838,6 +3870,13 @@ Editor::collect_new_region_view (RegionView* rv)
latest_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)
{
@ -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()));
}

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -99,18 +99,44 @@ 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;
@ -118,8 +144,8 @@ Editor::redisplay_tempo (bool immediate_redraw)
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;
}

View File

@ -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)"));
}
}
@ -1019,6 +1079,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 ()
{
@ -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;
@ -1305,27 +1424,6 @@ ExportDialog::window_closed (GdkEventAny *ignored)
return TRUE;
}
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 ()
{

View File

@ -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();
};

View File

@ -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 ();
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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*/

View File

@ -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 {

View File

@ -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 */
}
}

View File

@ -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;
}
/*

View File

@ -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 */

View File

@ -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
};