2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_track.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/audioplaylist.h"
53 #include "ardour/audioregion.h"
54 #include "ardour/auditioner.h"
55 #include "ardour/buffer_set.h"
56 #include "ardour/bundle.h"
57 #include "ardour/click.h"
58 #include "ardour/configuration.h"
59 #include "ardour/crossfade.h"
60 #include "ardour/cycle_timer.h"
61 #include "ardour/data_type.h"
62 #include "ardour/filename_extensions.h"
63 #include "ardour/io_processor.h"
64 #include "ardour/midi_diskstream.h"
65 #include "ardour/midi_playlist.h"
66 #include "ardour/midi_region.h"
67 #include "ardour/midi_track.h"
68 #include "ardour/named_selection.h"
69 #include "ardour/playlist.h"
70 #include "ardour/plugin_insert.h"
71 #include "ardour/port_insert.h"
72 #include "ardour/processor.h"
73 #include "ardour/recent_sessions.h"
74 #include "ardour/region_factory.h"
75 #include "ardour/route_group.h"
76 #include "ardour/send.h"
77 #include "ardour/session.h"
78 #include "ardour/session_directory.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_metadata.h"
81 #include "ardour/slave.h"
82 #include "ardour/smf_source.h"
83 #include "ardour/source_factory.h"
84 #include "ardour/tape_file_matcher.h"
85 #include "ardour/tempo.h"
86 #include "ardour/utils.h"
91 using namespace ARDOUR;
93 using boost::shared_ptr;
96 static const int CPU_CACHE_ALIGN = 64;
98 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
101 bool Session::_disable_all_loaded_plugins = false;
103 sigc::signal<void,std::string> Session::Dialog;
104 sigc::signal<int> Session::AskAboutPendingState;
105 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
106 sigc::signal<void> Session::SendFeedback;
108 sigc::signal<void> Session::SMPTEOffsetChanged;
109 sigc::signal<void> Session::StartTimeChanged;
110 sigc::signal<void> Session::EndTimeChanged;
111 sigc::signal<void> Session::AutoBindingOn;
112 sigc::signal<void> Session::AutoBindingOff;
113 sigc::signal<void, std::string, std::string> Session::Exported;
115 Session::Session (AudioEngine &eng,
116 const string& fullpath,
117 const string& snapshot_name,
121 _requested_return_frame (-1),
122 _scratch_buffers(new BufferSet()),
123 _silent_buffers(new BufferSet()),
124 _mix_buffers(new BufferSet()),
126 _mmc_port (default_mmc_port),
127 _mtc_port (default_mtc_port),
128 _midi_port (default_midi_port),
129 _midi_clock_port (default_midi_clock_port),
130 _session_dir (new SessionDirectory(fullpath)),
131 pending_events (2048),
133 butler_mixdown_buffer (0),
134 butler_gain_buffer (0),
135 post_transport_work((PostTransportWork)0),
136 _send_smpte_update (false),
137 midi_thread (pthread_t (0)),
138 midi_requests (128), // the size of this should match the midi request pool size
139 diskstreams (new DiskstreamList),
140 routes (new RouteList),
141 auditioner ((Auditioner*) 0),
142 _total_free_4k_blocks (0),
143 _bundles (new BundleList),
144 _bundle_xml_node (0),
147 click_emphasis_data (0),
149 _metadata (new SessionMetadata())
154 if (!eng.connected()) {
155 throw failed_constructor();
158 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
160 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
161 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
163 first_stage_init (fullpath, snapshot_name);
165 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
168 if (create (new_session, mix_template, compute_initial_length())) {
170 throw failed_constructor ();
174 if (second_stage_init (new_session)) {
176 throw failed_constructor ();
179 store_recent_sessions(_name, _path);
181 bool was_dirty = dirty();
183 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
185 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _requested_return_frame (-1),
205 _scratch_buffers(new BufferSet()),
206 _silent_buffers(new BufferSet()),
207 _mix_buffers(new BufferSet()),
209 _mmc_port (default_mmc_port),
210 _mtc_port (default_mtc_port),
211 _midi_port (default_midi_port),
212 _midi_clock_port (default_midi_clock_port),
213 _session_dir ( new SessionDirectory(fullpath)),
214 pending_events (2048),
216 butler_mixdown_buffer (0),
217 butler_gain_buffer (0),
218 post_transport_work((PostTransportWork)0),
219 _send_smpte_update (false),
220 midi_thread (pthread_t (0)),
222 diskstreams (new DiskstreamList),
223 routes (new RouteList),
224 auditioner ((Auditioner *) 0),
225 _total_free_4k_blocks (0),
226 _bundles (new BundleList),
227 _bundle_xml_node (0),
228 _click_io ((IO *) 0),
230 click_emphasis_data (0),
232 _metadata (new SessionMetadata())
236 if (!eng.connected()) {
237 throw failed_constructor();
240 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
242 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
243 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
245 if (n_physical_inputs) {
246 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
249 if (n_physical_outputs) {
250 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
253 first_stage_init (fullpath, snapshot_name);
255 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
258 if (create (new_session, string(), initial_length)) {
260 throw failed_constructor ();
265 /* set up Master Out and Control Out if necessary */
270 if (control_out_channels) {
271 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
272 r->set_remote_control_id (control_id++);
277 if (master_out_channels) {
278 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
279 r->set_remote_control_id (control_id);
283 /* prohibit auto-connect to master, because there isn't one */
284 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
288 add_routes (rl, false);
293 Config->set_input_auto_connect (input_ac);
294 Config->set_output_auto_connect (output_ac);
296 if (second_stage_init (new_session)) {
298 throw failed_constructor ();
301 store_recent_sessions (_name, _path);
303 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
305 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
316 /* if we got to here, leaving pending capture state around
320 remove_pending_capture_state ();
322 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
324 _engine.remove_session ();
326 GoingAway (); /* EMIT SIGNAL */
332 /* clear history so that no references to objects are held any more */
336 /* clear state tree so that no references to objects are held any more */
340 terminate_butler_thread ();
341 //terminate_midi_thread ();
343 if (click_data != default_click) {
344 delete [] click_data;
347 if (click_emphasis_data != default_click_emphasis) {
348 delete [] click_emphasis_data;
353 delete _scratch_buffers;
354 delete _silent_buffers;
357 AudioDiskstream::free_working_buffers();
359 Route::SyncOrderKeys.clear();
361 #undef TRACK_DESTRUCTION
362 #ifdef TRACK_DESTRUCTION
363 cerr << "delete named selections\n";
364 #endif /* TRACK_DESTRUCTION */
365 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
366 NamedSelectionList::iterator tmp;
375 #ifdef TRACK_DESTRUCTION
376 cerr << "delete playlists\n";
377 #endif /* TRACK_DESTRUCTION */
378 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
379 PlaylistList::iterator tmp;
384 (*i)->drop_references ();
389 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
390 PlaylistList::iterator tmp;
395 (*i)->drop_references ();
401 unused_playlists.clear ();
403 #ifdef TRACK_DESTRUCTION
404 cerr << "delete regions\n";
405 #endif /* TRACK_DESTRUCTION */
407 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
408 RegionList::iterator tmp;
413 i->second->drop_references ();
420 #ifdef TRACK_DESTRUCTION
421 cerr << "delete routes\n";
422 #endif /* TRACK_DESTRUCTION */
424 RCUWriter<RouteList> writer (routes);
425 boost::shared_ptr<RouteList> r = writer.get_copy ();
426 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
427 (*i)->drop_references ();
430 /* writer goes out of scope and updates master */
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete diskstreams\n";
437 #endif /* TRACK_DESTRUCTION */
439 RCUWriter<DiskstreamList> dwriter (diskstreams);
440 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
441 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
442 (*i)->drop_references ();
446 diskstreams.flush ();
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete audio sources\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
452 SourceMap::iterator tmp;
457 i->second->drop_references ();
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete mix groups\n";
465 #endif /* TRACK_DESTRUCTION */
466 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
467 list<RouteGroup*>::iterator tmp;
477 #ifdef TRACK_DESTRUCTION
478 cerr << "delete edit groups\n";
479 #endif /* TRACK_DESTRUCTION */
480 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
481 list<RouteGroup*>::iterator tmp;
491 delete [] butler_mixdown_buffer;
492 delete [] butler_gain_buffer;
494 Crossfade::set_buffer_size (0);
500 Session::set_worst_io_latencies ()
502 _worst_output_latency = 0;
503 _worst_input_latency = 0;
505 if (!_engine.connected()) {
509 boost::shared_ptr<RouteList> r = routes.reader ();
511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
512 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
513 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
518 Session::when_engine_running ()
520 string first_physical_output;
522 /* we don't want to run execute this again */
524 BootMessage (_("Set block size and sample rate"));
526 set_block_size (_engine.frames_per_cycle());
527 set_frame_rate (_engine.frame_rate());
529 BootMessage (_("Using configuration"));
531 Config->map_parameters (mem_fun (*this, &Session::config_changed));
533 /* every time we reconnect, recompute worst case output latencies */
535 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
537 if (synced_to_jack()) {
538 _engine.transport_stop ();
541 if (Config->get_jack_time_master()) {
542 _engine.transport_locate (_transport_frame);
550 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
552 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
554 /* existing state for Click */
556 if (_click_io->set_state (*child->children().front()) == 0) {
558 _clicking = Config->get_clicking ();
562 error << _("could not setup Click I/O") << endmsg;
568 /* default state for Click */
570 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
572 if (first_physical_output.length()) {
573 if (_click_io->add_output_port (first_physical_output, this)) {
574 // relax, even though its an error
576 _clicking = Config->get_clicking ();
582 catch (failed_constructor& err) {
583 error << _("cannot setup Click I/O") << endmsg;
586 BootMessage (_("Compute I/O Latencies"));
588 set_worst_io_latencies ();
591 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
594 BootMessage (_("Set up standard connections"));
596 /* Create a set of Bundle objects that map
597 to the physical I/O currently available. We create both
598 mono and stereo bundles, so that the common cases of mono
599 and stereo tracks get bundles to put in their mixer strip
600 in / out menus. There may be a nicer way of achieving that;
601 it doesn't really scale that well to higher channel counts */
603 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
605 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
607 shared_ptr<Bundle> c (new Bundle (buf, true));
608 c->add_channel (_("mono"));
609 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
614 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
615 if (np + 1 < n_physical_outputs) {
617 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
618 shared_ptr<Bundle> c (new Bundle (buf, true));
619 c->add_channel (_("L"));
620 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
621 c->add_channel (_("R"));
622 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
628 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
630 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
632 shared_ptr<Bundle> c (new Bundle (buf, false));
633 c->add_channel (_("mono"));
634 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
639 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
640 if (np + 1 < n_physical_inputs) {
642 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
644 shared_ptr<Bundle> c (new Bundle (buf, false));
645 c->add_channel (_("L"));
646 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
647 c->add_channel (_("R"));
648 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
656 /* create master/control ports */
661 /* force the master to ignore any later call to this */
663 if (_master_out->pending_state_node) {
664 _master_out->ports_became_legal();
667 /* no panner resets till we are through */
669 _master_out->defer_pan_reset ();
671 while (_master_out->n_inputs().n_audio()
672 < _master_out->input_maximum().n_audio()) {
673 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
674 error << _("cannot setup master inputs")
680 while (_master_out->n_outputs().n_audio()
681 < _master_out->output_maximum().n_audio()) {
682 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
683 error << _("cannot setup master outputs")
690 _master_out->allow_pan_reset ();
695 BootMessage (_("Setup signal flow and plugins"));
699 /* catch up on send+insert cnts */
701 BootMessage (_("Catch up with send/insert state"));
705 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
708 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
709 if (id > insert_cnt) {
717 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
720 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
728 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
730 /* hook us up to the engine */
732 BootMessage (_("Connect to engine"));
734 _engine.set_session (this);
738 Session::hookup_io ()
740 /* stop graph reordering notifications from
741 causing resorts, etc.
744 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
747 if (auditioner == 0) {
749 /* we delay creating the auditioner till now because
750 it makes its own connections to ports.
751 the engine has to be running for this to work.
755 auditioner.reset (new Auditioner (*this));
758 catch (failed_constructor& err) {
759 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
763 /* Tell all IO objects to create their ports */
769 vector<string> cports;
771 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
772 if (_control_out->add_input_port ("", this)) {
773 error << _("cannot setup control inputs")
779 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
780 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
781 error << _("cannot set up master outputs")
789 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
791 for (n = 0; n < ni; ++n) {
792 cports.push_back (_control_out->input(n)->name());
795 boost::shared_ptr<RouteList> r = routes.reader ();
797 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
798 (*x)->set_control_outs (cports);
802 /* load bundles, which we may have postponed earlier on */
803 if (_bundle_xml_node) {
804 load_bundles (*_bundle_xml_node);
805 delete _bundle_xml_node;
808 /* Tell all IO objects to connect themselves together */
810 IO::enable_connecting ();
812 /* Now reset all panners */
814 IO::reset_panners ();
816 /* Anyone who cares about input state, wake up and do something */
818 IOConnectionsComplete (); /* EMIT SIGNAL */
820 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
823 /* now handle the whole enchilada as if it was one
829 /* update mixer solo state */
835 Session::playlist_length_changed ()
837 /* we can't just increase end_location->end() if pl->get_maximum_extent()
838 if larger. if the playlist used to be the longest playlist,
839 and its now shorter, we have to decrease end_location->end(). hence,
840 we have to iterate over all diskstreams and check the
841 playlists currently in use.
847 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
849 boost::shared_ptr<Playlist> playlist;
851 if ((playlist = dstream->playlist()) != 0) {
852 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
855 /* see comment in playlist_length_changed () */
860 Session::record_enabling_legal () const
862 /* this used to be in here, but survey says.... we don't need to restrict it */
863 // if (record_status() == Recording) {
867 if (Config->get_all_safe()) {
874 Session::reset_input_monitor_state ()
876 if (transport_rolling()) {
878 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
880 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
881 if ((*i)->record_enabled ()) {
882 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
883 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
887 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
889 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
890 if ((*i)->record_enabled ()) {
891 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
892 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
899 Session::auto_punch_start_changed (Location* location)
901 replace_event (Event::PunchIn, location->start());
903 if (get_record_enabled() && Config->get_punch_in()) {
904 /* capture start has been changed, so save new pending state */
905 save_state ("", true);
910 Session::auto_punch_end_changed (Location* location)
912 nframes_t when_to_stop = location->end();
913 // when_to_stop += _worst_output_latency + _worst_input_latency;
914 replace_event (Event::PunchOut, when_to_stop);
918 Session::auto_punch_changed (Location* location)
920 nframes_t when_to_stop = location->end();
922 replace_event (Event::PunchIn, location->start());
923 //when_to_stop += _worst_output_latency + _worst_input_latency;
924 replace_event (Event::PunchOut, when_to_stop);
928 Session::auto_loop_changed (Location* location)
930 replace_event (Event::AutoLoop, location->end(), location->start());
932 if (transport_rolling() && play_loop) {
934 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
936 if (_transport_frame > location->end()) {
937 // relocate to beginning of loop
938 clear_events (Event::LocateRoll);
940 request_locate (location->start(), true);
943 else if (Config->get_seamless_loop() && !loop_changing) {
945 // schedule a locate-roll to refill the diskstreams at the
947 loop_changing = true;
949 if (location->end() > last_loopend) {
950 clear_events (Event::LocateRoll);
951 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
958 last_loopend = location->end();
962 Session::set_auto_punch_location (Location* location)
966 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
967 auto_punch_start_changed_connection.disconnect();
968 auto_punch_end_changed_connection.disconnect();
969 auto_punch_changed_connection.disconnect();
970 existing->set_auto_punch (false, this);
971 remove_event (existing->start(), Event::PunchIn);
972 clear_events (Event::PunchOut);
973 auto_punch_location_changed (0);
982 if (location->end() <= location->start()) {
983 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
987 auto_punch_start_changed_connection.disconnect();
988 auto_punch_end_changed_connection.disconnect();
989 auto_punch_changed_connection.disconnect();
991 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
992 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
993 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
995 location->set_auto_punch (true, this);
998 auto_punch_changed (location);
1000 auto_punch_location_changed (location);
1004 Session::set_auto_loop_location (Location* location)
1008 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1009 auto_loop_start_changed_connection.disconnect();
1010 auto_loop_end_changed_connection.disconnect();
1011 auto_loop_changed_connection.disconnect();
1012 existing->set_auto_loop (false, this);
1013 remove_event (existing->end(), Event::AutoLoop);
1014 auto_loop_location_changed (0);
1019 if (location == 0) {
1023 if (location->end() <= location->start()) {
1024 error << _("Session: you can't use a mark for auto loop") << endmsg;
1028 last_loopend = location->end();
1030 auto_loop_start_changed_connection.disconnect();
1031 auto_loop_end_changed_connection.disconnect();
1032 auto_loop_changed_connection.disconnect();
1034 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1035 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1036 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1038 location->set_auto_loop (true, this);
1040 /* take care of our stuff first */
1042 auto_loop_changed (location);
1044 /* now tell everyone else */
1046 auto_loop_location_changed (location);
1050 Session::locations_added (Location* ignored)
1056 Session::locations_changed ()
1058 _locations.apply (*this, &Session::handle_locations_changed);
1062 Session::handle_locations_changed (Locations::LocationList& locations)
1064 Locations::LocationList::iterator i;
1066 bool set_loop = false;
1067 bool set_punch = false;
1069 for (i = locations.begin(); i != locations.end(); ++i) {
1073 if (location->is_auto_punch()) {
1074 set_auto_punch_location (location);
1077 if (location->is_auto_loop()) {
1078 set_auto_loop_location (location);
1082 if (location->is_start()) {
1083 start_location = location;
1085 if (location->is_end()) {
1086 end_location = location;
1091 set_auto_loop_location (0);
1094 set_auto_punch_location (0);
1101 Session::enable_record ()
1103 /* XXX really atomic compare+swap here */
1104 if (g_atomic_int_get (&_record_status) != Recording) {
1105 g_atomic_int_set (&_record_status, Recording);
1106 _last_record_location = _transport_frame;
1107 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1109 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1110 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1111 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1112 if ((*i)->record_enabled ()) {
1113 (*i)->monitor_input (true);
1118 RecordStateChanged ();
1123 Session::disable_record (bool rt_context, bool force)
1127 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1129 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1130 g_atomic_int_set (&_record_status, Disabled);
1132 if (rs == Recording) {
1133 g_atomic_int_set (&_record_status, Enabled);
1137 // FIXME: timestamp correct? [DR]
1138 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1139 // does this /need/ to be sent in all cases?
1141 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1143 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1144 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1146 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1147 if ((*i)->record_enabled ()) {
1148 (*i)->monitor_input (false);
1153 RecordStateChanged (); /* emit signal */
1156 remove_pending_capture_state ();
1162 Session::step_back_from_record ()
1164 /* XXX really atomic compare+swap here */
1165 if (g_atomic_int_get (&_record_status) == Recording) {
1166 g_atomic_int_set (&_record_status, Enabled);
1168 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1169 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1171 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1172 if ((*i)->record_enabled ()) {
1173 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1174 (*i)->monitor_input (false);
1182 Session::maybe_enable_record ()
1184 g_atomic_int_set (&_record_status, Enabled);
1186 /* this function is currently called from somewhere other than an RT thread.
1187 this save_state() call therefore doesn't impact anything.
1190 save_state ("", true);
1192 if (_transport_speed) {
1193 if (!Config->get_punch_in()) {
1197 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1198 RecordStateChanged (); /* EMIT SIGNAL */
1205 Session::audible_frame () const
1211 /* the first of these two possible settings for "offset"
1212 mean that the audible frame is stationary until
1213 audio emerges from the latency compensation
1216 the second means that the audible frame is stationary
1217 until audio would emerge from a physical port
1218 in the absence of any plugin latency compensation
1221 offset = _worst_output_latency;
1223 if (offset > current_block_size) {
1224 offset -= current_block_size;
1226 /* XXX is this correct? if we have no external
1227 physical connections and everything is internal
1228 then surely this is zero? still, how
1229 likely is that anyway?
1231 offset = current_block_size;
1234 if (synced_to_jack()) {
1235 tf = _engine.transport_frame();
1237 tf = _transport_frame;
1242 if (!non_realtime_work_pending()) {
1246 /* check to see if we have passed the first guaranteed
1247 audible frame past our last start position. if not,
1248 return that last start point because in terms
1249 of audible frames, we have not moved yet.
1252 if (_transport_speed > 0.0f) {
1254 if (!play_loop || !have_looped) {
1255 if (tf < _last_roll_location + offset) {
1256 return _last_roll_location;
1264 } else if (_transport_speed < 0.0f) {
1266 /* XXX wot? no backward looping? */
1268 if (tf > _last_roll_location - offset) {
1269 return _last_roll_location;
1281 Session::set_frame_rate (nframes_t frames_per_second)
1283 /** \fn void Session::set_frame_size(nframes_t)
1284 the AudioEngine object that calls this guarantees
1285 that it will not be called while we are also in
1286 ::process(). Its fine to do things that block
1290 _base_frame_rate = frames_per_second;
1294 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1298 // XXX we need some equivalent to this, somehow
1299 // SndFileSource::setup_standard_crossfades (frames_per_second);
1303 /* XXX need to reset/reinstantiate all LADSPA plugins */
1307 Session::set_block_size (nframes_t nframes)
1309 /* the AudioEngine guarantees
1310 that it will not be called while we are also in
1311 ::process(). It is therefore fine to do things that block
1317 current_block_size = nframes;
1319 ensure_buffers(_scratch_buffers->available());
1321 delete [] _gain_automation_buffer;
1322 _gain_automation_buffer = new gain_t[nframes];
1324 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1326 boost::shared_ptr<RouteList> r = routes.reader ();
1328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1329 (*i)->set_block_size (nframes);
1332 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1333 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1334 (*i)->set_block_size (nframes);
1337 set_worst_io_latencies ();
1342 Session::set_default_fade (float steepness, float fade_msecs)
1345 nframes_t fade_frames;
1347 /* Don't allow fade of less 1 frame */
1349 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1356 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1360 default_fade_msecs = fade_msecs;
1361 default_fade_steepness = steepness;
1364 // jlc, WTF is this!
1365 Glib::RWLock::ReaderLock lm (route_lock);
1366 AudioRegion::set_default_fade (steepness, fade_frames);
1371 /* XXX have to do this at some point */
1372 /* foreach region using default fade, reset, then
1373 refill_all_diskstream_buffers ();
1378 struct RouteSorter {
1379 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1380 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1382 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1385 if (r1->fed_by.empty()) {
1386 if (r2->fed_by.empty()) {
1387 /* no ardour-based connections inbound to either route. just use signal order */
1388 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390 /* r2 has connections, r1 does not; run r1 early */
1394 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1401 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1403 shared_ptr<Route> r2;
1405 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1406 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1410 /* make a copy of the existing list of routes that feed r1 */
1412 set<shared_ptr<Route> > existing = r1->fed_by;
1414 /* for each route that feeds r1, recurse, marking it as feeding
1418 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1421 /* r2 is a route that feeds r1 which somehow feeds base. mark
1422 base as being fed by r2
1425 rbase->fed_by.insert (r2);
1429 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1433 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1437 /* now recurse, so that we can mark base as being fed by
1438 all routes that feed r2
1441 trace_terminal (r2, rbase);
1448 Session::resort_routes ()
1450 /* don't do anything here with signals emitted
1451 by Routes while we are being destroyed.
1454 if (_state_of_the_state & Deletion) {
1461 RCUWriter<RouteList> writer (routes);
1462 shared_ptr<RouteList> r = writer.get_copy ();
1463 resort_routes_using (r);
1464 /* writer goes out of scope and forces update */
1469 Session::resort_routes_using (shared_ptr<RouteList> r)
1471 RouteList::iterator i, j;
1473 for (i = r->begin(); i != r->end(); ++i) {
1475 (*i)->fed_by.clear ();
1477 for (j = r->begin(); j != r->end(); ++j) {
1479 /* although routes can feed themselves, it will
1480 cause an endless recursive descent if we
1481 detect it. so don't bother checking for
1489 if ((*j)->feeds (*i)) {
1490 (*i)->fed_by.insert (*j);
1495 for (i = r->begin(); i != r->end(); ++i) {
1496 trace_terminal (*i, *i);
1503 cerr << "finished route resort\n";
1505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1506 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1513 list<boost::shared_ptr<MidiTrack> >
1514 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1516 char track_name[32];
1517 uint32_t track_id = 0;
1520 RouteList new_routes;
1521 list<boost::shared_ptr<MidiTrack> > ret;
1522 //uint32_t control_id;
1524 // FIXME: need physical I/O and autoconnect stuff for MIDI
1526 /* count existing midi tracks */
1529 shared_ptr<RouteList> r = routes.reader ();
1531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1532 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1533 if (!(*i)->is_hidden()) {
1535 //channels_used += (*i)->n_inputs().n_midi();
1541 vector<string> physinputs;
1542 vector<string> physoutputs;
1544 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1545 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1547 // control_id = ntracks() + nbusses();
1551 /* check for duplicate route names, since we might have pre-existing
1552 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1553 save, close,restart,add new route - first named route is now
1561 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1563 if (route_by_name (track_name) == 0) {
1567 } while (track_id < (UINT_MAX-1));
1569 shared_ptr<MidiTrack> track;
1572 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1574 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1575 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1581 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1585 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1586 port = physinputs[(channels_used+x)%nphysical_in];
1589 if (port.length() && track->connect_input (track->input (x), port, this)) {
1595 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1599 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1600 port = physoutputs[(channels_used+x)%nphysical_out];
1601 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1603 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1607 if (port.length() && track->connect_output (track->output (x), port, this)) {
1612 channels_used += track->n_inputs ().n_midi();
1616 track->midi_diskstream()->non_realtime_input_change();
1618 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1619 //track->set_remote_control_id (control_id);
1621 new_routes.push_back (track);
1622 ret.push_back (track);
1625 catch (failed_constructor &err) {
1626 error << _("Session: could not create new midi track.") << endmsg;
1629 /* we need to get rid of this, since the track failed to be created */
1630 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1633 RCUWriter<DiskstreamList> writer (diskstreams);
1634 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1635 ds->remove (track->midi_diskstream());
1642 catch (AudioEngine::PortRegistrationFailure& pfe) {
1644 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1647 /* we need to get rid of this, since the track failed to be created */
1648 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1651 RCUWriter<DiskstreamList> writer (diskstreams);
1652 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1653 ds->remove (track->midi_diskstream());
1664 if (!new_routes.empty()) {
1665 add_routes (new_routes, false);
1666 save_state (_current_snapshot_name);
1672 list<boost::shared_ptr<AudioTrack> >
1673 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1675 char track_name[32];
1676 uint32_t track_id = 0;
1678 uint32_t channels_used = 0;
1680 RouteList new_routes;
1681 list<boost::shared_ptr<AudioTrack> > ret;
1682 uint32_t control_id;
1684 /* count existing audio tracks */
1687 shared_ptr<RouteList> r = routes.reader ();
1689 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1690 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1691 if (!(*i)->is_hidden()) {
1693 channels_used += (*i)->n_inputs().n_audio();
1699 vector<string> physinputs;
1700 vector<string> physoutputs;
1702 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1703 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1705 control_id = ntracks() + nbusses() + 1;
1709 /* check for duplicate route names, since we might have pre-existing
1710 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1711 save, close,restart,add new route - first named route is now
1719 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1721 if (route_by_name (track_name) == 0) {
1725 } while (track_id < (UINT_MAX-1));
1727 shared_ptr<AudioTrack> track;
1730 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1732 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1733 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1734 input_channels, output_channels)
1739 if (!physinputs.empty()) {
1740 uint32_t nphysical_in = physinputs.size();
1742 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1746 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1747 port = physinputs[(channels_used+x)%nphysical_in];
1750 if (port.length() && track->connect_input (track->input (x), port, this)) {
1756 if (!physoutputs.empty()) {
1757 uint32_t nphysical_out = physoutputs.size();
1759 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1763 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1764 port = physoutputs[(channels_used+x)%nphysical_out];
1765 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1767 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1771 if (port.length() && track->connect_output (track->output (x), port, this)) {
1777 channels_used += track->n_inputs ().n_audio();
1779 track->audio_diskstream()->non_realtime_input_change();
1781 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1782 track->set_remote_control_id (control_id);
1785 new_routes.push_back (track);
1786 ret.push_back (track);
1789 catch (failed_constructor &err) {
1790 error << _("Session: could not create new audio track.") << endmsg;
1793 /* we need to get rid of this, since the track failed to be created */
1794 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1797 RCUWriter<DiskstreamList> writer (diskstreams);
1798 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1799 ds->remove (track->audio_diskstream());
1806 catch (AudioEngine::PortRegistrationFailure& pfe) {
1808 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1811 /* we need to get rid of this, since the track failed to be created */
1812 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1815 RCUWriter<DiskstreamList> writer (diskstreams);
1816 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1817 ds->remove (track->audio_diskstream());
1828 if (!new_routes.empty()) {
1829 add_routes (new_routes, true);
1836 Session::set_remote_control_ids ()
1838 RemoteModel m = Config->get_remote_model();
1840 shared_ptr<RouteList> r = routes.reader ();
1842 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1843 if ( MixerOrdered == m) {
1844 long order = (*i)->order_key(N_("signal"));
1845 (*i)->set_remote_control_id( order+1 );
1846 } else if ( EditorOrdered == m) {
1847 long order = (*i)->order_key(N_("editor"));
1848 (*i)->set_remote_control_id( order+1 );
1849 } else if ( UserOrdered == m) {
1850 //do nothing ... only changes to remote id's are initiated by user
1857 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1860 uint32_t bus_id = 1;
1862 uint32_t channels_used = 0;
1865 uint32_t control_id;
1867 /* count existing audio busses */
1870 shared_ptr<RouteList> r = routes.reader ();
1872 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1873 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1875 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1878 channels_used += (*i)->n_inputs().n_audio();
1884 vector<string> physinputs;
1885 vector<string> physoutputs;
1887 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1888 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1890 n_physical_audio_outputs = physoutputs.size();
1891 n_physical_audio_inputs = physinputs.size();
1893 control_id = ntracks() + nbusses() + 1;
1898 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1902 if (route_by_name (bus_name) == 0) {
1906 } while (bus_id < (UINT_MAX-1));
1909 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1911 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1912 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1913 input_channels, output_channels)
1921 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1925 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1926 port = physinputs[((n+x)%n_physical_audio_inputs)];
1929 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1935 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1938 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1939 port = physoutputs[((n+x)%n_physical_outputs)];
1940 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1942 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1946 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1951 channels_used += bus->n_inputs ().n_audio();
1953 bus->set_remote_control_id (control_id);
1956 ret.push_back (bus);
1960 catch (failed_constructor &err) {
1961 error << _("Session: could not create new audio route.") << endmsg;
1965 catch (AudioEngine::PortRegistrationFailure& pfe) {
1966 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1976 add_routes (ret, true);
1984 Session::add_routes (RouteList& new_routes, bool save)
1987 RCUWriter<RouteList> writer (routes);
1988 shared_ptr<RouteList> r = writer.get_copy ();
1989 r->insert (r->end(), new_routes.begin(), new_routes.end());
1990 resort_routes_using (r);
1993 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1995 boost::weak_ptr<Route> wpr (*x);
1997 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1998 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1999 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2000 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2002 if ((*x)->is_master()) {
2006 if ((*x)->is_control()) {
2007 _control_out = (*x);
2011 if (_control_out && IO::connecting_legal) {
2013 vector<string> cports;
2014 uint32_t ni = _control_out->n_inputs().n_audio();
2016 for (uint32_t n = 0; n < ni; ++n) {
2017 cports.push_back (_control_out->input(n)->name());
2020 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2021 (*x)->set_control_outs (cports);
2028 save_state (_current_snapshot_name);
2031 RouteAdded (new_routes); /* EMIT SIGNAL */
2035 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2037 /* need to do this in case we're rolling at the time, to prevent false underruns */
2038 dstream->do_refill_with_alloc ();
2040 dstream->set_block_size (current_block_size);
2043 RCUWriter<DiskstreamList> writer (diskstreams);
2044 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2045 ds->push_back (dstream);
2046 /* writer goes out of scope, copies ds back to main */
2049 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2050 /* this will connect to future changes, and check the current length */
2051 diskstream_playlist_changed (dstream);
2053 dstream->prepare ();
2058 Session::remove_route (shared_ptr<Route> route)
2061 RCUWriter<RouteList> writer (routes);
2062 shared_ptr<RouteList> rs = writer.get_copy ();
2066 /* deleting the master out seems like a dumb
2067 idea, but its more of a UI policy issue
2071 if (route == _master_out) {
2072 _master_out = shared_ptr<Route> ();
2075 if (route == _control_out) {
2076 _control_out = shared_ptr<Route> ();
2078 /* cancel control outs for all routes */
2080 vector<string> empty;
2082 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2083 (*r)->set_control_outs (empty);
2087 update_route_solo_state ();
2089 /* writer goes out of scope, forces route list update */
2093 boost::shared_ptr<Diskstream> ds;
2095 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2096 ds = t->diskstream();
2102 RCUWriter<DiskstreamList> dsl (diskstreams);
2103 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2108 find_current_end ();
2110 // We need to disconnect the routes inputs and outputs
2112 route->disconnect_inputs (0);
2113 route->disconnect_outputs (0);
2115 update_latency_compensation (false, false);
2118 /* get rid of it from the dead wood collection in the route list manager */
2120 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2124 /* try to cause everyone to drop their references */
2126 route->drop_references ();
2128 sync_order_keys (N_("session"));
2130 /* save the new state of the world */
2132 if (save_state (_current_snapshot_name)) {
2133 save_history (_current_snapshot_name);
2138 Session::route_mute_changed (void* src)
2144 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2146 if (solo_update_disabled) {
2152 boost::shared_ptr<Route> route = wpr.lock ();
2155 /* should not happen */
2156 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2160 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2162 shared_ptr<RouteList> r = routes.reader ();
2164 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2166 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2170 /* don't mess with busses */
2172 if (dynamic_cast<Track*>((*i).get()) == 0) {
2178 /* don't mess with tracks */
2180 if (dynamic_cast<Track*>((*i).get()) != 0) {
2185 if ((*i) != route &&
2186 ((*i)->mix_group () == 0 ||
2187 (*i)->mix_group () != route->mix_group () ||
2188 !route->mix_group ()->is_active())) {
2190 if ((*i)->soloed()) {
2192 /* if its already soloed, and solo latching is enabled,
2193 then leave it as it is.
2196 if (Config->get_solo_latched()) {
2203 solo_update_disabled = true;
2204 (*i)->set_solo (false, src);
2205 solo_update_disabled = false;
2209 bool something_soloed = false;
2210 bool same_thing_soloed = false;
2211 bool signal = false;
2213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2214 if ((*i)->soloed()) {
2215 something_soloed = true;
2216 if (dynamic_cast<Track*>((*i).get())) {
2218 same_thing_soloed = true;
2223 same_thing_soloed = true;
2231 if (something_soloed != currently_soloing) {
2233 currently_soloing = something_soloed;
2236 modify_solo_mute (is_track, same_thing_soloed);
2239 SoloActive (currently_soloing); /* EMIT SIGNAL */
2242 SoloChanged (); /* EMIT SIGNAL */
2248 Session::update_route_solo_state ()
2251 bool is_track = false;
2252 bool signal = false;
2254 /* this is where we actually implement solo by changing
2255 the solo mute setting of each track.
2258 shared_ptr<RouteList> r = routes.reader ();
2260 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2261 if ((*i)->soloed()) {
2263 if (dynamic_cast<Track*>((*i).get())) {
2270 if (mute != currently_soloing) {
2272 currently_soloing = mute;
2275 if (!is_track && !mute) {
2277 /* nothing is soloed */
2279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2280 (*i)->set_solo_mute (false);
2290 modify_solo_mute (is_track, mute);
2293 SoloActive (currently_soloing);
2298 Session::modify_solo_mute (bool is_track, bool mute)
2300 shared_ptr<RouteList> r = routes.reader ();
2302 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2306 /* only alter track solo mute */
2308 if (dynamic_cast<Track*>((*i).get())) {
2309 if ((*i)->soloed()) {
2310 (*i)->set_solo_mute (!mute);
2312 (*i)->set_solo_mute (mute);
2318 /* only alter bus solo mute */
2320 if (!dynamic_cast<Track*>((*i).get())) {
2322 if ((*i)->soloed()) {
2324 (*i)->set_solo_mute (false);
2328 /* don't mute master or control outs
2329 in response to another bus solo
2332 if ((*i) != _master_out &&
2333 (*i) != _control_out) {
2334 (*i)->set_solo_mute (mute);
2345 Session::catch_up_on_solo ()
2347 /* this is called after set_state() to catch the full solo
2348 state, which can't be correctly determined on a per-route
2349 basis, but needs the global overview that only the session
2352 update_route_solo_state();
2356 Session::catch_up_on_solo_mute_override ()
2358 if (Config->get_solo_model() != InverseMute) {
2362 /* this is called whenever the param solo-mute-override is
2365 shared_ptr<RouteList> r = routes.reader ();
2367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2368 (*i)->catch_up_on_solo_mute_override ();
2373 Session::route_by_name (string name)
2375 shared_ptr<RouteList> r = routes.reader ();
2377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2378 if ((*i)->name() == name) {
2383 return shared_ptr<Route> ((Route*) 0);
2387 Session::route_by_id (PBD::ID id)
2389 shared_ptr<RouteList> r = routes.reader ();
2391 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2392 if ((*i)->id() == id) {
2397 return shared_ptr<Route> ((Route*) 0);
2401 Session::route_by_remote_id (uint32_t id)
2403 shared_ptr<RouteList> r = routes.reader ();
2405 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2406 if ((*i)->remote_control_id() == id) {
2411 return shared_ptr<Route> ((Route*) 0);
2415 Session::find_current_end ()
2417 if (_state_of_the_state & Loading) {
2421 nframes_t max = get_maximum_extent ();
2423 if (max > end_location->end()) {
2424 end_location->set_end (max);
2426 DurationChanged(); /* EMIT SIGNAL */
2431 Session::get_maximum_extent () const
2436 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2438 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2439 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2441 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2442 if ((me = pl->get_maximum_extent()) > max) {
2450 boost::shared_ptr<Diskstream>
2451 Session::diskstream_by_name (string name)
2453 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2455 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2456 if ((*i)->name() == name) {
2461 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2464 boost::shared_ptr<Diskstream>
2465 Session::diskstream_by_id (const PBD::ID& id)
2467 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2469 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2470 if ((*i)->id() == id) {
2475 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2478 /* Region management */
2481 Session::new_region_name (string old)
2483 string::size_type last_period;
2485 string::size_type len = old.length() + 64;
2488 if ((last_period = old.find_last_of ('.')) == string::npos) {
2490 /* no period present - add one explicitly */
2493 last_period = old.length() - 1;
2498 number = atoi (old.substr (last_period+1).c_str());
2502 while (number < (UINT_MAX-1)) {
2504 RegionList::const_iterator i;
2509 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2512 for (i = regions.begin(); i != regions.end(); ++i) {
2513 if (i->second->name() == sbuf) {
2518 if (i == regions.end()) {
2523 if (number != (UINT_MAX-1)) {
2527 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2532 Session::region_name (string& result, string base, bool newlevel)
2537 if (base.find("/") != string::npos) {
2538 base = base.substr(base.find_last_of("/") + 1);
2543 Glib::Mutex::Lock lm (region_lock);
2545 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2554 string::size_type pos;
2556 pos = base.find_last_of ('.');
2558 /* pos may be npos, but then we just use entire base */
2560 subbase = base.substr (0, pos);
2565 Glib::Mutex::Lock lm (region_lock);
2567 map<string,uint32_t>::iterator x;
2571 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2573 region_name_map[subbase] = 1;
2576 snprintf (buf, sizeof (buf), ".%d", x->second);
2587 Session::add_region (boost::shared_ptr<Region> region)
2589 vector<boost::shared_ptr<Region> > v;
2590 v.push_back (region);
2595 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2600 Glib::Mutex::Lock lm (region_lock);
2602 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2604 boost::shared_ptr<Region> region = *ii;
2608 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2612 RegionList::iterator x;
2614 for (x = regions.begin(); x != regions.end(); ++x) {
2616 if (region->region_list_equivalent (x->second)) {
2621 if (x == regions.end()) {
2623 pair<RegionList::key_type,RegionList::mapped_type> entry;
2625 entry.first = region->id();
2626 entry.second = region;
2628 pair<RegionList::iterator,bool> x = regions.insert (entry);
2640 /* mark dirty because something has changed even if we didn't
2641 add the region to the region list.
2648 vector<boost::weak_ptr<Region> > v;
2649 boost::shared_ptr<Region> first_r;
2651 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2653 boost::shared_ptr<Region> region = *ii;
2657 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2660 v.push_back (region);
2667 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2668 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2670 update_region_name_map (region);
2674 RegionsAdded (v); /* EMIT SIGNAL */
2680 Session::update_region_name_map (boost::shared_ptr<Region> region)
2682 string::size_type last_period = region->name().find_last_of ('.');
2684 if (last_period != string::npos && last_period < region->name().length() - 1) {
2686 string base = region->name().substr (0, last_period);
2687 string number = region->name().substr (last_period+1);
2688 map<string,uint32_t>::iterator x;
2690 /* note that if there is no number, we get zero from atoi,
2694 region_name_map[base] = atoi (number);
2699 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2701 boost::shared_ptr<Region> region (weak_region.lock ());
2707 if (what_changed & Region::HiddenChanged) {
2708 /* relay hidden changes */
2709 RegionHiddenChange (region);
2712 if (what_changed & NameChanged) {
2713 update_region_name_map (region);
2718 Session::remove_region (boost::weak_ptr<Region> weak_region)
2720 RegionList::iterator i;
2721 boost::shared_ptr<Region> region (weak_region.lock ());
2727 bool removed = false;
2730 Glib::Mutex::Lock lm (region_lock);
2732 if ((i = regions.find (region->id())) != regions.end()) {
2738 /* mark dirty because something has changed even if we didn't
2739 remove the region from the region list.
2745 RegionRemoved(region); /* EMIT SIGNAL */
2749 boost::shared_ptr<Region>
2750 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2752 RegionList::iterator i;
2753 boost::shared_ptr<Region> region;
2755 Glib::Mutex::Lock lm (region_lock);
2757 for (i = regions.begin(); i != regions.end(); ++i) {
2761 if (region->whole_file()) {
2763 if (child->source_equivalent (region)) {
2769 return boost::shared_ptr<Region> ();
2773 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2775 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2776 (*i)->get_region_list_equivalent_regions (region, result);
2780 Session::destroy_region (boost::shared_ptr<Region> region)
2782 vector<boost::shared_ptr<Source> > srcs;
2785 if (region->playlist()) {
2786 region->playlist()->destroy_region (region);
2789 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2790 srcs.push_back (region->source (n));
2794 region->drop_references ();
2796 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2798 (*i)->mark_for_remove ();
2799 (*i)->drop_references ();
2801 cerr << "source was not used by any playlist\n";
2808 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2810 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2811 destroy_region (*i);
2817 Session::remove_last_capture ()
2819 list<boost::shared_ptr<Region> > r;
2821 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2823 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2824 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2827 r.insert (r.end(), l.begin(), l.end());
2832 destroy_regions (r);
2834 save_state (_current_snapshot_name);
2840 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2846 /* Source Management */
2849 Session::add_source (boost::shared_ptr<Source> source)
2851 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2852 pair<SourceMap::iterator,bool> result;
2854 entry.first = source->id();
2855 entry.second = source;
2858 Glib::Mutex::Lock lm (source_lock);
2859 result = sources.insert (entry);
2862 if (result.second) {
2863 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2867 boost::shared_ptr<AudioFileSource> afs;
2869 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2870 if (Config->get_auto_analyse_audio()) {
2871 Analyser::queue_source_for_analysis (source, false);
2877 Session::remove_source (boost::weak_ptr<Source> src)
2879 SourceMap::iterator i;
2880 boost::shared_ptr<Source> source = src.lock();
2887 Glib::Mutex::Lock lm (source_lock);
2889 if ((i = sources.find (source->id())) != sources.end()) {
2894 if (!_state_of_the_state & InCleanup) {
2896 /* save state so we don't end up with a session file
2897 referring to non-existent sources.
2900 save_state (_current_snapshot_name);
2904 boost::shared_ptr<Source>
2905 Session::source_by_id (const PBD::ID& id)
2907 Glib::Mutex::Lock lm (source_lock);
2908 SourceMap::iterator i;
2909 boost::shared_ptr<Source> source;
2911 if ((i = sources.find (id)) != sources.end()) {
2918 boost::shared_ptr<Source>
2919 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2921 Glib::Mutex::Lock lm (source_lock);
2923 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2924 cerr << "comparing " << path << " with " << i->second->name() << endl;
2925 boost::shared_ptr<AudioFileSource> afs
2926 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2928 if (afs && afs->path() == path && chn == afs->channel()) {
2932 return boost::shared_ptr<Source>();
2937 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2940 string old_basename = PBD::basename_nosuffix (oldname);
2941 string new_legalized = legalize_for_path (newname);
2943 /* note: we know (or assume) the old path is already valid */
2947 /* destructive file sources have a name of the form:
2949 /path/to/Tnnnn-NAME(%[LR])?.wav
2951 the task here is to replace NAME with the new name.
2954 /* find last slash */
2958 string::size_type slash;
2959 string::size_type dash;
2961 if ((slash = path.find_last_of ('/')) == string::npos) {
2965 dir = path.substr (0, slash+1);
2967 /* '-' is not a legal character for the NAME part of the path */
2969 if ((dash = path.find_last_of ('-')) == string::npos) {
2973 prefix = path.substr (slash+1, dash-(slash+1));
2978 path += new_legalized;
2979 path += ".wav"; /* XXX gag me with a spoon */
2983 /* non-destructive file sources have a name of the form:
2985 /path/to/NAME-nnnnn(%[LR])?.ext
2987 the task here is to replace NAME with the new name.
2992 string::size_type slash;
2993 string::size_type dash;
2994 string::size_type postfix;
2996 /* find last slash */
2998 if ((slash = path.find_last_of ('/')) == string::npos) {
3002 dir = path.substr (0, slash+1);
3004 /* '-' is not a legal character for the NAME part of the path */
3006 if ((dash = path.find_last_of ('-')) == string::npos) {
3010 suffix = path.substr (dash+1);
3012 // Suffix is now everything after the dash. Now we need to eliminate
3013 // the nnnnn part, which is done by either finding a '%' or a '.'
3015 postfix = suffix.find_last_of ("%");
3016 if (postfix == string::npos) {
3017 postfix = suffix.find_last_of ('.');
3020 if (postfix != string::npos) {
3021 suffix = suffix.substr (postfix);
3023 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3027 const uint32_t limit = 10000;
3028 char buf[PATH_MAX+1];
3030 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3032 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3034 if (access (buf, F_OK) != 0) {
3042 error << "FATAL ERROR! Could not find a " << endl;
3050 /** Return the full path (in some session directory) for a new embedded source.
3051 * \a name must be a session-unique name that does not contain slashes
3052 * (e.g. as returned by new_*_source_name)
3055 Session::new_source_path_from_name (DataType type, const string& name)
3057 assert(name.find("/") == string::npos);
3059 SessionDirectory sdir(get_best_session_directory_for_new_source());
3062 if (type == DataType::AUDIO) {
3063 p = sdir.sound_path();
3064 } else if (type == DataType::MIDI) {
3065 p = sdir.midi_path();
3067 error << "Unknown source type, unable to create file path" << endmsg;
3072 return p.to_string();
3076 Session::peak_path (Glib::ustring base) const
3078 sys::path peakfile_path(_session_dir->peak_path());
3079 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3080 return peakfile_path.to_string();
3083 /** Return a unique name based on \a base for a new internal audio source */
3085 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3089 char buf[PATH_MAX+1];
3090 const uint32_t limit = 10000;
3094 legalized = legalize_for_path (base);
3096 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3097 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3099 vector<space_and_path>::iterator i;
3100 uint32_t existing = 0;
3102 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3104 SessionDirectory sdir((*i).path);
3106 spath = sdir.sound_path().to_string();
3111 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3112 spath.c_str(), cnt, legalized.c_str());
3113 } else if (nchan == 2) {
3115 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3116 spath.c_str(), cnt, legalized.c_str());
3118 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3119 spath.c_str(), cnt, legalized.c_str());
3121 } else if (nchan < 26) {
3122 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3123 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3125 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3126 spath.c_str(), cnt, legalized.c_str());
3135 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3136 } else if (nchan == 2) {
3138 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3140 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3142 } else if (nchan < 26) {
3143 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3145 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3149 if (sys::exists(buf)) {
3155 if (existing == 0) {
3160 error << string_compose(
3161 _("There are already %1 recordings for %2, which I consider too many."),
3162 limit, base) << endmsg;
3164 throw failed_constructor();
3168 return Glib::path_get_basename(buf);
3171 /** Create a new embedded audio source */
3172 boost::shared_ptr<AudioFileSource>
3173 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3175 const size_t n_chans = ds.n_channels().n_audio();
3176 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3177 const string path = new_source_path_from_name(DataType::AUDIO, name);
3178 return boost::dynamic_pointer_cast<AudioFileSource> (
3179 SourceFactory::createWritable (
3180 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3183 /** Return a unique name based on \a base for a new internal MIDI source */
3185 Session::new_midi_source_name (const string& base)
3188 char buf[PATH_MAX+1];
3189 const uint32_t limit = 10000;
3193 legalized = legalize_for_path (base);
3195 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3196 for (cnt = 1; cnt <= limit; ++cnt) {
3198 vector<space_and_path>::iterator i;
3199 uint32_t existing = 0;
3201 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3203 SessionDirectory sdir((*i).path);
3205 sys::path p = sdir.midi_path();
3208 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3210 if (sys::exists (buf)) {
3215 if (existing == 0) {
3220 error << string_compose(
3221 _("There are already %1 recordings for %2, which I consider too many."),
3222 limit, base) << endmsg;
3224 throw failed_constructor();
3228 return Glib::path_get_basename(buf);
3232 /** Create a new embedded MIDI source */
3233 boost::shared_ptr<MidiSource>
3234 Session::create_midi_source_for_session (MidiDiskstream& ds)
3236 const string name = new_midi_source_name (ds.name());
3237 const string path = new_source_path_from_name (DataType::MIDI, name);
3239 return boost::dynamic_pointer_cast<SMFSource> (
3240 SourceFactory::createWritable (
3241 DataType::MIDI, *this, path, true, false, frame_rate()));
3245 /* Playlist management */
3247 boost::shared_ptr<Playlist>
3248 Session::playlist_by_name (string name)
3250 Glib::Mutex::Lock lm (playlist_lock);
3251 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3252 if ((*i)->name() == name) {
3256 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3257 if ((*i)->name() == name) {
3262 return boost::shared_ptr<Playlist>();
3266 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3268 Glib::Mutex::Lock lm (playlist_lock);
3269 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3270 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3271 list.push_back (*i);
3274 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3275 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3276 list.push_back (*i);
3282 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3284 if (playlist->hidden()) {
3289 Glib::Mutex::Lock lm (playlist_lock);
3290 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3291 playlists.insert (playlists.begin(), playlist);
3292 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3293 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3298 playlist->release();
3303 PlaylistAdded (playlist); /* EMIT SIGNAL */
3307 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3310 Glib::Mutex::Lock lm (playlist_lock);
3311 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3314 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3321 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3323 boost::shared_ptr<Playlist> pl(wpl.lock());
3329 PlaylistList::iterator x;
3332 /* its not supposed to be visible */
3337 Glib::Mutex::Lock lm (playlist_lock);
3341 unused_playlists.insert (pl);
3343 if ((x = playlists.find (pl)) != playlists.end()) {
3344 playlists.erase (x);
3350 playlists.insert (pl);
3352 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3353 unused_playlists.erase (x);
3360 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3362 if (_state_of_the_state & Deletion) {
3366 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3373 Glib::Mutex::Lock lm (playlist_lock);
3375 PlaylistList::iterator i;
3377 i = find (playlists.begin(), playlists.end(), playlist);
3378 if (i != playlists.end()) {
3379 playlists.erase (i);
3382 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3383 if (i != unused_playlists.end()) {
3384 unused_playlists.erase (i);
3391 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3395 Session::set_audition (boost::shared_ptr<Region> r)
3397 pending_audition_region = r;
3398 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3399 schedule_butler_transport_work ();
3403 Session::audition_playlist ()
3405 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3406 ev->region.reset ();
3411 Session::non_realtime_set_audition ()
3413 if (!pending_audition_region) {
3414 auditioner->audition_current_playlist ();
3416 auditioner->audition_region (pending_audition_region);
3417 pending_audition_region.reset ();
3419 AuditionActive (true); /* EMIT SIGNAL */
3423 Session::audition_region (boost::shared_ptr<Region> r)
3425 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3431 Session::cancel_audition ()
3433 if (auditioner->active()) {
3434 auditioner->cancel_audition ();
3435 AuditionActive (false); /* EMIT SIGNAL */
3440 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3442 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3446 Session::remove_empty_sounds ()
3448 vector<string> audio_filenames;
3450 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3452 Glib::Mutex::Lock lm (source_lock);
3454 TapeFileMatcher tape_file_matcher;
3456 remove_if (audio_filenames.begin(), audio_filenames.end(),
3457 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3459 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3461 sys::path audio_file_path (_session_dir->sound_path());
3463 audio_file_path /= *i;
3465 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3469 sys::remove (audio_file_path);
3470 const string peakfile = peak_path (audio_file_path.to_string());
3471 sys::remove (peakfile);
3473 catch (const sys::filesystem_error& err)
3475 error << err.what() << endmsg;
3482 Session::is_auditioning () const
3484 /* can be called before we have an auditioner object */
3486 return auditioner->active();
3493 Session::set_all_solo (bool yn)
3495 shared_ptr<RouteList> r = routes.reader ();
3497 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3498 if (!(*i)->is_hidden()) {
3499 (*i)->set_solo (yn, this);
3507 Session::set_all_mute (bool yn)
3509 shared_ptr<RouteList> r = routes.reader ();
3511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3512 if (!(*i)->is_hidden()) {
3513 (*i)->set_mute (yn, this);
3521 Session::n_diskstreams () const
3525 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3527 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3528 if (!(*i)->hidden()) {
3536 Session::graph_reordered ()
3538 /* don't do this stuff if we are setting up connections
3539 from a set_state() call or creating new tracks.
3542 if (_state_of_the_state & InitialConnecting) {
3546 /* every track/bus asked for this to be handled but it was deferred because
3547 we were connecting. do it now.
3550 request_input_change_handling ();
3554 /* force all diskstreams to update their capture offset values to
3555 reflect any changes in latencies within the graph.
3558 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3560 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3561 (*i)->set_capture_offset ();
3566 Session::record_disenable_all ()
3568 record_enable_change_all (false);
3572 Session::record_enable_all ()
3574 record_enable_change_all (true);
3578 Session::record_enable_change_all (bool yn)
3580 shared_ptr<RouteList> r = routes.reader ();
3582 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3585 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3586 at->set_record_enable (yn, this);
3590 /* since we don't keep rec-enable state, don't mark session dirty */
3594 Session::add_processor (Processor* processor)
3597 PortInsert* port_insert;
3598 PluginInsert* plugin_insert;
3600 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3601 _port_inserts.insert (_port_inserts.begin(), port_insert);
3602 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3603 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3604 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3605 _sends.insert (_sends.begin(), send);
3607 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3611 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3617 Session::remove_processor (Processor* processor)
3620 PortInsert* port_insert;
3621 PluginInsert* plugin_insert;
3623 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3624 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3625 if (x != _port_inserts.end()) {
3626 insert_bitset[port_insert->bit_slot()] = false;
3627 _port_inserts.erase (x);
3629 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3630 _plugin_inserts.remove (plugin_insert);
3631 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3632 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3633 if (x != _sends.end()) {
3634 send_bitset[send->bit_slot()] = false;
3638 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3646 Session::available_capture_duration ()
3648 float sample_bytes_on_disk = 4.0; // keep gcc happy
3650 switch (Config->get_native_file_data_format()) {
3652 sample_bytes_on_disk = 4.0;
3656 sample_bytes_on_disk = 3.0;
3660 sample_bytes_on_disk = 2.0;
3664 /* impossible, but keep some gcc versions happy */
3665 fatal << string_compose (_("programming error: %1"),
3666 X_("illegal native file data format"))
3671 double scale = 4096.0 / sample_bytes_on_disk;
3673 if (_total_free_4k_blocks * scale > (double) max_frames) {
3677 return (nframes_t) floor (_total_free_4k_blocks * scale);
3681 Session::add_bundle (shared_ptr<Bundle> bundle)
3684 RCUWriter<BundleList> writer (_bundles);
3685 boost::shared_ptr<BundleList> b = writer.get_copy ();
3686 b->push_back (bundle);
3689 BundleAdded (bundle); /* EMIT SIGNAL */
3695 Session::remove_bundle (shared_ptr<Bundle> bundle)
3697 bool removed = false;
3700 RCUWriter<BundleList> writer (_bundles);
3701 boost::shared_ptr<BundleList> b = writer.get_copy ();
3702 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3704 if (i != b->end()) {
3711 BundleRemoved (bundle); /* EMIT SIGNAL */
3718 Session::bundle_by_name (string name) const
3720 boost::shared_ptr<BundleList> b = _bundles.reader ();
3722 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3723 if ((*i)->name() == name) {
3728 return boost::shared_ptr<Bundle> ();
3732 Session::tempo_map_changed (Change ignored)
3736 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3737 (*i)->update_after_tempo_map_change ();
3740 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3741 (*i)->update_after_tempo_map_change ();
3747 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3748 * the given count with the current block size.
3751 Session::ensure_buffers (ChanCount howmany)
3753 if (current_block_size == 0)
3754 return; // too early? (is this ok?)
3756 // We need at least 2 MIDI scratch buffers to mix/merge
3757 if (howmany.n_midi() < 2)
3758 howmany.set_midi(2);
3760 // FIXME: JACK needs to tell us maximum MIDI buffer size
3761 // Using nasty assumption (max # events == nframes) for now
3762 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3763 _mix_buffers->ensure_buffers(howmany, current_block_size);
3764 _silent_buffers->ensure_buffers(howmany, current_block_size);
3766 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3770 Session::next_insert_id ()
3772 /* this doesn't really loop forever. just think about it */
3775 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3776 if (!insert_bitset[n]) {
3777 insert_bitset[n] = true;
3783 /* none available, so resize and try again */
3785 insert_bitset.resize (insert_bitset.size() + 16, false);
3790 Session::next_send_id ()
3792 /* this doesn't really loop forever. just think about it */
3795 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3796 if (!send_bitset[n]) {
3797 send_bitset[n] = true;
3803 /* none available, so resize and try again */
3805 send_bitset.resize (send_bitset.size() + 16, false);
3810 Session::mark_send_id (uint32_t id)
3812 if (id >= send_bitset.size()) {
3813 send_bitset.resize (id+16, false);
3815 if (send_bitset[id]) {
3816 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3818 send_bitset[id] = true;
3822 Session::mark_insert_id (uint32_t id)
3824 if (id >= insert_bitset.size()) {
3825 insert_bitset.resize (id+16, false);
3827 if (insert_bitset[id]) {
3828 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3830 insert_bitset[id] = true;
3833 /* Named Selection management */
3836 Session::named_selection_by_name (string name)
3838 Glib::Mutex::Lock lm (named_selection_lock);
3839 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3840 if ((*i)->name == name) {
3848 Session::add_named_selection (NamedSelection* named_selection)
3851 Glib::Mutex::Lock lm (named_selection_lock);
3852 named_selections.insert (named_selections.begin(), named_selection);
3855 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3861 NamedSelectionAdded (); /* EMIT SIGNAL */
3865 Session::remove_named_selection (NamedSelection* named_selection)
3867 bool removed = false;
3870 Glib::Mutex::Lock lm (named_selection_lock);
3872 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3874 if (i != named_selections.end()) {
3876 named_selections.erase (i);
3883 NamedSelectionRemoved (); /* EMIT SIGNAL */
3888 Session::reset_native_file_format ()
3890 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3892 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3893 (*i)->reset_write_sources (false);
3898 Session::route_name_unique (string n) const
3900 shared_ptr<RouteList> r = routes.reader ();
3902 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3903 if ((*i)->name() == n) {
3912 Session::n_playlists () const
3914 Glib::Mutex::Lock lm (playlist_lock);
3915 return playlists.size();
3919 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3921 if (!force && howmany <= _npan_buffers) {
3925 if (_pan_automation_buffer) {
3927 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3928 delete [] _pan_automation_buffer[i];
3931 delete [] _pan_automation_buffer;
3934 _pan_automation_buffer = new pan_t*[howmany];
3936 for (uint32_t i = 0; i < howmany; ++i) {
3937 _pan_automation_buffer[i] = new pan_t[nframes];
3940 _npan_buffers = howmany;
3944 Session::freeze (InterThreadInfo& itt)
3946 shared_ptr<RouteList> r = routes.reader ();
3948 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3952 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3953 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3963 boost::shared_ptr<Region>
3964 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3965 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3967 boost::shared_ptr<Region> result;
3968 boost::shared_ptr<Playlist> playlist;
3969 boost::shared_ptr<AudioFileSource> fsource;
3971 char buf[PATH_MAX+1];
3972 ChanCount nchans(track.audio_diskstream()->n_channels());
3974 nframes_t this_chunk;
3977 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3978 const string sound_dir = sdir.sound_path().to_string();
3979 nframes_t len = end - start;
3982 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3983 end, start) << endmsg;
3987 // any bigger than this seems to cause stack overflows in called functions
3988 const nframes_t chunk_size = (128 * 1024)/4;
3990 g_atomic_int_set (&processing_prohibited, 1);
3992 /* call tree *MUST* hold route_lock */
3994 if ((playlist = track.diskstream()->playlist()) == 0) {
3998 /* external redirects will be a problem */
4000 if (track.has_external_redirects()) {
4004 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4006 for (x = 0; x < 99999; ++x) {
4007 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4008 if (access (buf, F_OK) != 0) {
4014 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4019 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4020 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4023 catch (failed_constructor& err) {
4024 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4028 srcs.push_back (fsource);
4031 /* XXX need to flush all redirects */
4036 /* create a set of reasonably-sized buffers */
4037 buffers.ensure_buffers(nchans, chunk_size);
4038 buffers.set_count(nchans);
4040 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4041 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4043 afs->prepare_for_peakfile_writes ();
4046 while (to_do && !itt.cancel) {
4048 this_chunk = min (to_do, chunk_size);
4050 if (track.export_stuff (buffers, start, this_chunk)) {
4055 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4056 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4059 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4065 start += this_chunk;
4066 to_do -= this_chunk;
4068 itt.progress = (float) (1.0 - ((double) to_do / len));
4077 xnow = localtime (&now);
4079 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4080 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4083 afs->update_header (position, *xnow, now);
4084 afs->flush_header ();
4088 /* construct a region to represent the bounced material */
4090 result = RegionFactory::create (srcs, 0,
4091 srcs.front()->length(srcs.front()->timeline_position()),
4092 region_name_from_path (srcs.front()->name(), true));
4097 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4098 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4101 afs->mark_for_remove ();
4104 (*src)->drop_references ();
4108 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4109 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4112 afs->done_with_peakfile_writes ();
4116 g_atomic_int_set (&processing_prohibited, 0);
4122 Session::get_silent_buffers (ChanCount count)
4124 assert(_silent_buffers->available() >= count);
4125 _silent_buffers->set_count(count);
4127 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4128 for (size_t i= 0; i < count.get(*t); ++i) {
4129 _silent_buffers->get(*t, i).clear();
4133 return *_silent_buffers;
4137 Session::get_scratch_buffers (ChanCount count)
4139 if (count != ChanCount::ZERO) {
4140 assert(_scratch_buffers->available() >= count);
4141 _scratch_buffers->set_count(count);
4143 _scratch_buffers->set_count (_scratch_buffers->available());
4146 return *_scratch_buffers;
4150 Session::get_mix_buffers (ChanCount count)
4152 assert(_mix_buffers->available() >= count);
4153 _mix_buffers->set_count(count);
4154 return *_mix_buffers;
4158 Session::ntracks () const
4161 shared_ptr<RouteList> r = routes.reader ();
4163 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4164 if (dynamic_cast<Track*> ((*i).get())) {
4173 Session::nbusses () const
4176 shared_ptr<RouteList> r = routes.reader ();
4178 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4179 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4188 Session::add_automation_list(AutomationList *al)
4190 automation_lists[al->id()] = al;
4194 Session::compute_initial_length ()
4196 return _engine.frame_rate() * 60 * 5;
4200 Session::sync_order_keys (const char* base)
4202 if (!Config->get_sync_all_route_ordering()) {
4203 /* leave order keys as they are */
4207 boost::shared_ptr<RouteList> r = routes.reader ();
4209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4210 (*i)->sync_order_keys (base);
4213 Route::SyncOrderKeys (base); // EMIT SIGNAL