summaryrefslogtreecommitdiff
path: root/gtk2_ardour/editor_timefx.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-01-27 16:29:01 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-01-27 16:29:01 +0000
commit33c61757fc8352fdb1280bca28b54d1adee183ff (patch)
tree3079597365e70769acd6befe3fa95dc8e9f87439 /gtk2_ardour/editor_timefx.cc
parentfc3be1d42c6400896a85edbc83bda38242cec30a (diff)
promote Playlist::RegionList to ARDOUR::RegionList; fix timefx on multiple regions, even regions of mixed type. this mostly involved some trivial code changes but to make the code simpler and less error prone, the API switched away from using RegionSelection (list of regionviews that catches regionviews vanishing) and used RegionList (lists of regions, no semantics) instead.
git-svn-id: svn://localhost/ardour2/branches/3.0@11362 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/editor_timefx.cc')
-rw-r--r--gtk2_ardour/editor_timefx.cc138
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*> (&regions.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;