#include "ardour/strip_silence.h"
#include "ardour/transient_detector.h"
#include "ardour/transpose.h"
+#include "ardour/vca_manager.h"
#include "canvas/canvas.h"
#include "transpose_dialog.h"
#include "transform_dialog.h"
#include "ui_config.h"
+#include "vca_time_axis.h"
#include "pbd/i18n.h"
break;
}
- float speed = 1.0f;
- RouteTimeAxisView *rtav;
-
- if (ontrack != 0 && (rtav = dynamic_cast<RouteTimeAxisView*>(ontrack)) != 0 ) {
- if (rtav->track() != 0) {
- speed = rtav->track()->speed();
- }
- }
-
- rpos = track_frame_to_session_frame (rpos, speed);
-
if (rpos < lpos) {
lpos = rpos;
}
boost::shared_ptr<Region> ret;
framepos_t rpos = 0;
- float track_speed;
framepos_t track_frame;
RouteTimeAxisView *rtav;
framecnt_t distance;
boost::shared_ptr<Region> r;
- track_speed = 1.0f;
- if ( (rtav = dynamic_cast<RouteTimeAxisView*>(*i)) != 0 ) {
- if (rtav->track()!=0)
- track_speed = rtav->track()->speed();
- }
-
- track_frame = session_frame_to_track_frame(frame, track_speed);
+ track_frame = frame;
if ((r = (*i)->find_next_region (track_frame, point, dir)) == 0) {
continue;
break;
}
- // rpos is a "track frame", converting it to "_session frame"
- rpos = track_frame_to_session_frame(rpos, track_speed);
-
if (rpos > frame) {
distance = rpos - frame;
} else {
break;
}
- float speed = 1.0f;
- RouteTimeAxisView *rtav;
-
- if ( ontrack != 0 && (rtav = dynamic_cast<RouteTimeAxisView*>(ontrack)) != 0 ) {
- if (rtav->track() != 0) {
- speed = rtav->track()->speed();
- }
- }
-
- pos = track_frame_to_session_frame(pos, speed);
-
if (cursor == playhead_cursor) {
_session->request_locate (pos);
} else {
break;
}
- float speed = 1.0f;
- RouteTimeAxisView *rtav;
-
- if (ontrack != 0 && (rtav = dynamic_cast<RouteTimeAxisView*>(ontrack)) != 0) {
- if (rtav->track() != 0) {
- speed = rtav->track()->speed();
- }
- }
-
- pos = track_frame_to_session_frame(pos, speed);
-
loc->move_to (pos, 0);
}
}
}
- // ToDo: encapsulate all of this into something like editor::get_session_extents() or editor::leftmost(), rightmost()
- {
- //ToDo: also incorporate automation regions (in case the session has no audio/midi but is just used for automating plugins or the like)
-
- //calculate the extents of all regions in every playlist
- framecnt_t session_extent_start = 0;
- framecnt_t session_extent_end = 0;
- {
- boost::shared_ptr<RouteList> rl = _session->get_routes();
- for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
- boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*r);
- if (tr) {
- boost::shared_ptr<Playlist> pl = tr->playlist();
- if (pl) {
- pair<framepos_t, framepos_t> e;
- e = pl->get_extent();
- if (e.first < session_extent_start) {
- session_extent_start = e.first;
- }
- if (e.second > session_extent_end) {
- session_extent_end = e.second;
- }
- }
- }
- }
- }
- framecnt_t session_extents = session_extent_end - session_extent_start;
-
- //in a session with no regions, use the start/end markers to set max zoom
- framecnt_t const session_length = _session->current_end_frame() - _session->current_start_frame ();
- if ( session_length > session_extents )
- session_extents = session_length;
-
- //in a session with no regions or start/end markers, use 2 minutes to set max zoom
- framecnt_t const min_length = _session->nominal_frame_rate()*60*2;
- if ( min_length > session_extents )
- session_extents = min_length;
-
- //convert to samples-per-pixel and limit our zoom to this value
- framecnt_t session_extents_pp = session_extents / _visible_canvas_width;
- if (nspp > session_extents_pp)
- nspp = session_extents_pp;
- }
+ //zoom-behavior-tweaks
+ //limit our maximum zoom to the session gui extents value
+ std::pair<framepos_t, framepos_t> ext = session_gui_extents();
+ framecnt_t session_extents_pp = ( ext.second - ext.first ) / _visible_canvas_width;
+ if (nspp > session_extents_pp)
+ nspp = session_extents_pp;
temporal_zoom (nspp);
}
}
}
+void
+Editor::temporal_zoom_extents ()
+{
+ ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_extents)
+
+ if (_session) {
+ std::pair<framepos_t, framepos_t> ext = session_gui_extents( false ); //in this case we want to zoom to the extents explicitly; ignore the users prefs for extra padding
+
+ framecnt_t start = ext.first;
+ framecnt_t end = ext.second;
+
+ if (_session->actively_recording () ) {
+ framepos_t cur = playhead_cursor->current_frame ();
+ if (cur > end) {
+ /* recording beyond the end marker; zoom out
+ * by 5 seconds more so that if 'follow
+ * playhead' is active we don't immediately
+ * scroll.
+ */
+ end = cur + _session->frame_rate() * 5;
+ }
+ }
+
+ if ((start == 0 && end == 0) || end < start) {
+ return;
+ }
+
+ calc_extra_zoom_edges(start, end);
+
+ temporal_zoom_by_frame (start, end);
+ }
+}
+
void
Editor::temporal_zoom_by_frame (framepos_t start, framepos_t end)
{
vector< boost::shared_ptr<Region> > v;
for (list<RegionView*>::iterator x = rs.begin(); x != rs.end(); ++x) {
- (*x)->region()->separate_by_channel (*_session, v);
+ (*x)->region()->separate_by_channel (v);
}
}
/* XXX need to consider musical time selections here at some point */
- double speed = rtv->track()->speed();
-
for (list<AudioRange>::const_iterator t = ts.begin(); t != ts.end(); ++t) {
sigc::connection c = rtv->view()->RegionViewAdded.connect (
latest_regionviews.clear ();
- playlist->partition ((framepos_t)((*t).start * speed),
- (framepos_t)((*t).end * speed), false);
+ playlist->partition ((*t).start, (*t).end, false);
c.disconnect ();
return;
}
- float speed = 1.0;
framepos_t start;
framepos_t end;
- if (tav->track() != 0) {
- speed = tav->track()->speed();
- }
-
- start = session_frame_to_track_frame (loc.start(), speed);
- end = session_frame_to_track_frame (loc.end(), speed);
+ start = loc.start();
+ end = loc.end();
rv->region()->clear_changes ();
rv->region()->trim_to (start, (end - start));
continue;
}
- float speed = 1.0;
-
- if (atav->track() != 0) {
- speed = atav->track()->speed();
- }
-
-
boost::shared_ptr<Region> region = arv->region();
boost::shared_ptr<Playlist> playlist (region->playlist());
continue;
}
- region->trim_end((framepos_t) ( (next_region->first_frame() - 1) * speed));
- arv->region_changed (PropertyChange (ARDOUR::Properties::length));
+ region->trim_end (next_region->first_frame() - 1);
+ arv->region_changed (PropertyChange (ARDOUR::Properties::length));
}
else {
next_region = playlist->find_next_region (region->first_frame(), Start, 0);
- if(!next_region){
+ if (!next_region) {
continue;
}
- region->trim_front((framepos_t) ((next_region->last_frame() + 1) * speed));
-
+ region->trim_front (next_region->last_frame() + 1);
arv->region_changed (ARDOUR::bounds_change);
}
if (did_edit) {
/* reset repeated paste state */
paste_count = 0;
- last_paste_pos = 0;
+ last_paste_pos = -1;
commit_reversible_command ();
}
if (in_command) {
commit_reversible_command ();
+ _session->set_dirty ();
}
}
boost::shared_ptr<ControlList> cl (new ControlList);
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
- RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(*i);
+ StripableTimeAxisView *stav = dynamic_cast<StripableTimeAxisView *>(*i);
- if (!rtav) {
+ if (!stav || !stav->stripable()->solo_control()) {
continue;
}
if (first) {
- new_state = !rtav->route()->soloed ();
+ new_state = !stav->stripable()->solo_control()->soloed ();
first = false;
}
- cl->push_back (rtav->route()->solo_control());
+ cl->push_back (stav->stripable()->solo_control());
}
_session->set_controls (cl, new_state ? 1.0 : 0.0, Controllable::UseGroup);
{
bool new_state = false;
bool first = true;
- boost::shared_ptr<RouteList> rl (new RouteList);
+ boost::shared_ptr<ControlList> cl (new ControlList);
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
- RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(*i);
+ StripableTimeAxisView *stav = dynamic_cast<StripableTimeAxisView *>(*i);
- if (!rtav) {
+ if (!stav || !stav->stripable()->mute_control()) {
continue;
}
if (first) {
- new_state = !rtav->route()->muted();
+ new_state = !stav->stripable()->mute_control()->muted();
first = false;
}
- rl->push_back (rtav->route());
+ cl->push_back (stav->stripable()->mute_control());
}
- _session->set_controls (route_list_to_control_list (rl, &Stripable::mute_control), new_state, Controllable::UseGroup);
+ _session->set_controls (cl, new_state, Controllable::UseGroup);
}
void
}
void
-Editor::select_next_route()
+Editor::select_next_stripable (bool routes_only)
{
if (selection->tracks.empty()) {
selection->set (track_views.front());
TimeAxisView* current = selection->tracks.front();
- RouteUI *rui;
+ bool valid;
do {
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
}
}
- rui = dynamic_cast<RouteUI *>(current);
+ if (routes_only) {
+ RouteUI* rui = dynamic_cast<RouteUI *>(current);
+ valid = rui && rui->route()->active();
+ } else {
+ valid = 0 != current->stripable ().get();
+ }
- } while (current->hidden() || (rui == NULL) || !rui->route()->active());
+ } while (current->hidden() || !valid);
selection->set (current);
}
void
-Editor::select_prev_route()
+Editor::select_prev_stripable (bool routes_only)
{
if (selection->tracks.empty()) {
selection->set (track_views.front());
TimeAxisView* current = selection->tracks.front();
- RouteUI *rui;
+ bool valid;
do {
for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) {
break;
}
}
- rui = dynamic_cast<RouteUI *>(current);
+ if (routes_only) {
+ RouteUI* rui = dynamic_cast<RouteUI *>(current);
+ valid = rui && rui->route()->active();
+ } else {
+ valid = 0 != current->stripable ().get();
+ }
- } while (current->hidden() || (rui == NULL) || !rui->route()->active());
+ } while (current->hidden() || !valid);
selection->set (current);
string prompt;
int ntracks = 0;
int nbusses = 0;
+ int nvcas = 0;
const char* trackstr;
const char* busstr;
+ const char* vcastr;
vector<boost::shared_ptr<Route> > routes;
+ vector<boost::shared_ptr<VCA> > vcas;
bool special_bus = false;
for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
+ VCATimeAxisView* vtv = dynamic_cast<VCATimeAxisView*> (*x);
+ if (vtv) {
+ vcas.push_back (vtv->vca());
+ ++nvcas;
+ continue;
+ }
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*x);
if (!rtv) {
continue;
}
if (rtv->is_track()) {
- ntracks++;
+ ++ntracks;
} else {
- nbusses++;
+ ++nbusses;
}
routes.push_back (rtv->_route);
return;
}
- if (ntracks + nbusses == 0) {
+ if (ntracks + nbusses + nvcas == 0) {
return;
}
+ string title;
+
trackstr = P_("track", "tracks", ntracks);
busstr = P_("bus", "busses", nbusses);
+ vcastr = P_("VCA", "VCAs", nvcas);
- if (ntracks) {
- if (nbusses) {
- prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?\n"
- "(You may also lose the playlists associated with the %2)\n\n"
- "This action cannot be undone, and the session file will be overwritten!"),
- ntracks, trackstr, nbusses, busstr);
- } else {
- prompt = string_compose (_("Do you really want to remove %1 %2?\n"
- "(You may also lose the playlists associated with the %2)\n\n"
- "This action cannot be undone, and the session file will be overwritten!"),
- ntracks, trackstr);
- }
- } else if (nbusses) {
- prompt = string_compose (_("Do you really want to remove %1 %2?\n\n"
- "This action cannot be undone, and the session file will be overwritten"),
- nbusses, busstr);
+ if (ntracks > 0 && nbusses > 0 && nvcas > 0) {
+ title = _("Remove various strips");
+ prompt = string_compose (_("Do you really want to remove %1 %2, %3 %4 and %5 %6?"),
+ ntracks, trackstr, nbusses, busstr, nvcas, vcastr);
+ }
+ else if (ntracks > 0 && nbusses > 0) {
+ title = string_compose (_("Remove %1 and %2"), trackstr, busstr);
+ prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?"),
+ ntracks, trackstr, nbusses, busstr);
+ }
+ else if (ntracks > 0 && nvcas > 0) {
+ title = string_compose (_("Remove %1 and %2"), trackstr, vcastr);
+ prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?"),
+ ntracks, trackstr, nvcas, vcastr);
+ }
+ else if (nbusses > 0 && nvcas > 0) {
+ title = string_compose (_("Remove %1 and %2"), busstr, vcastr);
+ prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?"),
+ nbusses, busstr, nvcas, vcastr);
+ }
+ else if (ntracks > 0) {
+ title = string_compose (_("Remove %1"), trackstr);
+ prompt = string_compose (_("Do you really want to remove %1 %2?"),
+ ntracks, trackstr);
+ }
+ else if (nbusses > 0) {
+ title = string_compose (_("Remove %1"), busstr);
+ prompt = string_compose (_("Do you really want to remove %1 %2?"),
+ nbusses, busstr);
+ }
+ else if (nvcas > 0) {
+ title = string_compose (_("Remove %1"), vcastr);
+ prompt = string_compose (_("Do you really want to remove %1 %2?"),
+ nvcas, vcastr);
}
+ else {
+ assert (0);
+ }
+
+ if (ntracks > 0) {
+ prompt += "\n" + string_compose ("(You may also lose the playlists associated with the %1)", trackstr) + "\n";
+ }
+
+ prompt += "\n" + string(_("This action cannot be undone, and the session file will be overwritten!"));
choices.push_back (_("No, do nothing."));
- if (ntracks + nbusses > 1) {
+ if (ntracks + nbusses + nvcas > 1) {
choices.push_back (_("Yes, remove them."));
} else {
choices.push_back (_("Yes, remove it."));
}
- string title;
- if (ntracks) {
- title = string_compose (_("Remove %1"), trackstr);
- } else {
- title = string_compose (_("Remove %1"), busstr);
- }
-
Choice prompter (title, prompt, choices);
if (prompter.run () != 1) {
rl->push_back (*x);
}
_session->remove_routes (rl);
+
+ for (vector<boost::shared_ptr<VCA> >::iterator x = vcas.begin(); x != vcas.end(); ++x) {
+ _session->vca_manager().remove_vca (*x);
+ }
+
}
/* TrackSelection and RouteList leave scope,
* destructors are called,