diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index cbb9756d86..1952fd8fdc 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2021,7 +2021,8 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& items) items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false))); items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection))); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Bounce range"), mem_fun(*this, &Editor::bounce_range_selection))); + items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true))); + items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false))); items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection))); } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index be86ba4baf..7f7ce96465 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1858,7 +1858,7 @@ public: bool write_region (string path, boost::shared_ptr); void export_region (); void bounce_region_selection (); - void bounce_range_selection (); + void bounce_range_selection (bool replace); void external_edit_region (); int write_audio_selection (TimeSelection&); diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 8ee0ac1f90..7768321436 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -149,7 +149,12 @@ Editor::bounce_region_selection () itt.cancel = false; itt.progress = 0.0f; - track->bounce_range (region->position(), region->position() + region->length(), itt); + boost::shared_ptr r = track->bounce_range (region->position(), region->position() + region->length(), itt); + cerr << "Result of bounce of " + << region->name() << " len = " << region->length() + << " was " + << r->name() << " len = " << r->length() + << endl; } } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 6ae78ff1cb..50980e4d09 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -3614,7 +3614,7 @@ Editor::freeze_route () } void -Editor::bounce_range_selection () +Editor::bounce_range_selection (bool replace) { if (selection->time.empty()) { return; @@ -3649,7 +3649,15 @@ Editor::bounce_range_selection () itt.progress = false; XMLNode &before = playlist->get_state(); - atv->audio_track()->bounce_range (start, cnt, itt); + boost::shared_ptr r = atv->audio_track()->bounce_range (start, start+cnt, itt); + + if (replace) { + list ranges; + ranges.push_back (AudioRange (start, start+cnt, 0)); + playlist->cut (ranges); // discard result + playlist->add_region (r, start); + } + XMLNode &after = playlist->get_state(); session->add_command (new MementoCommand (*playlist, &before, &after)); } diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 0405c30301..96a12c9bd4 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -58,8 +58,8 @@ class AudioTrack : public Track void freeze (InterThreadInfo&); void unfreeze (); - void bounce (InterThreadInfo&); - void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&); + boost::shared_ptr bounce (InterThreadInfo&); + boost::shared_ptr bounce_range (nframes_t start, nframes_t end, InterThreadInfo&); int set_state(const XMLNode& node); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index dfc5094885..bbe01b2a3d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -690,8 +690,8 @@ class Session : public PBD::StatefulDestructible /* flattening stuff */ - int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite, vector >&, - InterThreadInfo& wot); + boost::shared_ptr write_one_audio_track (AudioTrack&, nframes_t start, nframes_t end, bool overwrite, vector >&, + InterThreadInfo& wot); int freeze (InterThreadInfo&); /* session-wide solo/mute/rec-enable */ diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 9c99ecfd25..f99a29bcd1 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -76,8 +76,8 @@ class Track : public Route virtual void freeze (InterThreadInfo&) = 0; virtual void unfreeze () = 0; - virtual void bounce (InterThreadInfo&) = 0; - virtual void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0; + virtual boost::shared_ptr bounce (InterThreadInfo&) = 0; + virtual boost::shared_ptr bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0; XMLNode& get_state(); XMLNode& get_template(); diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 2b4f38c070..d3b5e442c7 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -763,19 +763,20 @@ AudioTrack::export_stuff (vector& buffers, uint32_t nbufs, nframes_t st return 0; } -void +boost::shared_ptr AudioTrack::bounce (InterThreadInfo& itt) { vector > srcs; - _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt); + return _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), + false, srcs, itt); } -void +boost::shared_ptr AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt) { vector > srcs; - _session.write_one_audio_track (*this, start, end, false, srcs, itt); + return _session.write_one_audio_track (*this, start, end, false, srcs, itt); } void @@ -816,7 +817,9 @@ AudioTrack::freeze (InterThreadInfo& itt) return; } - if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) { + boost::shared_ptr res; + + if ((res = _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) { return; } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 13358d99de..af0f31b1a4 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3949,11 +3949,11 @@ Session::freeze (InterThreadInfo& itt) return 0; } -int -Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len, +boost::shared_ptr +Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end, bool overwrite, vector >& srcs, InterThreadInfo& itt) { - int ret = -1; + boost::shared_ptr result; boost::shared_ptr playlist; boost::shared_ptr fsource; uint32_t x; @@ -3963,8 +3963,15 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le nframes_t position; nframes_t this_chunk; nframes_t to_do; + nframes_t len = end - start; vector buffers; + if (end <= start) { + error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"), + end, start) << endmsg; + return result; + } + // any bigger than this seems to cause stack overflows in called functions const nframes_t chunk_size = (128 * 1024)/4; @@ -4077,21 +4084,19 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le /* construct a region to represent the bounced material */ - boost::shared_ptr aregion = RegionFactory::create (srcs, 0, srcs.front()->length(), - region_name_from_path (srcs.front()->name(), true)); - - ret = 0; + result = RegionFactory::create (srcs, 0, srcs.front()->length(), + region_name_from_path (srcs.front()->name(), true)); } out: - if (ret) { + if (!result) { for (vector >::iterator src = srcs.begin(); src != srcs.end(); ++src) { boost::shared_ptr afs = boost::dynamic_pointer_cast(*src); if (afs) { afs->mark_for_remove (); } - + (*src)->drop_references (); } @@ -4102,14 +4107,14 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le } for (vector::iterator i = buffers.begin(); i != buffers.end(); ++i) { - free(*i); + free (*i); } g_atomic_int_set (&processing_prohibited, 0); itt.done = true; - return ret; + return result; } vector&