X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_state.cc;h=edcc52d729d12dff9f47445fb8dbe5e1c882da86;hb=13532c8500dce5f7a4525bcdfc3b44936fbaa5e6;hp=42614d15d0a82ce7f91b273fa46bf4ec3d9ffb52;hpb=1e668dfaf2392226db306ccfdaf7dbb6e45a0db4;p=ardour.git diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 42614d15d0..edcc52d729 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -44,26 +44,25 @@ #include #endif +#include + #include #include #include -#include -#include + +#include #include #include -#include #include #include #include #include -#include +#include #include #include -#include -#include +#include #include -#include #include #include #include @@ -81,6 +80,7 @@ #include #include #include +#include #include "i18n.h" #include @@ -117,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; @@ -126,8 +126,9 @@ Session::first_stage_init (string fullpath, string snapshot_name) _transport_frame = 0; last_stop_frame = 0; 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; @@ -154,6 +155,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) _solo_model = InverseMute; solo_update_disabled = false; currently_soloing = false; + _have_captured = false; _worst_output_latency = 0; _worst_input_latency = 0; _worst_track_latency = 0; @@ -164,16 +166,15 @@ Session::first_stage_init (string fullpath, string snapshot_name) butler_gain_buffer = 0; auditioner = 0; mmc_control = false; - midi_feedback = false; 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; @@ -182,7 +183,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) _master_out = 0; input_auto_connect = AutoConnectOption (0); output_auto_connect = AutoConnectOption (0); - _have_captured = false; waiting_to_start = false; _exporting = false; _gain_automation_buffer = 0; @@ -191,14 +191,16 @@ Session::first_stage_init (string fullpath, string snapshot_name) pending_abort = false; layer_model = MoveAddHigher; xfade_model = ShortCrossfade; + 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; @@ -264,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)); @@ -282,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)) { @@ -295,13 +297,9 @@ Session::second_stage_init (bool new_session) return -1; } - if (start_midi_thread ()) { + /*if (start_midi_thread ()) { return -1; - } - - if (init_feedback ()) { - return -1; - } + }*/ if (state_tree) { if (set_state (*state_tree->root())) { @@ -338,11 +336,12 @@ Session::second_stage_init (bool new_session) first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running)); } - send_full_time_code (); + //send_full_time_code (); _engine.transport_locate (0); deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0); deliver_mmc (MIDI::MachineControl::cmdLocate, 0); - send_all_midi_feedback(); + + ControlProtocolManager::instance().set_session (*this); if (new_session) { _end_location_is_free = true; @@ -400,13 +399,32 @@ Session::setup_raid_path (string path) if (colons == 0) { - /* no multiple search path, just one directory (common case) */ + /* no multiple search path, just one location (common case) */ sp.path = path; sp.blocks = 0; session_dirs.push_back (sp); + + string fspath; + + /* sounds dir */ + + fspath += sp.path; + if (fspath[fspath.length()-1] != '/') { + fspath += '/'; + } + fspath += sound_dir_name; + fspath += ':'; + + /* tape dir */ + + fspath += sp.path; + if (fspath[fspath.length()-1] != '/') { + fspath += '/'; + } + fspath += tape_dir_name; - FileSource::set_search_path (path + sound_dir_name); + AudioFileSource::set_search_path (fspath); return; } @@ -417,6 +435,9 @@ Session::setup_raid_path (string path) sp.blocks = 0; sp.path = remaining.substr (0, colon); + session_dirs.push_back (sp); + + /* add sounds to file search path */ fspath += sp.path; if (fspath[fspath.length()-1] != '/') { @@ -425,7 +446,14 @@ Session::setup_raid_path (string path) fspath += sound_dir_name; fspath += ':'; - session_dirs.push_back (sp); + /* add tape dir to file search path */ + + fspath += sp.path; + if (fspath[fspath.length()-1] != '/') { + fspath += '/'; + } + fspath += tape_dir_name; + fspath += ':'; remaining = remaining.substr (colon+1); } @@ -435,18 +463,26 @@ Session::setup_raid_path (string path) sp.blocks = 0; sp.path = remaining; + fspath += ':'; fspath += sp.path; if (fspath[fspath.length()-1] != '/') { fspath += '/'; } fspath += sound_dir_name; + fspath += ':'; + + fspath += sp.path; + if (fspath[fspath.length()-1] != '/') { + fspath += '/'; + } + fspath += tape_dir_name; 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 */ @@ -560,11 +596,14 @@ Session::create (bool& new_session, string* mix_template, jack_nframes_t initial if (new_session) { - /* set an initial end point */ + /* set initial start + end point */ + + start_location->set_end (0); + _locations.add (start_location); end_location->set_end (initial_length); _locations.add (end_location); - + _state_of_the_state = Clean; if (save_state (_current_snapshot_name)) { @@ -585,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) { @@ -677,7 +716,7 @@ Session::save_state (string snapshot_name, bool pending) if (!pending) { bool was_dirty = dirty(); - + _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); if (was_dirty) { @@ -981,6 +1020,12 @@ Session::load_options (const XMLNode& node) } } + if ((child = find_named_node (node, "end-marker-is-free")) != 0) { + if ((prop = child->property ("val")) != 0) { + _end_location_is_free = (prop->value() == "yes"); + } + } + if ((child = find_named_node (node, "layer-model")) != 0) { if ((prop = child->property ("val")) != 0) { if (prop->value() == X_("LaterHigher")) { @@ -1166,6 +1211,8 @@ Session::get_options () const child->add_property ("val", get_crossfades_active () ? "yes" : "no"); child = opthead->add_child ("audible-click"); child->add_property ("val", get_clicking () ? "yes" : "no"); + child = opthead->add_child ("end-marker-is-free"); + child->add_property ("val", _end_location_is_free ? "yes" : "no"); if (click_sound.length()) { child = opthead->add_child ("click-sound"); @@ -1228,7 +1275,7 @@ Session::get_template() sources in their state node. */ - disable_record (); + disable_record (false); return state(false); } @@ -1287,17 +1334,25 @@ 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; - - if ((fs = dynamic_cast ((*siter).second)) != 0) { - if (fs->length() == 0) { - continue; + AudioFileSource* fs; + + if ((fs = dynamic_cast ((*siter).second)) != 0) { + DestructiveFileSource* dfs = dynamic_cast (fs); + + /* destructive file sources are OK if they are empty, because + we will re-use them every time. + */ + + if (!dfs) { + if (fs->length() == 0) { + continue; + } } } @@ -1308,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) { @@ -1323,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()); } @@ -1335,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()); @@ -1345,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); @@ -1455,7 +1510,7 @@ Session::set_state (const XMLNode& node) Options Sources AudioRegions - DiskStreams + AudioDiskstreams Connections Locations Routes @@ -1551,9 +1606,17 @@ Session::set_state (const XMLNode& node) if ((location = _locations.end_location()) == 0) { _locations.add (end_location); } else { + delete end_location; end_location = location; } + if ((location = _locations.start_location()) == 0) { + _locations.add (start_location); + } else { + delete start_location; + start_location = location; + } + _locations.save_state (_("initial state")); if ((child = find_named_node (node, "EditGroups")) == 0) { @@ -1681,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]; @@ -1708,7 +1772,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full) return 0; } - sources.push_back(source); + as = dynamic_cast(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 */ @@ -1721,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(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); } } @@ -1740,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; } @@ -1803,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; @@ -1895,7 +1962,7 @@ Session::refresh_disk_space () #if HAVE_SYS_VFS_H struct statfs statfsbuf; vector::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 */ @@ -2197,13 +2264,7 @@ Session::sound_dir () const string Session::tape_dir () const { - string res = Config->get_tape_dir(); - - if (!res.empty()) { - return res; - } - - res = _path; + string res = _path; res += tape_dir_name; res += '/'; return res; @@ -2229,22 +2290,27 @@ Session::automation_dir () const string Session::template_dir () { - string path = Config->get_user_ardour_path(); + string path = get_user_ardour_path(); path += "templates/"; return path; } string -Session::template_path () +Session::suffixed_search_path (string suffix, bool data) { string path; - path += Config->get_user_ardour_path(); + path += get_user_ardour_path(); if (path[path.length()-1] != ':') { path += ':'; } - path += Config->get_system_ardour_path(); + + if (data) { + path += get_system_data_path(); + } else { + path += get_system_module_path(); + } vector split_path; @@ -2253,7 +2319,8 @@ Session::template_path () for (vector::iterator i = split_path.begin(); i != split_path.end(); ++i) { path += *i; - path += "templates/"; + path += suffix; + path += '/'; if (distance (i, split_path.end()) != 1) { path += ':'; @@ -2263,6 +2330,18 @@ Session::template_path () return path; } +string +Session::template_path () +{ + return suffixed_search_path (X_("templates"), true); +} + +string +Session::control_protocol_path () +{ + return suffixed_search_path (X_("surfaces"), false); +} + int Session::load_connections (const XMLNode& node) { @@ -2302,18 +2381,18 @@ Session::load_route_groups (const XMLNode& node, bool edit) { XMLNodeList nlist = node.children(); XMLNodeConstIterator niter; - RouteGroup* route; + RouteGroup* rg; set_dirty(); for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((*niter)->name() == "RouteGroup") { if (edit) { - route = add_edit_group (""); - route->set_state (**niter); + rg = add_edit_group (""); + rg->set_state (**niter); } else { - route = add_mix_group (""); - route->set_state (**niter); + rg = add_mix_group (""); + rg->set_state (**niter); } } } @@ -2324,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; @@ -2334,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); } @@ -2513,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()) { @@ -2533,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()) { @@ -2642,7 +2721,7 @@ Session::get_template_list (list &template_names) int Session::read_favorite_dirs (FavoriteDirs & favs) { - string path = Config->get_user_ardour_path(); + string path = get_user_ardour_path(); path += "/favorite_dirs"; ifstream fav (path.c_str()); @@ -2677,7 +2756,7 @@ Session::read_favorite_dirs (FavoriteDirs & favs) int Session::write_favorite_dirs (FavoriteDirs & favs) { - string path = Config->get_user_ardour_path(); + string path = get_user_ardour_path(); path += "/favorite_dirs"; ofstream fav (path.c_str()); @@ -2854,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; @@ -2873,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; @@ -2937,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 ((*i).second)) != 0) { + if ((fs = dynamic_cast ((*i).second)) != 0) { all_sources.insert (fs->path()); - } else if ((sfs = dynamic_cast ((*i).second)) != 0) { - all_sources.insert (sfs->path()); } } @@ -2990,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) { @@ -3137,7 +3213,7 @@ void Session::set_dirty () { bool was_dirty = dirty(); - + _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty); if (!was_dirty) {