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/return.h"
76 #include "ardour/route_group.h"
77 #include "ardour/send.h"
78 #include "ardour/session.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_directory.h"
81 #include "ardour/session_metadata.h"
82 #include "ardour/slave.h"
83 #include "ardour/smf_source.h"
84 #include "ardour/source_factory.h"
85 #include "ardour/tape_file_matcher.h"
86 #include "ardour/tempo.h"
87 #include "ardour/utils.h"
92 using namespace ARDOUR;
94 using boost::shared_ptr;
96 bool Session::_disable_all_loaded_plugins = false;
98 sigc::signal<void,std::string> Session::Dialog;
99 sigc::signal<int> Session::AskAboutPendingState;
100 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
101 sigc::signal<void> Session::SendFeedback;
103 sigc::signal<void> Session::SMPTEOffsetChanged;
104 sigc::signal<void> Session::StartTimeChanged;
105 sigc::signal<void> Session::EndTimeChanged;
106 sigc::signal<void> Session::AutoBindingOn;
107 sigc::signal<void> Session::AutoBindingOff;
108 sigc::signal<void, std::string, std::string> Session::Exported;
110 Session::Session (AudioEngine &eng,
111 const string& fullpath,
112 const string& snapshot_name,
116 _target_transport_speed (0.0),
117 _requested_return_frame (-1),
118 _scratch_buffers(new BufferSet()),
119 _silent_buffers(new BufferSet()),
120 _mix_buffers(new BufferSet()),
122 _mmc_port (default_mmc_port),
123 _mtc_port (default_mtc_port),
124 _midi_port (default_midi_port),
125 _midi_clock_port (default_midi_clock_port),
126 _session_dir (new SessionDirectory(fullpath)),
127 pending_events (2048),
129 butler_mixdown_buffer (0),
130 butler_gain_buffer (0),
131 post_transport_work((PostTransportWork)0),
132 _send_smpte_update (false),
133 midi_thread (pthread_t (0)),
134 midi_requests (128), // the size of this should match the midi request pool size
135 diskstreams (new DiskstreamList),
136 routes (new RouteList),
137 _total_free_4k_blocks (0),
138 _bundles (new BundleList),
139 _bundle_xml_node (0),
142 click_emphasis_data (0),
144 _metadata (new SessionMetadata()),
145 _have_rec_enabled_diskstream (false)
150 interpolation.add_channel_to (0, 0);
152 if (!eng.connected()) {
153 throw failed_constructor();
156 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
158 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
159 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
161 first_stage_init (fullpath, snapshot_name);
163 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
166 if (create (new_session, mix_template, compute_initial_length())) {
168 throw failed_constructor ();
172 if (second_stage_init (new_session)) {
174 throw failed_constructor ();
177 store_recent_sessions(_name, _path);
179 bool was_dirty = dirty();
181 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
183 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
184 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
187 DirtyChanged (); /* EMIT SIGNAL */
191 Session::Session (AudioEngine &eng,
193 string snapshot_name,
194 AutoConnectOption input_ac,
195 AutoConnectOption output_ac,
196 uint32_t control_out_channels,
197 uint32_t master_out_channels,
198 uint32_t requested_physical_in,
199 uint32_t requested_physical_out,
200 nframes_t initial_length)
203 _target_transport_speed (0.0),
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 _total_free_4k_blocks (0),
225 _bundles (new BundleList),
226 _bundle_xml_node (0),
227 _click_io ((IO *) 0),
229 click_emphasis_data (0),
231 _metadata (new SessionMetadata()),
232 _have_rec_enabled_diskstream (false)
236 interpolation.add_channel_to (0, 0);
238 if (!eng.connected()) {
239 throw failed_constructor();
242 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
244 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
245 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
247 if (n_physical_inputs) {
248 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
251 if (n_physical_outputs) {
252 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
255 first_stage_init (fullpath, snapshot_name);
257 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
260 if (create (new_session, string(), initial_length)) {
262 throw failed_constructor ();
267 /* set up Master Out and Control Out if necessary */
272 if (control_out_channels) {
273 ChanCount count(DataType::AUDIO, control_out_channels);
274 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
275 r->input()->ensure_io (count, false, this);
276 r->output()->ensure_io (count, false, this);
277 r->set_remote_control_id (control_id++);
282 if (master_out_channels) {
283 ChanCount count(DataType::AUDIO, master_out_channels);
284 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
285 r->input()->ensure_io (count, false, this);
286 r->output()->ensure_io (count, false, this);
287 r->set_remote_control_id (control_id);
291 /* prohibit auto-connect to master, because there isn't one */
292 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
296 add_routes (rl, false);
301 if (no_auto_connect()) {
302 input_ac = AutoConnectOption (0);
303 output_ac = AutoConnectOption (0);
306 Config->set_input_auto_connect (input_ac);
307 Config->set_output_auto_connect (output_ac);
309 if (second_stage_init (new_session)) {
311 throw failed_constructor ();
314 store_recent_sessions (_name, _path);
316 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
318 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
329 /* if we got to here, leaving pending capture state around
333 remove_pending_capture_state ();
335 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
337 _engine.remove_session ();
339 GoingAway (); /* EMIT SIGNAL */
345 /* clear history so that no references to objects are held any more */
349 /* clear state tree so that no references to objects are held any more */
353 terminate_butler_thread ();
354 //terminate_midi_thread ();
356 if (click_data != default_click) {
357 delete [] click_data;
360 if (click_emphasis_data != default_click_emphasis) {
361 delete [] click_emphasis_data;
366 delete _scratch_buffers;
367 delete _silent_buffers;
370 AudioDiskstream::free_working_buffers();
372 Route::SyncOrderKeys.clear();
374 #undef TRACK_DESTRUCTION
375 #ifdef TRACK_DESTRUCTION
376 cerr << "delete named selections\n";
377 #endif /* TRACK_DESTRUCTION */
378 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
379 NamedSelectionList::iterator tmp;
388 #ifdef TRACK_DESTRUCTION
389 cerr << "delete playlists\n";
390 #endif /* TRACK_DESTRUCTION */
391 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
392 PlaylistList::iterator tmp;
397 (*i)->drop_references ();
402 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
403 PlaylistList::iterator tmp;
408 (*i)->drop_references ();
414 unused_playlists.clear ();
416 #ifdef TRACK_DESTRUCTION
417 cerr << "delete regions\n";
418 #endif /* TRACK_DESTRUCTION */
420 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
421 RegionList::iterator tmp;
426 i->second->drop_references ();
433 #ifdef TRACK_DESTRUCTION
434 cerr << "delete routes\n";
435 #endif /* TRACK_DESTRUCTION */
437 RCUWriter<RouteList> writer (routes);
438 boost::shared_ptr<RouteList> r = writer.get_copy ();
439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
440 (*i)->drop_references ();
443 /* writer goes out of scope and updates master */
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete diskstreams\n";
450 #endif /* TRACK_DESTRUCTION */
452 RCUWriter<DiskstreamList> dwriter (diskstreams);
453 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
454 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
455 (*i)->drop_references ();
459 diskstreams.flush ();
461 #ifdef TRACK_DESTRUCTION
462 cerr << "delete audio sources\n";
463 #endif /* TRACK_DESTRUCTION */
464 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
465 SourceMap::iterator tmp;
470 i->second->drop_references ();
477 #ifdef TRACK_DESTRUCTION
478 cerr << "delete route groups\n";
479 #endif /* TRACK_DESTRUCTION */
480 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ) {
484 delete [] butler_mixdown_buffer;
485 delete [] butler_gain_buffer;
487 Crossfade::set_buffer_size (0);
493 Session::set_worst_io_latencies ()
495 _worst_output_latency = 0;
496 _worst_input_latency = 0;
498 if (!_engine.connected()) {
502 boost::shared_ptr<RouteList> r = routes.reader ();
504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
505 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
506 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
511 Session::when_engine_running ()
513 string first_physical_output;
515 BootMessage (_("Set block size and sample rate"));
517 set_block_size (_engine.frames_per_cycle());
518 set_frame_rate (_engine.frame_rate());
520 BootMessage (_("Using configuration"));
522 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
524 /* every time we reconnect, recompute worst case output latencies */
526 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
528 if (synced_to_jack()) {
529 _engine.transport_stop ();
532 if (config.get_jack_time_master()) {
533 _engine.transport_locate (_transport_frame);
541 _click_io.reset (new ClickIO (*this, "click"));
543 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
545 /* existing state for Click */
547 if (_click_io->set_state (*child->children().front()) == 0) {
549 _clicking = Config->get_clicking ();
553 error << _("could not setup Click I/O") << endmsg;
559 /* default state for Click: dual-mono to first 2 physical outputs */
561 for (int physport = 0; physport < 2; ++physport) {
562 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
564 if (physical_output.length()) {
565 if (_click_io->add_port (physical_output, this)) {
566 // relax, even though its an error
571 if (_click_io->n_ports () > ChanCount::ZERO) {
572 _clicking = Config->get_clicking ();
577 catch (failed_constructor& err) {
578 error << _("cannot setup Click I/O") << endmsg;
581 BootMessage (_("Compute I/O Latencies"));
583 set_worst_io_latencies ();
586 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
589 BootMessage (_("Set up standard connections"));
591 /* Create a set of Bundle objects that map
592 to the physical I/O currently available. We create both
593 mono and stereo bundles, so that the common cases of mono
594 and stereo tracks get bundles to put in their mixer strip
595 in / out menus. There may be a nicer way of achieving that;
596 it doesn't really scale that well to higher channel counts
599 /* mono output bundles */
601 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
603 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
605 shared_ptr<Bundle> c (new Bundle (buf, true));
606 c->add_channel (_("mono"));
607 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
612 /* stereo output bundles */
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 /* mono input bundles */
630 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
632 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
634 shared_ptr<Bundle> c (new Bundle (buf, false));
635 c->add_channel (_("mono"));
636 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
641 /* stereo input bundles */
643 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
644 if (np + 1 < n_physical_inputs) {
646 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
648 shared_ptr<Bundle> c (new Bundle (buf, false));
649 c->add_channel (_("L"));
650 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
651 c->add_channel (_("R"));
652 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
658 if (Config->get_auto_connect_standard_busses() && !no_auto_connect()) {
662 /* if requested auto-connect the outputs to the first N physical ports.
665 uint32_t limit = _master_out->n_outputs().n_total();
667 for (uint32_t n = 0; n < limit; ++n) {
668 Port* p = _master_out->output()->nth (n);
669 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
671 if (!connect_to.empty()) {
672 if (_master_out->output()->connect (p, connect_to, this)) {
673 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
683 uint32_t limit = _control_out->n_outputs().n_total();
685 for (uint32_t n = 0; n < limit; ++n) {
686 Port* p = _control_out->output()->nth (n);
687 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
689 if (!connect_to.empty()) {
690 if (_control_out->output()->connect (p, connect_to, this)) {
691 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
700 BootMessage (_("Setup signal flow and plugins"));
704 /* catch up on send+insert cnts */
706 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
708 /* hook us up to the engine */
710 BootMessage (_("Connect to engine"));
712 _engine.set_session (this);
716 Session::hookup_io ()
718 /* stop graph reordering notifications from
719 causing resorts, etc.
722 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
727 /* we delay creating the auditioner till now because
728 it makes its own connections to ports.
729 the engine has to be running for this to work.
733 auditioner.reset (new Auditioner (*this));
736 catch (failed_constructor& err) {
737 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
741 /* load bundles, which we may have postponed earlier on */
742 if (_bundle_xml_node) {
743 load_bundles (*_bundle_xml_node);
744 delete _bundle_xml_node;
747 /* Tell all IO objects to connect themselves together */
749 IO::enable_connecting ();
751 /* Now reset all panners */
753 Delivery::reset_panners ();
755 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
759 boost::shared_ptr<RouteList> r = routes.reader ();
761 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
763 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
766 t->listen_via (_control_out, X_("listen"));
771 /* Anyone who cares about input state, wake up and do something */
773 IOConnectionsComplete (); /* EMIT SIGNAL */
775 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
777 /* now handle the whole enchilada as if it was one
783 /* update mixer solo state */
789 Session::playlist_length_changed ()
791 /* we can't just increase end_location->end() if pl->get_maximum_extent()
792 if larger. if the playlist used to be the longest playlist,
793 and its now shorter, we have to decrease end_location->end(). hence,
794 we have to iterate over all diskstreams and check the
795 playlists currently in use.
801 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
803 boost::shared_ptr<Playlist> playlist;
805 if ((playlist = dstream->playlist()) != 0) {
806 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
809 /* see comment in playlist_length_changed () */
814 Session::record_enabling_legal () const
816 /* this used to be in here, but survey says.... we don't need to restrict it */
817 // if (record_status() == Recording) {
821 if (Config->get_all_safe()) {
828 Session::reset_input_monitor_state ()
830 if (transport_rolling()) {
832 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
834 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
835 if ((*i)->record_enabled ()) {
836 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
837 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
841 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
843 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
844 if ((*i)->record_enabled ()) {
845 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
846 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
853 Session::auto_punch_start_changed (Location* location)
855 replace_event (Event::PunchIn, location->start());
857 if (get_record_enabled() && config.get_punch_in()) {
858 /* capture start has been changed, so save new pending state */
859 save_state ("", true);
864 Session::auto_punch_end_changed (Location* location)
866 nframes_t when_to_stop = location->end();
867 // when_to_stop += _worst_output_latency + _worst_input_latency;
868 replace_event (Event::PunchOut, when_to_stop);
872 Session::auto_punch_changed (Location* location)
874 nframes_t when_to_stop = location->end();
876 replace_event (Event::PunchIn, location->start());
877 //when_to_stop += _worst_output_latency + _worst_input_latency;
878 replace_event (Event::PunchOut, when_to_stop);
882 Session::auto_loop_changed (Location* location)
884 replace_event (Event::AutoLoop, location->end(), location->start());
886 if (transport_rolling() && play_loop) {
888 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
890 if (_transport_frame > location->end()) {
891 // relocate to beginning of loop
892 clear_events (Event::LocateRoll);
894 request_locate (location->start(), true);
897 else if (Config->get_seamless_loop() && !loop_changing) {
899 // schedule a locate-roll to refill the diskstreams at the
901 loop_changing = true;
903 if (location->end() > last_loopend) {
904 clear_events (Event::LocateRoll);
905 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
912 last_loopend = location->end();
916 Session::set_auto_punch_location (Location* location)
920 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
921 auto_punch_start_changed_connection.disconnect();
922 auto_punch_end_changed_connection.disconnect();
923 auto_punch_changed_connection.disconnect();
924 existing->set_auto_punch (false, this);
925 remove_event (existing->start(), Event::PunchIn);
926 clear_events (Event::PunchOut);
927 auto_punch_location_changed (0);
936 if (location->end() <= location->start()) {
937 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
941 auto_punch_start_changed_connection.disconnect();
942 auto_punch_end_changed_connection.disconnect();
943 auto_punch_changed_connection.disconnect();
945 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
946 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
947 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
949 location->set_auto_punch (true, this);
952 auto_punch_changed (location);
954 auto_punch_location_changed (location);
958 Session::set_auto_loop_location (Location* location)
962 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
963 auto_loop_start_changed_connection.disconnect();
964 auto_loop_end_changed_connection.disconnect();
965 auto_loop_changed_connection.disconnect();
966 existing->set_auto_loop (false, this);
967 remove_event (existing->end(), Event::AutoLoop);
968 auto_loop_location_changed (0);
977 if (location->end() <= location->start()) {
978 error << _("Session: you can't use a mark for auto loop") << endmsg;
982 last_loopend = location->end();
984 auto_loop_start_changed_connection.disconnect();
985 auto_loop_end_changed_connection.disconnect();
986 auto_loop_changed_connection.disconnect();
988 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
989 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
990 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
992 location->set_auto_loop (true, this);
994 /* take care of our stuff first */
996 auto_loop_changed (location);
998 /* now tell everyone else */
1000 auto_loop_location_changed (location);
1004 Session::locations_added (Location* ignored)
1010 Session::locations_changed ()
1012 _locations.apply (*this, &Session::handle_locations_changed);
1016 Session::handle_locations_changed (Locations::LocationList& locations)
1018 Locations::LocationList::iterator i;
1020 bool set_loop = false;
1021 bool set_punch = false;
1023 for (i = locations.begin(); i != locations.end(); ++i) {
1027 if (location->is_auto_punch()) {
1028 set_auto_punch_location (location);
1031 if (location->is_auto_loop()) {
1032 set_auto_loop_location (location);
1036 if (location->is_start()) {
1037 start_location = location;
1039 if (location->is_end()) {
1040 end_location = location;
1045 set_auto_loop_location (0);
1048 set_auto_punch_location (0);
1055 Session::enable_record ()
1057 /* XXX really atomic compare+swap here */
1058 if (g_atomic_int_get (&_record_status) != Recording) {
1059 g_atomic_int_set (&_record_status, Recording);
1060 _last_record_location = _transport_frame;
1061 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1063 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1064 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1065 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1066 if ((*i)->record_enabled ()) {
1067 (*i)->monitor_input (true);
1072 RecordStateChanged ();
1077 Session::disable_record (bool rt_context, bool force)
1081 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1083 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1084 g_atomic_int_set (&_record_status, Disabled);
1086 if (rs == Recording) {
1087 g_atomic_int_set (&_record_status, Enabled);
1091 // FIXME: timestamp correct? [DR]
1092 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1093 // does this /need/ to be sent in all cases?
1095 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1097 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1098 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1100 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1101 if ((*i)->record_enabled ()) {
1102 (*i)->monitor_input (false);
1107 RecordStateChanged (); /* emit signal */
1110 remove_pending_capture_state ();
1116 Session::step_back_from_record ()
1118 /* XXX really atomic compare+swap here */
1119 if (g_atomic_int_get (&_record_status) == Recording) {
1120 g_atomic_int_set (&_record_status, Enabled);
1122 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1123 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1125 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1126 if ((*i)->record_enabled ()) {
1127 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1128 (*i)->monitor_input (false);
1136 Session::maybe_enable_record ()
1138 g_atomic_int_set (&_record_status, Enabled);
1140 /* this function is currently called from somewhere other than an RT thread.
1141 this save_state() call therefore doesn't impact anything.
1144 save_state ("", true);
1146 if (_transport_speed) {
1147 if (!config.get_punch_in()) {
1151 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1152 RecordStateChanged (); /* EMIT SIGNAL */
1159 Session::audible_frame () const
1165 /* the first of these two possible settings for "offset"
1166 mean that the audible frame is stationary until
1167 audio emerges from the latency compensation
1170 the second means that the audible frame is stationary
1171 until audio would emerge from a physical port
1172 in the absence of any plugin latency compensation
1175 offset = _worst_output_latency;
1177 if (offset > current_block_size) {
1178 offset -= current_block_size;
1180 /* XXX is this correct? if we have no external
1181 physical connections and everything is internal
1182 then surely this is zero? still, how
1183 likely is that anyway?
1185 offset = current_block_size;
1188 if (synced_to_jack()) {
1189 tf = _engine.transport_frame();
1191 tf = _transport_frame;
1196 if (!non_realtime_work_pending()) {
1200 /* check to see if we have passed the first guaranteed
1201 audible frame past our last start position. if not,
1202 return that last start point because in terms
1203 of audible frames, we have not moved yet.
1206 if (_transport_speed > 0.0f) {
1208 if (!play_loop || !have_looped) {
1209 if (tf < _last_roll_location + offset) {
1210 return _last_roll_location;
1218 } else if (_transport_speed < 0.0f) {
1220 /* XXX wot? no backward looping? */
1222 if (tf > _last_roll_location - offset) {
1223 return _last_roll_location;
1235 Session::set_frame_rate (nframes_t frames_per_second)
1237 /** \fn void Session::set_frame_size(nframes_t)
1238 the AudioEngine object that calls this guarantees
1239 that it will not be called while we are also in
1240 ::process(). Its fine to do things that block
1244 _base_frame_rate = frames_per_second;
1248 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1252 // XXX we need some equivalent to this, somehow
1253 // SndFileSource::setup_standard_crossfades (frames_per_second);
1257 /* XXX need to reset/reinstantiate all LADSPA plugins */
1261 Session::set_block_size (nframes_t nframes)
1263 /* the AudioEngine guarantees
1264 that it will not be called while we are also in
1265 ::process(). It is therefore fine to do things that block
1270 current_block_size = nframes;
1272 ensure_buffers(_scratch_buffers->available());
1274 delete [] _gain_automation_buffer;
1275 _gain_automation_buffer = new gain_t[nframes];
1277 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1279 boost::shared_ptr<RouteList> r = routes.reader ();
1281 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1282 (*i)->set_block_size (nframes);
1285 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1286 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1287 (*i)->set_block_size (nframes);
1290 set_worst_io_latencies ();
1295 Session::set_default_fade (float steepness, float fade_msecs)
1298 nframes_t fade_frames;
1300 /* Don't allow fade of less 1 frame */
1302 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1309 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1313 default_fade_msecs = fade_msecs;
1314 default_fade_steepness = steepness;
1317 // jlc, WTF is this!
1318 Glib::RWLock::ReaderLock lm (route_lock);
1319 AudioRegion::set_default_fade (steepness, fade_frames);
1324 /* XXX have to do this at some point */
1325 /* foreach region using default fade, reset, then
1326 refill_all_diskstream_buffers ();
1331 struct RouteSorter {
1332 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1333 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1335 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1338 if (r1->fed_by.empty()) {
1339 if (r2->fed_by.empty()) {
1340 /* no ardour-based connections inbound to either route. just use signal order */
1341 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1343 /* r2 has connections, r1 does not; run r1 early */
1347 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1354 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1356 shared_ptr<Route> r2;
1358 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1359 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1363 /* make a copy of the existing list of routes that feed r1 */
1365 set<shared_ptr<Route> > existing = r1->fed_by;
1367 /* for each route that feeds r1, recurse, marking it as feeding
1371 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1374 /* r2 is a route that feeds r1 which somehow feeds base. mark
1375 base as being fed by r2
1378 rbase->fed_by.insert (r2);
1382 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1386 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1390 /* now recurse, so that we can mark base as being fed by
1391 all routes that feed r2
1394 trace_terminal (r2, rbase);
1401 Session::resort_routes ()
1403 /* don't do anything here with signals emitted
1404 by Routes while we are being destroyed.
1407 if (_state_of_the_state & Deletion) {
1414 RCUWriter<RouteList> writer (routes);
1415 shared_ptr<RouteList> r = writer.get_copy ();
1416 resort_routes_using (r);
1417 /* writer goes out of scope and forces update */
1422 Session::resort_routes_using (shared_ptr<RouteList> r)
1424 RouteList::iterator i, j;
1426 for (i = r->begin(); i != r->end(); ++i) {
1428 (*i)->fed_by.clear ();
1430 for (j = r->begin(); j != r->end(); ++j) {
1432 /* although routes can feed themselves, it will
1433 cause an endless recursive descent if we
1434 detect it. so don't bother checking for
1442 if ((*j)->feeds (*i)) {
1443 (*i)->fed_by.insert (*j);
1448 for (i = r->begin(); i != r->end(); ++i) {
1449 trace_terminal (*i, *i);
1456 cerr << "finished route resort\n";
1458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1459 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1466 list<boost::shared_ptr<MidiTrack> >
1467 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1469 char track_name[32];
1470 uint32_t track_id = 0;
1473 RouteList new_routes;
1474 list<boost::shared_ptr<MidiTrack> > ret;
1475 //uint32_t control_id;
1477 // FIXME: need physical I/O and autoconnect stuff for MIDI
1479 /* count existing midi tracks */
1482 shared_ptr<RouteList> r = routes.reader ();
1484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1485 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1486 if (!(*i)->is_hidden()) {
1488 //channels_used += (*i)->n_inputs().n_midi();
1494 vector<string> physinputs;
1495 vector<string> physoutputs;
1497 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1498 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1500 // control_id = ntracks() + nbusses();
1504 /* check for duplicate route names, since we might have pre-existing
1505 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1506 save, close,restart,add new route - first named route is now
1514 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1516 if (route_by_name (track_name) == 0) {
1520 } while (track_id < (UINT_MAX-1));
1522 shared_ptr<MidiTrack> track;
1525 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1527 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1528 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1533 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1534 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1540 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1544 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1545 port = physinputs[(channels_used+x)%nphysical_in];
1548 if (port.length() && track->connect_input (track->input (x), port, this)) {
1554 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1558 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1559 port = physoutputs[(channels_used+x)%nphysical_out];
1560 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1562 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1566 if (port.length() && track->connect_output (track->output (x), port, this)) {
1571 channels_used += track->n_inputs ().n_midi();
1575 track->midi_diskstream()->non_realtime_input_change();
1576 track->set_route_group (route_group, 0);
1578 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1579 //track->set_remote_control_id (control_id);
1581 new_routes.push_back (track);
1582 ret.push_back (track);
1585 catch (failed_constructor &err) {
1586 error << _("Session: could not create new midi track.") << endmsg;
1589 /* we need to get rid of this, since the track failed to be created */
1590 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1593 RCUWriter<DiskstreamList> writer (diskstreams);
1594 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1595 ds->remove (track->midi_diskstream());
1602 catch (AudioEngine::PortRegistrationFailure& pfe) {
1604 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;
1607 /* we need to get rid of this, since the track failed to be created */
1608 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1611 RCUWriter<DiskstreamList> writer (diskstreams);
1612 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1613 ds->remove (track->midi_diskstream());
1624 if (!new_routes.empty()) {
1625 add_routes (new_routes, false);
1626 save_state (_current_snapshot_name);
1632 list<boost::shared_ptr<AudioTrack> >
1633 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1635 char track_name[32];
1636 uint32_t track_id = 0;
1638 uint32_t channels_used = 0;
1640 RouteList new_routes;
1641 list<boost::shared_ptr<AudioTrack> > ret;
1642 uint32_t control_id;
1644 /* count existing audio tracks */
1647 shared_ptr<RouteList> r = routes.reader ();
1649 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1650 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1651 if (!(*i)->is_hidden()) {
1653 channels_used += (*i)->n_inputs().n_audio();
1659 vector<string> physinputs;
1660 vector<string> physoutputs;
1662 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1663 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1665 control_id = ntracks() + nbusses() + 1;
1669 /* check for duplicate route names, since we might have pre-existing
1670 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1671 save, close,restart,add new route - first named route is now
1679 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1681 if (route_by_name (track_name) == 0) {
1685 } while (track_id < (UINT_MAX-1));
1687 shared_ptr<AudioTrack> track;
1690 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1692 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1693 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1694 input_channels, output_channels)
1699 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1700 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1701 input_channels, output_channels)
1706 if (!physinputs.empty()) {
1707 uint32_t nphysical_in = physinputs.size();
1709 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1713 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1714 port = physinputs[(channels_used+x)%nphysical_in];
1717 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1723 if (!physoutputs.empty()) {
1724 uint32_t nphysical_out = physoutputs.size();
1726 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1729 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1730 port = physoutputs[(channels_used+x)%nphysical_out];
1731 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1732 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1733 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1737 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1743 channels_used += track->n_inputs ().n_audio();
1745 track->set_route_group (route_group, 0);
1747 track->audio_diskstream()->non_realtime_input_change();
1749 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1750 track->set_remote_control_id (control_id);
1753 new_routes.push_back (track);
1754 ret.push_back (track);
1757 catch (failed_constructor &err) {
1758 error << _("Session: could not create new audio track.") << endmsg;
1761 /* we need to get rid of this, since the track failed to be created */
1762 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1765 RCUWriter<DiskstreamList> writer (diskstreams);
1766 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1767 ds->remove (track->audio_diskstream());
1774 catch (AudioEngine::PortRegistrationFailure& pfe) {
1776 error << pfe.what() << endmsg;
1779 /* we need to get rid of this, since the track failed to be created */
1780 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1783 RCUWriter<DiskstreamList> writer (diskstreams);
1784 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1785 ds->remove (track->audio_diskstream());
1796 if (!new_routes.empty()) {
1797 add_routes (new_routes, true);
1804 Session::set_remote_control_ids ()
1806 RemoteModel m = Config->get_remote_model();
1808 shared_ptr<RouteList> r = routes.reader ();
1810 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1811 if ( MixerOrdered == m) {
1812 long order = (*i)->order_key(N_("signal"));
1813 (*i)->set_remote_control_id( order+1 );
1814 } else if ( EditorOrdered == m) {
1815 long order = (*i)->order_key(N_("editor"));
1816 (*i)->set_remote_control_id( order+1 );
1817 } else if ( UserOrdered == m) {
1818 //do nothing ... only changes to remote id's are initiated by user
1825 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1828 uint32_t bus_id = 1;
1830 uint32_t channels_used = 0;
1833 uint32_t control_id;
1835 /* count existing audio busses */
1838 shared_ptr<RouteList> r = routes.reader ();
1840 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1841 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1843 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1846 channels_used += (*i)->n_inputs().n_audio();
1852 vector<string> physinputs;
1853 vector<string> physoutputs;
1855 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1856 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1858 n_physical_audio_outputs = physoutputs.size();
1859 n_physical_audio_inputs = physinputs.size();
1861 control_id = ntracks() + nbusses() + 1;
1866 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1870 if (route_by_name (bus_name) == 0) {
1874 } while (bus_id < (UINT_MAX-1));
1877 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1879 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1880 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1881 input_channels, output_channels)
1887 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1888 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1889 input_channels, output_channels)
1894 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1897 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1898 port = physinputs[((n+x)%n_physical_audio_inputs)];
1901 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1906 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1909 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1910 port = physoutputs[((n+x)%n_physical_outputs)];
1911 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1913 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1917 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1922 channels_used += bus->n_inputs ().n_audio();
1924 bus->set_route_group (route_group, 0);
1925 bus->set_remote_control_id (control_id);
1928 ret.push_back (bus);
1932 catch (failed_constructor &err) {
1933 error << _("Session: could not create new audio route.") << endmsg;
1937 catch (AudioEngine::PortRegistrationFailure& pfe) {
1938 error << pfe.what() << endmsg;
1948 add_routes (ret, true);
1956 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1960 uint32_t control_id;
1963 if (!tree.read (template_path.c_str())) {
1967 XMLNode* node = tree.root();
1969 control_id = ntracks() + nbusses() + 1;
1973 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1975 std::string node_name = IO::name_from_state (*node_copy.children().front());
1977 if (route_by_name (node_name) != 0) {
1979 /* generate a new name by adding a number to the end of the template name */
1981 uint32_t number = 1;
1984 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
1988 if (route_by_name (name) == 0) {
1992 } while (number < UINT_MAX);
1994 if (number == UINT_MAX) {
1995 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1999 IO::set_name_in_state (*node_copy.children().front(), name);
2002 Track::zero_diskstream_id_in_xml (node_copy);
2005 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2008 error << _("Session: cannot create track/bus from template description") << endmsg;
2012 if (boost::dynamic_pointer_cast<Track>(route)) {
2013 /* force input/output change signals so that the new diskstream
2014 picks up the configuration of the route. During session
2015 loading this normally happens in a different way.
2017 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2018 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2021 route->set_remote_control_id (control_id);
2024 ret.push_back (route);
2027 catch (failed_constructor &err) {
2028 error << _("Session: could not create new route from template") << endmsg;
2032 catch (AudioEngine::PortRegistrationFailure& pfe) {
2033 error << pfe.what() << endmsg;
2042 add_routes (ret, true);
2049 Session::add_routes (RouteList& new_routes, bool save)
2052 RCUWriter<RouteList> writer (routes);
2053 shared_ptr<RouteList> r = writer.get_copy ();
2054 r->insert (r->end(), new_routes.begin(), new_routes.end());
2056 if (!_control_out && IO::connecting_legal) {
2057 resort_routes_using (r);
2061 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2063 boost::weak_ptr<Route> wpr (*x);
2065 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2066 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2067 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2068 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2069 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2071 if ((*x)->is_master()) {
2075 if ((*x)->is_control()) {
2076 _control_out = (*x);
2080 if (_control_out && IO::connecting_legal) {
2082 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2083 (*x)->listen_via (_control_out, "control");
2092 save_state (_current_snapshot_name);
2095 RouteAdded (new_routes); /* EMIT SIGNAL */
2099 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2101 /* need to do this in case we're rolling at the time, to prevent false underruns */
2102 dstream->do_refill_with_alloc ();
2104 dstream->set_block_size (current_block_size);
2107 RCUWriter<DiskstreamList> writer (diskstreams);
2108 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2109 ds->push_back (dstream);
2110 /* writer goes out of scope, copies ds back to main */
2113 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2114 /* this will connect to future changes, and check the current length */
2115 diskstream_playlist_changed (dstream);
2117 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2119 dstream->prepare ();
2124 Session::remove_route (shared_ptr<Route> route)
2127 RCUWriter<RouteList> writer (routes);
2128 shared_ptr<RouteList> rs = writer.get_copy ();
2132 /* deleting the master out seems like a dumb
2133 idea, but its more of a UI policy issue
2137 if (route == _master_out) {
2138 _master_out = shared_ptr<Route> ();
2141 if (route == _control_out) {
2143 /* cancel control outs for all routes */
2145 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2146 (*r)->drop_listen (_control_out);
2149 _control_out.reset ();
2152 update_route_solo_state ();
2154 /* writer goes out of scope, forces route list update */
2157 boost::shared_ptr<Track> t;
2158 boost::shared_ptr<Diskstream> ds;
2160 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2161 ds = t->diskstream();
2167 RCUWriter<DiskstreamList> dsl (diskstreams);
2168 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2173 find_current_end ();
2175 // We need to disconnect the routes inputs and outputs
2177 route->input()->disconnect (0);
2178 route->output()->disconnect (0);
2180 update_latency_compensation (false, false);
2183 /* get rid of it from the dead wood collection in the route list manager */
2185 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2189 /* try to cause everyone to drop their references */
2191 route->drop_references ();
2193 sync_order_keys (N_("session"));
2195 /* save the new state of the world */
2197 if (save_state (_current_snapshot_name)) {
2198 save_history (_current_snapshot_name);
2203 Session::route_mute_changed (void* src)
2209 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2211 if (solo_update_disabled) {
2216 boost::shared_ptr<Route> route = wpr.lock ();
2219 /* should not happen */
2220 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2224 shared_ptr<RouteList> r = routes.reader ();
2227 if (route->soloed()) {
2233 solo_update_disabled = true;
2234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2236 if ((*i)->feeds (route)) {
2238 (*i)->mod_solo_level (delta);
2242 /* make sure master is never muted by solo */
2244 if (_master_out->solo_level() == 0) {
2245 _master_out->mod_solo_level (1);
2248 /* ditto for control outs make sure master is never muted by solo */
2250 if (_control_out && _control_out->solo_level() == 0) {
2251 _control_out->mod_solo_level (1);
2254 solo_update_disabled = false;
2255 update_route_solo_state (r);
2256 SoloChanged (); /* EMIT SIGNAL */
2261 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2263 /* now figure out if anything that matters is soloed */
2265 bool something_soloed = false;
2268 r = routes.reader();
2271 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2272 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2273 something_soloed = true;
2278 if (something_soloed != _non_soloed_outs_muted) {
2279 _non_soloed_outs_muted = something_soloed;
2280 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2285 Session::catch_up_on_solo ()
2287 /* this is called after set_state() to catch the full solo
2288 state, which can't be correctly determined on a per-route
2289 basis, but needs the global overview that only the session
2292 update_route_solo_state();
2296 Session::catch_up_on_solo_mute_override ()
2298 if (Config->get_solo_model() != SoloInPlace) {
2302 /* this is called whenever the param solo-mute-override is
2305 shared_ptr<RouteList> r = routes.reader ();
2307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2308 // (*i)->catch_up_on_solo_mute_override ();
2313 Session::route_by_name (string name)
2315 shared_ptr<RouteList> r = routes.reader ();
2317 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2318 if ((*i)->name() == name) {
2323 return shared_ptr<Route> ((Route*) 0);
2327 Session::route_by_id (PBD::ID id)
2329 shared_ptr<RouteList> r = routes.reader ();
2331 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2332 if ((*i)->id() == id) {
2337 return shared_ptr<Route> ((Route*) 0);
2341 Session::route_by_remote_id (uint32_t id)
2343 shared_ptr<RouteList> r = routes.reader ();
2345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2346 if ((*i)->remote_control_id() == id) {
2351 return shared_ptr<Route> ((Route*) 0);
2355 Session::find_current_end ()
2357 if (_state_of_the_state & Loading) {
2361 nframes_t max = get_maximum_extent ();
2363 if (max > end_location->end()) {
2364 end_location->set_end (max);
2366 DurationChanged(); /* EMIT SIGNAL */
2371 Session::get_maximum_extent () const
2376 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2378 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2379 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2381 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2382 if ((me = pl->get_maximum_extent()) > max) {
2390 boost::shared_ptr<Diskstream>
2391 Session::diskstream_by_name (string name)
2393 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2395 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2396 if ((*i)->name() == name) {
2401 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2404 boost::shared_ptr<Diskstream>
2405 Session::diskstream_by_id (const PBD::ID& id)
2407 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2409 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2410 if ((*i)->id() == id) {
2415 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2418 /* Region management */
2421 Session::new_region_name (string old)
2423 string::size_type last_period;
2425 string::size_type len = old.length() + 64;
2428 if ((last_period = old.find_last_of ('.')) == string::npos) {
2430 /* no period present - add one explicitly */
2433 last_period = old.length() - 1;
2438 number = atoi (old.substr (last_period+1).c_str());
2442 while (number < (UINT_MAX-1)) {
2444 RegionList::const_iterator i;
2449 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2452 for (i = regions.begin(); i != regions.end(); ++i) {
2453 if (i->second->name() == sbuf) {
2458 if (i == regions.end()) {
2463 if (number != (UINT_MAX-1)) {
2467 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2472 Session::region_name (string& result, string base, bool newlevel)
2477 if (base.find("/") != string::npos) {
2478 base = base.substr(base.find_last_of("/") + 1);
2483 Glib::Mutex::Lock lm (region_lock);
2485 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2494 string::size_type pos;
2496 pos = base.find_last_of ('.');
2498 /* pos may be npos, but then we just use entire base */
2500 subbase = base.substr (0, pos);
2505 Glib::Mutex::Lock lm (region_lock);
2507 map<string,uint32_t>::iterator x;
2511 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2513 region_name_map[subbase] = 1;
2516 snprintf (buf, sizeof (buf), ".%d", x->second);
2527 Session::add_region (boost::shared_ptr<Region> region)
2529 vector<boost::shared_ptr<Region> > v;
2530 v.push_back (region);
2535 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2540 Glib::Mutex::Lock lm (region_lock);
2542 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2544 boost::shared_ptr<Region> region = *ii;
2548 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2552 RegionList::iterator x;
2554 for (x = regions.begin(); x != regions.end(); ++x) {
2556 if (region->region_list_equivalent (x->second)) {
2561 if (x == regions.end()) {
2563 pair<RegionList::key_type,RegionList::mapped_type> entry;
2565 entry.first = region->id();
2566 entry.second = region;
2568 pair<RegionList::iterator,bool> x = regions.insert (entry);
2580 /* mark dirty because something has changed even if we didn't
2581 add the region to the region list.
2588 vector<boost::weak_ptr<Region> > v;
2589 boost::shared_ptr<Region> first_r;
2591 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2593 boost::shared_ptr<Region> region = *ii;
2597 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2600 v.push_back (region);
2607 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2608 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2610 update_region_name_map (region);
2614 RegionsAdded (v); /* EMIT SIGNAL */
2620 Session::update_region_name_map (boost::shared_ptr<Region> region)
2622 string::size_type last_period = region->name().find_last_of ('.');
2624 if (last_period != string::npos && last_period < region->name().length() - 1) {
2626 string base = region->name().substr (0, last_period);
2627 string number = region->name().substr (last_period+1);
2628 map<string,uint32_t>::iterator x;
2630 /* note that if there is no number, we get zero from atoi,
2634 region_name_map[base] = atoi (number);
2639 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2641 boost::shared_ptr<Region> region (weak_region.lock ());
2647 if (what_changed & Region::HiddenChanged) {
2648 /* relay hidden changes */
2649 RegionHiddenChange (region);
2652 if (what_changed & NameChanged) {
2653 update_region_name_map (region);
2658 Session::remove_region (boost::weak_ptr<Region> weak_region)
2660 RegionList::iterator i;
2661 boost::shared_ptr<Region> region (weak_region.lock ());
2667 bool removed = false;
2670 Glib::Mutex::Lock lm (region_lock);
2672 if ((i = regions.find (region->id())) != regions.end()) {
2678 /* mark dirty because something has changed even if we didn't
2679 remove the region from the region list.
2685 RegionRemoved(region); /* EMIT SIGNAL */
2689 boost::shared_ptr<Region>
2690 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2692 RegionList::iterator i;
2693 boost::shared_ptr<Region> region;
2695 Glib::Mutex::Lock lm (region_lock);
2697 for (i = regions.begin(); i != regions.end(); ++i) {
2701 if (region->whole_file()) {
2703 if (child->source_equivalent (region)) {
2709 return boost::shared_ptr<Region> ();
2713 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2715 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2716 (*i)->get_region_list_equivalent_regions (region, result);
2720 Session::destroy_region (boost::shared_ptr<Region> region)
2722 vector<boost::shared_ptr<Source> > srcs;
2725 if (region->playlist()) {
2726 region->playlist()->destroy_region (region);
2729 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2730 srcs.push_back (region->source (n));
2734 region->drop_references ();
2736 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2738 (*i)->mark_for_remove ();
2739 (*i)->drop_references ();
2741 cerr << "source was not used by any playlist\n";
2748 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2750 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2751 destroy_region (*i);
2757 Session::remove_last_capture ()
2759 list<boost::shared_ptr<Region> > r;
2761 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2763 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2764 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2767 r.insert (r.end(), l.begin(), l.end());
2772 destroy_regions (r);
2774 save_state (_current_snapshot_name);
2780 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2786 /* Source Management */
2789 Session::add_source (boost::shared_ptr<Source> source)
2791 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2792 pair<SourceMap::iterator,bool> result;
2794 entry.first = source->id();
2795 entry.second = source;
2798 Glib::Mutex::Lock lm (source_lock);
2799 result = sources.insert (entry);
2802 if (result.second) {
2803 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2807 boost::shared_ptr<AudioFileSource> afs;
2809 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2810 if (Config->get_auto_analyse_audio()) {
2811 Analyser::queue_source_for_analysis (source, false);
2817 Session::remove_source (boost::weak_ptr<Source> src)
2819 SourceMap::iterator i;
2820 boost::shared_ptr<Source> source = src.lock();
2827 Glib::Mutex::Lock lm (source_lock);
2829 if ((i = sources.find (source->id())) != sources.end()) {
2834 if (!_state_of_the_state & InCleanup) {
2836 /* save state so we don't end up with a session file
2837 referring to non-existent sources.
2840 save_state (_current_snapshot_name);
2844 boost::shared_ptr<Source>
2845 Session::source_by_id (const PBD::ID& id)
2847 Glib::Mutex::Lock lm (source_lock);
2848 SourceMap::iterator i;
2849 boost::shared_ptr<Source> source;
2851 if ((i = sources.find (id)) != sources.end()) {
2858 boost::shared_ptr<Source>
2859 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2861 Glib::Mutex::Lock lm (source_lock);
2863 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2864 cerr << "comparing " << path << " with " << i->second->name() << endl;
2865 boost::shared_ptr<AudioFileSource> afs
2866 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2868 if (afs && afs->path() == path && chn == afs->channel()) {
2872 return boost::shared_ptr<Source>();
2877 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2880 string old_basename = PBD::basename_nosuffix (oldname);
2881 string new_legalized = legalize_for_path (newname);
2883 /* note: we know (or assume) the old path is already valid */
2887 /* destructive file sources have a name of the form:
2889 /path/to/Tnnnn-NAME(%[LR])?.wav
2891 the task here is to replace NAME with the new name.
2894 /* find last slash */
2898 string::size_type slash;
2899 string::size_type dash;
2901 if ((slash = path.find_last_of ('/')) == string::npos) {
2905 dir = path.substr (0, slash+1);
2907 /* '-' is not a legal character for the NAME part of the path */
2909 if ((dash = path.find_last_of ('-')) == string::npos) {
2913 prefix = path.substr (slash+1, dash-(slash+1));
2918 path += new_legalized;
2919 path += ".wav"; /* XXX gag me with a spoon */
2923 /* non-destructive file sources have a name of the form:
2925 /path/to/NAME-nnnnn(%[LR])?.ext
2927 the task here is to replace NAME with the new name.
2932 string::size_type slash;
2933 string::size_type dash;
2934 string::size_type postfix;
2936 /* find last slash */
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 suffix = path.substr (dash+1);
2952 // Suffix is now everything after the dash. Now we need to eliminate
2953 // the nnnnn part, which is done by either finding a '%' or a '.'
2955 postfix = suffix.find_last_of ("%");
2956 if (postfix == string::npos) {
2957 postfix = suffix.find_last_of ('.');
2960 if (postfix != string::npos) {
2961 suffix = suffix.substr (postfix);
2963 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2967 const uint32_t limit = 10000;
2968 char buf[PATH_MAX+1];
2970 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2972 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2974 if (access (buf, F_OK) != 0) {
2982 error << "FATAL ERROR! Could not find a " << endl;
2990 /** Return the full path (in some session directory) for a new embedded source.
2991 * \a name must be a session-unique name that does not contain slashes
2992 * (e.g. as returned by new_*_source_name)
2995 Session::new_source_path_from_name (DataType type, const string& name)
2997 assert(name.find("/") == string::npos);
2999 SessionDirectory sdir(get_best_session_directory_for_new_source());
3002 if (type == DataType::AUDIO) {
3003 p = sdir.sound_path();
3004 } else if (type == DataType::MIDI) {
3005 p = sdir.midi_path();
3007 error << "Unknown source type, unable to create file path" << endmsg;
3012 return p.to_string();
3016 Session::peak_path (Glib::ustring base) const
3018 sys::path peakfile_path(_session_dir->peak_path());
3019 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3020 return peakfile_path.to_string();
3023 /** Return a unique name based on \a base for a new internal audio source */
3025 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3029 char buf[PATH_MAX+1];
3030 const uint32_t limit = 10000;
3034 legalized = legalize_for_path (base);
3036 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3037 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3039 vector<space_and_path>::iterator i;
3040 uint32_t existing = 0;
3042 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3044 SessionDirectory sdir((*i).path);
3046 spath = sdir.sound_path().to_string();
3051 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3052 spath.c_str(), cnt, legalized.c_str());
3053 } else if (nchan == 2) {
3055 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3056 spath.c_str(), cnt, legalized.c_str());
3058 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3059 spath.c_str(), cnt, legalized.c_str());
3061 } else if (nchan < 26) {
3062 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3063 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3065 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3066 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(
3101 _("There are already %1 recordings for %2, which I consider too many."),
3102 limit, base) << endmsg;
3104 throw failed_constructor();
3108 return Glib::path_get_basename(buf);
3111 /** Create a new embedded audio source */
3112 boost::shared_ptr<AudioFileSource>
3113 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3115 const size_t n_chans = ds.n_channels().n_audio();
3116 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3117 const string path = new_source_path_from_name(DataType::AUDIO, name);
3118 return boost::dynamic_pointer_cast<AudioFileSource> (
3119 SourceFactory::createWritable (
3120 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3123 /** Return a unique name based on \a base for a new internal MIDI source */
3125 Session::new_midi_source_name (const string& base)
3128 char buf[PATH_MAX+1];
3129 const uint32_t limit = 10000;
3133 legalized = legalize_for_path (base);
3135 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3136 for (cnt = 1; cnt <= limit; ++cnt) {
3138 vector<space_and_path>::iterator i;
3139 uint32_t existing = 0;
3141 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3143 SessionDirectory sdir((*i).path);
3145 sys::path p = sdir.midi_path();
3148 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3150 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);
3172 /** Create a new embedded MIDI source */
3173 boost::shared_ptr<MidiSource>
3174 Session::create_midi_source_for_session (MidiDiskstream& ds)
3176 const string name = new_midi_source_name (ds.name());
3177 const string path = new_source_path_from_name (DataType::MIDI, name);
3179 return boost::dynamic_pointer_cast<SMFSource> (
3180 SourceFactory::createWritable (
3181 DataType::MIDI, *this, path, true, false, frame_rate()));
3185 /* Playlist management */
3187 boost::shared_ptr<Playlist>
3188 Session::playlist_by_name (string name)
3190 Glib::Mutex::Lock lm (playlist_lock);
3191 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3192 if ((*i)->name() == name) {
3196 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3197 if ((*i)->name() == name) {
3202 return boost::shared_ptr<Playlist>();
3206 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3208 Glib::Mutex::Lock lm (playlist_lock);
3209 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3210 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3211 list.push_back (*i);
3214 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3215 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3216 list.push_back (*i);
3222 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3224 if (playlist->hidden()) {
3229 Glib::Mutex::Lock lm (playlist_lock);
3230 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3231 playlists.insert (playlists.begin(), playlist);
3232 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3233 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3238 playlist->release();
3243 PlaylistAdded (playlist); /* EMIT SIGNAL */
3247 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3250 Glib::Mutex::Lock lm (playlist_lock);
3251 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3254 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3261 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3263 boost::shared_ptr<Playlist> pl(wpl.lock());
3269 PlaylistList::iterator x;
3272 /* its not supposed to be visible */
3277 Glib::Mutex::Lock lm (playlist_lock);
3281 unused_playlists.insert (pl);
3283 if ((x = playlists.find (pl)) != playlists.end()) {
3284 playlists.erase (x);
3290 playlists.insert (pl);
3292 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3293 unused_playlists.erase (x);
3300 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3302 if (_state_of_the_state & Deletion) {
3306 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3313 Glib::Mutex::Lock lm (playlist_lock);
3315 PlaylistList::iterator i;
3317 i = find (playlists.begin(), playlists.end(), playlist);
3318 if (i != playlists.end()) {
3319 playlists.erase (i);
3322 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3323 if (i != unused_playlists.end()) {
3324 unused_playlists.erase (i);
3331 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3335 Session::set_audition (boost::shared_ptr<Region> r)
3337 pending_audition_region = r;
3338 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3339 schedule_butler_transport_work ();
3343 Session::audition_playlist ()
3345 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3346 ev->region.reset ();
3351 Session::non_realtime_set_audition ()
3353 if (!pending_audition_region) {
3354 auditioner->audition_current_playlist ();
3356 auditioner->audition_region (pending_audition_region);
3357 pending_audition_region.reset ();
3359 AuditionActive (true); /* EMIT SIGNAL */
3363 Session::audition_region (boost::shared_ptr<Region> r)
3365 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3371 Session::cancel_audition ()
3373 if (auditioner->active()) {
3374 auditioner->cancel_audition ();
3375 AuditionActive (false); /* EMIT SIGNAL */
3380 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3382 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3386 Session::remove_empty_sounds ()
3388 vector<string> audio_filenames;
3390 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3392 Glib::Mutex::Lock lm (source_lock);
3394 TapeFileMatcher tape_file_matcher;
3396 remove_if (audio_filenames.begin(), audio_filenames.end(),
3397 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3399 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3401 sys::path audio_file_path (_session_dir->sound_path());
3403 audio_file_path /= *i;
3405 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3409 sys::remove (audio_file_path);
3410 const string peakfile = peak_path (audio_file_path.to_string());
3411 sys::remove (peakfile);
3413 catch (const sys::filesystem_error& err)
3415 error << err.what() << endmsg;
3422 Session::is_auditioning () const
3424 /* can be called before we have an auditioner object */
3426 return auditioner->active();
3433 Session::set_all_solo (bool yn)
3435 shared_ptr<RouteList> r = routes.reader ();
3437 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3438 if (!(*i)->is_hidden()) {
3439 (*i)->set_solo (yn, this);
3447 Session::set_all_mute (bool yn)
3449 shared_ptr<RouteList> r = routes.reader ();
3451 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3452 if (!(*i)->is_hidden()) {
3453 (*i)->set_mute (yn, this);
3461 Session::n_diskstreams () const
3465 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3467 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3468 if (!(*i)->hidden()) {
3476 Session::graph_reordered ()
3478 /* don't do this stuff if we are setting up connections
3479 from a set_state() call or creating new tracks.
3482 if (_state_of_the_state & InitialConnecting) {
3486 /* every track/bus asked for this to be handled but it was deferred because
3487 we were connecting. do it now.
3490 request_input_change_handling ();
3494 /* force all diskstreams to update their capture offset values to
3495 reflect any changes in latencies within the graph.
3498 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3500 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3501 (*i)->set_capture_offset ();
3506 Session::record_disenable_all ()
3508 record_enable_change_all (false);
3512 Session::record_enable_all ()
3514 record_enable_change_all (true);
3518 Session::record_enable_change_all (bool yn)
3520 shared_ptr<RouteList> r = routes.reader ();
3522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3523 boost::shared_ptr<Track> t;
3525 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3526 t->set_record_enable (yn, this);
3530 /* since we don't keep rec-enable state, don't mark session dirty */
3534 Session::add_processor (Processor* processor)
3536 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3541 Session::remove_processor (Processor* processor)
3545 PortInsert* port_insert;
3547 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3548 insert_bitset[port_insert->bit_slot()] = false;
3549 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3550 send_bitset[send->bit_slot()] = false;
3551 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3552 return_bitset[send->bit_slot()] = false;
3559 Session::available_capture_duration ()
3561 float sample_bytes_on_disk = 4.0; // keep gcc happy
3563 switch (config.get_native_file_data_format()) {
3565 sample_bytes_on_disk = 4.0;
3569 sample_bytes_on_disk = 3.0;
3573 sample_bytes_on_disk = 2.0;
3577 /* impossible, but keep some gcc versions happy */
3578 fatal << string_compose (_("programming error: %1"),
3579 X_("illegal native file data format"))
3584 double scale = 4096.0 / sample_bytes_on_disk;
3586 if (_total_free_4k_blocks * scale > (double) max_frames) {
3590 return (nframes_t) floor (_total_free_4k_blocks * scale);
3594 Session::add_bundle (shared_ptr<Bundle> bundle)
3597 RCUWriter<BundleList> writer (_bundles);
3598 boost::shared_ptr<BundleList> b = writer.get_copy ();
3599 b->push_back (bundle);
3602 BundleAdded (bundle); /* EMIT SIGNAL */
3608 Session::remove_bundle (shared_ptr<Bundle> bundle)
3610 bool removed = false;
3613 RCUWriter<BundleList> writer (_bundles);
3614 boost::shared_ptr<BundleList> b = writer.get_copy ();
3615 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3617 if (i != b->end()) {
3624 BundleRemoved (bundle); /* EMIT SIGNAL */
3631 Session::bundle_by_name (string name) const
3633 boost::shared_ptr<BundleList> b = _bundles.reader ();
3635 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3636 if ((*i)->name() == name) {
3641 return boost::shared_ptr<Bundle> ();
3645 Session::tempo_map_changed (Change ignored)
3649 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3650 (*i)->update_after_tempo_map_change ();
3653 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3654 (*i)->update_after_tempo_map_change ();
3660 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3661 * the given count with the current block size.
3664 Session::ensure_buffers (ChanCount howmany)
3666 if (current_block_size == 0) {
3667 return; // too early? (is this ok?)
3670 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3671 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3672 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3673 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3674 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3677 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3681 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3683 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3684 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3689 Session::next_insert_id ()
3691 /* this doesn't really loop forever. just think about it */
3694 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3695 if (!insert_bitset[n]) {
3696 insert_bitset[n] = true;
3702 /* none available, so resize and try again */
3704 insert_bitset.resize (insert_bitset.size() + 16, false);
3709 Session::next_send_id ()
3711 /* this doesn't really loop forever. just think about it */
3714 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3715 if (!send_bitset[n]) {
3716 send_bitset[n] = true;
3722 /* none available, so resize and try again */
3724 send_bitset.resize (send_bitset.size() + 16, false);
3729 Session::next_return_id ()
3731 /* this doesn't really loop forever. just think about it */
3734 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3735 if (!return_bitset[n]) {
3736 return_bitset[n] = true;
3742 /* none available, so resize and try again */
3744 return_bitset.resize (return_bitset.size() + 16, false);
3749 Session::mark_send_id (uint32_t id)
3751 if (id >= send_bitset.size()) {
3752 send_bitset.resize (id+16, false);
3754 if (send_bitset[id]) {
3755 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3757 send_bitset[id] = true;
3761 Session::mark_return_id (uint32_t id)
3763 if (id >= return_bitset.size()) {
3764 return_bitset.resize (id+16, false);
3766 if (return_bitset[id]) {
3767 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3769 return_bitset[id] = true;
3773 Session::mark_insert_id (uint32_t id)
3775 if (id >= insert_bitset.size()) {
3776 insert_bitset.resize (id+16, false);
3778 if (insert_bitset[id]) {
3779 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3781 insert_bitset[id] = true;
3784 /* Named Selection management */
3787 Session::named_selection_by_name (string name)
3789 Glib::Mutex::Lock lm (named_selection_lock);
3790 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3791 if ((*i)->name == name) {
3799 Session::add_named_selection (NamedSelection* named_selection)
3802 Glib::Mutex::Lock lm (named_selection_lock);
3803 named_selections.insert (named_selections.begin(), named_selection);
3806 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3812 NamedSelectionAdded (); /* EMIT SIGNAL */
3816 Session::remove_named_selection (NamedSelection* named_selection)
3818 bool removed = false;
3821 Glib::Mutex::Lock lm (named_selection_lock);
3823 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3825 if (i != named_selections.end()) {
3827 named_selections.erase (i);
3834 NamedSelectionRemoved (); /* EMIT SIGNAL */
3839 Session::reset_native_file_format ()
3841 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3843 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3844 (*i)->reset_write_sources (false);
3849 Session::route_name_unique (string n) const
3851 shared_ptr<RouteList> r = routes.reader ();
3853 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3854 if ((*i)->name() == n) {
3863 Session::route_name_internal (string n) const
3865 if (auditioner && auditioner->name() == n) {
3869 if (_click_io && _click_io->name() == n) {
3877 Session::n_playlists () const
3879 Glib::Mutex::Lock lm (playlist_lock);
3880 return playlists.size();
3884 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3886 if (!force && howmany <= _npan_buffers) {
3890 if (_pan_automation_buffer) {
3892 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3893 delete [] _pan_automation_buffer[i];
3896 delete [] _pan_automation_buffer;
3899 _pan_automation_buffer = new pan_t*[howmany];
3901 for (uint32_t i = 0; i < howmany; ++i) {
3902 _pan_automation_buffer[i] = new pan_t[nframes];
3905 _npan_buffers = howmany;
3909 Session::freeze (InterThreadInfo& itt)
3911 shared_ptr<RouteList> r = routes.reader ();
3913 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3915 boost::shared_ptr<Track> t;
3917 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3918 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3928 boost::shared_ptr<Region>
3929 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3930 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
3931 InterThreadInfo& itt, bool enable_processing)
3933 boost::shared_ptr<Region> result;
3934 boost::shared_ptr<Playlist> playlist;
3935 boost::shared_ptr<AudioFileSource> fsource;
3937 char buf[PATH_MAX+1];
3938 ChanCount nchans(track.audio_diskstream()->n_channels());
3940 nframes_t this_chunk;
3943 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3944 const string sound_dir = sdir.sound_path().to_string();
3945 nframes_t len = end - start;
3948 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3949 end, start) << endmsg;
3953 // any bigger than this seems to cause stack overflows in called functions
3954 const nframes_t chunk_size = (128 * 1024)/4;
3956 // block all process callback handling
3958 block_processing ();
3960 /* call tree *MUST* hold route_lock */
3962 if ((playlist = track.diskstream()->playlist()) == 0) {
3966 /* external redirects will be a problem */
3968 if (track.has_external_redirects()) {
3972 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3974 for (x = 0; x < 99999; ++x) {
3975 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3976 if (access (buf, F_OK) != 0) {
3982 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3987 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3988 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
3991 catch (failed_constructor& err) {
3992 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3996 srcs.push_back (fsource);
3999 /* XXX need to flush all redirects */
4004 /* create a set of reasonably-sized buffers */
4005 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4006 buffers.set_count(nchans);
4008 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4009 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4011 afs->prepare_for_peakfile_writes ();
4014 while (to_do && !itt.cancel) {
4016 this_chunk = min (to_do, chunk_size);
4018 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4023 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4024 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4027 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4033 start += this_chunk;
4034 to_do -= this_chunk;
4036 itt.progress = (float) (1.0 - ((double) to_do / len));
4045 xnow = localtime (&now);
4047 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4048 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4051 afs->update_header (position, *xnow, now);
4052 afs->flush_header ();
4056 /* construct a region to represent the bounced material */
4058 result = RegionFactory::create (srcs, 0,
4059 srcs.front()->length(srcs.front()->timeline_position()),
4060 region_name_from_path (srcs.front()->name(), true));
4065 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4066 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4069 afs->mark_for_remove ();
4072 (*src)->drop_references ();
4076 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4077 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4080 afs->done_with_peakfile_writes ();
4084 unblock_processing ();
4090 Session::get_silent_buffers (ChanCount count)
4092 assert(_silent_buffers->available() >= count);
4093 _silent_buffers->set_count(count);
4095 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4096 for (size_t i= 0; i < count.get(*t); ++i) {
4097 _silent_buffers->get(*t, i).clear();
4101 return *_silent_buffers;
4105 Session::get_scratch_buffers (ChanCount count)
4107 if (count != ChanCount::ZERO) {
4108 assert(_scratch_buffers->available() >= count);
4109 _scratch_buffers->set_count(count);
4111 _scratch_buffers->set_count (_scratch_buffers->available());
4114 return *_scratch_buffers;
4118 Session::get_mix_buffers (ChanCount count)
4120 assert(_mix_buffers->available() >= count);
4121 _mix_buffers->set_count(count);
4122 return *_mix_buffers;
4126 Session::ntracks () const
4129 shared_ptr<RouteList> r = routes.reader ();
4131 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4132 if (boost::dynamic_pointer_cast<Track> (*i)) {
4141 Session::nbusses () const
4144 shared_ptr<RouteList> r = routes.reader ();
4146 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4147 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4156 Session::add_automation_list(AutomationList *al)
4158 automation_lists[al->id()] = al;
4162 Session::compute_initial_length ()
4164 return _engine.frame_rate() * 60 * 5;
4168 Session::sync_order_keys (const char* base)
4170 if (!Config->get_sync_all_route_ordering()) {
4171 /* leave order keys as they are */
4175 boost::shared_ptr<RouteList> r = routes.reader ();
4177 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4178 (*i)->sync_order_keys (base);
4181 Route::SyncOrderKeys (base); // EMIT SIGNAL
4185 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4187 Session::have_rec_enabled_diskstream () const
4189 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4192 /** Update the state of our rec-enabled diskstreams flag */
4194 Session::update_have_rec_enabled_diskstream ()
4196 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4197 DiskstreamList::iterator i = dsl->begin ();
4198 while (i != dsl->end () && (*i)->record_enabled () == false) {
4202 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4204 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4206 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4207 RecordStateChanged (); /* EMIT SIGNAL */
4212 Session::solo_model_changed ()
4216 switch (Config->get_solo_model()) {
4229 boost::shared_ptr<RouteList> r = routes.reader ();
4231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4232 (*i)->put_control_outs_at (p);
4237 Session::route_group_changed ()
4239 RouteGroupChanged (); /* EMIT SIGNAL */