summaryrefslogtreecommitdiff
path: root/libs/ardour/session.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/session.cc')
-rw-r--r--libs/ardour/session.cc312
1 files changed, 158 insertions, 154 deletions
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 7d5f838499..0a85c47cb9 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -71,6 +71,7 @@
#include <ardour/click.h>
#include <ardour/data_type.h>
#include <ardour/buffer_set.h>
+#include <ardour/source_factory.h>
#ifdef HAVE_LIBLO
#include <ardour/osc.h>
@@ -282,10 +283,12 @@ Session::Session (AudioEngine &eng,
first_stage_init (fullpath, snapshot_name);
if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
+ cerr << "create failed\n";
throw failed_constructor ();
}
if (second_stage_init (new_session)) {
+ cerr << "2nd state failed\n";
throw failed_constructor ();
}
@@ -386,9 +389,23 @@ Session::~Session ()
_state_of_the_state = StateOfTheState (CannotSave|Deletion);
_engine.remove_session ();
+
+ GoingAway (); /* EMIT SIGNAL */
- going_away (); /* EMIT SIGNAL */
+ /* do this */
+
+ notify_callbacks ();
+
+ /* clear history so that no references to objects are held any more */
+
+ history.clear ();
+
+ /* clear state tree so that no references to objects are held any more */
+ if (state_tree) {
+ delete state_tree;
+ }
+
terminate_butler_thread ();
//terminate_midi_thread ();
@@ -439,16 +456,12 @@ Session::~Session ()
#ifdef TRACK_DESTRUCTION
cerr << "delete regions\n";
#endif /* TRACK_DESTRUCTION */
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
- RegionList::iterator tmp;
-
- tmp =i;
- ++tmp;
-
- delete i->second;
-
- i = tmp;
+
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ i->second->drop_references ();
}
+
+ regions.clear ();
#ifdef TRACK_DESTRUCTION
cerr << "delete routes\n";
@@ -456,12 +469,8 @@ Session::~Session ()
{
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> r = writer.get_copy ();
- for (RouteList::iterator i = r->begin(); i != r->end(); ) {
- RouteList::iterator tmp;
- tmp = i;
- ++tmp;
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->drop_references ();
- i = tmp;
}
r->clear ();
/* writer goes out of scope and updates master */
@@ -475,15 +484,8 @@ Session::~Session ()
{
RCUWriter<DiskstreamList> dwriter (diskstreams);
boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
- DiskstreamList::iterator tmp;
-
- tmp = i;
- ++tmp;
-
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->drop_references ();
-
- i = tmp;
}
dsl->clear ();
}
@@ -492,17 +494,19 @@ Session::~Session ()
#ifdef TRACK_DESTRUCTION
cerr << "delete audio sources\n";
#endif /* TRACK_DESTRUCTION */
- for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
- SourceList::iterator tmp;
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
+ SourceMap::iterator tmp;
tmp = i;
++tmp;
- delete i->second;
+ i->second->drop_references ();
i = tmp;
}
+ sources.clear ();
+
#ifdef TRACK_DESTRUCTION
cerr << "delete mix groups\n";
#endif /* TRACK_DESTRUCTION */
@@ -558,10 +562,6 @@ Session::~Session ()
if (mmc) {
delete mmc;
}
-
- if (state_tree) {
- delete state_tree;
- }
}
void
@@ -2712,8 +2712,9 @@ Session::region_name (string& result, string base, bool newlevel) const
}
void
-Session::add_region (Region* region)
+Session::add_region (boost::shared_ptr<Region> region)
{
+ boost::shared_ptr<Region> other;
bool added = false;
{
@@ -2723,7 +2724,9 @@ Session::add_region (Region* region)
for (x = regions.begin(); x != regions.end(); ++x) {
- if (region->region_list_equivalent (*x->second)) {
+ other = x->second;
+
+ if (region->region_list_equivalent (other)) {
break;
}
}
@@ -2737,6 +2740,7 @@ Session::add_region (Region* region)
pair<RegionList::iterator,bool> x = regions.insert (entry);
+
if (!x.second) {
return;
}
@@ -2748,19 +2752,19 @@ Session::add_region (Region* region)
/* mark dirty because something has changed even if we didn't
add the region to the region list.
- */
-
+ */
+
set_dirty();
-
+
if (added) {
- region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
+ region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
RegionAdded (region); /* EMIT SIGNAL */
}
}
void
-Session::region_changed (Change what_changed, Region* region)
+Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (what_changed & Region::HiddenChanged) {
/* relay hidden changes */
@@ -2769,17 +2773,17 @@ Session::region_changed (Change what_changed, Region* region)
}
void
-Session::region_renamed (Region* region)
+Session::region_renamed (boost::shared_ptr<Region> region)
{
add_region (region);
}
void
-Session::remove_region (Region* region)
+Session::remove_region (boost::shared_ptr<Region> region)
{
RegionList::iterator i;
bool removed = false;
-
+
{
Glib::Mutex::Lock lm (region_lock);
@@ -2787,25 +2791,25 @@ Session::remove_region (Region* region)
regions.erase (i);
removed = true;
}
-
}
/* mark dirty because something has changed even if we didn't
remove the region from the region list.
- */
+ */
set_dirty();
if (removed) {
- RegionRemoved(region); /* EMIT SIGNAL */
+ RegionRemoved(region); /* EMIT SIGNAL */
}
}
-Region*
+boost::shared_ptr<Region>
Session::find_whole_file_parent (Region& child)
{
RegionList::iterator i;
- Region* region;
+ boost::shared_ptr<Region> region;
+
Glib::Mutex::Lock lm (region_lock);
for (i = regions.begin(); i != regions.end(); ++i) {
@@ -2814,49 +2818,51 @@ Session::find_whole_file_parent (Region& child)
if (region->whole_file()) {
- if (child.source_equivalent (*region)) {
+ if (child.source_equivalent (region)) {
return region;
}
}
}
- return 0;
+ return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
}
void
-Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
+Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
{
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
(*i)->get_region_list_equivalent_regions (region, result);
}
int
-Session::destroy_region (Region* region)
+Session::destroy_region (boost::shared_ptr<Region> region)
{
- AudioRegion* aregion;
+ boost::shared_ptr<AudioRegion> aregion;
- if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
+ if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
return 0;
}
-
+
if (aregion->playlist()) {
aregion->playlist()->destroy_region (region);
}
- vector<Source*> srcs;
+ vector<boost::shared_ptr<Source> > srcs;
for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
- srcs.push_back (&aregion->source (n));
+ srcs.push_back (aregion->source (n));
}
- for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
+ for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
- if ((*i)->use_cnt() == 0) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
+ if ((*i).use_count() == 1) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
+
if (afs) {
(afs)->mark_for_remove ();
}
- delete *i;
+
+ (*i)->drop_references ();
}
}
@@ -2864,9 +2870,9 @@ Session::destroy_region (Region* region)
}
int
-Session::destroy_regions (list<Region*> regions)
+Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
{
- for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
+ for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
destroy_region (*i);
}
return 0;
@@ -2875,12 +2881,12 @@ Session::destroy_regions (list<Region*> regions)
int
Session::remove_last_capture ()
{
- list<Region*> r;
+ list<boost::shared_ptr<Region> > r;
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- list<Region*>& l = (*i)->last_capture_regions();
+ list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
if (!l.empty()) {
r.insert (r.end(), l.begin(), l.end());
@@ -2893,62 +2899,77 @@ Session::remove_last_capture ()
}
int
-Session::remove_region_from_region_list (Region& r)
+Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
{
- remove_region (&r);
+ remove_region (r);
return 0;
}
/* Source Management */
void
-Session::add_source (Source* source)
+Session::add_source (boost::shared_ptr<Source> source)
{
- pair<SourceList::key_type, SourceList::mapped_type> entry;
+ cerr << "add new source " << source->name() << endl;
+
+ pair<SourceMap::key_type, SourceMap::mapped_type> entry;
+ pair<SourceMap::iterator,bool> result;
- {
- Glib::Mutex::Lock lm (source_lock);
- entry.first = source->id();
- entry.second = source;
- sources.insert (entry);
- }
+ entry.first = source->id();
+ entry.second = source;
- source->GoingAway.connect (mem_fun (this, &Session::remove_source));
+ {
+ Glib::Mutex::Lock lm (source_lock);
+ result = sources.insert (entry);
+ }
+
+ if (!result.second) {
+ cerr << "\tNOT inserted ? " << result.second << endl;
+ }
+
+ source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
set_dirty();
SourceAdded (source); /* EMIT SIGNAL */
}
void
-Session::remove_source (Source* source)
+Session::remove_source (boost::weak_ptr<Source> src)
{
- SourceList::iterator i;
+ SourceMap::iterator i;
+ boost::shared_ptr<Source> source = src.lock();
- {
- Glib::Mutex::Lock lm (source_lock);
-
- if ((i = sources.find (source->id())) != sources.end()) {
- sources.erase (i);
- }
- }
-
- if (!_state_of_the_state & InCleanup) {
-
- /* save state so we don't end up with a session file
- referring to non-existent sources.
- */
+ if (!source) {
+ cerr << "removing a source DEAD\n";
+ } else {
+ cerr << "removing a source " << source->name () << endl;
- save_state (_current_snapshot_name);
+ {
+ Glib::Mutex::Lock lm (source_lock);
+
+ if ((i = sources.find (source->id())) != sources.end()) {
+ sources.erase (i);
+ }
+ }
+
+ if (!_state_of_the_state & InCleanup) {
+
+ /* save state so we don't end up with a session file
+ referring to non-existent sources.
+ */
+
+ save_state (_current_snapshot_name);
+ }
+
+ SourceRemoved(source); /* EMIT SIGNAL */
}
-
- SourceRemoved(source); /* EMIT SIGNAL */
}
-Source *
+boost::shared_ptr<Source>
Session::source_by_id (const PBD::ID& id)
{
Glib::Mutex::Lock lm (source_lock);
- SourceList::iterator i;
- Source* source = 0;
+ SourceMap::iterator i;
+ boost::shared_ptr<Source> source;
if ((i = sources.find (id)) != sources.end()) {
source = i->second;
@@ -3194,24 +3215,11 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
return spath;
}
-AudioFileSource *
+boost::shared_ptr<AudioFileSource>
Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
{
string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
-
- /* this might throw failed_constructor(), which is OK */
-
- if (destructive) {
- return new DestructiveFileSource (spath,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
- } else {
- return new SndFileSource (spath,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
- }
+ return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, spath, destructive, frame_rate()));
}
string
@@ -3277,13 +3285,12 @@ Session::midi_path_from_name (string name)
return spath;
}
-MidiSource *
+boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (MidiDiskstream& ds)
{
string spath = midi_path_from_name (ds.name());
-
- /* this might throw failed_constructor(), which is OK */
- return new SMFSource (spath);
+
+ return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, spath, false, frame_rate()));
}
@@ -3319,7 +3326,7 @@ Session::add_playlist (Playlist* playlist)
playlists.insert (playlists.begin(), playlist);
// playlist->ref();
playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
- playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
+ playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
}
}
@@ -3390,7 +3397,7 @@ Session::remove_playlist (Playlist* playlist)
}
void
-Session::set_audition (AudioRegion* r)
+Session::set_audition (boost::shared_ptr<Region> r)
{
pending_audition_region = r;
post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
@@ -3398,42 +3405,39 @@ Session::set_audition (AudioRegion* r)
}
void
+Session::audition_playlist ()
+{
+ Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
+ ev->region.reset ();
+ queue_event (ev);
+}
+
+void
Session::non_realtime_set_audition ()
{
- if (pending_audition_region == (AudioRegion*) 0xfeedface) {
+ if (!pending_audition_region) {
auditioner->audition_current_playlist ();
- } else if (pending_audition_region) {
- auditioner->audition_region (*pending_audition_region);
+ } else {
+ auditioner->audition_region (pending_audition_region);
+ pending_audition_region.reset ();
}
- pending_audition_region = 0;
AuditionActive (true); /* EMIT SIGNAL */
}
void
-Session::audition_playlist ()
+Session::audition_region (boost::shared_ptr<Region> r)
{
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr ((void*) 0xfeedface);
+ ev->region = r;
queue_event (ev);
}
void
-Session::audition_region (Region& r)
-{
- AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
- if (ar) {
- Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr (ar);
- queue_event (ev);
- }
-}
-
-void
Session::cancel_audition ()
{
if (auditioner->active()) {
auditioner->cancel_audition ();
- AuditionActive (false); /* EMIT SIGNAL */
+ AuditionActive (false); /* EMIT SIGNAL */
}
}
@@ -3600,7 +3604,7 @@ Session::add_redirect (Redirect* redirect)
/*NOTREACHED*/
}
- redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
+ redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
set_dirty();
}
@@ -3822,9 +3826,9 @@ Session::route_name_unique (string n) const
}
int
-Session::cleanup_audio_file_source (AudioFileSource& fs)
+Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
{
- return fs.move_to_trash (dead_sound_dir_name);
+ return fs->move_to_trash (dead_sound_dir_name);
}
uint32_t
@@ -3891,11 +3895,12 @@ Session::freeze (InterThreadInfo& itt)
int
Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
- bool overwrite, vector<Source*>& srcs, InterThreadInfo& itt)
+ bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
{
+ boost::shared_ptr<AudioFileSource> fsource;
+
int ret = -1;
Playlist* playlist = 0;
- AudioFileSource* fsource = 0;
uint32_t x;
char buf[PATH_MAX+1];
string dir;
@@ -3939,11 +3944,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
}
try {
- fsource = new SndFileSource (buf,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
-
+ fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, buf, false, frame_rate()));
}
catch (failed_constructor& err) {
@@ -3951,7 +3952,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
goto out;
}
- srcs.push_back(fsource);
+ srcs.push_back (fsource);
}
/* XXX need to flush all redirects */
@@ -3972,9 +3973,9 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
}
uint32_t n = 0;
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
-
+ for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
goto out;
@@ -3996,8 +3997,9 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
time (&now);
xnow = localtime (&now);
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*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->update_header (position, *xnow, now);
}
@@ -4005,8 +4007,8 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
/* build peakfile for new source */
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*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->build_peaks ();
}
@@ -4017,12 +4019,14 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
out:
if (ret) {
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*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->mark_for_remove ();
}
- delete *src;
+
+ (*src)->drop_references ();
}
}