diff options
Diffstat (limited to 'gtk2_ardour/editor_timefx.cc')
-rw-r--r-- | gtk2_ardour/editor_timefx.cc | 138 |
1 files changed, 79 insertions, 59 deletions
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc index 830d8999a4..d4d02ea1c4 100644 --- a/gtk2_ardour/editor_timefx.cc +++ b/gtk2_ardour/editor_timefx.cc @@ -21,8 +21,8 @@ #include <cstdlib> #include <cmath> #include <ctime> - #include <string> +#include <set> #include "pbd/error.h" #include "pbd/pthread_utils.h" @@ -63,45 +63,87 @@ using namespace Gtkmm2ext; int Editor::time_stretch (RegionSelection& regions, float fraction) { - // FIXME: kludge, implement stretching of selection of both types + RegionList audio; + RegionList midi; + int aret; + + begin_reversible_command (_("stretch/shrink")); + + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->region()->data_type() == DataType::AUDIO) { + audio.push_back ((*i)->region()); + } else if ((*i)->region()->data_type() == DataType::MIDI) { + midi.push_back ((*i)->region()); + } + } + + if ((aret = time_fx (audio, fraction, false)) != 0) { + return aret; + } + + set<boost::shared_ptr<Playlist> > midi_playlists_affected; + + for (RegionList::iterator i = midi.begin(); i != midi.end(); ++i) { + boost::shared_ptr<Playlist> playlist = (*i)->playlist(); + + if (playlist) { + playlist->clear_changes (); + } + + } + + ARDOUR::TimeFXRequest request; + request.time_fraction = fraction; + + for (RegionList::iterator i = midi.begin(); i != midi.end(); ++i) { + boost::shared_ptr<Playlist> playlist = (*i)->playlist(); + + if (!playlist) { + continue; + } + + MidiStretch stretch (*_session, request); + stretch.run (*i); - if (regions.front()->region()->data_type() == DataType::AUDIO) { - // Audio, pop up timefx dialog - return time_fx (regions, fraction, false); - } else { - // MIDI, just stretch - RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (®ions.front()->get_time_axis_view()); - if (!rtv) - return -1; - - boost::shared_ptr<Playlist> playlist = rtv->track()->playlist(); - - ARDOUR::TimeFXRequest request; - request.time_fraction = fraction; - MidiStretch stretch(*_session, request); - begin_reversible_command ("midi stretch"); - stretch.run(regions.front()->region()); - playlist->clear_changes (); playlist->replace_region (regions.front()->region(), stretch.results[0], - regions.front()->region()->position()); - _session->add_command (new StatefulDiffCommand (playlist)); - commit_reversible_command (); + regions.front()->region()->position()); + midi_playlists_affected.insert (playlist); } + for (set<boost::shared_ptr<Playlist> >::iterator p = midi_playlists_affected.begin(); p != midi_playlists_affected.end(); ++p) { + _session->add_command (new StatefulDiffCommand (*p)); + } + + commit_reversible_command (); + return 0; } int Editor::pitch_shift (RegionSelection& regions, float fraction) { - return time_fx (regions, fraction, true); + RegionList rl; + + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + rl.push_back ((*i)->region()); + } + + begin_reversible_command (_("pitch shift")); + + int ret = time_fx (rl, fraction, true); + + if (ret == 0) { + commit_reversible_command (); + } + + return ret; } /** @param val Percentage to time stretch by; ignored if pitch-shifting. * @param pitching true to pitch shift, false to time stretch. * @return -1 in case of error, 1 if operation was cancelled by the user, 0 if everything went ok */ int -Editor::time_fx (RegionSelection& regions, float val, bool pitching) +Editor::time_fx (RegionList& regions, float val, bool pitching) { delete current_timefx; @@ -264,45 +306,31 @@ Editor::time_fx (RegionSelection& regions, float val, bool pitching) void Editor::do_timefx (TimeFXDialog& dialog) { - Track* t; boost::shared_ptr<Playlist> playlist; boost::shared_ptr<Region> new_region; - bool in_command = false; + set<boost::shared_ptr<Playlist> > playlists_affected; uint32_t const N = dialog.regions.size (); - for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) { - AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i); + for (RegionList::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ++i) { + boost::shared_ptr<Playlist> playlist = (*i)->playlist(); - if (!arv) { - continue; + if (playlist) { + playlist->clear_changes (); } + } - boost::shared_ptr<AudioRegion> region (arv->audio_region()); - TimeAxisView* tv = &(arv->get_time_axis_view()); - RouteTimeAxisView* rtv; - RegionSelection::iterator tmp; - - tmp = i; - ++tmp; - - if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv)) == 0) { - i = tmp; - continue; - } + for (RegionList::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ++i) { - if ((t = dynamic_cast<Track*> (rtv->route().get())) == 0) { - i = tmp; - continue; - } + boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (*i); - if ((playlist = t->playlist()) == 0) { - i = tmp; + if (!region || (playlist = region->playlist()) == 0) { continue; } if (dialog.request.cancel) { /* we were cancelled */ + /* XXX what to do about playlists already affected ? */ dialog.status = 1; return; } @@ -331,24 +359,16 @@ Editor::do_timefx (TimeFXDialog& dialog) if (!fx->results.empty()) { new_region = fx->results.front(); - if (!in_command) { - _session->begin_reversible_command (dialog.pitching ? _("pitch shift") : _("time stretch")); - in_command = true; - } - - playlist->clear_changes (); playlist->replace_region (region, new_region, region->position()); - _session->add_command (new StatefulDiffCommand (playlist)); + playlists_affected.insert (playlist); } current_timefx->ascend (); - - i = tmp; delete fx; } - if (in_command) { - _session->commit_reversible_command (); + for (set<boost::shared_ptr<Playlist> >::iterator p = playlists_affected.begin(); p != playlists_affected.end(); ++p) { + _session->add_command (new StatefulDiffCommand (*p)); } dialog.status = 0; |