diff options
author | David Robillard <d@drobilla.net> | 2006-11-19 16:45:16 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-11-19 16:45:16 +0000 |
commit | ef6b25432d9c46d71b08c0f7d5f2686df428c4e8 (patch) | |
tree | 9b30d87b6670aadce365c9b112321dd674a0bab4 /libs/ardour/audio_diskstream.cc | |
parent | af105afe6cde5b0088647cea7d5e4e3314f8478b (diff) |
Merged with trunk R1141
git-svn-id: svn://localhost/ardour2/branches/midi@1142 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/audio_diskstream.cc')
-rw-r--r-- | libs/ardour/audio_diskstream.cc | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index f08d38a9b9..9c5f5233b7 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -383,7 +383,7 @@ AudioDiskstream::setup_destructive_playlist () void AudioDiskstream::use_destructive_playlist () { - /* this is called from the XML-based constructor. when its done, + /* this is called from the XML-based constructor or ::set_destructive. when called, we already have a playlist and a region, but we need to set up our sources for write. we use the sources associated with the (presumed single, full-extent) region. @@ -402,6 +402,10 @@ AudioDiskstream::use_destructive_playlist () throw failed_constructor(); } + /* be sure to stretch the region out to the maximum length */ + + region->set_length (max_frames - region->position(), this); + uint32_t n; ChannelList::iterator chan; @@ -409,6 +413,10 @@ AudioDiskstream::use_destructive_playlist () (*chan).write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n)); assert((*chan).write_source); (*chan).write_source->set_allow_remove_if_empty (false); + + /* this might be false if we switched modes, so force it */ + + (*chan).write_source->set_destructive (true); } /* the source list will never be reset for a destructive track */ @@ -1544,6 +1552,9 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca } else { + string whole_file_region_name; + whole_file_region_name = region_name_from_path (channels[0].write_source->name()); + /* Register a new region with the Session that describes the entire source. Do this first so that any sub-regions will obviously be @@ -1552,7 +1563,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca try { boost::shared_ptr<Region> rx (RegionFactory::create (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, - region_name_from_path (channels[0].write_source->name()), + whole_file_region_name, 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile))); region = boost::dynamic_pointer_cast<AudioRegion> (rx); @@ -1575,7 +1586,8 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { string region_name; - _session.region_name (region_name, channels[0].write_source->name(), false); + + _session.region_name (region_name, whole_file_region_name, false); // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl; @@ -1589,9 +1601,9 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca continue; /* XXX is this OK? */ } - _last_capture_regions.push_back (region); + region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region))); - // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl; + _last_capture_regions.push_back (region); i_am_the_modifier++; _playlist->add_region (region, (*ci)->start); @@ -2234,3 +2246,70 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node) return 0; } + +int +AudioDiskstream::set_destructive (bool yn) +{ + bool bounce_ignored; + + if (yn != destructive()) { + + if (yn) { + /* requestor should already have checked this and + bounced if necessary and desired + */ + if (!can_become_destructive (bounce_ignored)) { + return -1; + } + _flags |= Destructive; + use_destructive_playlist (); + } else { + _flags &= ~Destructive; + reset_write_sources (true, true); + } + } + + return 0; +} + +bool +AudioDiskstream::can_become_destructive (bool& requires_bounce) const +{ + if (!_playlist) { + requires_bounce = false; + return false; + } + + /* is there only one region ? */ + + if (_playlist->n_regions() != 1) { + requires_bounce = true; + return false; + } + + boost::shared_ptr<Region> first = _playlist->find_next_region (_session.current_start_frame(), Start, 1); + assert (first); + + /* do the source(s) for the region cover the session start position ? */ + + if (first->position() != _session.current_start_frame()) { + if (first->start() > _session.current_start_frame()) { + requires_bounce = true; + return false; + } + } + + /* is the source used by only 1 playlist ? */ + + boost::shared_ptr<AudioRegion> afirst = boost::dynamic_pointer_cast<AudioRegion> (first); + + assert (afirst); + + if (afirst->source()->used() > 1) { + requires_bounce = true; + return false; + } + + requires_bounce = false; + return true; +} |