diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h index ceb049b29c..c8fa3d1798 100644 --- a/libs/ardour/ardour/destructive_filesource.h +++ b/libs/ardour/ardour/destructive_filesource.h @@ -43,6 +43,8 @@ class DestructiveFileSource : public FileSource { jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf); + XMLNode& get_state (); + private: static jack_nframes_t xfade_frames; static gain_t* out_coefficient; diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index 69ade5b170..a163c125d7 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -439,6 +439,7 @@ class DiskStream : public Stateful, public sigc::trackable void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record); void set_align_style_from_io(); void setup_destructive_playlist (); + void use_destructive_playlist (); }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 804e378a16..59ddd12c47 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -123,7 +123,6 @@ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) { sources.push_back (*i); master_sources.push_back (*i); - (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted)); } diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc index 3e535fbaf4..9081fc9b38 100644 --- a/libs/ardour/destructive_filesource.cc +++ b/libs/ardour/destructive_filesource.cc @@ -96,8 +96,6 @@ DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_ DestructiveFileSource::~DestructiveFileSource() { - delete [] out_coefficient; - delete [] in_coefficient; delete xfade_buf; } @@ -182,7 +180,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in, } if (file_cnt) { - if ((retval = file_read (xfade_buf, fade_position, xfade, workbuf)) != (ssize_t) xfade) { + if ((retval = file_read (xfade_buf, fade_position, file_cnt, workbuf)) != (ssize_t) file_cnt) { if (retval >= 0 && errno == EAGAIN) { /* XXX - can we really trust that errno is meaningful here? yes POSIX, i'm talking to you. * short or no data there */ @@ -200,7 +198,6 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in, } if (nofade && !fade_in) { - cerr << "write " << nofade << " frames of prefade OUT data to " << file_pos << " .. " << file_pos + nofade << endl; if (file_write (data, file_pos, nofade, workbuf) != (ssize_t) nofade) { error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; return 0; @@ -243,8 +240,6 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in, } if (xfade) { - cerr << "write " << xfade << " frames of xfade data to " << fade_position << " .. " << fade_position + xfade << endl; - if (file_write (xfade_buf, fade_position, xfade, workbuf) != (ssize_t) xfade) { error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; return 0; @@ -252,8 +247,6 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in, } if (fade_in && nofade) { - cerr << "write " << nofade << " frames of postfade IN data to " << file_pos + xfade << " .. " - << file_pos + xfade + nofade << endl; if (file_write (data + xfade, file_pos + xfade, nofade, workbuf) != (ssize_t) nofade) { error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; return 0; @@ -330,11 +323,11 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf) oldlen = _length; if (file_pos + cnt > _length) { - _length += cnt; + _length = file_pos + cnt; } file_pos += cnt; - - cerr << "at end of write, file_pos = " << file_pos << endl; + + cerr << this << ' ' << _name << " at end of write, file_pos = " << file_pos << " length = " << ((int) &_length - (int) this) << ' ' << &_length << ' ' << _length << endl; if (_build_peakfiles) { PeakBuildRecord *pbr = 0; @@ -372,3 +365,11 @@ DestructiveFileSource::last_capture_start_frame () const { return capture_start_frame; } + +XMLNode& +DestructiveFileSource::get_state () +{ + XMLNode& node = FileSource::get_state (); + node.add_property (X_("destructive"), "true"); + return node; +} diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 2a2ab3aa62..c40094dde0 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -73,6 +73,10 @@ DiskStream::DiskStream (Session &sess, const string &name, Flag flag) use_new_playlist (); in_set_state = false; + if (destructive()) { + setup_destructive_playlist (); + } + DiskStreamCreated (this); /* EMIT SIGNAL */ } @@ -90,6 +94,10 @@ DiskStream::DiskStream (Session& sess, const XMLNode& node) in_set_state = false; + if (destructive()) { + use_destructive_playlist (); + } + DiskStreamCreated (this); /* EMIT SIGNAL */ } @@ -406,17 +414,7 @@ DiskStream::use_new_playlist () if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) { playlist->set_orig_diskstream_id (id()); - - if (use_playlist (playlist)) { - return -1; - } - - if (destructive()) { - setup_destructive_playlist (); - } - - return 0; - + return use_playlist (playlist); } else { return -1; } @@ -462,6 +460,22 @@ DiskStream::setup_destructive_playlist () _playlist->add_region (*region, 0); } +void +DiskStream::use_destructive_playlist () +{ + /* use the sources associated with the single full-extent region */ + + AudioRegion* region = dynamic_cast (_playlist->regions_at (0)->front()); + uint32_t n; + ChannelList::iterator chan; + + for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) { + (*chan).write_source = dynamic_cast(®ion->source (n)); + } + + /* the source list will never be reset for a destructive track */ +} + void DiskStream::set_io (IO& io) { @@ -2122,7 +2136,8 @@ DiskStream::set_state (const XMLNode& node) capturing_sources.clear (); - if (recordable()) { + if (recordable() && !destructive()) { + /* destructive diskstreams get their sources set up elsewhere */ reset_write_sources (false); } @@ -2169,6 +2184,8 @@ DiskStream::use_new_write_source (uint32_t n) return -1; } + cerr << _name << " using a new source " << chan.write_source << " for channel " << n << endl; + chan.write_source->use (); return 0; diff --git a/libs/ardour/filesource.cc b/libs/ardour/filesource.cc index 303113174d..3451239d3b 100644 --- a/libs/ardour/filesource.cc +++ b/libs/ardour/filesource.cc @@ -989,7 +989,7 @@ FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt } if (file_cnt) { - if (file_read(dst, start, file_cnt, workbuf) != (ssize_t) cnt) { + if (file_read(dst, start, file_cnt, workbuf) != (ssize_t) file_cnt) { return 0; } } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index bd80ad50a5..acd6829e93 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -1801,8 +1802,13 @@ Session::XMLSourceFactory (const XMLNode& node) return 0; } + try { - src = new FileSource (node, frame_rate()); + if (node.property (X_("destructive")) != 0) { + src = new DestructiveFileSource (node, frame_rate()); + } else { + src = new FileSource (node, frame_rate()); + } } catch (failed_constructor& err) {