+bool
+AudioTrack::bounceable (boost::shared_ptr<Processor> endpoint, bool include_endpoint) const
+{
+ if (!endpoint && !include_endpoint) {
+ /* no processing - just read from the playlist and create new
+ files: always possible.
+ */
+ return true;
+ }
+
+ Glib::RWLock::ReaderLock lm (_processor_lock);
+ uint32_t naudio = n_inputs().n_audio();
+
+ for (ProcessorList::const_iterator r = _processors.begin(); r != _processors.end(); ++r) {
+
+ /* if we're not including the endpoint, potentially stop
+ right here before we test matching i/o valences.
+ */
+
+ if (!include_endpoint && (*r) == endpoint) {
+ return true;
+ }
+
+ /* ignore any processors that do routing, because we will not
+ * use them during a bounce/freeze/export operation.
+ */
+
+ if ((*r)->does_routing()) {
+ continue;
+ }
+
+ /* does the output from the last considered processor match the
+ * input to this one?
+ */
+
+ if (naudio != (*r)->input_streams().n_audio()) {
+ return false;
+ }
+
+ /* we're including the endpoint - if we just hit it,
+ then stop.
+ */
+
+ if ((*r) == endpoint) {
+ return true;
+ }
+
+ /* save outputs of this processor to test against inputs
+ of the next one.
+ */
+
+ naudio = (*r)->output_streams().n_audio();
+ }
+
+ return true;
+}
+