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
This commit is contained in:
parent
8387e1bff8
commit
86ac707573
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include <gtkmm/messagedialog.h>
|
#include <gtkmm/messagedialog.h>
|
||||||
|
|
||||||
|
#include "gtkmm2ext/choice.h"
|
||||||
|
|
||||||
#include "export_dialog.h"
|
#include "export_dialog.h"
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include "public_editor.h"
|
#include "public_editor.h"
|
||||||
@ -137,11 +139,27 @@ Editor::write_region_selection (RegionSelection& regions)
|
|||||||
void
|
void
|
||||||
Editor::bounce_region_selection ()
|
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) {
|
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||||
|
|
||||||
boost::shared_ptr<Region> region ((*i)->region());
|
boost::shared_ptr<Region> region ((*i)->region());
|
||||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view());
|
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;
|
InterThreadInfo itt;
|
||||||
|
|
||||||
|
@ -3547,6 +3547,19 @@ Editor::freeze_route ()
|
|||||||
return;
|
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;
|
InterThreadInfo itt;
|
||||||
current_interthread_info = &itt;
|
current_interthread_info = &itt;
|
||||||
|
|
||||||
@ -3573,6 +3586,19 @@ Editor::bounce_range_selection (bool replace, bool enable_processing)
|
|||||||
|
|
||||||
TrackSelection views = selection->tracks;
|
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 start = selection->time[clicked_selection].start;
|
||||||
framepos_t end = selection->time[clicked_selection].end;
|
framepos_t end = selection->time[clicked_selection].end;
|
||||||
framepos_t cnt = end - start + 1;
|
framepos_t cnt = end - start + 1;
|
||||||
|
@ -61,6 +61,8 @@ class AudioTrack : public Track
|
|||||||
|
|
||||||
boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0);
|
boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0);
|
||||||
|
|
||||||
|
bool bounceable () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
boost::shared_ptr<AudioDiskstream> audio_diskstream () const;
|
boost::shared_ptr<AudioDiskstream> audio_diskstream () const;
|
||||||
XMLNode& state (bool full);
|
XMLNode& state (bool full);
|
||||||
|
@ -103,6 +103,10 @@ public:
|
|||||||
uint16_t get_channel_mask ();
|
uint16_t get_channel_mask ();
|
||||||
boost::shared_ptr<MidiPlaylist> midi_playlist ();
|
boost::shared_ptr<MidiPlaylist> midi_playlist ();
|
||||||
|
|
||||||
|
bool bounceable () const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded;
|
PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -99,6 +99,11 @@ class Track : public Route, public PublicDiskstream
|
|||||||
|
|
||||||
void set_block_size (pframes_t);
|
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 */
|
/* PublicDiskstream interface */
|
||||||
boost::shared_ptr<Playlist> playlist ();
|
boost::shared_ptr<Playlist> playlist ();
|
||||||
void monitor_input (bool);
|
void monitor_input (bool);
|
||||||
|
@ -729,3 +729,8 @@ AudioTrack::write_source (uint32_t n)
|
|||||||
return ds->write_source (n);
|
return ds->write_source (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AudioTrack::bounceable () const
|
||||||
|
{
|
||||||
|
return n_inputs().n_audio() >= n_outputs().n_audio();
|
||||||
|
}
|
||||||
|
@ -3599,7 +3599,7 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
|
|||||||
boost::shared_ptr<AudioFileSource> fsource;
|
boost::shared_ptr<AudioFileSource> fsource;
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
char buf[PATH_MAX+1];
|
char buf[PATH_MAX+1];
|
||||||
ChanCount nchans(track.n_channels());
|
ChanCount diskstream_channels (track.n_channels());
|
||||||
framepos_t position;
|
framepos_t position;
|
||||||
framecnt_t this_chunk;
|
framecnt_t this_chunk;
|
||||||
framepos_t to_do;
|
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;
|
framepos_t len = end - start;
|
||||||
bool need_block_size_reset = false;
|
bool need_block_size_reset = false;
|
||||||
string ext;
|
string ext;
|
||||||
|
ChanCount const max_proc = track.max_processor_streams ();
|
||||||
|
|
||||||
if (end <= start) {
|
if (end <= start) {
|
||||||
error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
|
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);
|
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) {
|
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());
|
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;
|
to_do = len;
|
||||||
|
|
||||||
/* create a set of reasonably-sized buffers */
|
/* create a set of reasonably-sized buffers */
|
||||||
buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
|
buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
|
||||||
buffers.set_count(nchans);
|
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);
|
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
|
||||||
if (afs)
|
if (afs)
|
||||||
afs->prepare_for_peakfile_writes ();
|
afs->prepare_for_peakfile_writes ();
|
||||||
|
Loading…
Reference in New Issue
Block a user