Merged with trunk
[ardour.git] / libs / ardour / session_state.cc
index 602ac943149fc845080a1a36035c40e4112bce43..edcc52d729d12dff9f47445fb8dbe5e1c882da86 100644 (file)
 #include <sys/param.h>
 #endif
 
+#include <glibmm.h>
+
 #include <midi++/mmc.h>
 #include <midi++/port.h>
 #include <pbd/error.h>
-#include <pbd/dirname.h>
-#include <pbd/lockmonitor.h>
+
+#include <glibmm/thread.h>
 #include <pbd/pathscanner.h>
 #include <pbd/pthread_utils.h>
-#include <pbd/basename.h>
 #include <pbd/strsplit.h>
 
 #include <ardour/audioengine.h>
 #include <ardour/configuration.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/utils.h>
 #include <ardour/audioplaylist.h>
-#include <ardour/source.h>
-#include <ardour/filesource.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/destructive_filesource.h>
-#include <ardour/sndfilesource.h>
 #include <ardour/sndfile_helpers.h>
 #include <ardour/auditioner.h>
 #include <ardour/export.h>
@@ -118,7 +117,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        _tempo_map = new TempoMap (_current_frame_rate);
        _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
 
-       atomic_set (&processing_prohibited, 0);
+       g_atomic_int_set (&processing_prohibited, 0);
        send_cnt = 0;
        insert_cnt = 0;
        _transport_speed = 0;
@@ -129,7 +128,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
        start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
        _end_location_is_free = true;
-       atomic_set (&_record_status, Disabled);
+       g_atomic_int_set (&_record_status, Disabled);
        auto_play = false;
        punch_in = false;
        punch_out = false;
@@ -150,7 +149,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        state_was_pending = false;
        set_next_event ();
        outbound_mtc_smpte_frame = 0;
-       next_quarter_frame_to_send = 0;
+       next_quarter_frame_to_send = -1;
        current_block_size = 0;
        _solo_latched = true;
        _solo_model = InverseMute;
@@ -170,12 +169,12 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        midi_control = true;
        mmc = 0;
        post_transport_work = PostTransportWork (0);
-       atomic_set (&butler_should_do_transport_work, 0);
-       atomic_set (&butler_active, 0);
-       atomic_set (&_playback_load, 100);
-       atomic_set (&_capture_load, 100);
-       atomic_set (&_playback_load_min, 100);
-       atomic_set (&_capture_load_min, 100);
+       g_atomic_int_set (&butler_should_do_transport_work, 0);
+       g_atomic_int_set (&butler_active, 0);
+       g_atomic_int_set (&_playback_load, 100);
+       g_atomic_int_set (&_capture_load, 100);
+       g_atomic_int_set (&_playback_load_min, 100);
+       g_atomic_int_set (&_capture_load_min, 100);
        pending_audition_region = 0;
        _edit_mode = Slide;
        pending_edit_mode = _edit_mode;
@@ -195,12 +194,13 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        destructive_index = 0;
 
        /* allocate conversion buffers */
-       _conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
-       _conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
+       _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
+       _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
        
        /* default short fade = 15ms */
 
        Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
+       DestructiveFileSource::setup_standard_crossfades (frame_rate());
 
        last_mmc_step.tv_sec = 0;
        last_mmc_step.tv_usec = 0;
@@ -266,10 +266,10 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        /* These are all static "per-class" signals */
 
        Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
-       Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
+       AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
        Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
        Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
-       DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
+       AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
        NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
 
        IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
@@ -284,7 +284,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 int
 Session::second_stage_init (bool new_session)
 {
-       ExternalSource::set_peak_dir (peak_dir());
+       AudioFileSource::set_peak_dir (peak_dir());
 
        if (!new_session) {
                if (load_state (_current_snapshot_name)) {
@@ -297,11 +297,9 @@ Session::second_stage_init (bool new_session)
                return -1;
        }
 
-       /* FIXME
-       if (start_midi_thread ()) {
+       /*if (start_midi_thread ()) {
                return -1;
-       }
-       */
+       }*/
 
        if (state_tree) {
                if (set_state (*state_tree->root())) {
@@ -338,11 +336,10 @@ Session::second_stage_init (bool new_session)
                first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
        }
 
-       // FIXME
        //send_full_time_code ();
        _engine.transport_locate (0);
-       //deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
-       //deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
+       deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
+       deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
 
        ControlProtocolManager::instance().set_session (*this);
 
@@ -427,7 +424,7 @@ Session::setup_raid_path (string path)
                }
                fspath += tape_dir_name;
                
-               FileSource::set_search_path (fspath);
+               AudioFileSource::set_search_path (fspath);
 
                return;
        }
@@ -483,9 +480,9 @@ Session::setup_raid_path (string path)
                session_dirs.push_back (sp);
        }
 
-       /* set the FileSource search path */
+       /* set the AudioFileSource search path */
 
-       FileSource::set_search_path (fspath);
+       AudioFileSource::set_search_path (fspath);
 
        /* reset the round-robin soundfile path thingie */
 
@@ -627,11 +624,11 @@ Session::load_diskstreams (const XMLNode& node)
 
        for (citer = clist.begin(); citer != clist.end(); ++citer) {
                
-               DiskStream* dstream;
+               AudioDiskstream* dstream;
 
                try {
-                       dstream = new DiskStream (*this, **citer);
-                       /* added automatically by DiskStreamCreated handler */
+                       dstream = new AudioDiskstream (*this, **citer);
+                       /* added automatically by AudioDiskstreamCreated handler */
                } 
                
                catch (failed_constructor& err) {
@@ -1337,15 +1334,15 @@ Session::state(bool full_state)
        child = node->add_child ("Sources");
 
        if (full_state) {
-               LockMonitor sl (source_lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock sl (audio_source_lock);
 
-               for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
+               for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
                        
-                       /* Don't save information about FileSources that are empty */
+                       /* Don't save information about AudioFileSources that are empty */
                        
-                       FileSource* fs;
+                       AudioFileSource* fs;
 
-                       if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
+                       if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
                                DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
 
                                /* destructive file sources are OK if they are empty, because
@@ -1366,7 +1363,7 @@ Session::state(bool full_state)
        child = node->add_child ("Regions");
 
        if (full_state) { 
-               LockMonitor rl (region_lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock rl (region_lock);
 
                for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
                        
@@ -1381,8 +1378,8 @@ Session::state(bool full_state)
        child = node->add_child ("DiskStreams");
 
        { 
-               RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               Glib::RWLock::ReaderLock dl (diskstream_lock);
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if (!(*i)->hidden()) {
                                child->add_child_nocopy ((*i)->get_state());
                        }
@@ -1393,7 +1390,7 @@ Session::state(bool full_state)
        
        child = node->add_child ("Connections");
        {
-               LockMonitor lm (connection_lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (connection_lock);
                for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
                        if (!(*i)->system_dependent()) {
                                child->add_child_nocopy ((*i)->get_state());
@@ -1403,7 +1400,7 @@ Session::state(bool full_state)
 
        child = node->add_child ("Routes");
        {
-               RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
+               Glib::RWLock::ReaderLock lm (route_lock);
                
                RoutePublicOrderSorter cmp;
                RouteList public_order(routes);
@@ -1513,7 +1510,7 @@ Session::set_state (const XMLNode& node)
        Options
        Sources
        AudioRegions
-       DiskStreams
+       AudioDiskstreams
        Connections
        Locations
        Routes
@@ -1747,6 +1744,7 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
        const XMLProperty* prop;
        id_t s_id;
        Source* source;
+       AudioSource* as;
        AudioRegion::SourceList sources;
        uint32_t nchans = 1;
        char buf[128];
@@ -1774,7 +1772,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
                return 0;
        }
 
-       sources.push_back(source);
+       as = dynamic_cast<AudioSource*>(source);
+       if (!as) {
+               error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
+               return 0;
+       }
+
+       sources.push_back (as);
 
        /* pickup other channels */
 
@@ -1787,7 +1791,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
                                error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
                                return 0;
                        }
-                       sources.push_back(source);
+                       
+                       as = dynamic_cast<AudioSource*>(source);
+                       if (!as) {
+                               error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
+                               return 0;
+                       }
+                       sources.push_back (as);
                }
        }
        
@@ -1806,12 +1816,14 @@ Session::get_sources_as_xml ()
 
 {
        XMLNode* node = new XMLNode (X_("Sources"));
-       LockMonitor lm (source_lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock lm (audio_source_lock);
 
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
                node->add_child_nocopy ((*i).second->get_state());
        }
 
+       /* XXX get MIDI and other sources here */
+
        return *node;
 }
 
@@ -1869,23 +1881,12 @@ Session::XMLSourceFactory (const XMLNode& node)
        }
 
        try {
-               if (node.property (X_("destructive")) != 0) {
-                       src = new DestructiveFileSource (node, frame_rate());
-               } else {
-                       src = new FileSource (node, frame_rate());
-               }
+               src = AudioFileSource::create (node);
        }
        
        catch (failed_constructor& err) {
-
-               try {
-                       src = ExternalSource::create (node);
-               }
-
-               catch (failed_constructor& err) {
-                       error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
-                       return 0;
-               } 
+               error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
+               return 0;
        }
 
        return src;
@@ -1961,7 +1962,7 @@ Session::refresh_disk_space ()
 #if HAVE_SYS_VFS_H
        struct statfs statfsbuf;
        vector<space_and_path>::iterator i;
-       LockMonitor lm (space_lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock lm (space_lock);
        double scale;
 
        /* get freespace on every FS that is part of the session path */
@@ -2402,7 +2403,7 @@ Session::load_route_groups (const XMLNode& node, bool edit)
 void
 Session::swap_configuration(Configuration** new_config)
 {
-       RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
+       Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
        Configuration* tmp = *new_config;
        *new_config = Config;
        Config = tmp;
@@ -2412,7 +2413,7 @@ Session::swap_configuration(Configuration** new_config)
 void
 Session::copy_configuration(Configuration* new_config)
 {
-       RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
+       Glib::RWLock::WriterLock lm (route_lock);
        new_config = new Configuration(*Config);
 }
 
@@ -2591,7 +2592,7 @@ Session::GlobalRouteBooleanState
 Session::get_global_route_boolean (bool (Route::*method)(void) const)
 {
        GlobalRouteBooleanState s;
-       RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
+       Glib::RWLock::ReaderLock lm (route_lock);
 
        for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
                if (!(*i)->hidden()) {
@@ -2611,7 +2612,7 @@ Session::GlobalRouteMeterState
 Session::get_global_route_metering ()
 {
        GlobalRouteMeterState s;
-       RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
+       Glib::RWLock::ReaderLock lm (route_lock);
 
        for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
                if (!(*i)->hidden()) {
@@ -2932,9 +2933,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
        rep.paths.clear ();
        rep.space = 0;
 
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
 
-               SourceList::iterator tmp;
+               AudioSourceList::iterator tmp;
 
                tmp = i;
                ++tmp;
@@ -2951,7 +2952,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                           adding it to the list of all sources below
                        */
 
-                       sources.erase (i);
+                       audio_sources.erase (i);
                }
 
                i = tmp;
@@ -3015,20 +3016,17 @@ Session::cleanup_sources (Session::cleanup_report& rep)
           state file on disk still references sources we may have already
           dropped.
        */
-
+       
        find_all_sources_across_snapshots (all_sources, true);
 
-       /* add our current source list
+       /*  add our current source list
         */
-
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
-               FileSource* fs;
-               ExternalSource* sfs;
+       
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
+               AudioFileSource* fs;
                
-               if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
+               if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
                        all_sources.insert (fs->path());
-               } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
-                       all_sources.insert (sfs->path());
                } 
        }
 
@@ -3068,13 +3066,13 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                   on whichever filesystem it was already on.
                */
 
-               newpath = PBD::dirname (*x);
-               newpath = PBD::dirname (newpath);
+               newpath = Glib::path_get_dirname (*x);
+               newpath = Glib::path_get_dirname (newpath);
 
                newpath += '/';
                newpath += dead_sound_dir_name;
                newpath += '/';
-               newpath += PBD::basename ((*x));
+               newpath += Glib::path_get_basename ((*x));
                
                if (access (newpath.c_str(), F_OK) == 0) {