From 86ac707573a5f5124c4a26b4e48e9756415700c4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 Dec 2010 22:28:29 +0000 Subject: [PATCH] Stop bounce / freeze on tracks that have more outputs than inputs and so cannot record all the outputs in their diskstreams. Fix buffer shortage when bouncing tracks whose processing chains temporarily need more buffers than there are inputs. Fixes #3573. git-svn-id: svn://localhost/ardour2/branches/3.0@8239 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor_export_audio.cc | 20 +++++++++++++++++++- gtk2_ardour/editor_ops.cc | 26 ++++++++++++++++++++++++++ libs/ardour/ardour/audio_track.h | 2 ++ libs/ardour/ardour/midi_track.h | 4 ++++ libs/ardour/ardour/track.h | 5 +++++ libs/ardour/audio_track.cc | 5 +++++ libs/ardour/session.cc | 11 ++++++----- 7 files changed, 67 insertions(+), 6 deletions(-) diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 59109c508e..928a9809bc 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -25,6 +25,8 @@ #include +#include "gtkmm2ext/choice.h" + #include "export_dialog.h" #include "editor.h" #include "public_editor.h" @@ -137,11 +139,27 @@ Editor::write_region_selection (RegionSelection& regions) void Editor::bounce_region_selection () { + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + + RouteTimeAxisView* rtv = dynamic_cast (&(*i)->get_time_axis_view()); + boost::shared_ptr track = boost::dynamic_pointer_cast (rtv->route()); + + if (!track->bounceable()) { + MessageDialog d ( + _("One or more of the selected regions' tracks cannot be bounced because it has more outputs than inputs. " + "You can fix this by increasing the number of inputs on that track.") + ); + d.set_title (_("Cannot bounce")); + d.run (); + return; + } + } + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { boost::shared_ptr region ((*i)->region()); RouteTimeAxisView* rtv = dynamic_cast(&(*i)->get_time_axis_view()); - Track* track = dynamic_cast(rtv->route().get()); + boost::shared_ptr track = boost::dynamic_pointer_cast (rtv->route()); InterThreadInfo itt; diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 4bf5a70cd8..77b2f40bcc 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -3547,6 +3547,19 @@ Editor::freeze_route () return; } + if (!clicked_routeview->track()->bounceable()) { + RouteTimeAxisView* rtv = dynamic_cast (clicked_routeview); + if (rtv && !rtv->track()->bounceable()) { + MessageDialog d ( + _("This route cannot be frozen because it has more outputs than inputs. " + "You can fix this by increasing the number of inputs.") + ); + d.set_title (_("Cannot freeze")); + d.run (); + return; + } + } + InterThreadInfo itt; current_interthread_info = &itt; @@ -3573,6 +3586,19 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) TrackSelection views = selection->tracks; + for (TrackViewList::iterator i = views.begin(); i != views.end(); ++i) { + RouteTimeAxisView* rtv = dynamic_cast (*i); + if (rtv && !rtv->track()->bounceable()) { + MessageDialog d ( + _("One or more selected tracks cannot be bounced because it has more outputs than inputs. " + "You can fix this by increasing the number of inputs on that track.") + ); + d.set_title (_("Cannot bounce")); + d.run (); + return; + } + } + framepos_t start = selection->time[clicked_selection].start; framepos_t end = selection->time[clicked_selection].end; framepos_t cnt = end - start + 1; diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index b9c60d5107..80124300fd 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -61,6 +61,8 @@ class AudioTrack : public Track boost::shared_ptr write_source (uint32_t n = 0); + bool bounceable () const; + protected: boost::shared_ptr audio_diskstream () const; XMLNode& state (bool full); diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 60d2567c21..3c742bd3ce 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -103,6 +103,10 @@ public: uint16_t get_channel_mask (); boost::shared_ptr midi_playlist (); + bool bounceable () const { + return false; + } + PBD::Signal2, boost::weak_ptr > DataRecorded; protected: diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 5087ddda3a..36e6aefc23 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -99,6 +99,11 @@ class Track : public Route, public PublicDiskstream void set_block_size (pframes_t); + /** @return true if the track can be bounced, or false if it cannot because + * it has more outputs than diskstream channels. + */ + virtual bool bounceable () const = 0; + /* PublicDiskstream interface */ boost::shared_ptr playlist (); void monitor_input (bool); diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 0b963f19bc..41a8d4c7f0 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -729,3 +729,8 @@ AudioTrack::write_source (uint32_t n) return ds->write_source (n); } +bool +AudioTrack::bounceable () const +{ + return n_inputs().n_audio() >= n_outputs().n_audio(); +} diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 690fbc5e9a..11fd1fc635 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3599,7 +3599,7 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end, boost::shared_ptr fsource; uint32_t x; char buf[PATH_MAX+1]; - ChanCount nchans(track.n_channels()); + ChanCount diskstream_channels (track.n_channels()); framepos_t position; framecnt_t this_chunk; framepos_t to_do; @@ -3609,6 +3609,7 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end, framepos_t len = end - start; bool need_block_size_reset = false; string ext; + ChanCount const max_proc = track.max_processor_streams (); if (end <= start) { error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"), @@ -3636,7 +3637,7 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end, ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO); - for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) { + for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) { for (x = 0; x < 99999; ++x) { snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 "%s", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1, ext.c_str()); @@ -3674,10 +3675,10 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end, to_do = len; /* create a set of reasonably-sized buffers */ - buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size); - buffers.set_count(nchans); + buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size); + buffers.set_count (max_proc); - for (vector >::iterator src=srcs.begin(); src != srcs.end(); ++src) { + for (vector >::iterator src = srcs.begin(); src != srcs.end(); ++src) { boost::shared_ptr afs = boost::dynamic_pointer_cast(*src); if (afs) afs->prepare_for_peakfile_writes (); -- 2.30.2