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/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/session_directory.h>
50 #include <ardour/session_metadata.h>
51 #include <ardour/utils.h>
52 #include <ardour/audio_diskstream.h>
53 #include <ardour/audioplaylist.h>
54 #include <ardour/audioregion.h>
55 #include <ardour/audiofilesource.h>
56 #include <ardour/midi_diskstream.h>
57 #include <ardour/midi_playlist.h>
58 #include <ardour/midi_region.h>
59 #include <ardour/smf_source.h>
60 #include <ardour/auditioner.h>
61 #include <ardour/recent_sessions.h>
62 #include <ardour/io_processor.h>
63 #include <ardour/send.h>
64 #include <ardour/processor.h>
65 #include <ardour/plugin_insert.h>
66 #include <ardour/port_insert.h>
67 #include <ardour/auto_bundle.h>
68 #include <ardour/slave.h>
69 #include <ardour/tempo.h>
70 #include <ardour/audio_track.h>
71 #include <ardour/midi_track.h>
72 #include <ardour/cycle_timer.h>
73 #include <ardour/named_selection.h>
74 #include <ardour/crossfade.h>
75 #include <ardour/playlist.h>
76 #include <ardour/click.h>
77 #include <ardour/data_type.h>
78 #include <ardour/buffer_set.h>
79 #include <ardour/source_factory.h>
80 #include <ardour/region_factory.h>
81 #include <ardour/filename_extensions.h>
82 #include <ardour/session_directory.h>
83 #include <ardour/tape_file_matcher.h>
84 #include <ardour/analyser.h>
87 #include <ardour/osc.h>
93 using namespace ARDOUR;
95 using boost::shared_ptr;
98 static const int CPU_CACHE_ALIGN = 64;
100 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
103 bool Session::_disable_all_loaded_plugins = false;
105 sigc::signal<void,std::string> Session::Dialog;
106 sigc::signal<int> Session::AskAboutPendingState;
107 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
108 sigc::signal<void> Session::SendFeedback;
110 sigc::signal<void> Session::SMPTEOffsetChanged;
111 sigc::signal<void> Session::StartTimeChanged;
112 sigc::signal<void> Session::EndTimeChanged;
113 sigc::signal<void> Session::AutoBindingOn;
114 sigc::signal<void> Session::AutoBindingOff;
115 sigc::signal<void, std::string, std::string> Session::Exported;
117 Session::Session (AudioEngine &eng,
118 const string& fullpath,
119 const string& snapshot_name,
123 _scratch_buffers(new BufferSet()),
124 _silent_buffers(new BufferSet()),
125 _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),
132 post_transport_work((PostTransportWork)0),
133 _send_smpte_update (false),
135 diskstreams (new DiskstreamList),
136 routes (new RouteList),
137 auditioner ((Auditioner*) 0),
138 _total_free_4k_blocks (0),
139 _bundle_xml_node (0),
142 _metadata (new SessionMetadata())
146 if (!eng.connected()) {
147 throw failed_constructor();
150 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
152 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
153 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
155 first_stage_init (fullpath, snapshot_name);
157 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
160 if (create (new_session, mix_template, compute_initial_length())) {
162 throw failed_constructor ();
166 if (second_stage_init (new_session)) {
168 throw failed_constructor ();
171 store_recent_sessions(_name, _path);
173 bool was_dirty = dirty();
175 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
177 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
180 DirtyChanged (); /* EMIT SIGNAL */
184 Session::Session (AudioEngine &eng,
186 string snapshot_name,
187 AutoConnectOption input_ac,
188 AutoConnectOption output_ac,
189 uint32_t control_out_channels,
190 uint32_t master_out_channels,
191 uint32_t requested_physical_in,
192 uint32_t requested_physical_out,
193 nframes_t initial_length)
196 _scratch_buffers(new BufferSet()),
197 _silent_buffers(new BufferSet()),
198 _mix_buffers(new BufferSet()),
199 _mmc_port (default_mmc_port),
200 _mtc_port (default_mtc_port),
201 _midi_port (default_midi_port),
202 _midi_clock_port (default_midi_clock_port),
203 _session_dir ( new SessionDirectory(fullpath)),
204 pending_events (2048),
205 post_transport_work((PostTransportWork)0),
206 _send_smpte_update (false),
208 diskstreams (new DiskstreamList),
209 routes (new RouteList),
210 _total_free_4k_blocks (0),
211 _bundle_xml_node (0),
217 if (!eng.connected()) {
218 throw failed_constructor();
221 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
223 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
224 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
226 if (n_physical_inputs) {
227 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
230 if (n_physical_outputs) {
231 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
234 first_stage_init (fullpath, snapshot_name);
236 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
239 if (create (new_session, string(), initial_length)) {
241 throw failed_constructor ();
246 /* set up Master Out and Control Out if necessary */
251 if (control_out_channels) {
252 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
253 r->set_remote_control_id (control_id++);
258 if (master_out_channels) {
259 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
260 r->set_remote_control_id (control_id);
264 /* prohibit auto-connect to master, because there isn't one */
265 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
269 add_routes (rl, false);
274 Config->set_input_auto_connect (input_ac);
275 Config->set_output_auto_connect (output_ac);
277 if (second_stage_init (new_session)) {
279 throw failed_constructor ();
282 store_recent_sessions (_name, _path);
284 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
286 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
297 /* if we got to here, leaving pending capture state around
301 remove_pending_capture_state ();
303 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
305 _engine.remove_session ();
307 GoingAway (); /* EMIT SIGNAL */
313 /* clear history so that no references to objects are held any more */
317 /* clear state tree so that no references to objects are held any more */
323 terminate_butler_thread ();
324 //terminate_midi_thread ();
326 if (click_data && click_data != default_click) {
327 delete [] click_data;
330 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
331 delete [] click_emphasis_data;
336 delete _scratch_buffers;
337 delete _silent_buffers;
340 AudioDiskstream::free_working_buffers();
342 Route::SyncOrderKeys.clear();
344 #undef TRACK_DESTRUCTION
345 #ifdef TRACK_DESTRUCTION
346 cerr << "delete named selections\n";
347 #endif /* TRACK_DESTRUCTION */
348 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
349 NamedSelectionList::iterator tmp;
358 #ifdef TRACK_DESTRUCTION
359 cerr << "delete playlists\n";
360 #endif /* TRACK_DESTRUCTION */
361 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
362 PlaylistList::iterator tmp;
367 (*i)->drop_references ();
372 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
373 PlaylistList::iterator tmp;
378 (*i)->drop_references ();
384 unused_playlists.clear ();
386 #ifdef TRACK_DESTRUCTION
387 cerr << "delete regions\n";
388 #endif /* TRACK_DESTRUCTION */
390 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
391 RegionList::iterator tmp;
396 i->second->drop_references ();
403 #ifdef TRACK_DESTRUCTION
404 cerr << "delete routes\n";
405 #endif /* TRACK_DESTRUCTION */
407 RCUWriter<RouteList> writer (routes);
408 boost::shared_ptr<RouteList> r = writer.get_copy ();
409 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
410 (*i)->drop_references ();
413 /* writer goes out of scope and updates master */
418 #ifdef TRACK_DESTRUCTION
419 cerr << "delete diskstreams\n";
420 #endif /* TRACK_DESTRUCTION */
422 RCUWriter<DiskstreamList> dwriter (diskstreams);
423 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
424 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
425 (*i)->drop_references ();
429 diskstreams.flush ();
431 #ifdef TRACK_DESTRUCTION
432 cerr << "delete audio sources\n";
433 #endif /* TRACK_DESTRUCTION */
434 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
435 SourceMap::iterator tmp;
440 i->second->drop_references ();
446 #ifdef TRACK_DESTRUCTION
447 cerr << "delete mix groups\n";
448 #endif /* TRACK_DESTRUCTION */
449 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
450 list<RouteGroup*>::iterator tmp;
460 #ifdef TRACK_DESTRUCTION
461 cerr << "delete edit groups\n";
462 #endif /* TRACK_DESTRUCTION */
463 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
464 list<RouteGroup*>::iterator tmp;
474 if (butler_mixdown_buffer) {
475 delete [] butler_mixdown_buffer;
478 if (butler_gain_buffer) {
479 delete [] butler_gain_buffer;
482 Crossfade::set_buffer_size (0);
490 Session::set_worst_io_latencies ()
492 _worst_output_latency = 0;
493 _worst_input_latency = 0;
495 if (!_engine.connected()) {
499 boost::shared_ptr<RouteList> r = routes.reader ();
501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
502 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
503 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
508 Session::when_engine_running ()
510 string first_physical_output;
512 /* we don't want to run execute this again */
514 BootMessage (_("Set block size and sample rate"));
516 set_block_size (_engine.frames_per_cycle());
517 set_frame_rate (_engine.frame_rate());
519 BootMessage (_("Using configuration"));
521 Config->map_parameters (mem_fun (*this, &Session::config_changed));
523 /* every time we reconnect, recompute worst case output latencies */
525 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
527 if (synced_to_jack()) {
528 _engine.transport_stop ();
531 if (Config->get_jack_time_master()) {
532 _engine.transport_locate (_transport_frame);
540 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
542 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
544 /* existing state for Click */
546 if (_click_io->set_state (*child->children().front()) == 0) {
548 _clicking = Config->get_clicking ();
552 error << _("could not setup Click I/O") << endmsg;
558 /* default state for Click */
560 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
562 if (first_physical_output.length()) {
563 if (_click_io->add_output_port (first_physical_output, this)) {
564 // relax, even though its an error
566 _clicking = Config->get_clicking ();
572 catch (failed_constructor& err) {
573 error << _("cannot setup Click I/O") << endmsg;
576 BootMessage (_("Compute I/O Latencies"));
578 set_worst_io_latencies ();
581 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
584 /* Create a set of Bundle objects that map
585 to the physical outputs currently available
588 BootMessage (_("Set up standard connections"));
592 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
594 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
596 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
598 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
603 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
605 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
607 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
609 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
616 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
618 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
620 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
622 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
623 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
628 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
630 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
632 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
634 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
635 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
644 /* create master/control ports */
649 /* force the master to ignore any later call to this */
651 if (_master_out->pending_state_node) {
652 _master_out->ports_became_legal();
655 /* no panner resets till we are through */
657 _master_out->defer_pan_reset ();
659 while (_master_out->n_inputs().n_audio()
660 < _master_out->input_maximum().n_audio()) {
661 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
662 error << _("cannot setup master inputs")
668 while (_master_out->n_outputs().n_audio()
669 < _master_out->output_maximum().n_audio()) {
670 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
671 error << _("cannot setup master outputs")
678 _master_out->allow_pan_reset ();
682 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
684 c->set_channels (_master_out->n_inputs().n_total());
685 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
686 c->set_port (n, _master_out->input(n)->name());
691 BootMessage (_("Setup signal flow and plugins"));
695 /* catch up on send+insert cnts */
697 BootMessage (_("Catch up with send/insert state"));
701 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
704 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
705 if (id > insert_cnt) {
713 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
716 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
724 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
726 /* hook us up to the engine */
728 BootMessage (_("Connect to engine"));
730 _engine.set_session (this);
735 BootMessage (_("OSC startup"));
737 osc->set_session (*this);
743 Session::hookup_io ()
745 /* stop graph reordering notifications from
746 causing resorts, etc.
749 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
752 if (auditioner == 0) {
754 /* we delay creating the auditioner till now because
755 it makes its own connections to ports.
756 the engine has to be running for this to work.
760 auditioner.reset (new Auditioner (*this));
763 catch (failed_constructor& err) {
764 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
768 /* Tell all IO objects to create their ports */
774 vector<string> cports;
776 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
777 if (_control_out->add_input_port ("", this)) {
778 error << _("cannot setup control inputs")
784 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
785 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
786 error << _("cannot set up master outputs")
794 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
796 for (n = 0; n < ni; ++n) {
797 cports.push_back (_control_out->input(n)->name());
800 boost::shared_ptr<RouteList> r = routes.reader ();
802 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
803 (*x)->set_control_outs (cports);
807 /* load bundles, which we may have postponed earlier on */
808 if (_bundle_xml_node) {
809 load_bundles (*_bundle_xml_node);
810 delete _bundle_xml_node;
813 /* Tell all IO objects to connect themselves together */
815 IO::enable_connecting ();
817 /* Now reset all panners */
819 IO::reset_panners ();
821 /* Anyone who cares about input state, wake up and do something */
823 IOConnectionsComplete (); /* EMIT SIGNAL */
825 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
828 /* now handle the whole enchilada as if it was one
834 /* update mixer solo state */
840 Session::playlist_length_changed ()
842 /* we can't just increase end_location->end() if pl->get_maximum_extent()
843 if larger. if the playlist used to be the longest playlist,
844 and its now shorter, we have to decrease end_location->end(). hence,
845 we have to iterate over all diskstreams and check the
846 playlists currently in use.
852 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
854 boost::shared_ptr<Playlist> playlist;
856 if ((playlist = dstream->playlist()) != 0) {
857 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
860 /* see comment in playlist_length_changed () */
865 Session::record_enabling_legal () const
867 /* this used to be in here, but survey says.... we don't need to restrict it */
868 // if (record_status() == Recording) {
872 if (Config->get_all_safe()) {
879 Session::reset_input_monitor_state ()
881 if (transport_rolling()) {
883 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
885 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
886 if ((*i)->record_enabled ()) {
887 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
888 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
892 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
894 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
895 if ((*i)->record_enabled ()) {
896 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
897 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
904 Session::auto_punch_start_changed (Location* location)
906 replace_event (Event::PunchIn, location->start());
908 if (get_record_enabled() && Config->get_punch_in()) {
909 /* capture start has been changed, so save new pending state */
910 save_state ("", true);
915 Session::auto_punch_end_changed (Location* location)
917 nframes_t when_to_stop = location->end();
918 // when_to_stop += _worst_output_latency + _worst_input_latency;
919 replace_event (Event::PunchOut, when_to_stop);
923 Session::auto_punch_changed (Location* location)
925 nframes_t when_to_stop = location->end();
927 replace_event (Event::PunchIn, location->start());
928 //when_to_stop += _worst_output_latency + _worst_input_latency;
929 replace_event (Event::PunchOut, when_to_stop);
933 Session::auto_loop_changed (Location* location)
935 replace_event (Event::AutoLoop, location->end(), location->start());
937 if (transport_rolling() && play_loop) {
939 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
941 if (_transport_frame > location->end()) {
942 // relocate to beginning of loop
943 clear_events (Event::LocateRoll);
945 request_locate (location->start(), true);
948 else if (Config->get_seamless_loop() && !loop_changing) {
950 // schedule a locate-roll to refill the diskstreams at the
952 loop_changing = true;
954 if (location->end() > last_loopend) {
955 clear_events (Event::LocateRoll);
956 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
963 last_loopend = location->end();
967 Session::set_auto_punch_location (Location* location)
971 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
972 auto_punch_start_changed_connection.disconnect();
973 auto_punch_end_changed_connection.disconnect();
974 auto_punch_changed_connection.disconnect();
975 existing->set_auto_punch (false, this);
976 remove_event (existing->start(), Event::PunchIn);
977 clear_events (Event::PunchOut);
978 auto_punch_location_changed (0);
987 if (location->end() <= location->start()) {
988 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
992 auto_punch_start_changed_connection.disconnect();
993 auto_punch_end_changed_connection.disconnect();
994 auto_punch_changed_connection.disconnect();
996 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
997 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
998 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1000 location->set_auto_punch (true, this);
1003 auto_punch_changed (location);
1005 auto_punch_location_changed (location);
1009 Session::set_auto_loop_location (Location* location)
1013 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1014 auto_loop_start_changed_connection.disconnect();
1015 auto_loop_end_changed_connection.disconnect();
1016 auto_loop_changed_connection.disconnect();
1017 existing->set_auto_loop (false, this);
1018 remove_event (existing->end(), Event::AutoLoop);
1019 auto_loop_location_changed (0);
1024 if (location == 0) {
1028 if (location->end() <= location->start()) {
1029 error << _("Session: you can't use a mark for auto loop") << endmsg;
1033 last_loopend = location->end();
1035 auto_loop_start_changed_connection.disconnect();
1036 auto_loop_end_changed_connection.disconnect();
1037 auto_loop_changed_connection.disconnect();
1039 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1040 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1041 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1043 location->set_auto_loop (true, this);
1045 /* take care of our stuff first */
1047 auto_loop_changed (location);
1049 /* now tell everyone else */
1051 auto_loop_location_changed (location);
1055 Session::locations_added (Location* ignored)
1061 Session::locations_changed ()
1063 _locations.apply (*this, &Session::handle_locations_changed);
1067 Session::handle_locations_changed (Locations::LocationList& locations)
1069 Locations::LocationList::iterator i;
1071 bool set_loop = false;
1072 bool set_punch = false;
1074 for (i = locations.begin(); i != locations.end(); ++i) {
1078 if (location->is_auto_punch()) {
1079 set_auto_punch_location (location);
1082 if (location->is_auto_loop()) {
1083 set_auto_loop_location (location);
1087 if (location->is_start()) {
1088 start_location = location;
1090 if (location->is_end()) {
1091 end_location = location;
1096 set_auto_loop_location (0);
1099 set_auto_punch_location (0);
1106 Session::enable_record ()
1108 /* XXX really atomic compare+swap here */
1109 if (g_atomic_int_get (&_record_status) != Recording) {
1110 g_atomic_int_set (&_record_status, Recording);
1111 _last_record_location = _transport_frame;
1112 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1114 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1116 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1117 if ((*i)->record_enabled ()) {
1118 (*i)->monitor_input (true);
1123 RecordStateChanged ();
1128 Session::disable_record (bool rt_context, bool force)
1132 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1134 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1135 g_atomic_int_set (&_record_status, Disabled);
1137 if (rs == Recording) {
1138 g_atomic_int_set (&_record_status, Enabled);
1142 // FIXME: timestamp correct? [DR]
1143 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1144 // does this /need/ to be sent in all cases?
1146 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1148 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1149 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1151 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1152 if ((*i)->record_enabled ()) {
1153 (*i)->monitor_input (false);
1158 RecordStateChanged (); /* emit signal */
1161 remove_pending_capture_state ();
1167 Session::step_back_from_record ()
1169 /* XXX really atomic compare+swap here */
1170 if (g_atomic_int_get (&_record_status) == Recording) {
1171 g_atomic_int_set (&_record_status, Enabled);
1173 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1174 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1176 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1177 if ((*i)->record_enabled ()) {
1178 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1179 (*i)->monitor_input (false);
1187 Session::maybe_enable_record ()
1189 g_atomic_int_set (&_record_status, Enabled);
1191 /* this function is currently called from somewhere other than an RT thread.
1192 this save_state() call therefore doesn't impact anything.
1195 save_state ("", true);
1197 if (_transport_speed) {
1198 if (!Config->get_punch_in()) {
1202 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1203 RecordStateChanged (); /* EMIT SIGNAL */
1210 Session::audible_frame () const
1216 /* the first of these two possible settings for "offset"
1217 mean that the audible frame is stationary until
1218 audio emerges from the latency compensation
1221 the second means that the audible frame is stationary
1222 until audio would emerge from a physical port
1223 in the absence of any plugin latency compensation
1226 offset = _worst_output_latency;
1228 if (offset > current_block_size) {
1229 offset -= current_block_size;
1231 /* XXX is this correct? if we have no external
1232 physical connections and everything is internal
1233 then surely this is zero? still, how
1234 likely is that anyway?
1236 offset = current_block_size;
1239 if (synced_to_jack()) {
1240 tf = _engine.transport_frame();
1242 tf = _transport_frame;
1245 if (_transport_speed == 0) {
1255 if (!non_realtime_work_pending()) {
1259 /* take latency into account */
1268 Session::set_frame_rate (nframes_t frames_per_second)
1270 /** \fn void Session::set_frame_size(nframes_t)
1271 the AudioEngine object that calls this guarantees
1272 that it will not be called while we are also in
1273 ::process(). Its fine to do things that block
1277 _base_frame_rate = frames_per_second;
1281 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1285 // XXX we need some equivalent to this, somehow
1286 // SndFileSource::setup_standard_crossfades (frames_per_second);
1290 /* XXX need to reset/reinstantiate all LADSPA plugins */
1294 Session::set_block_size (nframes_t nframes)
1296 /* the AudioEngine guarantees
1297 that it will not be called while we are also in
1298 ::process(). It is therefore fine to do things that block
1304 current_block_size = nframes;
1306 ensure_buffers(_scratch_buffers->available());
1308 if (_gain_automation_buffer) {
1309 delete [] _gain_automation_buffer;
1311 _gain_automation_buffer = new gain_t[nframes];
1313 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1315 boost::shared_ptr<RouteList> r = routes.reader ();
1317 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1318 (*i)->set_block_size (nframes);
1321 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1322 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1323 (*i)->set_block_size (nframes);
1326 set_worst_io_latencies ();
1331 Session::set_default_fade (float steepness, float fade_msecs)
1334 nframes_t fade_frames;
1336 /* Don't allow fade of less 1 frame */
1338 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1345 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1349 default_fade_msecs = fade_msecs;
1350 default_fade_steepness = steepness;
1353 // jlc, WTF is this!
1354 Glib::RWLock::ReaderLock lm (route_lock);
1355 AudioRegion::set_default_fade (steepness, fade_frames);
1360 /* XXX have to do this at some point */
1361 /* foreach region using default fade, reset, then
1362 refill_all_diskstream_buffers ();
1367 struct RouteSorter {
1368 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1369 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1371 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1374 if (r1->fed_by.empty()) {
1375 if (r2->fed_by.empty()) {
1376 /* no ardour-based connections inbound to either route. just use signal order */
1377 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1379 /* r2 has connections, r1 does not; run r1 early */
1383 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1392 shared_ptr<Route> r2;
1394 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1395 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1399 /* make a copy of the existing list of routes that feed r1 */
1401 set<shared_ptr<Route> > existing = r1->fed_by;
1403 /* for each route that feeds r1, recurse, marking it as feeding
1407 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1410 /* r2 is a route that feeds r1 which somehow feeds base. mark
1411 base as being fed by r2
1414 rbase->fed_by.insert (r2);
1418 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1422 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1426 /* now recurse, so that we can mark base as being fed by
1427 all routes that feed r2
1430 trace_terminal (r2, rbase);
1437 Session::resort_routes ()
1439 /* don't do anything here with signals emitted
1440 by Routes while we are being destroyed.
1443 if (_state_of_the_state & Deletion) {
1450 RCUWriter<RouteList> writer (routes);
1451 shared_ptr<RouteList> r = writer.get_copy ();
1452 resort_routes_using (r);
1453 /* writer goes out of scope and forces update */
1458 Session::resort_routes_using (shared_ptr<RouteList> r)
1460 RouteList::iterator i, j;
1462 for (i = r->begin(); i != r->end(); ++i) {
1464 (*i)->fed_by.clear ();
1466 for (j = r->begin(); j != r->end(); ++j) {
1468 /* although routes can feed themselves, it will
1469 cause an endless recursive descent if we
1470 detect it. so don't bother checking for
1478 if ((*j)->feeds (*i)) {
1479 (*i)->fed_by.insert (*j);
1484 for (i = r->begin(); i != r->end(); ++i) {
1485 trace_terminal (*i, *i);
1492 cerr << "finished route resort\n";
1494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1495 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1502 list<boost::shared_ptr<MidiTrack> >
1503 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1505 char track_name[32];
1506 uint32_t track_id = 0;
1509 RouteList new_routes;
1510 list<boost::shared_ptr<MidiTrack> > ret;
1511 //uint32_t control_id;
1513 // FIXME: need physical I/O and autoconnect stuff for MIDI
1515 /* count existing midi tracks */
1518 shared_ptr<RouteList> r = routes.reader ();
1520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1521 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1522 if (!(*i)->is_hidden()) {
1524 //channels_used += (*i)->n_inputs().n_midi();
1530 vector<string> physinputs;
1531 vector<string> physoutputs;
1533 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1534 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1536 // control_id = ntracks() + nbusses();
1540 /* check for duplicate route names, since we might have pre-existing
1541 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1542 save, close,restart,add new route - first named route is now
1550 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1552 if (route_by_name (track_name) == 0) {
1556 } while (track_id < (UINT_MAX-1));
1558 shared_ptr<MidiTrack> track;
1561 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1563 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1564 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1570 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1574 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1575 port = physinputs[(channels_used+x)%nphysical_in];
1578 if (port.length() && track->connect_input (track->input (x), port, this)) {
1584 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1588 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1589 port = physoutputs[(channels_used+x)%nphysical_out];
1590 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1592 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1596 if (port.length() && track->connect_output (track->output (x), port, this)) {
1601 channels_used += track->n_inputs ().n_midi();
1605 track->midi_diskstream()->non_realtime_input_change();
1607 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1608 //track->set_remote_control_id (control_id);
1610 new_routes.push_back (track);
1611 ret.push_back (track);
1614 catch (failed_constructor &err) {
1615 error << _("Session: could not create new midi track.") << endmsg;
1618 /* we need to get rid of this, since the track failed to be created */
1619 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1622 RCUWriter<DiskstreamList> writer (diskstreams);
1623 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1624 ds->remove (track->midi_diskstream());
1631 catch (AudioEngine::PortRegistrationFailure& pfe) {
1633 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;
1636 /* we need to get rid of this, since the track failed to be created */
1637 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1640 RCUWriter<DiskstreamList> writer (diskstreams);
1641 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1642 ds->remove (track->midi_diskstream());
1653 if (!new_routes.empty()) {
1654 add_routes (new_routes, false);
1655 save_state (_current_snapshot_name);
1661 list<boost::shared_ptr<AudioTrack> >
1662 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1664 char track_name[32];
1665 uint32_t track_id = 0;
1667 uint32_t channels_used = 0;
1669 RouteList new_routes;
1670 list<boost::shared_ptr<AudioTrack> > ret;
1671 uint32_t control_id;
1673 /* count existing audio tracks */
1676 shared_ptr<RouteList> r = routes.reader ();
1678 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1679 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1680 if (!(*i)->is_hidden()) {
1682 channels_used += (*i)->n_inputs().n_audio();
1688 vector<string> physinputs;
1689 vector<string> physoutputs;
1691 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1692 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1694 control_id = ntracks() + nbusses() + 1;
1698 /* check for duplicate route names, since we might have pre-existing
1699 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1700 save, close,restart,add new route - first named route is now
1708 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1710 if (route_by_name (track_name) == 0) {
1714 } while (track_id < (UINT_MAX-1));
1716 shared_ptr<AudioTrack> track;
1719 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1721 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1722 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1723 input_channels, output_channels)
1728 if (!physinputs.empty()) {
1729 uint32_t nphysical_in = physinputs.size();
1731 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1735 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1736 port = physinputs[(channels_used+x)%nphysical_in];
1739 if (port.length() && track->connect_input (track->input (x), port, this)) {
1745 if (!physoutputs.empty()) {
1746 uint32_t nphysical_out = physoutputs.size();
1748 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1752 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1753 port = physoutputs[(channels_used+x)%nphysical_out];
1754 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1756 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1760 if (port.length() && track->connect_output (track->output (x), port, this)) {
1766 channels_used += track->n_inputs ().n_audio();
1768 track->audio_diskstream()->non_realtime_input_change();
1770 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1771 track->set_remote_control_id (control_id);
1774 new_routes.push_back (track);
1775 ret.push_back (track);
1778 catch (failed_constructor &err) {
1779 error << _("Session: could not create new audio track.") << endmsg;
1782 /* we need to get rid of this, since the track failed to be created */
1783 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1786 RCUWriter<DiskstreamList> writer (diskstreams);
1787 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1788 ds->remove (track->audio_diskstream());
1795 catch (AudioEngine::PortRegistrationFailure& pfe) {
1797 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;
1800 /* we need to get rid of this, since the track failed to be created */
1801 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1804 RCUWriter<DiskstreamList> writer (diskstreams);
1805 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1806 ds->remove (track->audio_diskstream());
1817 if (!new_routes.empty()) {
1818 add_routes (new_routes, true);
1825 Session::set_remote_control_ids ()
1827 RemoteModel m = Config->get_remote_model();
1829 shared_ptr<RouteList> r = routes.reader ();
1831 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1832 if ( MixerOrdered == m) {
1833 long order = (*i)->order_key(N_("signal"));
1834 (*i)->set_remote_control_id( order+1 );
1835 } else if ( EditorOrdered == m) {
1836 long order = (*i)->order_key(N_("editor"));
1837 (*i)->set_remote_control_id( order+1 );
1838 } else if ( UserOrdered == m) {
1839 //do nothing ... only changes to remote id's are initiated by user
1846 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1849 uint32_t bus_id = 1;
1851 uint32_t channels_used = 0;
1854 uint32_t control_id;
1856 /* count existing audio busses */
1859 shared_ptr<RouteList> r = routes.reader ();
1861 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1862 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1864 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1867 channels_used += (*i)->n_inputs().n_audio();
1873 vector<string> physinputs;
1874 vector<string> physoutputs;
1876 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1877 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1878 control_id = ntracks() + nbusses() + 1;
1883 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1887 if (route_by_name (bus_name) == 0) {
1891 } while (bus_id < (UINT_MAX-1));
1894 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1896 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1897 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1898 input_channels, output_channels)
1903 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1907 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1908 port = physinputs[((n+x)%n_physical_inputs)];
1911 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1916 for (uint32_t x = 0; x < bus->n_outputs().n_audio(); ++x) {
1920 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1921 port = physoutputs[((n+x)%n_physical_outputs)];
1922 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1924 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1928 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1933 channels_used += bus->n_inputs ().n_audio();
1935 bus->set_remote_control_id (control_id);
1938 ret.push_back (bus);
1942 catch (failed_constructor &err) {
1943 error << _("Session: could not create new audio route.") << endmsg;
1947 catch (AudioEngine::PortRegistrationFailure& pfe) {
1948 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;
1958 add_routes (ret, true);
1966 Session::add_routes (RouteList& new_routes, bool save)
1969 RCUWriter<RouteList> writer (routes);
1970 shared_ptr<RouteList> r = writer.get_copy ();
1971 r->insert (r->end(), new_routes.begin(), new_routes.end());
1972 resort_routes_using (r);
1975 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1977 boost::weak_ptr<Route> wpr (*x);
1979 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1980 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1981 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1982 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1984 if ((*x)->is_master()) {
1988 if ((*x)->is_control()) {
1989 _control_out = (*x);
1992 /* only busses get automatic bundles formed */
1994 if (!boost::dynamic_pointer_cast<Track> (*x)) {
1995 add_bundle ((*x)->bundle_for_inputs());
1996 add_bundle ((*x)->bundle_for_outputs());
2000 if (_control_out && IO::connecting_legal) {
2002 vector<string> cports;
2003 uint32_t ni = _control_out->n_inputs().n_audio();
2005 for (uint32_t n = 0; n < ni; ++n) {
2006 cports.push_back (_control_out->input(n)->name());
2009 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2010 (*x)->set_control_outs (cports);
2017 save_state (_current_snapshot_name);
2020 RouteAdded (new_routes); /* EMIT SIGNAL */
2024 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2026 /* need to do this in case we're rolling at the time, to prevent false underruns */
2027 dstream->do_refill_with_alloc ();
2029 dstream->set_block_size (current_block_size);
2032 RCUWriter<DiskstreamList> writer (diskstreams);
2033 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2034 ds->push_back (dstream);
2035 /* writer goes out of scope, copies ds back to main */
2038 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2039 /* this will connect to future changes, and check the current length */
2040 diskstream_playlist_changed (dstream);
2042 dstream->prepare ();
2047 Session::remove_route (shared_ptr<Route> route)
2050 RCUWriter<RouteList> writer (routes);
2051 shared_ptr<RouteList> rs = writer.get_copy ();
2055 /* deleting the master out seems like a dumb
2056 idea, but its more of a UI policy issue
2060 if (route == _master_out) {
2061 _master_out = shared_ptr<Route> ();
2064 if (route == _control_out) {
2065 _control_out = shared_ptr<Route> ();
2067 /* cancel control outs for all routes */
2069 vector<string> empty;
2071 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2072 (*r)->set_control_outs (empty);
2076 update_route_solo_state ();
2078 /* writer goes out of scope, forces route list update */
2082 boost::shared_ptr<Diskstream> ds;
2084 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2085 ds = t->diskstream();
2091 RCUWriter<DiskstreamList> dsl (diskstreams);
2092 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2097 find_current_end ();
2099 // We need to disconnect the routes inputs and outputs
2101 route->disconnect_inputs (0);
2102 route->disconnect_outputs (0);
2104 update_latency_compensation (false, false);
2107 /* get rid of it from the dead wood collection in the route list manager */
2109 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2113 /* try to cause everyone to drop their references */
2115 route->drop_references ();
2117 /* save the new state of the world */
2119 if (save_state (_current_snapshot_name)) {
2120 save_history (_current_snapshot_name);
2125 Session::route_mute_changed (void* src)
2131 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2133 if (solo_update_disabled) {
2139 boost::shared_ptr<Route> route = wpr.lock ();
2142 /* should not happen */
2143 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2147 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2149 shared_ptr<RouteList> r = routes.reader ();
2151 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2153 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2157 /* don't mess with busses */
2159 if (dynamic_cast<Track*>((*i).get()) == 0) {
2165 /* don't mess with tracks */
2167 if (dynamic_cast<Track*>((*i).get()) != 0) {
2172 if ((*i) != route &&
2173 ((*i)->mix_group () == 0 ||
2174 (*i)->mix_group () != route->mix_group () ||
2175 !route->mix_group ()->is_active())) {
2177 if ((*i)->soloed()) {
2179 /* if its already soloed, and solo latching is enabled,
2180 then leave it as it is.
2183 if (Config->get_solo_latched()) {
2190 solo_update_disabled = true;
2191 (*i)->set_solo (false, src);
2192 solo_update_disabled = false;
2196 bool something_soloed = false;
2197 bool same_thing_soloed = false;
2198 bool signal = false;
2200 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2201 if ((*i)->soloed()) {
2202 something_soloed = true;
2203 if (dynamic_cast<Track*>((*i).get())) {
2205 same_thing_soloed = true;
2210 same_thing_soloed = true;
2218 if (something_soloed != currently_soloing) {
2220 currently_soloing = something_soloed;
2223 modify_solo_mute (is_track, same_thing_soloed);
2226 SoloActive (currently_soloing); /* EMIT SIGNAL */
2229 SoloChanged (); /* EMIT SIGNAL */
2235 Session::update_route_solo_state ()
2238 bool is_track = false;
2239 bool signal = false;
2241 /* caller must hold RouteLock */
2243 /* this is where we actually implement solo by changing
2244 the solo mute setting of each track.
2247 shared_ptr<RouteList> r = routes.reader ();
2249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2250 if ((*i)->soloed()) {
2252 if (dynamic_cast<Track*>((*i).get())) {
2259 if (mute != currently_soloing) {
2261 currently_soloing = mute;
2264 if (!is_track && !mute) {
2266 /* nothing is soloed */
2268 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2269 (*i)->set_solo_mute (false);
2279 modify_solo_mute (is_track, mute);
2282 SoloActive (currently_soloing);
2287 Session::modify_solo_mute (bool is_track, bool mute)
2289 shared_ptr<RouteList> r = routes.reader ();
2291 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2295 /* only alter track solo mute */
2297 if (dynamic_cast<Track*>((*i).get())) {
2298 if ((*i)->soloed()) {
2299 (*i)->set_solo_mute (!mute);
2301 (*i)->set_solo_mute (mute);
2307 /* only alter bus solo mute */
2309 if (!dynamic_cast<Track*>((*i).get())) {
2311 if ((*i)->soloed()) {
2313 (*i)->set_solo_mute (false);
2317 /* don't mute master or control outs
2318 in response to another bus solo
2321 if ((*i) != _master_out &&
2322 (*i) != _control_out) {
2323 (*i)->set_solo_mute (mute);
2334 Session::catch_up_on_solo ()
2336 /* this is called after set_state() to catch the full solo
2337 state, which can't be correctly determined on a per-route
2338 basis, but needs the global overview that only the session
2341 update_route_solo_state();
2345 Session::route_by_name (string name)
2347 shared_ptr<RouteList> r = routes.reader ();
2349 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2350 if ((*i)->name() == name) {
2355 return shared_ptr<Route> ((Route*) 0);
2359 Session::route_by_id (PBD::ID id)
2361 shared_ptr<RouteList> r = routes.reader ();
2363 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2364 if ((*i)->id() == id) {
2369 return shared_ptr<Route> ((Route*) 0);
2373 Session::route_by_remote_id (uint32_t id)
2375 shared_ptr<RouteList> r = routes.reader ();
2377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2378 if ((*i)->remote_control_id() == id) {
2383 return shared_ptr<Route> ((Route*) 0);
2387 Session::find_current_end ()
2389 if (_state_of_the_state & Loading) {
2393 nframes_t max = get_maximum_extent ();
2395 if (max > end_location->end()) {
2396 end_location->set_end (max);
2398 DurationChanged(); /* EMIT SIGNAL */
2403 Session::get_maximum_extent () const
2408 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2410 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2411 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2413 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2414 if ((me = pl->get_maximum_extent()) > max) {
2422 boost::shared_ptr<Diskstream>
2423 Session::diskstream_by_name (string name)
2425 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2427 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2428 if ((*i)->name() == name) {
2433 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2436 boost::shared_ptr<Diskstream>
2437 Session::diskstream_by_id (const PBD::ID& id)
2439 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2441 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2442 if ((*i)->id() == id) {
2447 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2450 /* Region management */
2453 Session::new_region_name (string old)
2455 string::size_type last_period;
2457 string::size_type len = old.length() + 64;
2460 if ((last_period = old.find_last_of ('.')) == string::npos) {
2462 /* no period present - add one explicitly */
2465 last_period = old.length() - 1;
2470 number = atoi (old.substr (last_period+1).c_str());
2474 while (number < (UINT_MAX-1)) {
2476 RegionList::const_iterator i;
2481 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2484 for (i = regions.begin(); i != regions.end(); ++i) {
2485 if (i->second->name() == sbuf) {
2490 if (i == regions.end()) {
2495 if (number != (UINT_MAX-1)) {
2499 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2504 Session::region_name (string& result, string base, bool newlevel)
2509 assert(base.find("/") == string::npos);
2513 Glib::Mutex::Lock lm (region_lock);
2515 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2524 string::size_type pos;
2526 pos = base.find_last_of ('.');
2528 /* pos may be npos, but then we just use entire base */
2530 subbase = base.substr (0, pos);
2535 Glib::Mutex::Lock lm (region_lock);
2537 map<string,uint32_t>::iterator x;
2541 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2543 region_name_map[subbase] = 1;
2546 snprintf (buf, sizeof (buf), ".%d", x->second);
2557 Session::add_region (boost::shared_ptr<Region> region)
2559 vector<boost::shared_ptr<Region> > v;
2560 v.push_back (region);
2565 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2570 Glib::Mutex::Lock lm (region_lock);
2572 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2574 boost::shared_ptr<Region> region = *ii;
2578 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2582 RegionList::iterator x;
2584 for (x = regions.begin(); x != regions.end(); ++x) {
2586 if (region->region_list_equivalent (x->second)) {
2591 if (x == regions.end()) {
2593 pair<RegionList::key_type,RegionList::mapped_type> entry;
2595 entry.first = region->id();
2596 entry.second = region;
2598 pair<RegionList::iterator,bool> x = regions.insert (entry);
2610 /* mark dirty because something has changed even if we didn't
2611 add the region to the region list.
2618 vector<boost::weak_ptr<Region> > v;
2619 boost::shared_ptr<Region> first_r;
2621 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2623 boost::shared_ptr<Region> region = *ii;
2627 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2630 v.push_back (region);
2637 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2638 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2640 update_region_name_map (region);
2644 RegionsAdded (v); /* EMIT SIGNAL */
2650 Session::update_region_name_map (boost::shared_ptr<Region> region)
2652 string::size_type last_period = region->name().find_last_of ('.');
2654 if (last_period != string::npos && last_period < region->name().length() - 1) {
2656 string base = region->name().substr (0, last_period);
2657 string number = region->name().substr (last_period+1);
2658 map<string,uint32_t>::iterator x;
2660 /* note that if there is no number, we get zero from atoi,
2664 region_name_map[base] = atoi (number);
2669 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2671 boost::shared_ptr<Region> region (weak_region.lock ());
2677 if (what_changed & Region::HiddenChanged) {
2678 /* relay hidden changes */
2679 RegionHiddenChange (region);
2682 if (what_changed & NameChanged) {
2683 update_region_name_map (region);
2688 Session::remove_region (boost::weak_ptr<Region> weak_region)
2690 RegionList::iterator i;
2691 boost::shared_ptr<Region> region (weak_region.lock ());
2697 bool removed = false;
2700 Glib::Mutex::Lock lm (region_lock);
2702 if ((i = regions.find (region->id())) != regions.end()) {
2708 /* mark dirty because something has changed even if we didn't
2709 remove the region from the region list.
2715 RegionRemoved(region); /* EMIT SIGNAL */
2719 boost::shared_ptr<Region>
2720 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2722 RegionList::iterator i;
2723 boost::shared_ptr<Region> region;
2725 Glib::Mutex::Lock lm (region_lock);
2727 for (i = regions.begin(); i != regions.end(); ++i) {
2731 if (region->whole_file()) {
2733 if (child->source_equivalent (region)) {
2739 return boost::shared_ptr<Region> ();
2743 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2745 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2746 (*i)->get_region_list_equivalent_regions (region, result);
2750 Session::destroy_region (boost::shared_ptr<Region> region)
2752 vector<boost::shared_ptr<Source> > srcs;
2755 if (region->playlist()) {
2756 region->playlist()->destroy_region (region);
2759 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2760 srcs.push_back (region->source (n));
2764 region->drop_references ();
2766 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2768 (*i)->mark_for_remove ();
2769 (*i)->drop_references ();
2771 cerr << "source was not used by any playlist\n";
2778 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2780 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2781 destroy_region (*i);
2787 Session::remove_last_capture ()
2789 list<boost::shared_ptr<Region> > r;
2791 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2793 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2794 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2797 r.insert (r.end(), l.begin(), l.end());
2802 destroy_regions (r);
2804 save_state (_current_snapshot_name);
2810 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2816 /* Source Management */
2818 Session::add_source (boost::shared_ptr<Source> source)
2820 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2821 pair<SourceMap::iterator,bool> result;
2823 entry.first = source->id();
2824 entry.second = source;
2827 Glib::Mutex::Lock lm (source_lock);
2828 result = sources.insert (entry);
2831 if (result.second) {
2832 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2836 boost::shared_ptr<AudioFileSource> afs;
2838 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2839 if (Config->get_auto_analyse_audio()) {
2840 Analyser::queue_source_for_analysis (source, false);
2846 Session::remove_source (boost::weak_ptr<Source> src)
2848 SourceMap::iterator i;
2849 boost::shared_ptr<Source> source = src.lock();
2856 Glib::Mutex::Lock lm (source_lock);
2858 if ((i = sources.find (source->id())) != sources.end()) {
2863 if (!_state_of_the_state & InCleanup) {
2865 /* save state so we don't end up with a session file
2866 referring to non-existent sources.
2869 save_state (_current_snapshot_name);
2873 boost::shared_ptr<Source>
2874 Session::source_by_id (const PBD::ID& id)
2876 Glib::Mutex::Lock lm (source_lock);
2877 SourceMap::iterator i;
2878 boost::shared_ptr<Source> source;
2880 if ((i = sources.find (id)) != sources.end()) {
2888 boost::shared_ptr<Source>
2889 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2891 Glib::Mutex::Lock lm (source_lock);
2893 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2894 cerr << "comparing " << path << " with " << i->second->name() << endl;
2895 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2897 if (afs && afs->path() == path && chn == afs->channel()) {
2902 return boost::shared_ptr<Source>();
2906 Session::peak_path (Glib::ustring base) const
2908 sys::path peakfile_path(_session_dir->peak_path());
2909 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2910 return peakfile_path.to_string();
2914 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2917 string old_basename = PBD::basename_nosuffix (oldname);
2918 string new_legalized = legalize_for_path (newname);
2920 /* note: we know (or assume) the old path is already valid */
2924 /* destructive file sources have a name of the form:
2926 /path/to/Tnnnn-NAME(%[LR])?.wav
2928 the task here is to replace NAME with the new name.
2931 /* find last slash */
2935 string::size_type slash;
2936 string::size_type dash;
2938 if ((slash = path.find_last_of ('/')) == string::npos) {
2942 dir = path.substr (0, slash+1);
2944 /* '-' is not a legal character for the NAME part of the path */
2946 if ((dash = path.find_last_of ('-')) == string::npos) {
2950 prefix = path.substr (slash+1, dash-(slash+1));
2955 path += new_legalized;
2956 path += ".wav"; /* XXX gag me with a spoon */
2960 /* non-destructive file sources have a name of the form:
2962 /path/to/NAME-nnnnn(%[LR])?.wav
2964 the task here is to replace NAME with the new name.
2969 string::size_type slash;
2970 string::size_type dash;
2971 string::size_type postfix;
2973 /* find last slash */
2975 if ((slash = path.find_last_of ('/')) == string::npos) {
2979 dir = path.substr (0, slash+1);
2981 /* '-' is not a legal character for the NAME part of the path */
2983 if ((dash = path.find_last_of ('-')) == string::npos) {
2987 suffix = path.substr (dash+1);
2989 // Suffix is now everything after the dash. Now we need to eliminate
2990 // the nnnnn part, which is done by either finding a '%' or a '.'
2992 postfix = suffix.find_last_of ("%");
2993 if (postfix == string::npos) {
2994 postfix = suffix.find_last_of ('.');
2997 if (postfix != string::npos) {
2998 suffix = suffix.substr (postfix);
3000 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3004 const uint32_t limit = 10000;
3005 char buf[PATH_MAX+1];
3007 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3009 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3011 if (access (buf, F_OK) != 0) {
3019 error << "FATAL ERROR! Could not find a " << endl;
3028 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3032 char buf[PATH_MAX+1];
3033 const uint32_t limit = 10000;
3037 legalized = legalize_for_path (name);
3039 /* find a "version" of the file name that doesn't exist in
3040 any of the possible directories.
3043 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3045 vector<space_and_path>::iterator i;
3046 uint32_t existing = 0;
3048 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3050 SessionDirectory sdir((*i).path);
3052 spath = sdir.sound_path().to_string();
3056 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3057 } else if (nchan == 2) {
3059 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3061 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3063 } else if (nchan < 26) {
3064 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3066 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3075 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3076 } else if (nchan == 2) {
3078 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3080 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3082 } else if (nchan < 26) {
3083 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3085 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3089 if (sys::exists(buf)) {
3095 if (existing == 0) {
3100 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3102 throw failed_constructor();
3106 /* we now have a unique name for the file, but figure out where to
3112 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3114 spath = sdir.sound_path().to_string();
3117 string::size_type pos = foo.find_last_of ('/');
3119 if (pos == string::npos) {
3122 spath += foo.substr (pos + 1);
3128 boost::shared_ptr<AudioFileSource>
3129 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3131 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3132 return boost::dynamic_pointer_cast<AudioFileSource> (
3133 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3136 // FIXME: _terrible_ code duplication
3138 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3141 string old_basename = PBD::basename_nosuffix (oldname);
3142 string new_legalized = legalize_for_path (newname);
3144 /* note: we know (or assume) the old path is already valid */
3148 /* destructive file sources have a name of the form:
3150 /path/to/Tnnnn-NAME(%[LR])?.wav
3152 the task here is to replace NAME with the new name.
3155 /* find last slash */
3159 string::size_type slash;
3160 string::size_type dash;
3162 if ((slash = path.find_last_of ('/')) == string::npos) {
3166 dir = path.substr (0, slash+1);
3168 /* '-' is not a legal character for the NAME part of the path */
3170 if ((dash = path.find_last_of ('-')) == string::npos) {
3174 prefix = path.substr (slash+1, dash-(slash+1));
3179 path += new_legalized;
3180 path += ".mid"; /* XXX gag me with a spoon */
3184 /* non-destructive file sources have a name of the form:
3186 /path/to/NAME-nnnnn(%[LR])?.wav
3188 the task here is to replace NAME with the new name.
3193 string::size_type slash;
3194 string::size_type dash;
3195 string::size_type postfix;
3197 /* find last slash */
3199 if ((slash = path.find_last_of ('/')) == string::npos) {
3203 dir = path.substr (0, slash+1);
3205 /* '-' is not a legal character for the NAME part of the path */
3207 if ((dash = path.find_last_of ('-')) == string::npos) {
3211 suffix = path.substr (dash+1);
3213 // Suffix is now everything after the dash. Now we need to eliminate
3214 // the nnnnn part, which is done by either finding a '%' or a '.'
3216 postfix = suffix.find_last_of ("%");
3217 if (postfix == string::npos) {
3218 postfix = suffix.find_last_of ('.');
3221 if (postfix != string::npos) {
3222 suffix = suffix.substr (postfix);
3224 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3228 const uint32_t limit = 10000;
3229 char buf[PATH_MAX+1];
3231 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3233 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3235 if (access (buf, F_OK) != 0) {
3243 error << "FATAL ERROR! Could not find a " << endl;
3252 Session::midi_path_from_name (string name)
3256 char buf[PATH_MAX+1];
3257 const uint32_t limit = 10000;
3261 legalized = legalize_for_path (name);
3263 /* find a "version" of the file name that doesn't exist in
3264 any of the possible directories.
3267 for (cnt = 1; cnt <= limit; ++cnt) {
3269 vector<space_and_path>::iterator i;
3270 uint32_t existing = 0;
3272 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3274 SessionDirectory sdir((*i).path);
3276 sys::path p = sdir.midi_path();
3280 spath = p.to_string();
3282 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3284 if (sys::exists (buf)) {
3289 if (existing == 0) {
3294 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3295 throw failed_constructor();
3299 /* we now have a unique name for the file, but figure out where to
3305 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3307 spath = sdir.midi_path().to_string();
3310 string::size_type pos = foo.find_last_of ('/');
3312 if (pos == string::npos) {
3315 spath += foo.substr (pos + 1);
3321 boost::shared_ptr<MidiSource>
3322 Session::create_midi_source_for_session (MidiDiskstream& ds)
3324 string mpath = midi_path_from_name (ds.name());
3326 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3330 /* Playlist management */
3332 boost::shared_ptr<Playlist>
3333 Session::playlist_by_name (string name)
3335 Glib::Mutex::Lock lm (playlist_lock);
3336 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3337 if ((*i)->name() == name) {
3341 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3342 if ((*i)->name() == name) {
3347 return boost::shared_ptr<Playlist>();
3351 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3353 Glib::Mutex::Lock lm (playlist_lock);
3354 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3355 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3356 list.push_back (*i);
3359 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3360 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3361 list.push_back (*i);
3367 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3369 if (playlist->hidden()) {
3374 Glib::Mutex::Lock lm (playlist_lock);
3375 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3376 playlists.insert (playlists.begin(), playlist);
3377 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3378 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3383 playlist->release();
3388 PlaylistAdded (playlist); /* EMIT SIGNAL */
3392 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3395 Glib::Mutex::Lock lm (playlist_lock);
3396 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3399 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3406 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3408 boost::shared_ptr<Playlist> pl(wpl.lock());
3414 PlaylistList::iterator x;
3417 /* its not supposed to be visible */
3422 Glib::Mutex::Lock lm (playlist_lock);
3426 unused_playlists.insert (pl);
3428 if ((x = playlists.find (pl)) != playlists.end()) {
3429 playlists.erase (x);
3435 playlists.insert (pl);
3437 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3438 unused_playlists.erase (x);
3445 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3447 if (_state_of_the_state & Deletion) {
3451 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3458 Glib::Mutex::Lock lm (playlist_lock);
3460 PlaylistList::iterator i;
3462 i = find (playlists.begin(), playlists.end(), playlist);
3463 if (i != playlists.end()) {
3464 playlists.erase (i);
3467 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3468 if (i != unused_playlists.end()) {
3469 unused_playlists.erase (i);
3476 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3480 Session::set_audition (boost::shared_ptr<Region> r)
3482 pending_audition_region = r;
3483 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3484 schedule_butler_transport_work ();
3488 Session::audition_playlist ()
3490 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3491 ev->region.reset ();
3496 Session::non_realtime_set_audition ()
3498 if (!pending_audition_region) {
3499 auditioner->audition_current_playlist ();
3501 auditioner->audition_region (pending_audition_region);
3502 pending_audition_region.reset ();
3504 AuditionActive (true); /* EMIT SIGNAL */
3508 Session::audition_region (boost::shared_ptr<Region> r)
3510 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3516 Session::cancel_audition ()
3518 if (auditioner->active()) {
3519 auditioner->cancel_audition ();
3520 AuditionActive (false); /* EMIT SIGNAL */
3525 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3527 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3531 Session::remove_empty_sounds ()
3533 vector<string> audio_filenames;
3535 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3537 Glib::Mutex::Lock lm (source_lock);
3539 TapeFileMatcher tape_file_matcher;
3541 remove_if (audio_filenames.begin(), audio_filenames.end(),
3542 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3544 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3546 sys::path audio_file_path (_session_dir->sound_path());
3548 audio_file_path /= *i;
3550 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3554 sys::remove (audio_file_path);
3555 const string peakfile = peak_path (audio_file_path.to_string());
3556 sys::remove (peakfile);
3558 catch (const sys::filesystem_error& err)
3560 error << err.what() << endmsg;
3567 Session::is_auditioning () const
3569 /* can be called before we have an auditioner object */
3571 return auditioner->active();
3578 Session::set_all_solo (bool yn)
3580 shared_ptr<RouteList> r = routes.reader ();
3582 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3583 if (!(*i)->is_hidden()) {
3584 (*i)->set_solo (yn, this);
3592 Session::set_all_mute (bool yn)
3594 shared_ptr<RouteList> r = routes.reader ();
3596 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3597 if (!(*i)->is_hidden()) {
3598 (*i)->set_mute (yn, this);
3606 Session::n_diskstreams () const
3610 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3612 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3613 if (!(*i)->hidden()) {
3621 Session::graph_reordered ()
3623 /* don't do this stuff if we are setting up connections
3624 from a set_state() call or creating new tracks.
3627 if (_state_of_the_state & InitialConnecting) {
3631 /* every track/bus asked for this to be handled but it was deferred because
3632 we were connecting. do it now.
3635 request_input_change_handling ();
3639 /* force all diskstreams to update their capture offset values to
3640 reflect any changes in latencies within the graph.
3643 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3645 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3646 (*i)->set_capture_offset ();
3651 Session::record_disenable_all ()
3653 record_enable_change_all (false);
3657 Session::record_enable_all ()
3659 record_enable_change_all (true);
3663 Session::record_enable_change_all (bool yn)
3665 shared_ptr<RouteList> r = routes.reader ();
3667 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3670 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3671 at->set_record_enable (yn, this);
3675 /* since we don't keep rec-enable state, don't mark session dirty */
3679 Session::add_processor (Processor* processor)
3682 PortInsert* port_insert;
3683 PluginInsert* plugin_insert;
3685 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3686 _port_inserts.insert (_port_inserts.begin(), port_insert);
3687 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3688 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3689 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3690 _sends.insert (_sends.begin(), send);
3692 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3696 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3702 Session::remove_processor (Processor* processor)
3705 PortInsert* port_insert;
3706 PluginInsert* plugin_insert;
3708 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3709 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3710 if (x != _port_inserts.end()) {
3711 insert_bitset[port_insert->bit_slot()] = false;
3712 _port_inserts.erase (x);
3714 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3715 _plugin_inserts.remove (plugin_insert);
3716 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3717 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3718 if (x != _sends.end()) {
3719 send_bitset[send->bit_slot()] = false;
3723 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3731 Session::available_capture_duration ()
3733 float sample_bytes_on_disk = 4.0; // keep gcc happy
3735 switch (Config->get_native_file_data_format()) {
3737 sample_bytes_on_disk = 4.0;
3741 sample_bytes_on_disk = 3.0;
3745 sample_bytes_on_disk = 2.0;
3749 /* impossible, but keep some gcc versions happy */
3750 fatal << string_compose (_("programming error: %1"),
3751 X_("illegal native file data format"))
3756 double scale = 4096.0 / sample_bytes_on_disk;
3758 if (_total_free_4k_blocks * scale > (double) max_frames) {
3762 return (nframes_t) floor (_total_free_4k_blocks * scale);
3766 Session::add_bundle (shared_ptr<Bundle> bundle)
3769 Glib::Mutex::Lock guard (bundle_lock);
3770 _bundles.push_back (bundle);
3773 BundleAdded (bundle); /* EMIT SIGNAL */
3779 Session::remove_bundle (shared_ptr<Bundle> bundle)
3781 bool removed = false;
3784 Glib::Mutex::Lock guard (bundle_lock);
3785 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3787 if (i != _bundles.end()) {
3794 BundleRemoved (bundle); /* EMIT SIGNAL */
3801 Session::bundle_by_name (string name) const
3803 Glib::Mutex::Lock lm (bundle_lock);
3805 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3806 if ((*i)->name() == name) {
3811 return boost::shared_ptr<Bundle> ();
3815 Session::tempo_map_changed (Change ignored)
3819 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3820 (*i)->update_after_tempo_map_change ();
3823 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3824 (*i)->update_after_tempo_map_change ();
3830 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3831 * the given count with the current block size.
3834 Session::ensure_buffers (ChanCount howmany)
3836 if (current_block_size == 0)
3837 return; // too early? (is this ok?)
3839 // We need at least 2 MIDI scratch buffers to mix/merge
3840 if (howmany.n_midi() < 2)
3841 howmany.set_midi(2);
3843 // FIXME: JACK needs to tell us maximum MIDI buffer size
3844 // Using nasty assumption (max # events == nframes) for now
3845 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3846 _mix_buffers->ensure_buffers(howmany, current_block_size);
3847 _silent_buffers->ensure_buffers(howmany, current_block_size);
3849 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3853 Session::next_insert_id ()
3855 /* this doesn't really loop forever. just think about it */
3858 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3859 if (!insert_bitset[n]) {
3860 insert_bitset[n] = true;
3866 /* none available, so resize and try again */
3868 insert_bitset.resize (insert_bitset.size() + 16, false);
3873 Session::next_send_id ()
3875 /* this doesn't really loop forever. just think about it */
3878 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3879 if (!send_bitset[n]) {
3880 send_bitset[n] = true;
3886 /* none available, so resize and try again */
3888 send_bitset.resize (send_bitset.size() + 16, false);
3893 Session::mark_send_id (uint32_t id)
3895 if (id >= send_bitset.size()) {
3896 send_bitset.resize (id+16, false);
3898 if (send_bitset[id]) {
3899 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3901 send_bitset[id] = true;
3905 Session::mark_insert_id (uint32_t id)
3907 if (id >= insert_bitset.size()) {
3908 insert_bitset.resize (id+16, false);
3910 if (insert_bitset[id]) {
3911 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3913 insert_bitset[id] = true;
3916 /* Named Selection management */
3919 Session::named_selection_by_name (string name)
3921 Glib::Mutex::Lock lm (named_selection_lock);
3922 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3923 if ((*i)->name == name) {
3931 Session::add_named_selection (NamedSelection* named_selection)
3934 Glib::Mutex::Lock lm (named_selection_lock);
3935 named_selections.insert (named_selections.begin(), named_selection);
3938 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3944 NamedSelectionAdded (); /* EMIT SIGNAL */
3948 Session::remove_named_selection (NamedSelection* named_selection)
3950 bool removed = false;
3953 Glib::Mutex::Lock lm (named_selection_lock);
3955 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3957 if (i != named_selections.end()) {
3959 named_selections.erase (i);
3966 NamedSelectionRemoved (); /* EMIT SIGNAL */
3971 Session::reset_native_file_format ()
3973 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3975 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3976 (*i)->reset_write_sources (false);
3981 Session::route_name_unique (string n) const
3983 shared_ptr<RouteList> r = routes.reader ();
3985 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3986 if ((*i)->name() == n) {
3995 Session::n_playlists () const
3997 Glib::Mutex::Lock lm (playlist_lock);
3998 return playlists.size();
4002 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4004 if (!force && howmany <= _npan_buffers) {
4008 if (_pan_automation_buffer) {
4010 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4011 delete [] _pan_automation_buffer[i];
4014 delete [] _pan_automation_buffer;
4017 _pan_automation_buffer = new pan_t*[howmany];
4019 for (uint32_t i = 0; i < howmany; ++i) {
4020 _pan_automation_buffer[i] = new pan_t[nframes];
4023 _npan_buffers = howmany;
4027 Session::freeze (InterThreadInfo& itt)
4029 shared_ptr<RouteList> r = routes.reader ();
4031 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4035 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4036 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4046 boost::shared_ptr<Region>
4047 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4048 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4050 boost::shared_ptr<Region> result;
4051 boost::shared_ptr<Playlist> playlist;
4052 boost::shared_ptr<AudioFileSource> fsource;
4054 char buf[PATH_MAX+1];
4055 ChanCount nchans(track.audio_diskstream()->n_channels());
4057 nframes_t this_chunk;
4060 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4061 const string sound_dir = sdir.sound_path().to_string();
4062 nframes_t len = end - start;
4065 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4066 end, start) << endmsg;
4070 // any bigger than this seems to cause stack overflows in called functions
4071 const nframes_t chunk_size = (128 * 1024)/4;
4073 g_atomic_int_set (&processing_prohibited, 1);
4075 /* call tree *MUST* hold route_lock */
4077 if ((playlist = track.diskstream()->playlist()) == 0) {
4081 /* external redirects will be a problem */
4083 if (track.has_external_redirects()) {
4087 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4089 for (x = 0; x < 99999; ++x) {
4090 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4091 if (access (buf, F_OK) != 0) {
4097 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4102 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4103 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4106 catch (failed_constructor& err) {
4107 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4111 srcs.push_back (fsource);
4114 /* XXX need to flush all redirects */
4119 /* create a set of reasonably-sized buffers */
4120 buffers.ensure_buffers(nchans, chunk_size);
4121 buffers.set_count(nchans);
4123 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4124 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4126 afs->prepare_for_peakfile_writes ();
4129 while (to_do && !itt.cancel) {
4131 this_chunk = min (to_do, chunk_size);
4133 if (track.export_stuff (buffers, start, this_chunk)) {
4138 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4139 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4142 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4148 start += this_chunk;
4149 to_do -= this_chunk;
4151 itt.progress = (float) (1.0 - ((double) to_do / len));
4160 xnow = localtime (&now);
4162 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4163 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4166 afs->update_header (position, *xnow, now);
4167 afs->flush_header ();
4171 /* construct a region to represent the bounced material */
4173 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4174 region_name_from_path (srcs.front()->name(), true));
4179 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4180 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4183 afs->mark_for_remove ();
4186 (*src)->drop_references ();
4190 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4191 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4194 afs->done_with_peakfile_writes ();
4198 g_atomic_int_set (&processing_prohibited, 0);
4204 Session::get_silent_buffers (ChanCount count)
4206 assert(_silent_buffers->available() >= count);
4207 _silent_buffers->set_count(count);
4209 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4210 for (size_t i= 0; i < count.get(*t); ++i) {
4211 _silent_buffers->get(*t, i).clear();
4215 return *_silent_buffers;
4219 Session::get_scratch_buffers (ChanCount count)
4221 assert(_scratch_buffers->available() >= count);
4222 _scratch_buffers->set_count(count);
4223 return *_scratch_buffers;
4227 Session::get_mix_buffers (ChanCount count)
4229 assert(_mix_buffers->available() >= count);
4230 _mix_buffers->set_count(count);
4231 return *_mix_buffers;
4235 Session::ntracks () const
4238 shared_ptr<RouteList> r = routes.reader ();
4240 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4241 if (dynamic_cast<Track*> ((*i).get())) {
4250 Session::nbusses () const
4253 shared_ptr<RouteList> r = routes.reader ();
4255 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4256 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4265 Session::add_automation_list(AutomationList *al)
4267 automation_lists[al->id()] = al;
4271 Session::compute_initial_length ()
4273 return _engine.frame_rate() * 60 * 5;
4277 Session::sync_order_keys ()
4279 if (!Config->get_sync_all_route_ordering()) {
4280 /* leave order keys as they are */
4284 boost::shared_ptr<RouteList> r = routes.reader ();
4286 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4287 (*i)->sync_order_keys ();
4290 Route::SyncOrderKeys (); // EMIT SIGNAL
4294 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4296 Glib::Mutex::Lock lm (bundle_lock);
4297 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {