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 if (!eng.connected()) {
151 throw failed_constructor();
154 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
156 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
157 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
159 first_stage_init (fullpath, snapshot_name);
161 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
164 if (create (new_session, mix_template, compute_initial_length())) {
166 throw failed_constructor ();
170 if (second_stage_init (new_session)) {
172 throw failed_constructor ();
175 store_recent_sessions(_name, _path);
177 bool was_dirty = dirty();
179 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
181 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
182 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
185 DirtyChanged (); /* EMIT SIGNAL */
189 Session::Session (AudioEngine &eng,
191 string snapshot_name,
192 AutoConnectOption input_ac,
193 AutoConnectOption output_ac,
194 uint32_t control_out_channels,
195 uint32_t master_out_channels,
196 uint32_t requested_physical_in,
197 uint32_t requested_physical_out,
198 nframes_t initial_length)
201 _target_transport_speed (0.0),
202 _requested_return_frame (-1),
203 _scratch_buffers(new BufferSet()),
204 _silent_buffers(new BufferSet()),
205 _mix_buffers(new BufferSet()),
207 _mmc_port (default_mmc_port),
208 _mtc_port (default_mtc_port),
209 _midi_port (default_midi_port),
210 _midi_clock_port (default_midi_clock_port),
211 _session_dir ( new SessionDirectory(fullpath)),
212 pending_events (2048),
214 butler_mixdown_buffer (0),
215 butler_gain_buffer (0),
216 post_transport_work((PostTransportWork)0),
217 _send_smpte_update (false),
218 midi_thread (pthread_t (0)),
220 diskstreams (new DiskstreamList),
221 routes (new RouteList),
222 _total_free_4k_blocks (0),
223 _bundles (new BundleList),
224 _bundle_xml_node (0),
225 _click_io ((IO *) 0),
227 click_emphasis_data (0),
229 _metadata (new SessionMetadata()),
230 _have_rec_enabled_diskstream (false)
234 if (!eng.connected()) {
235 throw failed_constructor();
238 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
240 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
241 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
243 if (n_physical_inputs) {
244 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
247 if (n_physical_outputs) {
248 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
251 first_stage_init (fullpath, snapshot_name);
253 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
256 if (create (new_session, string(), initial_length)) {
258 throw failed_constructor ();
263 /* set up Master Out and Control Out if necessary */
268 if (control_out_channels) {
269 ChanCount count(DataType::AUDIO, control_out_channels);
270 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
271 r->input()->ensure_io (count, false, this);
272 r->output()->ensure_io (count, false, this);
273 r->set_remote_control_id (control_id++);
278 if (master_out_channels) {
279 ChanCount count(DataType::AUDIO, master_out_channels);
280 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
281 r->input()->ensure_io (count, false, this);
282 r->output()->ensure_io (count, false, this);
283 r->set_remote_control_id (control_id);
287 /* prohibit auto-connect to master, because there isn't one */
288 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
292 add_routes (rl, false);
297 if (no_auto_connect()) {
298 input_ac = AutoConnectOption (0);
299 output_ac = AutoConnectOption (0);
302 Config->set_input_auto_connect (input_ac);
303 Config->set_output_auto_connect (output_ac);
305 if (second_stage_init (new_session)) {
307 throw failed_constructor ();
310 store_recent_sessions (_name, _path);
312 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
314 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
325 /* if we got to here, leaving pending capture state around
329 remove_pending_capture_state ();
331 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
333 _engine.remove_session ();
335 GoingAway (); /* EMIT SIGNAL */
341 /* clear history so that no references to objects are held any more */
345 /* clear state tree so that no references to objects are held any more */
349 terminate_butler_thread ();
350 //terminate_midi_thread ();
352 if (click_data != default_click) {
353 delete [] click_data;
356 if (click_emphasis_data != default_click_emphasis) {
357 delete [] click_emphasis_data;
362 delete _scratch_buffers;
363 delete _silent_buffers;
366 AudioDiskstream::free_working_buffers();
368 Route::SyncOrderKeys.clear();
370 #undef TRACK_DESTRUCTION
371 #ifdef TRACK_DESTRUCTION
372 cerr << "delete named selections\n";
373 #endif /* TRACK_DESTRUCTION */
374 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
375 NamedSelectionList::iterator tmp;
384 #ifdef TRACK_DESTRUCTION
385 cerr << "delete playlists\n";
386 #endif /* TRACK_DESTRUCTION */
387 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
388 PlaylistList::iterator tmp;
393 (*i)->drop_references ();
398 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
399 PlaylistList::iterator tmp;
404 (*i)->drop_references ();
410 unused_playlists.clear ();
412 #ifdef TRACK_DESTRUCTION
413 cerr << "delete regions\n";
414 #endif /* TRACK_DESTRUCTION */
416 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
417 RegionList::iterator tmp;
422 i->second->drop_references ();
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete routes\n";
431 #endif /* TRACK_DESTRUCTION */
433 RCUWriter<RouteList> writer (routes);
434 boost::shared_ptr<RouteList> r = writer.get_copy ();
435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
436 (*i)->drop_references ();
439 /* writer goes out of scope and updates master */
444 #ifdef TRACK_DESTRUCTION
445 cerr << "delete diskstreams\n";
446 #endif /* TRACK_DESTRUCTION */
448 RCUWriter<DiskstreamList> dwriter (diskstreams);
449 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
450 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
451 (*i)->drop_references ();
455 diskstreams.flush ();
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete audio sources\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
461 SourceMap::iterator tmp;
466 i->second->drop_references ();
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete mix groups\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
476 list<RouteGroup*>::iterator tmp;
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete edit groups\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
490 list<RouteGroup*>::iterator tmp;
500 delete [] butler_mixdown_buffer;
501 delete [] butler_gain_buffer;
503 Crossfade::set_buffer_size (0);
509 Session::set_worst_io_latencies ()
511 _worst_output_latency = 0;
512 _worst_input_latency = 0;
514 if (!_engine.connected()) {
518 boost::shared_ptr<RouteList> r = routes.reader ();
520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
521 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
522 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
527 Session::when_engine_running ()
529 string first_physical_output;
531 BootMessage (_("Set block size and sample rate"));
533 set_block_size (_engine.frames_per_cycle());
534 set_frame_rate (_engine.frame_rate());
536 BootMessage (_("Using configuration"));
538 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
540 /* every time we reconnect, recompute worst case output latencies */
542 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
544 if (synced_to_jack()) {
545 _engine.transport_stop ();
548 if (config.get_jack_time_master()) {
549 _engine.transport_locate (_transport_frame);
557 _click_io.reset (new ClickIO (*this, "click"));
559 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
561 /* existing state for Click */
563 if (_click_io->set_state (*child->children().front()) == 0) {
565 _clicking = Config->get_clicking ();
569 error << _("could not setup Click I/O") << endmsg;
575 /* default state for Click: dual-mono to first 2 physical outputs */
577 for (int physport = 0; physport < 2; ++physport) {
578 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
580 if (physical_output.length()) {
581 if (_click_io->add_port (physical_output, this)) {
582 // relax, even though its an error
587 if (_click_io->n_ports () > ChanCount::ZERO) {
588 _clicking = Config->get_clicking ();
593 catch (failed_constructor& err) {
594 error << _("cannot setup Click I/O") << endmsg;
597 BootMessage (_("Compute I/O Latencies"));
599 set_worst_io_latencies ();
602 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
605 BootMessage (_("Set up standard connections"));
607 /* Create a set of Bundle objects that map
608 to the physical I/O currently available. We create both
609 mono and stereo bundles, so that the common cases of mono
610 and stereo tracks get bundles to put in their mixer strip
611 in / out menus. There may be a nicer way of achieving that;
612 it doesn't really scale that well to higher channel counts
615 /* mono output bundles */
617 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
619 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
621 shared_ptr<Bundle> c (new Bundle (buf, true));
622 c->add_channel (_("mono"));
623 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
628 /* stereo output bundles */
630 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
631 if (np + 1 < n_physical_outputs) {
633 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
634 shared_ptr<Bundle> c (new Bundle (buf, true));
635 c->add_channel (_("L"));
636 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
637 c->add_channel (_("R"));
638 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
644 /* mono input bundles */
646 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
648 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
650 shared_ptr<Bundle> c (new Bundle (buf, false));
651 c->add_channel (_("mono"));
652 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
657 /* stereo input bundles */
659 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
660 if (np + 1 < n_physical_inputs) {
662 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
664 shared_ptr<Bundle> c (new Bundle (buf, false));
665 c->add_channel (_("L"));
666 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
667 c->add_channel (_("R"));
668 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
674 if (Config->get_auto_connect_standard_busses() && !no_auto_connect()) {
678 /* if requested auto-connect the outputs to the first N physical ports.
681 uint32_t limit = _master_out->n_outputs().n_total();
683 for (uint32_t n = 0; n < limit; ++n) {
684 Port* p = _master_out->output()->nth (n);
685 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
687 if (!connect_to.empty()) {
688 if (_master_out->output()->connect (p, connect_to, this)) {
689 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
699 uint32_t limit = _control_out->n_outputs().n_total();
701 for (uint32_t n = 0; n < limit; ++n) {
702 Port* p = _control_out->output()->nth (n);
703 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
705 if (!connect_to.empty()) {
706 if (_control_out->output()->connect (p, connect_to, this)) {
707 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
716 BootMessage (_("Setup signal flow and plugins"));
720 /* catch up on send+insert cnts */
722 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
724 /* hook us up to the engine */
726 BootMessage (_("Connect to engine"));
728 _engine.set_session (this);
732 Session::hookup_io ()
734 /* stop graph reordering notifications from
735 causing resorts, etc.
738 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
743 /* we delay creating the auditioner till now because
744 it makes its own connections to ports.
745 the engine has to be running for this to work.
749 auditioner.reset (new Auditioner (*this));
752 catch (failed_constructor& err) {
753 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
757 /* load bundles, which we may have postponed earlier on */
758 if (_bundle_xml_node) {
759 load_bundles (*_bundle_xml_node);
760 delete _bundle_xml_node;
763 /* Tell all IO objects to connect themselves together */
765 IO::enable_connecting ();
767 /* Now reset all panners */
769 Delivery::reset_panners ();
771 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
775 boost::shared_ptr<RouteList> r = routes.reader ();
777 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
779 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
782 t->listen_via (_control_out, X_("listen"));
787 /* Anyone who cares about input state, wake up and do something */
789 IOConnectionsComplete (); /* EMIT SIGNAL */
791 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
793 /* now handle the whole enchilada as if it was one
799 /* update mixer solo state */
805 Session::playlist_length_changed ()
807 /* we can't just increase end_location->end() if pl->get_maximum_extent()
808 if larger. if the playlist used to be the longest playlist,
809 and its now shorter, we have to decrease end_location->end(). hence,
810 we have to iterate over all diskstreams and check the
811 playlists currently in use.
817 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
819 boost::shared_ptr<Playlist> playlist;
821 if ((playlist = dstream->playlist()) != 0) {
822 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
825 /* see comment in playlist_length_changed () */
830 Session::record_enabling_legal () const
832 /* this used to be in here, but survey says.... we don't need to restrict it */
833 // if (record_status() == Recording) {
837 if (Config->get_all_safe()) {
844 Session::reset_input_monitor_state ()
846 if (transport_rolling()) {
848 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
850 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
851 if ((*i)->record_enabled ()) {
852 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
853 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
857 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
859 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
860 if ((*i)->record_enabled ()) {
861 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
862 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
869 Session::auto_punch_start_changed (Location* location)
871 replace_event (Event::PunchIn, location->start());
873 if (get_record_enabled() && config.get_punch_in()) {
874 /* capture start has been changed, so save new pending state */
875 save_state ("", true);
880 Session::auto_punch_end_changed (Location* location)
882 nframes_t when_to_stop = location->end();
883 // when_to_stop += _worst_output_latency + _worst_input_latency;
884 replace_event (Event::PunchOut, when_to_stop);
888 Session::auto_punch_changed (Location* location)
890 nframes_t when_to_stop = location->end();
892 replace_event (Event::PunchIn, location->start());
893 //when_to_stop += _worst_output_latency + _worst_input_latency;
894 replace_event (Event::PunchOut, when_to_stop);
898 Session::auto_loop_changed (Location* location)
900 replace_event (Event::AutoLoop, location->end(), location->start());
902 if (transport_rolling() && play_loop) {
904 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
906 if (_transport_frame > location->end()) {
907 // relocate to beginning of loop
908 clear_events (Event::LocateRoll);
910 request_locate (location->start(), true);
913 else if (Config->get_seamless_loop() && !loop_changing) {
915 // schedule a locate-roll to refill the diskstreams at the
917 loop_changing = true;
919 if (location->end() > last_loopend) {
920 clear_events (Event::LocateRoll);
921 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
928 last_loopend = location->end();
932 Session::set_auto_punch_location (Location* location)
936 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
937 auto_punch_start_changed_connection.disconnect();
938 auto_punch_end_changed_connection.disconnect();
939 auto_punch_changed_connection.disconnect();
940 existing->set_auto_punch (false, this);
941 remove_event (existing->start(), Event::PunchIn);
942 clear_events (Event::PunchOut);
943 auto_punch_location_changed (0);
952 if (location->end() <= location->start()) {
953 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
957 auto_punch_start_changed_connection.disconnect();
958 auto_punch_end_changed_connection.disconnect();
959 auto_punch_changed_connection.disconnect();
961 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
962 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
963 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
965 location->set_auto_punch (true, this);
968 auto_punch_changed (location);
970 auto_punch_location_changed (location);
974 Session::set_auto_loop_location (Location* location)
978 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
979 auto_loop_start_changed_connection.disconnect();
980 auto_loop_end_changed_connection.disconnect();
981 auto_loop_changed_connection.disconnect();
982 existing->set_auto_loop (false, this);
983 remove_event (existing->end(), Event::AutoLoop);
984 auto_loop_location_changed (0);
993 if (location->end() <= location->start()) {
994 error << _("Session: you can't use a mark for auto loop") << endmsg;
998 last_loopend = location->end();
1000 auto_loop_start_changed_connection.disconnect();
1001 auto_loop_end_changed_connection.disconnect();
1002 auto_loop_changed_connection.disconnect();
1004 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1005 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1006 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1008 location->set_auto_loop (true, this);
1010 /* take care of our stuff first */
1012 auto_loop_changed (location);
1014 /* now tell everyone else */
1016 auto_loop_location_changed (location);
1020 Session::locations_added (Location* ignored)
1026 Session::locations_changed ()
1028 _locations.apply (*this, &Session::handle_locations_changed);
1032 Session::handle_locations_changed (Locations::LocationList& locations)
1034 Locations::LocationList::iterator i;
1036 bool set_loop = false;
1037 bool set_punch = false;
1039 for (i = locations.begin(); i != locations.end(); ++i) {
1043 if (location->is_auto_punch()) {
1044 set_auto_punch_location (location);
1047 if (location->is_auto_loop()) {
1048 set_auto_loop_location (location);
1052 if (location->is_start()) {
1053 start_location = location;
1055 if (location->is_end()) {
1056 end_location = location;
1061 set_auto_loop_location (0);
1064 set_auto_punch_location (0);
1071 Session::enable_record ()
1073 /* XXX really atomic compare+swap here */
1074 if (g_atomic_int_get (&_record_status) != Recording) {
1075 g_atomic_int_set (&_record_status, Recording);
1076 _last_record_location = _transport_frame;
1077 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1079 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1080 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1081 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1082 if ((*i)->record_enabled ()) {
1083 (*i)->monitor_input (true);
1088 RecordStateChanged ();
1093 Session::disable_record (bool rt_context, bool force)
1097 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1099 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1100 g_atomic_int_set (&_record_status, Disabled);
1102 if (rs == Recording) {
1103 g_atomic_int_set (&_record_status, Enabled);
1107 // FIXME: timestamp correct? [DR]
1108 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1109 // does this /need/ to be sent in all cases?
1111 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1113 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1114 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 (false);
1123 RecordStateChanged (); /* emit signal */
1126 remove_pending_capture_state ();
1132 Session::step_back_from_record ()
1134 /* XXX really atomic compare+swap here */
1135 if (g_atomic_int_get (&_record_status) == Recording) {
1136 g_atomic_int_set (&_record_status, Enabled);
1138 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1139 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1141 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1142 if ((*i)->record_enabled ()) {
1143 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1144 (*i)->monitor_input (false);
1152 Session::maybe_enable_record ()
1154 g_atomic_int_set (&_record_status, Enabled);
1156 /* this function is currently called from somewhere other than an RT thread.
1157 this save_state() call therefore doesn't impact anything.
1160 save_state ("", true);
1162 if (_transport_speed) {
1163 if (!config.get_punch_in()) {
1167 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1168 RecordStateChanged (); /* EMIT SIGNAL */
1175 Session::audible_frame () const
1181 /* the first of these two possible settings for "offset"
1182 mean that the audible frame is stationary until
1183 audio emerges from the latency compensation
1186 the second means that the audible frame is stationary
1187 until audio would emerge from a physical port
1188 in the absence of any plugin latency compensation
1191 offset = _worst_output_latency;
1193 if (offset > current_block_size) {
1194 offset -= current_block_size;
1196 /* XXX is this correct? if we have no external
1197 physical connections and everything is internal
1198 then surely this is zero? still, how
1199 likely is that anyway?
1201 offset = current_block_size;
1204 if (synced_to_jack()) {
1205 tf = _engine.transport_frame();
1207 tf = _transport_frame;
1212 if (!non_realtime_work_pending()) {
1216 /* check to see if we have passed the first guaranteed
1217 audible frame past our last start position. if not,
1218 return that last start point because in terms
1219 of audible frames, we have not moved yet.
1222 if (_transport_speed > 0.0f) {
1224 if (!play_loop || !have_looped) {
1225 if (tf < _last_roll_location + offset) {
1226 return _last_roll_location;
1234 } else if (_transport_speed < 0.0f) {
1236 /* XXX wot? no backward looping? */
1238 if (tf > _last_roll_location - offset) {
1239 return _last_roll_location;
1251 Session::set_frame_rate (nframes_t frames_per_second)
1253 /** \fn void Session::set_frame_size(nframes_t)
1254 the AudioEngine object that calls this guarantees
1255 that it will not be called while we are also in
1256 ::process(). Its fine to do things that block
1260 _base_frame_rate = frames_per_second;
1264 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1268 // XXX we need some equivalent to this, somehow
1269 // SndFileSource::setup_standard_crossfades (frames_per_second);
1273 /* XXX need to reset/reinstantiate all LADSPA plugins */
1277 Session::set_block_size (nframes_t nframes)
1279 /* the AudioEngine guarantees
1280 that it will not be called while we are also in
1281 ::process(). It is therefore fine to do things that block
1286 current_block_size = nframes;
1288 ensure_buffers(_scratch_buffers->available());
1290 delete [] _gain_automation_buffer;
1291 _gain_automation_buffer = new gain_t[nframes];
1293 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1295 boost::shared_ptr<RouteList> r = routes.reader ();
1297 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1298 (*i)->set_block_size (nframes);
1301 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1303 (*i)->set_block_size (nframes);
1306 set_worst_io_latencies ();
1311 Session::set_default_fade (float steepness, float fade_msecs)
1314 nframes_t fade_frames;
1316 /* Don't allow fade of less 1 frame */
1318 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1325 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1329 default_fade_msecs = fade_msecs;
1330 default_fade_steepness = steepness;
1333 // jlc, WTF is this!
1334 Glib::RWLock::ReaderLock lm (route_lock);
1335 AudioRegion::set_default_fade (steepness, fade_frames);
1340 /* XXX have to do this at some point */
1341 /* foreach region using default fade, reset, then
1342 refill_all_diskstream_buffers ();
1347 struct RouteSorter {
1348 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1349 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1351 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1354 if (r1->fed_by.empty()) {
1355 if (r2->fed_by.empty()) {
1356 /* no ardour-based connections inbound to either route. just use signal order */
1357 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1359 /* r2 has connections, r1 does not; run r1 early */
1363 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1370 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1372 shared_ptr<Route> r2;
1374 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1375 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1379 /* make a copy of the existing list of routes that feed r1 */
1381 set<shared_ptr<Route> > existing = r1->fed_by;
1383 /* for each route that feeds r1, recurse, marking it as feeding
1387 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1390 /* r2 is a route that feeds r1 which somehow feeds base. mark
1391 base as being fed by r2
1394 rbase->fed_by.insert (r2);
1398 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1402 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1406 /* now recurse, so that we can mark base as being fed by
1407 all routes that feed r2
1410 trace_terminal (r2, rbase);
1417 Session::resort_routes ()
1419 /* don't do anything here with signals emitted
1420 by Routes while we are being destroyed.
1423 if (_state_of_the_state & Deletion) {
1430 RCUWriter<RouteList> writer (routes);
1431 shared_ptr<RouteList> r = writer.get_copy ();
1432 resort_routes_using (r);
1433 /* writer goes out of scope and forces update */
1438 Session::resort_routes_using (shared_ptr<RouteList> r)
1440 RouteList::iterator i, j;
1442 for (i = r->begin(); i != r->end(); ++i) {
1444 (*i)->fed_by.clear ();
1446 for (j = r->begin(); j != r->end(); ++j) {
1448 /* although routes can feed themselves, it will
1449 cause an endless recursive descent if we
1450 detect it. so don't bother checking for
1458 if ((*j)->feeds (*i)) {
1459 (*i)->fed_by.insert (*j);
1464 for (i = r->begin(); i != r->end(); ++i) {
1465 trace_terminal (*i, *i);
1472 cerr << "finished route resort\n";
1474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1475 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1482 list<boost::shared_ptr<MidiTrack> >
1483 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1485 char track_name[32];
1486 uint32_t track_id = 0;
1489 RouteList new_routes;
1490 list<boost::shared_ptr<MidiTrack> > ret;
1491 //uint32_t control_id;
1493 // FIXME: need physical I/O and autoconnect stuff for MIDI
1495 /* count existing midi tracks */
1498 shared_ptr<RouteList> r = routes.reader ();
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1502 if (!(*i)->is_hidden()) {
1504 //channels_used += (*i)->n_inputs().n_midi();
1510 vector<string> physinputs;
1511 vector<string> physoutputs;
1513 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1514 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1516 // control_id = ntracks() + nbusses();
1520 /* check for duplicate route names, since we might have pre-existing
1521 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1522 save, close,restart,add new route - first named route is now
1530 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1532 if (route_by_name (track_name) == 0) {
1536 } while (track_id < (UINT_MAX-1));
1538 shared_ptr<MidiTrack> track;
1541 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1543 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1544 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1549 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1550 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1556 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1560 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1561 port = physinputs[(channels_used+x)%nphysical_in];
1564 if (port.length() && track->connect_input (track->input (x), port, this)) {
1570 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1574 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1575 port = physoutputs[(channels_used+x)%nphysical_out];
1576 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1578 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1582 if (port.length() && track->connect_output (track->output (x), port, this)) {
1587 channels_used += track->n_inputs ().n_midi();
1591 track->midi_diskstream()->non_realtime_input_change();
1593 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1594 //track->set_remote_control_id (control_id);
1596 new_routes.push_back (track);
1597 ret.push_back (track);
1600 catch (failed_constructor &err) {
1601 error << _("Session: could not create new midi track.") << endmsg;
1604 /* we need to get rid of this, since the track failed to be created */
1605 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1608 RCUWriter<DiskstreamList> writer (diskstreams);
1609 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1610 ds->remove (track->midi_diskstream());
1617 catch (AudioEngine::PortRegistrationFailure& pfe) {
1619 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;
1622 /* we need to get rid of this, since the track failed to be created */
1623 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1626 RCUWriter<DiskstreamList> writer (diskstreams);
1627 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1628 ds->remove (track->midi_diskstream());
1639 if (!new_routes.empty()) {
1640 add_routes (new_routes, false);
1641 save_state (_current_snapshot_name);
1647 list<boost::shared_ptr<AudioTrack> >
1648 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1650 char track_name[32];
1651 uint32_t track_id = 0;
1653 uint32_t channels_used = 0;
1655 RouteList new_routes;
1656 list<boost::shared_ptr<AudioTrack> > ret;
1657 uint32_t control_id;
1659 /* count existing audio tracks */
1662 shared_ptr<RouteList> r = routes.reader ();
1664 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1665 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1666 if (!(*i)->is_hidden()) {
1668 channels_used += (*i)->n_inputs().n_audio();
1674 vector<string> physinputs;
1675 vector<string> physoutputs;
1677 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1678 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1680 control_id = ntracks() + nbusses() + 1;
1684 /* check for duplicate route names, since we might have pre-existing
1685 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1686 save, close,restart,add new route - first named route is now
1694 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1696 if (route_by_name (track_name) == 0) {
1700 } while (track_id < (UINT_MAX-1));
1702 shared_ptr<AudioTrack> track;
1705 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1707 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1708 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1709 input_channels, output_channels)
1714 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1715 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1716 input_channels, output_channels)
1721 if (!physinputs.empty()) {
1722 uint32_t nphysical_in = physinputs.size();
1724 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1728 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1729 port = physinputs[(channels_used+x)%nphysical_in];
1732 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1738 if (!physoutputs.empty()) {
1739 uint32_t nphysical_out = physoutputs.size();
1741 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1744 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1745 port = physoutputs[(channels_used+x)%nphysical_out];
1746 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1747 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1748 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1752 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1758 channels_used += track->n_inputs ().n_audio();
1760 track->audio_diskstream()->non_realtime_input_change();
1762 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1763 track->set_remote_control_id (control_id);
1766 new_routes.push_back (track);
1767 ret.push_back (track);
1770 catch (failed_constructor &err) {
1771 error << _("Session: could not create new audio track.") << endmsg;
1774 /* we need to get rid of this, since the track failed to be created */
1775 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1778 RCUWriter<DiskstreamList> writer (diskstreams);
1779 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1780 ds->remove (track->audio_diskstream());
1787 catch (AudioEngine::PortRegistrationFailure& pfe) {
1789 error << pfe.what() << endmsg;
1792 /* we need to get rid of this, since the track failed to be created */
1793 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1796 RCUWriter<DiskstreamList> writer (diskstreams);
1797 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1798 ds->remove (track->audio_diskstream());
1809 if (!new_routes.empty()) {
1810 add_routes (new_routes, true);
1817 Session::set_remote_control_ids ()
1819 RemoteModel m = Config->get_remote_model();
1821 shared_ptr<RouteList> r = routes.reader ();
1823 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1824 if ( MixerOrdered == m) {
1825 long order = (*i)->order_key(N_("signal"));
1826 (*i)->set_remote_control_id( order+1 );
1827 } else if ( EditorOrdered == m) {
1828 long order = (*i)->order_key(N_("editor"));
1829 (*i)->set_remote_control_id( order+1 );
1830 } else if ( UserOrdered == m) {
1831 //do nothing ... only changes to remote id's are initiated by user
1838 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1841 uint32_t bus_id = 1;
1843 uint32_t channels_used = 0;
1846 uint32_t control_id;
1848 /* count existing audio busses */
1851 shared_ptr<RouteList> r = routes.reader ();
1853 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1854 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1856 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1859 channels_used += (*i)->n_inputs().n_audio();
1865 vector<string> physinputs;
1866 vector<string> physoutputs;
1868 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1869 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1871 n_physical_audio_outputs = physoutputs.size();
1872 n_physical_audio_inputs = physinputs.size();
1874 control_id = ntracks() + nbusses() + 1;
1879 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1883 if (route_by_name (bus_name) == 0) {
1887 } while (bus_id < (UINT_MAX-1));
1890 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1892 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1893 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1894 input_channels, output_channels)
1900 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1901 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1902 input_channels, output_channels)
1907 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1910 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1911 port = physinputs[((n+x)%n_physical_audio_inputs)];
1914 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1919 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1922 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1923 port = physoutputs[((n+x)%n_physical_outputs)];
1924 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1926 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1930 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1935 channels_used += bus->n_inputs ().n_audio();
1937 bus->set_remote_control_id (control_id);
1940 ret.push_back (bus);
1944 catch (failed_constructor &err) {
1945 error << _("Session: could not create new audio route.") << endmsg;
1949 catch (AudioEngine::PortRegistrationFailure& pfe) {
1950 error << pfe.what() << endmsg;
1960 add_routes (ret, true);
1968 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1972 uint32_t control_id;
1975 if (!tree.read (template_path.c_str())) {
1979 XMLNode* node = tree.root();
1981 control_id = ntracks() + nbusses() + 1;
1985 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1987 std::string node_name = IO::name_from_state (*node_copy.children().front());
1989 if (route_by_name (node_name) != 0) {
1991 /* generate a new name by adding a number to the end of the template name */
1993 uint32_t number = 1;
1996 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2000 if (route_by_name (name) == 0) {
2004 } while (number < UINT_MAX);
2006 if (number == UINT_MAX) {
2007 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2011 IO::set_name_in_state (*node_copy.children().front(), name);
2014 Track::zero_diskstream_id_in_xml (node_copy);
2017 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2020 error << _("Session: cannot create track/bus from template description") << endmsg;
2024 if (boost::dynamic_pointer_cast<Track>(route)) {
2025 /* force input/output change signals so that the new diskstream
2026 picks up the configuration of the route. During session
2027 loading this normally happens in a different way.
2029 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2030 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2033 route->set_remote_control_id (control_id);
2036 ret.push_back (route);
2039 catch (failed_constructor &err) {
2040 error << _("Session: could not create new route from template") << endmsg;
2044 catch (AudioEngine::PortRegistrationFailure& pfe) {
2045 error << pfe.what() << endmsg;
2054 add_routes (ret, true);
2061 Session::add_routes (RouteList& new_routes, bool save)
2064 RCUWriter<RouteList> writer (routes);
2065 shared_ptr<RouteList> r = writer.get_copy ();
2066 r->insert (r->end(), new_routes.begin(), new_routes.end());
2068 if (!_control_out && IO::connecting_legal) {
2069 resort_routes_using (r);
2073 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2075 boost::weak_ptr<Route> wpr (*x);
2077 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2078 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2079 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2080 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2082 if ((*x)->is_master()) {
2086 if ((*x)->is_control()) {
2087 _control_out = (*x);
2091 if (_control_out && IO::connecting_legal) {
2093 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2094 (*x)->listen_via (_control_out, "control");
2103 save_state (_current_snapshot_name);
2106 RouteAdded (new_routes); /* EMIT SIGNAL */
2110 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2112 /* need to do this in case we're rolling at the time, to prevent false underruns */
2113 dstream->do_refill_with_alloc ();
2115 dstream->set_block_size (current_block_size);
2118 RCUWriter<DiskstreamList> writer (diskstreams);
2119 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2120 ds->push_back (dstream);
2121 /* writer goes out of scope, copies ds back to main */
2124 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2125 /* this will connect to future changes, and check the current length */
2126 diskstream_playlist_changed (dstream);
2128 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2130 dstream->prepare ();
2135 Session::remove_route (shared_ptr<Route> route)
2138 RCUWriter<RouteList> writer (routes);
2139 shared_ptr<RouteList> rs = writer.get_copy ();
2143 /* deleting the master out seems like a dumb
2144 idea, but its more of a UI policy issue
2148 if (route == _master_out) {
2149 _master_out = shared_ptr<Route> ();
2152 if (route == _control_out) {
2154 /* cancel control outs for all routes */
2156 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2157 (*r)->drop_listen (_control_out);
2160 _control_out.reset ();
2163 update_route_solo_state ();
2165 /* writer goes out of scope, forces route list update */
2168 boost::shared_ptr<Track> t;
2169 boost::shared_ptr<Diskstream> ds;
2171 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2172 ds = t->diskstream();
2178 RCUWriter<DiskstreamList> dsl (diskstreams);
2179 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2184 find_current_end ();
2186 // We need to disconnect the routes inputs and outputs
2188 route->input()->disconnect (0);
2189 route->output()->disconnect (0);
2191 update_latency_compensation (false, false);
2194 /* get rid of it from the dead wood collection in the route list manager */
2196 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2200 /* try to cause everyone to drop their references */
2202 route->drop_references ();
2204 sync_order_keys (N_("session"));
2206 /* save the new state of the world */
2208 if (save_state (_current_snapshot_name)) {
2209 save_history (_current_snapshot_name);
2214 Session::route_mute_changed (void* src)
2220 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2222 if (solo_update_disabled) {
2227 boost::shared_ptr<Route> route = wpr.lock ();
2230 /* should not happen */
2231 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2235 shared_ptr<RouteList> r = routes.reader ();
2238 if (route->soloed()) {
2244 solo_update_disabled = true;
2245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 if ((*i)->feeds (route)) {
2249 (*i)->mod_solo_level (delta);
2253 /* make sure master is never muted by solo */
2255 if (_master_out->solo_level() == 0) {
2256 _master_out->mod_solo_level (1);
2259 /* ditto for control outs make sure master is never muted by solo */
2261 if (_control_out && _control_out->solo_level() == 0) {
2262 _control_out->mod_solo_level (1);
2265 solo_update_disabled = false;
2266 update_route_solo_state (r);
2267 SoloChanged (); /* EMIT SIGNAL */
2272 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2274 /* now figure out if anything that matters is soloed */
2276 bool something_soloed = false;
2279 r = routes.reader();
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2284 something_soloed = true;
2289 if (something_soloed != _non_soloed_outs_muted) {
2290 _non_soloed_outs_muted = something_soloed;
2291 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2296 Session::catch_up_on_solo ()
2298 /* this is called after set_state() to catch the full solo
2299 state, which can't be correctly determined on a per-route
2300 basis, but needs the global overview that only the session
2303 update_route_solo_state();
2307 Session::catch_up_on_solo_mute_override ()
2309 if (Config->get_solo_model() != SoloInPlace) {
2313 /* this is called whenever the param solo-mute-override is
2316 shared_ptr<RouteList> r = routes.reader ();
2318 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2319 // (*i)->catch_up_on_solo_mute_override ();
2324 Session::route_by_name (string name)
2326 shared_ptr<RouteList> r = routes.reader ();
2328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2329 if ((*i)->name() == name) {
2334 return shared_ptr<Route> ((Route*) 0);
2338 Session::route_by_id (PBD::ID id)
2340 shared_ptr<RouteList> r = routes.reader ();
2342 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2343 if ((*i)->id() == id) {
2348 return shared_ptr<Route> ((Route*) 0);
2352 Session::route_by_remote_id (uint32_t id)
2354 shared_ptr<RouteList> r = routes.reader ();
2356 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2357 if ((*i)->remote_control_id() == id) {
2362 return shared_ptr<Route> ((Route*) 0);
2366 Session::find_current_end ()
2368 if (_state_of_the_state & Loading) {
2372 nframes_t max = get_maximum_extent ();
2374 if (max > end_location->end()) {
2375 end_location->set_end (max);
2377 DurationChanged(); /* EMIT SIGNAL */
2382 Session::get_maximum_extent () const
2387 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2389 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2390 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2392 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2393 if ((me = pl->get_maximum_extent()) > max) {
2401 boost::shared_ptr<Diskstream>
2402 Session::diskstream_by_name (string name)
2404 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2406 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2407 if ((*i)->name() == name) {
2412 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2415 boost::shared_ptr<Diskstream>
2416 Session::diskstream_by_id (const PBD::ID& id)
2418 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2420 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2421 if ((*i)->id() == id) {
2426 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2429 /* Region management */
2432 Session::new_region_name (string old)
2434 string::size_type last_period;
2436 string::size_type len = old.length() + 64;
2439 if ((last_period = old.find_last_of ('.')) == string::npos) {
2441 /* no period present - add one explicitly */
2444 last_period = old.length() - 1;
2449 number = atoi (old.substr (last_period+1).c_str());
2453 while (number < (UINT_MAX-1)) {
2455 RegionList::const_iterator i;
2460 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2463 for (i = regions.begin(); i != regions.end(); ++i) {
2464 if (i->second->name() == sbuf) {
2469 if (i == regions.end()) {
2474 if (number != (UINT_MAX-1)) {
2478 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2483 Session::region_name (string& result, string base, bool newlevel)
2488 if (base.find("/") != string::npos) {
2489 base = base.substr(base.find_last_of("/") + 1);
2494 Glib::Mutex::Lock lm (region_lock);
2496 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2505 string::size_type pos;
2507 pos = base.find_last_of ('.');
2509 /* pos may be npos, but then we just use entire base */
2511 subbase = base.substr (0, pos);
2516 Glib::Mutex::Lock lm (region_lock);
2518 map<string,uint32_t>::iterator x;
2522 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2524 region_name_map[subbase] = 1;
2527 snprintf (buf, sizeof (buf), ".%d", x->second);
2538 Session::add_region (boost::shared_ptr<Region> region)
2540 vector<boost::shared_ptr<Region> > v;
2541 v.push_back (region);
2546 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2551 Glib::Mutex::Lock lm (region_lock);
2553 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2555 boost::shared_ptr<Region> region = *ii;
2559 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2563 RegionList::iterator x;
2565 for (x = regions.begin(); x != regions.end(); ++x) {
2567 if (region->region_list_equivalent (x->second)) {
2572 if (x == regions.end()) {
2574 pair<RegionList::key_type,RegionList::mapped_type> entry;
2576 entry.first = region->id();
2577 entry.second = region;
2579 pair<RegionList::iterator,bool> x = regions.insert (entry);
2591 /* mark dirty because something has changed even if we didn't
2592 add the region to the region list.
2599 vector<boost::weak_ptr<Region> > v;
2600 boost::shared_ptr<Region> first_r;
2602 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2604 boost::shared_ptr<Region> region = *ii;
2608 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2611 v.push_back (region);
2618 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2619 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2621 update_region_name_map (region);
2625 RegionsAdded (v); /* EMIT SIGNAL */
2631 Session::update_region_name_map (boost::shared_ptr<Region> region)
2633 string::size_type last_period = region->name().find_last_of ('.');
2635 if (last_period != string::npos && last_period < region->name().length() - 1) {
2637 string base = region->name().substr (0, last_period);
2638 string number = region->name().substr (last_period+1);
2639 map<string,uint32_t>::iterator x;
2641 /* note that if there is no number, we get zero from atoi,
2645 region_name_map[base] = atoi (number);
2650 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2652 boost::shared_ptr<Region> region (weak_region.lock ());
2658 if (what_changed & Region::HiddenChanged) {
2659 /* relay hidden changes */
2660 RegionHiddenChange (region);
2663 if (what_changed & NameChanged) {
2664 update_region_name_map (region);
2669 Session::remove_region (boost::weak_ptr<Region> weak_region)
2671 RegionList::iterator i;
2672 boost::shared_ptr<Region> region (weak_region.lock ());
2678 bool removed = false;
2681 Glib::Mutex::Lock lm (region_lock);
2683 if ((i = regions.find (region->id())) != regions.end()) {
2689 /* mark dirty because something has changed even if we didn't
2690 remove the region from the region list.
2696 RegionRemoved(region); /* EMIT SIGNAL */
2700 boost::shared_ptr<Region>
2701 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2703 RegionList::iterator i;
2704 boost::shared_ptr<Region> region;
2706 Glib::Mutex::Lock lm (region_lock);
2708 for (i = regions.begin(); i != regions.end(); ++i) {
2712 if (region->whole_file()) {
2714 if (child->source_equivalent (region)) {
2720 return boost::shared_ptr<Region> ();
2724 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2726 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2727 (*i)->get_region_list_equivalent_regions (region, result);
2731 Session::destroy_region (boost::shared_ptr<Region> region)
2733 vector<boost::shared_ptr<Source> > srcs;
2736 if (region->playlist()) {
2737 region->playlist()->destroy_region (region);
2740 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2741 srcs.push_back (region->source (n));
2745 region->drop_references ();
2747 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2749 (*i)->mark_for_remove ();
2750 (*i)->drop_references ();
2752 cerr << "source was not used by any playlist\n";
2759 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2761 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2762 destroy_region (*i);
2768 Session::remove_last_capture ()
2770 list<boost::shared_ptr<Region> > r;
2772 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2774 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2775 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2778 r.insert (r.end(), l.begin(), l.end());
2783 destroy_regions (r);
2785 save_state (_current_snapshot_name);
2791 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2797 /* Source Management */
2800 Session::add_source (boost::shared_ptr<Source> source)
2802 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2803 pair<SourceMap::iterator,bool> result;
2805 entry.first = source->id();
2806 entry.second = source;
2809 Glib::Mutex::Lock lm (source_lock);
2810 result = sources.insert (entry);
2813 if (result.second) {
2814 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2818 boost::shared_ptr<AudioFileSource> afs;
2820 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2821 if (Config->get_auto_analyse_audio()) {
2822 Analyser::queue_source_for_analysis (source, false);
2828 Session::remove_source (boost::weak_ptr<Source> src)
2830 SourceMap::iterator i;
2831 boost::shared_ptr<Source> source = src.lock();
2838 Glib::Mutex::Lock lm (source_lock);
2840 if ((i = sources.find (source->id())) != sources.end()) {
2845 if (!_state_of_the_state & InCleanup) {
2847 /* save state so we don't end up with a session file
2848 referring to non-existent sources.
2851 save_state (_current_snapshot_name);
2855 boost::shared_ptr<Source>
2856 Session::source_by_id (const PBD::ID& id)
2858 Glib::Mutex::Lock lm (source_lock);
2859 SourceMap::iterator i;
2860 boost::shared_ptr<Source> source;
2862 if ((i = sources.find (id)) != sources.end()) {
2869 boost::shared_ptr<Source>
2870 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2872 Glib::Mutex::Lock lm (source_lock);
2874 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2875 cerr << "comparing " << path << " with " << i->second->name() << endl;
2876 boost::shared_ptr<AudioFileSource> afs
2877 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2879 if (afs && afs->path() == path && chn == afs->channel()) {
2883 return boost::shared_ptr<Source>();
2888 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2891 string old_basename = PBD::basename_nosuffix (oldname);
2892 string new_legalized = legalize_for_path (newname);
2894 /* note: we know (or assume) the old path is already valid */
2898 /* destructive file sources have a name of the form:
2900 /path/to/Tnnnn-NAME(%[LR])?.wav
2902 the task here is to replace NAME with the new name.
2905 /* find last slash */
2909 string::size_type slash;
2910 string::size_type dash;
2912 if ((slash = path.find_last_of ('/')) == string::npos) {
2916 dir = path.substr (0, slash+1);
2918 /* '-' is not a legal character for the NAME part of the path */
2920 if ((dash = path.find_last_of ('-')) == string::npos) {
2924 prefix = path.substr (slash+1, dash-(slash+1));
2929 path += new_legalized;
2930 path += ".wav"; /* XXX gag me with a spoon */
2934 /* non-destructive file sources have a name of the form:
2936 /path/to/NAME-nnnnn(%[LR])?.ext
2938 the task here is to replace NAME with the new name.
2943 string::size_type slash;
2944 string::size_type dash;
2945 string::size_type postfix;
2947 /* find last slash */
2949 if ((slash = path.find_last_of ('/')) == string::npos) {
2953 dir = path.substr (0, slash+1);
2955 /* '-' is not a legal character for the NAME part of the path */
2957 if ((dash = path.find_last_of ('-')) == string::npos) {
2961 suffix = path.substr (dash+1);
2963 // Suffix is now everything after the dash. Now we need to eliminate
2964 // the nnnnn part, which is done by either finding a '%' or a '.'
2966 postfix = suffix.find_last_of ("%");
2967 if (postfix == string::npos) {
2968 postfix = suffix.find_last_of ('.');
2971 if (postfix != string::npos) {
2972 suffix = suffix.substr (postfix);
2974 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2978 const uint32_t limit = 10000;
2979 char buf[PATH_MAX+1];
2981 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2983 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2985 if (access (buf, F_OK) != 0) {
2993 error << "FATAL ERROR! Could not find a " << endl;
3001 /** Return the full path (in some session directory) for a new embedded source.
3002 * \a name must be a session-unique name that does not contain slashes
3003 * (e.g. as returned by new_*_source_name)
3006 Session::new_source_path_from_name (DataType type, const string& name)
3008 assert(name.find("/") == string::npos);
3010 SessionDirectory sdir(get_best_session_directory_for_new_source());
3013 if (type == DataType::AUDIO) {
3014 p = sdir.sound_path();
3015 } else if (type == DataType::MIDI) {
3016 p = sdir.midi_path();
3018 error << "Unknown source type, unable to create file path" << endmsg;
3023 return p.to_string();
3027 Session::peak_path (Glib::ustring base) const
3029 sys::path peakfile_path(_session_dir->peak_path());
3030 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3031 return peakfile_path.to_string();
3034 /** Return a unique name based on \a base for a new internal audio source */
3036 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3040 char buf[PATH_MAX+1];
3041 const uint32_t limit = 10000;
3045 legalized = legalize_for_path (base);
3047 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3048 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3050 vector<space_and_path>::iterator i;
3051 uint32_t existing = 0;
3053 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3055 SessionDirectory sdir((*i).path);
3057 spath = sdir.sound_path().to_string();
3062 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3063 spath.c_str(), cnt, legalized.c_str());
3064 } else if (nchan == 2) {
3066 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3067 spath.c_str(), cnt, legalized.c_str());
3069 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3070 spath.c_str(), cnt, legalized.c_str());
3072 } else if (nchan < 26) {
3073 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3074 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3076 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3077 spath.c_str(), cnt, legalized.c_str());
3086 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3087 } else if (nchan == 2) {
3089 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3091 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3093 } else if (nchan < 26) {
3094 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3096 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3100 if (sys::exists(buf)) {
3106 if (existing == 0) {
3111 error << string_compose(
3112 _("There are already %1 recordings for %2, which I consider too many."),
3113 limit, base) << endmsg;
3115 throw failed_constructor();
3119 return Glib::path_get_basename(buf);
3122 /** Create a new embedded audio source */
3123 boost::shared_ptr<AudioFileSource>
3124 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3126 const size_t n_chans = ds.n_channels().n_audio();
3127 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3128 const string path = new_source_path_from_name(DataType::AUDIO, name);
3129 return boost::dynamic_pointer_cast<AudioFileSource> (
3130 SourceFactory::createWritable (
3131 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3134 /** Return a unique name based on \a base for a new internal MIDI source */
3136 Session::new_midi_source_name (const string& base)
3139 char buf[PATH_MAX+1];
3140 const uint32_t limit = 10000;
3144 legalized = legalize_for_path (base);
3146 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3147 for (cnt = 1; cnt <= limit; ++cnt) {
3149 vector<space_and_path>::iterator i;
3150 uint32_t existing = 0;
3152 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3154 SessionDirectory sdir((*i).path);
3156 sys::path p = sdir.midi_path();
3159 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3161 if (sys::exists (buf)) {
3166 if (existing == 0) {
3171 error << string_compose(
3172 _("There are already %1 recordings for %2, which I consider too many."),
3173 limit, base) << endmsg;
3175 throw failed_constructor();
3179 return Glib::path_get_basename(buf);
3183 /** Create a new embedded MIDI source */
3184 boost::shared_ptr<MidiSource>
3185 Session::create_midi_source_for_session (MidiDiskstream& ds)
3187 const string name = new_midi_source_name (ds.name());
3188 const string path = new_source_path_from_name (DataType::MIDI, name);
3190 return boost::dynamic_pointer_cast<SMFSource> (
3191 SourceFactory::createWritable (
3192 DataType::MIDI, *this, path, true, false, frame_rate()));
3196 /* Playlist management */
3198 boost::shared_ptr<Playlist>
3199 Session::playlist_by_name (string name)
3201 Glib::Mutex::Lock lm (playlist_lock);
3202 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3203 if ((*i)->name() == name) {
3207 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3208 if ((*i)->name() == name) {
3213 return boost::shared_ptr<Playlist>();
3217 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3219 Glib::Mutex::Lock lm (playlist_lock);
3220 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3221 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3222 list.push_back (*i);
3225 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3226 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3227 list.push_back (*i);
3233 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3235 if (playlist->hidden()) {
3240 Glib::Mutex::Lock lm (playlist_lock);
3241 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3242 playlists.insert (playlists.begin(), playlist);
3243 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3244 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3249 playlist->release();
3254 PlaylistAdded (playlist); /* EMIT SIGNAL */
3258 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3261 Glib::Mutex::Lock lm (playlist_lock);
3262 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3265 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3272 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3274 boost::shared_ptr<Playlist> pl(wpl.lock());
3280 PlaylistList::iterator x;
3283 /* its not supposed to be visible */
3288 Glib::Mutex::Lock lm (playlist_lock);
3292 unused_playlists.insert (pl);
3294 if ((x = playlists.find (pl)) != playlists.end()) {
3295 playlists.erase (x);
3301 playlists.insert (pl);
3303 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3304 unused_playlists.erase (x);
3311 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3313 if (_state_of_the_state & Deletion) {
3317 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3324 Glib::Mutex::Lock lm (playlist_lock);
3326 PlaylistList::iterator i;
3328 i = find (playlists.begin(), playlists.end(), playlist);
3329 if (i != playlists.end()) {
3330 playlists.erase (i);
3333 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3334 if (i != unused_playlists.end()) {
3335 unused_playlists.erase (i);
3342 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3346 Session::set_audition (boost::shared_ptr<Region> r)
3348 pending_audition_region = r;
3349 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3350 schedule_butler_transport_work ();
3354 Session::audition_playlist ()
3356 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3357 ev->region.reset ();
3362 Session::non_realtime_set_audition ()
3364 if (!pending_audition_region) {
3365 auditioner->audition_current_playlist ();
3367 auditioner->audition_region (pending_audition_region);
3368 pending_audition_region.reset ();
3370 AuditionActive (true); /* EMIT SIGNAL */
3374 Session::audition_region (boost::shared_ptr<Region> r)
3376 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3382 Session::cancel_audition ()
3384 if (auditioner->active()) {
3385 auditioner->cancel_audition ();
3386 AuditionActive (false); /* EMIT SIGNAL */
3391 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3393 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3397 Session::remove_empty_sounds ()
3399 vector<string> audio_filenames;
3401 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3403 Glib::Mutex::Lock lm (source_lock);
3405 TapeFileMatcher tape_file_matcher;
3407 remove_if (audio_filenames.begin(), audio_filenames.end(),
3408 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3410 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3412 sys::path audio_file_path (_session_dir->sound_path());
3414 audio_file_path /= *i;
3416 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3420 sys::remove (audio_file_path);
3421 const string peakfile = peak_path (audio_file_path.to_string());
3422 sys::remove (peakfile);
3424 catch (const sys::filesystem_error& err)
3426 error << err.what() << endmsg;
3433 Session::is_auditioning () const
3435 /* can be called before we have an auditioner object */
3437 return auditioner->active();
3444 Session::set_all_solo (bool yn)
3446 shared_ptr<RouteList> r = routes.reader ();
3448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3449 if (!(*i)->is_hidden()) {
3450 (*i)->set_solo (yn, this);
3458 Session::set_all_mute (bool yn)
3460 shared_ptr<RouteList> r = routes.reader ();
3462 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3463 if (!(*i)->is_hidden()) {
3464 (*i)->set_mute (yn, this);
3472 Session::n_diskstreams () const
3476 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3478 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3479 if (!(*i)->hidden()) {
3487 Session::graph_reordered ()
3489 /* don't do this stuff if we are setting up connections
3490 from a set_state() call or creating new tracks.
3493 if (_state_of_the_state & InitialConnecting) {
3497 /* every track/bus asked for this to be handled but it was deferred because
3498 we were connecting. do it now.
3501 request_input_change_handling ();
3505 /* force all diskstreams to update their capture offset values to
3506 reflect any changes in latencies within the graph.
3509 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3511 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3512 (*i)->set_capture_offset ();
3517 Session::record_disenable_all ()
3519 record_enable_change_all (false);
3523 Session::record_enable_all ()
3525 record_enable_change_all (true);
3529 Session::record_enable_change_all (bool yn)
3531 shared_ptr<RouteList> r = routes.reader ();
3533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3534 boost::shared_ptr<Track> t;
3536 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3537 t->set_record_enable (yn, this);
3541 /* since we don't keep rec-enable state, don't mark session dirty */
3545 Session::add_processor (Processor* processor)
3547 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3552 Session::remove_processor (Processor* processor)
3556 PortInsert* port_insert;
3558 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3559 insert_bitset[port_insert->bit_slot()] = false;
3560 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3561 send_bitset[send->bit_slot()] = false;
3562 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3563 return_bitset[send->bit_slot()] = false;
3570 Session::available_capture_duration ()
3572 float sample_bytes_on_disk = 4.0; // keep gcc happy
3574 switch (config.get_native_file_data_format()) {
3576 sample_bytes_on_disk = 4.0;
3580 sample_bytes_on_disk = 3.0;
3584 sample_bytes_on_disk = 2.0;
3588 /* impossible, but keep some gcc versions happy */
3589 fatal << string_compose (_("programming error: %1"),
3590 X_("illegal native file data format"))
3595 double scale = 4096.0 / sample_bytes_on_disk;
3597 if (_total_free_4k_blocks * scale > (double) max_frames) {
3601 return (nframes_t) floor (_total_free_4k_blocks * scale);
3605 Session::add_bundle (shared_ptr<Bundle> bundle)
3608 RCUWriter<BundleList> writer (_bundles);
3609 boost::shared_ptr<BundleList> b = writer.get_copy ();
3610 b->push_back (bundle);
3613 BundleAdded (bundle); /* EMIT SIGNAL */
3619 Session::remove_bundle (shared_ptr<Bundle> bundle)
3621 bool removed = false;
3624 RCUWriter<BundleList> writer (_bundles);
3625 boost::shared_ptr<BundleList> b = writer.get_copy ();
3626 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3628 if (i != b->end()) {
3635 BundleRemoved (bundle); /* EMIT SIGNAL */
3642 Session::bundle_by_name (string name) const
3644 boost::shared_ptr<BundleList> b = _bundles.reader ();
3646 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3647 if ((*i)->name() == name) {
3652 return boost::shared_ptr<Bundle> ();
3656 Session::tempo_map_changed (Change ignored)
3660 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3661 (*i)->update_after_tempo_map_change ();
3664 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3665 (*i)->update_after_tempo_map_change ();
3671 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3672 * the given count with the current block size.
3675 Session::ensure_buffers (ChanCount howmany)
3677 if (current_block_size == 0) {
3678 return; // too early? (is this ok?)
3681 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3682 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3683 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3684 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3685 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3688 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3692 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3694 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3695 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3700 Session::next_insert_id ()
3702 /* this doesn't really loop forever. just think about it */
3705 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3706 if (!insert_bitset[n]) {
3707 insert_bitset[n] = true;
3713 /* none available, so resize and try again */
3715 insert_bitset.resize (insert_bitset.size() + 16, false);
3720 Session::next_send_id ()
3722 /* this doesn't really loop forever. just think about it */
3725 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3726 if (!send_bitset[n]) {
3727 send_bitset[n] = true;
3733 /* none available, so resize and try again */
3735 send_bitset.resize (send_bitset.size() + 16, false);
3740 Session::next_return_id ()
3742 /* this doesn't really loop forever. just think about it */
3745 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3746 if (!return_bitset[n]) {
3747 return_bitset[n] = true;
3753 /* none available, so resize and try again */
3755 return_bitset.resize (return_bitset.size() + 16, false);
3760 Session::mark_send_id (uint32_t id)
3762 if (id >= send_bitset.size()) {
3763 send_bitset.resize (id+16, false);
3765 if (send_bitset[id]) {
3766 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3768 send_bitset[id] = true;
3772 Session::mark_return_id (uint32_t id)
3774 if (id >= return_bitset.size()) {
3775 return_bitset.resize (id+16, false);
3777 if (return_bitset[id]) {
3778 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3780 return_bitset[id] = true;
3784 Session::mark_insert_id (uint32_t id)
3786 if (id >= insert_bitset.size()) {
3787 insert_bitset.resize (id+16, false);
3789 if (insert_bitset[id]) {
3790 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3792 insert_bitset[id] = true;
3795 /* Named Selection management */
3798 Session::named_selection_by_name (string name)
3800 Glib::Mutex::Lock lm (named_selection_lock);
3801 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3802 if ((*i)->name == name) {
3810 Session::add_named_selection (NamedSelection* named_selection)
3813 Glib::Mutex::Lock lm (named_selection_lock);
3814 named_selections.insert (named_selections.begin(), named_selection);
3817 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3823 NamedSelectionAdded (); /* EMIT SIGNAL */
3827 Session::remove_named_selection (NamedSelection* named_selection)
3829 bool removed = false;
3832 Glib::Mutex::Lock lm (named_selection_lock);
3834 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3836 if (i != named_selections.end()) {
3838 named_selections.erase (i);
3845 NamedSelectionRemoved (); /* EMIT SIGNAL */
3850 Session::reset_native_file_format ()
3852 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3854 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3855 (*i)->reset_write_sources (false);
3860 Session::route_name_unique (string n) const
3862 shared_ptr<RouteList> r = routes.reader ();
3864 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3865 if ((*i)->name() == n) {
3874 Session::route_name_internal (string n) const
3876 if (auditioner && auditioner->name() == n) {
3880 if (_click_io && _click_io->name() == n) {
3888 Session::n_playlists () const
3890 Glib::Mutex::Lock lm (playlist_lock);
3891 return playlists.size();
3895 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3897 if (!force && howmany <= _npan_buffers) {
3901 if (_pan_automation_buffer) {
3903 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3904 delete [] _pan_automation_buffer[i];
3907 delete [] _pan_automation_buffer;
3910 _pan_automation_buffer = new pan_t*[howmany];
3912 for (uint32_t i = 0; i < howmany; ++i) {
3913 _pan_automation_buffer[i] = new pan_t[nframes];
3916 _npan_buffers = howmany;
3920 Session::freeze (InterThreadInfo& itt)
3922 shared_ptr<RouteList> r = routes.reader ();
3924 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3926 boost::shared_ptr<Track> t;
3928 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3929 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3939 boost::shared_ptr<Region>
3940 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3941 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
3942 InterThreadInfo& itt, bool enable_processing)
3944 boost::shared_ptr<Region> result;
3945 boost::shared_ptr<Playlist> playlist;
3946 boost::shared_ptr<AudioFileSource> fsource;
3948 char buf[PATH_MAX+1];
3949 ChanCount nchans(track.audio_diskstream()->n_channels());
3951 nframes_t this_chunk;
3954 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3955 const string sound_dir = sdir.sound_path().to_string();
3956 nframes_t len = end - start;
3959 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3960 end, start) << endmsg;
3964 // any bigger than this seems to cause stack overflows in called functions
3965 const nframes_t chunk_size = (128 * 1024)/4;
3967 // block all process callback handling
3969 block_processing ();
3971 /* call tree *MUST* hold route_lock */
3973 if ((playlist = track.diskstream()->playlist()) == 0) {
3977 /* external redirects will be a problem */
3979 if (track.has_external_redirects()) {
3983 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3985 for (x = 0; x < 99999; ++x) {
3986 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3987 if (access (buf, F_OK) != 0) {
3993 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3998 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3999 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4002 catch (failed_constructor& err) {
4003 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4007 srcs.push_back (fsource);
4010 /* XXX need to flush all redirects */
4015 /* create a set of reasonably-sized buffers */
4016 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4017 buffers.set_count(nchans);
4019 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4020 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4022 afs->prepare_for_peakfile_writes ();
4025 while (to_do && !itt.cancel) {
4027 this_chunk = min (to_do, chunk_size);
4029 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4034 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4035 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4038 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4044 start += this_chunk;
4045 to_do -= this_chunk;
4047 itt.progress = (float) (1.0 - ((double) to_do / len));
4056 xnow = localtime (&now);
4058 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4059 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4062 afs->update_header (position, *xnow, now);
4063 afs->flush_header ();
4067 /* construct a region to represent the bounced material */
4069 result = RegionFactory::create (srcs, 0,
4070 srcs.front()->length(srcs.front()->timeline_position()),
4071 region_name_from_path (srcs.front()->name(), true));
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->mark_for_remove ();
4083 (*src)->drop_references ();
4087 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4088 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4091 afs->done_with_peakfile_writes ();
4095 unblock_processing ();
4101 Session::get_silent_buffers (ChanCount count)
4103 assert(_silent_buffers->available() >= count);
4104 _silent_buffers->set_count(count);
4106 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4107 for (size_t i= 0; i < count.get(*t); ++i) {
4108 _silent_buffers->get(*t, i).clear();
4112 return *_silent_buffers;
4116 Session::get_scratch_buffers (ChanCount count)
4118 if (count != ChanCount::ZERO) {
4119 assert(_scratch_buffers->available() >= count);
4120 _scratch_buffers->set_count(count);
4122 _scratch_buffers->set_count (_scratch_buffers->available());
4125 return *_scratch_buffers;
4129 Session::get_mix_buffers (ChanCount count)
4131 assert(_mix_buffers->available() >= count);
4132 _mix_buffers->set_count(count);
4133 return *_mix_buffers;
4137 Session::ntracks () const
4140 shared_ptr<RouteList> r = routes.reader ();
4142 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4143 if (boost::dynamic_pointer_cast<Track> (*i)) {
4152 Session::nbusses () const
4155 shared_ptr<RouteList> r = routes.reader ();
4157 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4158 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4167 Session::add_automation_list(AutomationList *al)
4169 automation_lists[al->id()] = al;
4173 Session::compute_initial_length ()
4175 return _engine.frame_rate() * 60 * 5;
4179 Session::sync_order_keys (const char* base)
4181 if (!Config->get_sync_all_route_ordering()) {
4182 /* leave order keys as they are */
4186 boost::shared_ptr<RouteList> r = routes.reader ();
4188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4189 (*i)->sync_order_keys (base);
4192 Route::SyncOrderKeys (base); // EMIT SIGNAL
4196 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4198 Session::have_rec_enabled_diskstream () const
4200 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4203 /** Update the state of our rec-enabled diskstreams flag */
4205 Session::update_have_rec_enabled_diskstream ()
4207 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4208 DiskstreamList::iterator i = dsl->begin ();
4209 while (i != dsl->end () && (*i)->record_enabled () == false) {
4213 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4215 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4217 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4218 RecordStateChanged (); /* EMIT SIGNAL */
4223 Session::solo_model_changed ()
4227 switch (Config->get_solo_model()) {
4240 boost::shared_ptr<RouteList> r = routes.reader ();
4242 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4243 (*i)->put_control_outs_at (p);