summaryrefslogtreecommitdiff
path: root/libs/ardour/session_state.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-09-10 15:41:19 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-09-10 15:41:19 -0400
commit209e4bdcaed8e0f7d66fa5673f9049948e1f1d53 (patch)
treebdf1ffca2a5f1f20ac652e6803a77cfcf8278363 /libs/ardour/session_state.cc
parenta6815efb86e5091ce82f66ddfb60b2b2cffc587a (diff)
many changes relating to session construction and audioengine interaction
every session member is now initialized using C++ constructor syntax session construction reordered to clarify the split(s) between work where the engine is not relevant and work where is it is. this split is still not 100% obvious, but is enormously clearer than previously. if engine/backend are not running as session is created, and the SR of the sample rate is known, attempt to force backend to that value.
Diffstat (limited to 'libs/ardour/session_state.cc')
-rw-r--r--libs/ardour/session_state.cc179
1 files changed, 88 insertions, 91 deletions
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 2491712c49..b4364f4c13 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -125,10 +125,35 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-/** @param snapshot_name Snapshot name, without the .ardour prefix */
void
-Session::first_stage_init (string fullpath, string /*snapshot_name*/)
+Session::pre_engine_init (string fullpath)
{
+ if (fullpath.empty()) {
+ destroy ();
+ throw failed_constructor();
+ }
+
+ /* discover canonical fullpath */
+
+ char buf[PATH_MAX+1];
+ if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
+ error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
+ destroy ();
+ throw failed_constructor();
+ }
+
+ _path = string(buf);
+
+ /* we require _path to end with a dir separator */
+
+ if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
+ _path += G_DIR_SEPARATOR;
+ }
+
+ /* is it new ? */
+
+ _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
+
/* finish initialization that can't be done in a normal C++ constructor
definition.
*/
@@ -168,32 +193,6 @@ Session::first_stage_init (string fullpath, string /*snapshot_name*/)
boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
add_controllable (_solo_cut_control);
- /* discover canonical fullpath */
-
- if (fullpath.length() == 0) {
- destroy ();
- throw failed_constructor();
- }
-
- char buf[PATH_MAX+1];
- if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
- error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
- destroy ();
- throw failed_constructor();
- }
-
- _path = string(buf);
-
- /* we require _path to end with a dir separator */
-
- if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
- _path += G_DIR_SEPARATOR;
- }
-
- /* is it new ? */
-
- _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
-
/* These are all static "per-class" signals */
SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
@@ -207,95 +206,90 @@ Session::first_stage_init (string fullpath, string /*snapshot_name*/)
Delivery::disable_panners ();
IO::disable_connecting ();
- /* ENGINE */
+ AudioFileSource::set_peak_dir (_session_dir->peak_path());
+}
+
+int
+Session::post_engine_init ()
+{
+ BootMessage (_("Set block size and sample rate"));
+
+ set_block_size (_engine.samples_per_cycle());
+ set_frame_rate (_engine.sample_rate());
n_physical_outputs = _engine.n_physical_outputs ();
n_physical_inputs = _engine.n_physical_inputs ();
- _current_frame_rate = _engine.sample_rate ();
- _nominal_frame_rate = _current_frame_rate;
- _base_frame_rate = _current_frame_rate;
+ BootMessage (_("Using configuration"));
_midi_ports = new MidiPortManager;
- _mmc = new MIDI::MachineControl;
-
- _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
+ setup_midi_machine_control ();
- _tempo_map = new TempoMap (_current_frame_rate);
- _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
-
- AudioDiskstream::allocate_working_buffers();
-
- SndFileSource::setup_standard_crossfades (*this, frame_rate());
- _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
-
- refresh_disk_space ();
- sync_time_vars ();
-}
-
-int
-Session::second_stage_init ()
-{
- AudioFileSource::set_peak_dir (_session_dir->peak_path());
-
if (_butler->start_thread()) {
return -1;
}
-
+
if (start_midi_thread ()) {
return -1;
}
+
+ setup_click_sounds (0);
+ setup_midi_control ();
- setup_midi_machine_control ();
-
- // set_state() will call setup_raid_path(), but if it's a new session we need
- // to call setup_raid_path() here.
-
- if (state_tree) {
- if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
- return -1;
- }
- } else {
- setup_raid_path(_path);
- }
+ _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
+ _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
- /* we can't save till after ::when_engine_running() is called,
- because otherwise we save state with no connections made.
- therefore, we reset _state_of_the_state because ::set_state()
- will have cleared it.
+ try {
+ /* tempo map requires sample rate knowledge */
- we also have to include Loading so that any events that get
- generated between here and the end of ::when_engine_running()
- will be processed directly rather than queued.
- */
+ _tempo_map = new TempoMap (_current_frame_rate);
+ _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
+
+ /* MidiClock requires a tempo map */
- _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
+ midi_clock = new MidiClockTicker ();
+ midi_clock->set_session (this);
- _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
- _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
- setup_click_sounds (0);
- setup_midi_control ();
+ /* crossfades require sample rate knowledge */
- /* Pay attention ... */
+ SndFileSource::setup_standard_crossfades (*this, frame_rate());
+ _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
+
+ AudioDiskstream::allocate_working_buffers();
+ refresh_disk_space ();
+
+ /* we're finally ready to call set_state() ... all objects have
+ * been created, the engine is running.
+ */
+
+ if (state_tree) {
+ if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
+ return -1;
+ }
+ } else {
+ // set_state() will call setup_raid_path(), but if it's a new session we need
+ // to call setup_raid_path() here.
+ setup_raid_path (_path);
+ }
- _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
- _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
+ /* ENGINE */
- midi_clock = new MidiClockTicker ();
- midi_clock->set_session (this);
+ boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
+ boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
+
+ Config->map_parameters (ff);
+ config.map_parameters (ft);
- try {
when_engine_running ();
- }
-
- /* handle this one in a different way than all others, so that its clear what happened */
- catch (AudioEngine::PortRegistrationFailure& err) {
+ _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
+ _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
+
+ } catch (AudioEngine::PortRegistrationFailure& err) {
+ /* handle this one in a different way than all others, so that its clear what happened */
error << err.what() << endmsg;
return -1;
- }
-
- catch (...) {
+ } catch (...) {
return -1;
}
@@ -3516,6 +3510,9 @@ Session::load_diskstreams_2X (XMLNode const & node, int)
void
Session::setup_midi_machine_control ()
{
+ _mmc = new MIDI::MachineControl;
+ _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
+
_mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
_mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
_mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));