Stop bounce / freeze on tracks that have more outputs than inputs and so cannot recor...
authorCarl Hetherington <carl@carlh.net>
Fri, 10 Dec 2010 22:28:29 +0000 (22:28 +0000)
committerCarl Hetherington <carl@carlh.net>
Fri, 10 Dec 2010 22:28:29 +0000 (22:28 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8239 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor_export_audio.cc
gtk2_ardour/editor_ops.cc
libs/ardour/ardour/audio_track.h
libs/ardour/ardour/midi_track.h
libs/ardour/ardour/track.h
libs/ardour/audio_track.cc
libs/ardour/session.cc

index 59109c508eac545a8575614386b45c418a982b33..928a9809bc714c4de153bf5efa1162067e863845 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <gtkmm/messagedialog.h>
 
+#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<RouteTimeAxisView*> (&(*i)->get_time_axis_view());
+               boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (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> region ((*i)->region());
                RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view());
-               Track* track = dynamic_cast<Track*>(rtv->route().get());
+               boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (rtv->route());
 
                InterThreadInfo itt;
 
index 4bf5a70cd8ba3a9bd9c5dd406b478d3c9a0ac308..77b2f40bcc5aa33e818ebac642f112aad083c5a7 100644 (file)
@@ -3547,6 +3547,19 @@ Editor::freeze_route ()
                return;
        }
 
+       if (!clicked_routeview->track()->bounceable()) {
+               RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (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<RouteTimeAxisView*> (*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;
index b9c60d5107a96f82edddb04bcaca846835ac34f2..80124300fd7a5c624e1e7ee4dad5a6152fb5495b 100644 (file)
@@ -61,6 +61,8 @@ class AudioTrack : public Track
 
        boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0);
 
+       bool bounceable () const;
+       
   protected:
        boost::shared_ptr<AudioDiskstream> audio_diskstream () const;
        XMLNode& state (bool full);
index 60d2567c21be929fc4ed791594590352bd0300f4..3c742bd3cece5173fbdf770ac88aa92caa588a65 100644 (file)
@@ -103,6 +103,10 @@ public:
        uint16_t get_channel_mask ();
        boost::shared_ptr<MidiPlaylist> midi_playlist ();
 
+       bool bounceable () const {
+               return false;
+       }
+       
        PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded;
 
 protected:
index 5087ddda3af9a1fdd64f7cb9656b7d4ffc8f410e..36e6aefc230f0124a05f00b9d0d6d60611aa5ad8 100644 (file)
@@ -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> playlist ();
        void monitor_input (bool);
index 0b963f19bc69a5849e5f04f864cad4cd1aab9364..41a8d4c7f0cea160bc908175b9a9f8f29763d10e 100644 (file)
@@ -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();
+}
index 690fbc5e9a7a44576bad9cfa2377a174674c251e..11fd1fc635508f33036a6e2e67a023996703dd03 100644 (file)
@@ -3599,7 +3599,7 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
        boost::shared_ptr<AudioFileSource> 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<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+       for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
                boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
                if (afs)
                        afs->prepare_for_peakfile_writes ();