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);
794 /* now handle the whole enchilada as if it was one
800 /* update mixer solo state */
806 Session::playlist_length_changed ()
808 /* we can't just increase end_location->end() if pl->get_maximum_extent()
809 if larger. if the playlist used to be the longest playlist,
810 and its now shorter, we have to decrease end_location->end(). hence,
811 we have to iterate over all diskstreams and check the
812 playlists currently in use.
818 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
820 boost::shared_ptr<Playlist> playlist;
822 if ((playlist = dstream->playlist()) != 0) {
823 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
826 /* see comment in playlist_length_changed () */
831 Session::record_enabling_legal () const
833 /* this used to be in here, but survey says.... we don't need to restrict it */
834 // if (record_status() == Recording) {
838 if (Config->get_all_safe()) {
845 Session::reset_input_monitor_state ()
847 if (transport_rolling()) {
849 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
851 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
852 if ((*i)->record_enabled ()) {
853 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
854 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
858 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
860 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
861 if ((*i)->record_enabled ()) {
862 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
863 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
870 Session::auto_punch_start_changed (Location* location)
872 replace_event (Event::PunchIn, location->start());
874 if (get_record_enabled() && config.get_punch_in()) {
875 /* capture start has been changed, so save new pending state */
876 save_state ("", true);
881 Session::auto_punch_end_changed (Location* location)
883 nframes_t when_to_stop = location->end();
884 // when_to_stop += _worst_output_latency + _worst_input_latency;
885 replace_event (Event::PunchOut, when_to_stop);
889 Session::auto_punch_changed (Location* location)
891 nframes_t when_to_stop = location->end();
893 replace_event (Event::PunchIn, location->start());
894 //when_to_stop += _worst_output_latency + _worst_input_latency;
895 replace_event (Event::PunchOut, when_to_stop);
899 Session::auto_loop_changed (Location* location)
901 replace_event (Event::AutoLoop, location->end(), location->start());
903 if (transport_rolling() && play_loop) {
905 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
907 if (_transport_frame > location->end()) {
908 // relocate to beginning of loop
909 clear_events (Event::LocateRoll);
911 request_locate (location->start(), true);
914 else if (Config->get_seamless_loop() && !loop_changing) {
916 // schedule a locate-roll to refill the diskstreams at the
918 loop_changing = true;
920 if (location->end() > last_loopend) {
921 clear_events (Event::LocateRoll);
922 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
929 last_loopend = location->end();
933 Session::set_auto_punch_location (Location* location)
937 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
938 auto_punch_start_changed_connection.disconnect();
939 auto_punch_end_changed_connection.disconnect();
940 auto_punch_changed_connection.disconnect();
941 existing->set_auto_punch (false, this);
942 remove_event (existing->start(), Event::PunchIn);
943 clear_events (Event::PunchOut);
944 auto_punch_location_changed (0);
953 if (location->end() <= location->start()) {
954 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
958 auto_punch_start_changed_connection.disconnect();
959 auto_punch_end_changed_connection.disconnect();
960 auto_punch_changed_connection.disconnect();
962 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
963 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
964 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
966 location->set_auto_punch (true, this);
969 auto_punch_changed (location);
971 auto_punch_location_changed (location);
975 Session::set_auto_loop_location (Location* location)
979 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
980 auto_loop_start_changed_connection.disconnect();
981 auto_loop_end_changed_connection.disconnect();
982 auto_loop_changed_connection.disconnect();
983 existing->set_auto_loop (false, this);
984 remove_event (existing->end(), Event::AutoLoop);
985 auto_loop_location_changed (0);
994 if (location->end() <= location->start()) {
995 error << _("Session: you can't use a mark for auto loop") << endmsg;
999 last_loopend = location->end();
1001 auto_loop_start_changed_connection.disconnect();
1002 auto_loop_end_changed_connection.disconnect();
1003 auto_loop_changed_connection.disconnect();
1005 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1006 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1007 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1009 location->set_auto_loop (true, this);
1011 /* take care of our stuff first */
1013 auto_loop_changed (location);
1015 /* now tell everyone else */
1017 auto_loop_location_changed (location);
1021 Session::locations_added (Location* ignored)
1027 Session::locations_changed ()
1029 _locations.apply (*this, &Session::handle_locations_changed);
1033 Session::handle_locations_changed (Locations::LocationList& locations)
1035 Locations::LocationList::iterator i;
1037 bool set_loop = false;
1038 bool set_punch = false;
1040 for (i = locations.begin(); i != locations.end(); ++i) {
1044 if (location->is_auto_punch()) {
1045 set_auto_punch_location (location);
1048 if (location->is_auto_loop()) {
1049 set_auto_loop_location (location);
1053 if (location->is_start()) {
1054 start_location = location;
1056 if (location->is_end()) {
1057 end_location = location;
1062 set_auto_loop_location (0);
1065 set_auto_punch_location (0);
1072 Session::enable_record ()
1074 /* XXX really atomic compare+swap here */
1075 if (g_atomic_int_get (&_record_status) != Recording) {
1076 g_atomic_int_set (&_record_status, Recording);
1077 _last_record_location = _transport_frame;
1078 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1080 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1081 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1082 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1083 if ((*i)->record_enabled ()) {
1084 (*i)->monitor_input (true);
1089 RecordStateChanged ();
1094 Session::disable_record (bool rt_context, bool force)
1098 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1100 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1101 g_atomic_int_set (&_record_status, Disabled);
1103 if (rs == Recording) {
1104 g_atomic_int_set (&_record_status, Enabled);
1108 // FIXME: timestamp correct? [DR]
1109 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1110 // does this /need/ to be sent in all cases?
1112 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1114 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1117 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1118 if ((*i)->record_enabled ()) {
1119 (*i)->monitor_input (false);
1124 RecordStateChanged (); /* emit signal */
1127 remove_pending_capture_state ();
1133 Session::step_back_from_record ()
1135 /* XXX really atomic compare+swap here */
1136 if (g_atomic_int_get (&_record_status) == Recording) {
1137 g_atomic_int_set (&_record_status, Enabled);
1139 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1140 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1142 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1143 if ((*i)->record_enabled ()) {
1144 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1145 (*i)->monitor_input (false);
1153 Session::maybe_enable_record ()
1155 g_atomic_int_set (&_record_status, Enabled);
1157 /* this function is currently called from somewhere other than an RT thread.
1158 this save_state() call therefore doesn't impact anything.
1161 save_state ("", true);
1163 if (_transport_speed) {
1164 if (!config.get_punch_in()) {
1168 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1169 RecordStateChanged (); /* EMIT SIGNAL */
1176 Session::audible_frame () const
1182 /* the first of these two possible settings for "offset"
1183 mean that the audible frame is stationary until
1184 audio emerges from the latency compensation
1187 the second means that the audible frame is stationary
1188 until audio would emerge from a physical port
1189 in the absence of any plugin latency compensation
1192 offset = _worst_output_latency;
1194 if (offset > current_block_size) {
1195 offset -= current_block_size;
1197 /* XXX is this correct? if we have no external
1198 physical connections and everything is internal
1199 then surely this is zero? still, how
1200 likely is that anyway?
1202 offset = current_block_size;
1205 if (synced_to_jack()) {
1206 tf = _engine.transport_frame();
1208 tf = _transport_frame;
1213 if (!non_realtime_work_pending()) {
1217 /* check to see if we have passed the first guaranteed
1218 audible frame past our last start position. if not,
1219 return that last start point because in terms
1220 of audible frames, we have not moved yet.
1223 if (_transport_speed > 0.0f) {
1225 if (!play_loop || !have_looped) {
1226 if (tf < _last_roll_location + offset) {
1227 return _last_roll_location;
1235 } else if (_transport_speed < 0.0f) {
1237 /* XXX wot? no backward looping? */
1239 if (tf > _last_roll_location - offset) {
1240 return _last_roll_location;
1252 Session::set_frame_rate (nframes_t frames_per_second)
1254 /** \fn void Session::set_frame_size(nframes_t)
1255 the AudioEngine object that calls this guarantees
1256 that it will not be called while we are also in
1257 ::process(). Its fine to do things that block
1261 _base_frame_rate = frames_per_second;
1265 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1269 // XXX we need some equivalent to this, somehow
1270 // SndFileSource::setup_standard_crossfades (frames_per_second);
1274 /* XXX need to reset/reinstantiate all LADSPA plugins */
1278 Session::set_block_size (nframes_t nframes)
1280 /* the AudioEngine guarantees
1281 that it will not be called while we are also in
1282 ::process(). It is therefore fine to do things that block
1287 current_block_size = nframes;
1289 ensure_buffers(_scratch_buffers->available());
1291 delete [] _gain_automation_buffer;
1292 _gain_automation_buffer = new gain_t[nframes];
1294 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1296 boost::shared_ptr<RouteList> r = routes.reader ();
1298 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1299 (*i)->set_block_size (nframes);
1302 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1303 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1304 (*i)->set_block_size (nframes);
1307 set_worst_io_latencies ();
1312 Session::set_default_fade (float steepness, float fade_msecs)
1315 nframes_t fade_frames;
1317 /* Don't allow fade of less 1 frame */
1319 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1326 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1330 default_fade_msecs = fade_msecs;
1331 default_fade_steepness = steepness;
1334 // jlc, WTF is this!
1335 Glib::RWLock::ReaderLock lm (route_lock);
1336 AudioRegion::set_default_fade (steepness, fade_frames);
1341 /* XXX have to do this at some point */
1342 /* foreach region using default fade, reset, then
1343 refill_all_diskstream_buffers ();
1348 struct RouteSorter {
1349 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1350 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1352 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1355 if (r1->fed_by.empty()) {
1356 if (r2->fed_by.empty()) {
1357 /* no ardour-based connections inbound to either route. just use signal order */
1358 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1360 /* r2 has connections, r1 does not; run r1 early */
1364 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1371 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1373 shared_ptr<Route> r2;
1375 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1376 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1380 /* make a copy of the existing list of routes that feed r1 */
1382 set<shared_ptr<Route> > existing = r1->fed_by;
1384 /* for each route that feeds r1, recurse, marking it as feeding
1388 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1391 /* r2 is a route that feeds r1 which somehow feeds base. mark
1392 base as being fed by r2
1395 rbase->fed_by.insert (r2);
1399 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1403 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1407 /* now recurse, so that we can mark base as being fed by
1408 all routes that feed r2
1411 trace_terminal (r2, rbase);
1418 Session::resort_routes ()
1420 /* don't do anything here with signals emitted
1421 by Routes while we are being destroyed.
1424 if (_state_of_the_state & Deletion) {
1431 RCUWriter<RouteList> writer (routes);
1432 shared_ptr<RouteList> r = writer.get_copy ();
1433 resort_routes_using (r);
1434 /* writer goes out of scope and forces update */
1439 Session::resort_routes_using (shared_ptr<RouteList> r)
1441 RouteList::iterator i, j;
1443 for (i = r->begin(); i != r->end(); ++i) {
1445 (*i)->fed_by.clear ();
1447 for (j = r->begin(); j != r->end(); ++j) {
1449 /* although routes can feed themselves, it will
1450 cause an endless recursive descent if we
1451 detect it. so don't bother checking for
1459 if ((*j)->feeds (*i)) {
1460 (*i)->fed_by.insert (*j);
1465 for (i = r->begin(); i != r->end(); ++i) {
1466 trace_terminal (*i, *i);
1473 cerr << "finished route resort\n";
1475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1476 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1483 list<boost::shared_ptr<MidiTrack> >
1484 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1486 char track_name[32];
1487 uint32_t track_id = 0;
1490 RouteList new_routes;
1491 list<boost::shared_ptr<MidiTrack> > ret;
1492 //uint32_t control_id;
1494 // FIXME: need physical I/O and autoconnect stuff for MIDI
1496 /* count existing midi tracks */
1499 shared_ptr<RouteList> r = routes.reader ();
1501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1502 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1503 if (!(*i)->is_hidden()) {
1505 //channels_used += (*i)->n_inputs().n_midi();
1511 vector<string> physinputs;
1512 vector<string> physoutputs;
1514 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1515 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1517 // control_id = ntracks() + nbusses();
1521 /* check for duplicate route names, since we might have pre-existing
1522 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1523 save, close,restart,add new route - first named route is now
1531 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1533 if (route_by_name (track_name) == 0) {
1537 } while (track_id < (UINT_MAX-1));
1539 shared_ptr<MidiTrack> track;
1542 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1544 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1545 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1550 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1551 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1557 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1561 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1562 port = physinputs[(channels_used+x)%nphysical_in];
1565 if (port.length() && track->connect_input (track->input (x), port, this)) {
1571 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1575 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1576 port = physoutputs[(channels_used+x)%nphysical_out];
1577 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1579 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1583 if (port.length() && track->connect_output (track->output (x), port, this)) {
1588 channels_used += track->n_inputs ().n_midi();
1592 track->midi_diskstream()->non_realtime_input_change();
1594 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1595 //track->set_remote_control_id (control_id);
1597 new_routes.push_back (track);
1598 ret.push_back (track);
1601 catch (failed_constructor &err) {
1602 error << _("Session: could not create new midi track.") << endmsg;
1605 /* we need to get rid of this, since the track failed to be created */
1606 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1609 RCUWriter<DiskstreamList> writer (diskstreams);
1610 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1611 ds->remove (track->midi_diskstream());
1618 catch (AudioEngine::PortRegistrationFailure& pfe) {
1620 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;
1623 /* we need to get rid of this, since the track failed to be created */
1624 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1627 RCUWriter<DiskstreamList> writer (diskstreams);
1628 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1629 ds->remove (track->midi_diskstream());
1640 if (!new_routes.empty()) {
1641 add_routes (new_routes, false);
1642 save_state (_current_snapshot_name);
1648 list<boost::shared_ptr<AudioTrack> >
1649 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1651 char track_name[32];
1652 uint32_t track_id = 0;
1654 uint32_t channels_used = 0;
1656 RouteList new_routes;
1657 list<boost::shared_ptr<AudioTrack> > ret;
1658 uint32_t control_id;
1660 /* count existing audio tracks */
1663 shared_ptr<RouteList> r = routes.reader ();
1665 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1666 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1667 if (!(*i)->is_hidden()) {
1669 channels_used += (*i)->n_inputs().n_audio();
1675 vector<string> physinputs;
1676 vector<string> physoutputs;
1678 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1679 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1681 control_id = ntracks() + nbusses() + 1;
1685 /* check for duplicate route names, since we might have pre-existing
1686 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1687 save, close,restart,add new route - first named route is now
1695 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1697 if (route_by_name (track_name) == 0) {
1701 } while (track_id < (UINT_MAX-1));
1703 shared_ptr<AudioTrack> track;
1706 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1708 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1709 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1710 input_channels, output_channels)
1715 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1716 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1717 input_channels, output_channels)
1722 if (!physinputs.empty()) {
1723 uint32_t nphysical_in = physinputs.size();
1725 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1729 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1730 port = physinputs[(channels_used+x)%nphysical_in];
1733 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1739 if (!physoutputs.empty()) {
1740 uint32_t nphysical_out = physoutputs.size();
1742 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1745 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1746 port = physoutputs[(channels_used+x)%nphysical_out];
1747 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1748 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1749 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1753 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1759 channels_used += track->n_inputs ().n_audio();
1761 track->audio_diskstream()->non_realtime_input_change();
1763 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1764 track->set_remote_control_id (control_id);
1767 new_routes.push_back (track);
1768 ret.push_back (track);
1771 catch (failed_constructor &err) {
1772 error << _("Session: could not create new audio track.") << endmsg;
1775 /* we need to get rid of this, since the track failed to be created */
1776 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1779 RCUWriter<DiskstreamList> writer (diskstreams);
1780 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1781 ds->remove (track->audio_diskstream());
1788 catch (AudioEngine::PortRegistrationFailure& pfe) {
1790 error << pfe.what() << endmsg;
1793 /* we need to get rid of this, since the track failed to be created */
1794 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1797 RCUWriter<DiskstreamList> writer (diskstreams);
1798 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1799 ds->remove (track->audio_diskstream());
1810 if (!new_routes.empty()) {
1811 add_routes (new_routes, true);
1818 Session::set_remote_control_ids ()
1820 RemoteModel m = Config->get_remote_model();
1822 shared_ptr<RouteList> r = routes.reader ();
1824 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1825 if ( MixerOrdered == m) {
1826 long order = (*i)->order_key(N_("signal"));
1827 (*i)->set_remote_control_id( order+1 );
1828 } else if ( EditorOrdered == m) {
1829 long order = (*i)->order_key(N_("editor"));
1830 (*i)->set_remote_control_id( order+1 );
1831 } else if ( UserOrdered == m) {
1832 //do nothing ... only changes to remote id's are initiated by user
1839 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1842 uint32_t bus_id = 1;
1844 uint32_t channels_used = 0;
1847 uint32_t control_id;
1849 /* count existing audio busses */
1852 shared_ptr<RouteList> r = routes.reader ();
1854 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1855 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1857 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1860 channels_used += (*i)->n_inputs().n_audio();
1866 vector<string> physinputs;
1867 vector<string> physoutputs;
1869 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1870 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1872 n_physical_audio_outputs = physoutputs.size();
1873 n_physical_audio_inputs = physinputs.size();
1875 control_id = ntracks() + nbusses() + 1;
1880 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1884 if (route_by_name (bus_name) == 0) {
1888 } while (bus_id < (UINT_MAX-1));
1891 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1893 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1894 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1895 input_channels, output_channels)
1901 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1902 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1903 input_channels, output_channels)
1908 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1911 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1912 port = physinputs[((n+x)%n_physical_audio_inputs)];
1915 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1920 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1923 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1924 port = physoutputs[((n+x)%n_physical_outputs)];
1925 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1927 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1931 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1936 channels_used += bus->n_inputs ().n_audio();
1938 bus->set_remote_control_id (control_id);
1941 ret.push_back (bus);
1945 catch (failed_constructor &err) {
1946 error << _("Session: could not create new audio route.") << endmsg;
1950 catch (AudioEngine::PortRegistrationFailure& pfe) {
1951 error << pfe.what() << endmsg;
1961 add_routes (ret, true);
1969 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1973 uint32_t control_id;
1976 if (!tree.read (template_path.c_str())) {
1980 XMLNode* node = tree.root();
1982 control_id = ntracks() + nbusses() + 1;
1986 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1988 std::string node_name = IO::name_from_state (*node_copy.children().front());
1990 if (route_by_name (node_name) != 0) {
1992 /* generate a new name by adding a number to the end of the template name */
1994 uint32_t number = 1;
1997 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2001 if (route_by_name (name) == 0) {
2005 } while (number < UINT_MAX);
2007 if (number == UINT_MAX) {
2008 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2012 IO::set_name_in_state (*node_copy.children().front(), name);
2015 Track::zero_diskstream_id_in_xml (node_copy);
2018 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2021 error << _("Session: cannot create track/bus from template description") << endmsg;
2025 if (boost::dynamic_pointer_cast<Track>(route)) {
2026 /* force input/output change signals so that the new diskstream
2027 picks up the configuration of the route. During session
2028 loading this normally happens in a different way.
2030 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2031 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2034 route->set_remote_control_id (control_id);
2037 ret.push_back (route);
2040 catch (failed_constructor &err) {
2041 error << _("Session: could not create new route from template") << endmsg;
2045 catch (AudioEngine::PortRegistrationFailure& pfe) {
2046 error << pfe.what() << endmsg;
2055 add_routes (ret, true);
2062 Session::add_routes (RouteList& new_routes, bool save)
2065 RCUWriter<RouteList> writer (routes);
2066 shared_ptr<RouteList> r = writer.get_copy ();
2067 r->insert (r->end(), new_routes.begin(), new_routes.end());
2069 if (!_control_out && IO::connecting_legal) {
2070 resort_routes_using (r);
2074 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2076 boost::weak_ptr<Route> wpr (*x);
2078 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2079 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2080 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2081 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2083 if ((*x)->is_master()) {
2087 if ((*x)->is_control()) {
2088 _control_out = (*x);
2092 if (_control_out && IO::connecting_legal) {
2094 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2095 (*x)->listen_via (_control_out, "control");
2104 save_state (_current_snapshot_name);
2107 RouteAdded (new_routes); /* EMIT SIGNAL */
2111 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2113 /* need to do this in case we're rolling at the time, to prevent false underruns */
2114 dstream->do_refill_with_alloc ();
2116 dstream->set_block_size (current_block_size);
2119 RCUWriter<DiskstreamList> writer (diskstreams);
2120 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2121 ds->push_back (dstream);
2122 /* writer goes out of scope, copies ds back to main */
2125 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2126 /* this will connect to future changes, and check the current length */
2127 diskstream_playlist_changed (dstream);
2129 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2131 dstream->prepare ();
2136 Session::remove_route (shared_ptr<Route> route)
2139 RCUWriter<RouteList> writer (routes);
2140 shared_ptr<RouteList> rs = writer.get_copy ();
2144 /* deleting the master out seems like a dumb
2145 idea, but its more of a UI policy issue
2149 if (route == _master_out) {
2150 _master_out = shared_ptr<Route> ();
2153 if (route == _control_out) {
2155 /* cancel control outs for all routes */
2157 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2158 (*r)->drop_listen (_control_out);
2161 _control_out.reset ();
2164 update_route_solo_state ();
2166 /* writer goes out of scope, forces route list update */
2169 boost::shared_ptr<Track> t;
2170 boost::shared_ptr<Diskstream> ds;
2172 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2173 ds = t->diskstream();
2179 RCUWriter<DiskstreamList> dsl (diskstreams);
2180 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2185 find_current_end ();
2187 // We need to disconnect the routes inputs and outputs
2189 route->input()->disconnect (0);
2190 route->output()->disconnect (0);
2192 update_latency_compensation (false, false);
2195 /* get rid of it from the dead wood collection in the route list manager */
2197 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2201 /* try to cause everyone to drop their references */
2203 route->drop_references ();
2205 sync_order_keys (N_("session"));
2207 /* save the new state of the world */
2209 if (save_state (_current_snapshot_name)) {
2210 save_history (_current_snapshot_name);
2215 Session::route_mute_changed (void* src)
2221 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2223 if (solo_update_disabled) {
2228 boost::shared_ptr<Route> route = wpr.lock ();
2231 /* should not happen */
2232 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2236 shared_ptr<RouteList> r = routes.reader ();
2239 if (route->soloed()) {
2245 solo_update_disabled = true;
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 if ((*i)->feeds (route)) {
2251 (*i)->main_outs()->mod_solo_level (delta);
2255 /* make sure master is never muted by solo */
2257 if (_master_out->main_outs()->solo_level() == 0) {
2258 _master_out->main_outs()->mod_solo_level (1);
2261 solo_update_disabled = false;
2262 update_route_solo_state (r);
2263 SoloChanged (); /* EMIT SIGNAL */
2268 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2270 /* now figure out if anything that matters is soloed */
2272 bool something_soloed = false;
2275 r = routes.reader();
2278 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2279 if (!(*i)->is_master() && !(*i)->is_hidden() && (*i)->soloed()) {
2280 something_soloed = true;
2285 if (something_soloed != _non_soloed_outs_muted) {
2286 _non_soloed_outs_muted = something_soloed;
2287 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2292 Session::catch_up_on_solo ()
2294 /* this is called after set_state() to catch the full solo
2295 state, which can't be correctly determined on a per-route
2296 basis, but needs the global overview that only the session
2299 update_route_solo_state();
2303 Session::catch_up_on_solo_mute_override ()
2305 if (Config->get_solo_model() != InverseMute) {
2309 /* this is called whenever the param solo-mute-override is
2312 shared_ptr<RouteList> r = routes.reader ();
2314 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2315 // (*i)->catch_up_on_solo_mute_override ();
2320 Session::route_by_name (string name)
2322 shared_ptr<RouteList> r = routes.reader ();
2324 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2325 if ((*i)->name() == name) {
2330 return shared_ptr<Route> ((Route*) 0);
2334 Session::route_by_id (PBD::ID id)
2336 shared_ptr<RouteList> r = routes.reader ();
2338 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2339 if ((*i)->id() == id) {
2344 return shared_ptr<Route> ((Route*) 0);
2348 Session::route_by_remote_id (uint32_t id)
2350 shared_ptr<RouteList> r = routes.reader ();
2352 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2353 if ((*i)->remote_control_id() == id) {
2358 return shared_ptr<Route> ((Route*) 0);
2362 Session::find_current_end ()
2364 if (_state_of_the_state & Loading) {
2368 nframes_t max = get_maximum_extent ();
2370 if (max > end_location->end()) {
2371 end_location->set_end (max);
2373 DurationChanged(); /* EMIT SIGNAL */
2378 Session::get_maximum_extent () const
2383 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2385 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2386 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2388 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2389 if ((me = pl->get_maximum_extent()) > max) {
2397 boost::shared_ptr<Diskstream>
2398 Session::diskstream_by_name (string name)
2400 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2402 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2403 if ((*i)->name() == name) {
2408 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2411 boost::shared_ptr<Diskstream>
2412 Session::diskstream_by_id (const PBD::ID& id)
2414 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2416 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2417 if ((*i)->id() == id) {
2422 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2425 /* Region management */
2428 Session::new_region_name (string old)
2430 string::size_type last_period;
2432 string::size_type len = old.length() + 64;
2435 if ((last_period = old.find_last_of ('.')) == string::npos) {
2437 /* no period present - add one explicitly */
2440 last_period = old.length() - 1;
2445 number = atoi (old.substr (last_period+1).c_str());
2449 while (number < (UINT_MAX-1)) {
2451 RegionList::const_iterator i;
2456 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2459 for (i = regions.begin(); i != regions.end(); ++i) {
2460 if (i->second->name() == sbuf) {
2465 if (i == regions.end()) {
2470 if (number != (UINT_MAX-1)) {
2474 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2479 Session::region_name (string& result, string base, bool newlevel)
2484 if (base.find("/") != string::npos) {
2485 base = base.substr(base.find_last_of("/") + 1);
2490 Glib::Mutex::Lock lm (region_lock);
2492 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2501 string::size_type pos;
2503 pos = base.find_last_of ('.');
2505 /* pos may be npos, but then we just use entire base */
2507 subbase = base.substr (0, pos);
2512 Glib::Mutex::Lock lm (region_lock);
2514 map<string,uint32_t>::iterator x;
2518 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2520 region_name_map[subbase] = 1;
2523 snprintf (buf, sizeof (buf), ".%d", x->second);
2534 Session::add_region (boost::shared_ptr<Region> region)
2536 vector<boost::shared_ptr<Region> > v;
2537 v.push_back (region);
2542 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2547 Glib::Mutex::Lock lm (region_lock);
2549 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2551 boost::shared_ptr<Region> region = *ii;
2555 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2559 RegionList::iterator x;
2561 for (x = regions.begin(); x != regions.end(); ++x) {
2563 if (region->region_list_equivalent (x->second)) {
2568 if (x == regions.end()) {
2570 pair<RegionList::key_type,RegionList::mapped_type> entry;
2572 entry.first = region->id();
2573 entry.second = region;
2575 pair<RegionList::iterator,bool> x = regions.insert (entry);
2587 /* mark dirty because something has changed even if we didn't
2588 add the region to the region list.
2595 vector<boost::weak_ptr<Region> > v;
2596 boost::shared_ptr<Region> first_r;
2598 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2600 boost::shared_ptr<Region> region = *ii;
2604 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2607 v.push_back (region);
2614 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2615 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2617 update_region_name_map (region);
2621 RegionsAdded (v); /* EMIT SIGNAL */
2627 Session::update_region_name_map (boost::shared_ptr<Region> region)
2629 string::size_type last_period = region->name().find_last_of ('.');
2631 if (last_period != string::npos && last_period < region->name().length() - 1) {
2633 string base = region->name().substr (0, last_period);
2634 string number = region->name().substr (last_period+1);
2635 map<string,uint32_t>::iterator x;
2637 /* note that if there is no number, we get zero from atoi,
2641 region_name_map[base] = atoi (number);
2646 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2648 boost::shared_ptr<Region> region (weak_region.lock ());
2654 if (what_changed & Region::HiddenChanged) {
2655 /* relay hidden changes */
2656 RegionHiddenChange (region);
2659 if (what_changed & NameChanged) {
2660 update_region_name_map (region);
2665 Session::remove_region (boost::weak_ptr<Region> weak_region)
2667 RegionList::iterator i;
2668 boost::shared_ptr<Region> region (weak_region.lock ());
2674 bool removed = false;
2677 Glib::Mutex::Lock lm (region_lock);
2679 if ((i = regions.find (region->id())) != regions.end()) {
2685 /* mark dirty because something has changed even if we didn't
2686 remove the region from the region list.
2692 RegionRemoved(region); /* EMIT SIGNAL */
2696 boost::shared_ptr<Region>
2697 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2699 RegionList::iterator i;
2700 boost::shared_ptr<Region> region;
2702 Glib::Mutex::Lock lm (region_lock);
2704 for (i = regions.begin(); i != regions.end(); ++i) {
2708 if (region->whole_file()) {
2710 if (child->source_equivalent (region)) {
2716 return boost::shared_ptr<Region> ();
2720 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2722 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2723 (*i)->get_region_list_equivalent_regions (region, result);
2727 Session::destroy_region (boost::shared_ptr<Region> region)
2729 vector<boost::shared_ptr<Source> > srcs;
2732 if (region->playlist()) {
2733 region->playlist()->destroy_region (region);
2736 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2737 srcs.push_back (region->source (n));
2741 region->drop_references ();
2743 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2745 (*i)->mark_for_remove ();
2746 (*i)->drop_references ();
2748 cerr << "source was not used by any playlist\n";
2755 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2757 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2758 destroy_region (*i);
2764 Session::remove_last_capture ()
2766 list<boost::shared_ptr<Region> > r;
2768 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2770 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2771 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2774 r.insert (r.end(), l.begin(), l.end());
2779 destroy_regions (r);
2781 save_state (_current_snapshot_name);
2787 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2793 /* Source Management */
2796 Session::add_source (boost::shared_ptr<Source> source)
2798 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2799 pair<SourceMap::iterator,bool> result;
2801 entry.first = source->id();
2802 entry.second = source;
2805 Glib::Mutex::Lock lm (source_lock);
2806 result = sources.insert (entry);
2809 if (result.second) {
2810 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2814 boost::shared_ptr<AudioFileSource> afs;
2816 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2817 if (Config->get_auto_analyse_audio()) {
2818 Analyser::queue_source_for_analysis (source, false);
2824 Session::remove_source (boost::weak_ptr<Source> src)
2826 SourceMap::iterator i;
2827 boost::shared_ptr<Source> source = src.lock();
2834 Glib::Mutex::Lock lm (source_lock);
2836 if ((i = sources.find (source->id())) != sources.end()) {
2841 if (!_state_of_the_state & InCleanup) {
2843 /* save state so we don't end up with a session file
2844 referring to non-existent sources.
2847 save_state (_current_snapshot_name);
2851 boost::shared_ptr<Source>
2852 Session::source_by_id (const PBD::ID& id)
2854 Glib::Mutex::Lock lm (source_lock);
2855 SourceMap::iterator i;
2856 boost::shared_ptr<Source> source;
2858 if ((i = sources.find (id)) != sources.end()) {
2865 boost::shared_ptr<Source>
2866 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2868 Glib::Mutex::Lock lm (source_lock);
2870 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2871 cerr << "comparing " << path << " with " << i->second->name() << endl;
2872 boost::shared_ptr<AudioFileSource> afs
2873 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2875 if (afs && afs->path() == path && chn == afs->channel()) {
2879 return boost::shared_ptr<Source>();
2884 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2887 string old_basename = PBD::basename_nosuffix (oldname);
2888 string new_legalized = legalize_for_path (newname);
2890 /* note: we know (or assume) the old path is already valid */
2894 /* destructive file sources have a name of the form:
2896 /path/to/Tnnnn-NAME(%[LR])?.wav
2898 the task here is to replace NAME with the new name.
2901 /* find last slash */
2905 string::size_type slash;
2906 string::size_type dash;
2908 if ((slash = path.find_last_of ('/')) == string::npos) {
2912 dir = path.substr (0, slash+1);
2914 /* '-' is not a legal character for the NAME part of the path */
2916 if ((dash = path.find_last_of ('-')) == string::npos) {
2920 prefix = path.substr (slash+1, dash-(slash+1));
2925 path += new_legalized;
2926 path += ".wav"; /* XXX gag me with a spoon */
2930 /* non-destructive file sources have a name of the form:
2932 /path/to/NAME-nnnnn(%[LR])?.ext
2934 the task here is to replace NAME with the new name.
2939 string::size_type slash;
2940 string::size_type dash;
2941 string::size_type postfix;
2943 /* find last slash */
2945 if ((slash = path.find_last_of ('/')) == string::npos) {
2949 dir = path.substr (0, slash+1);
2951 /* '-' is not a legal character for the NAME part of the path */
2953 if ((dash = path.find_last_of ('-')) == string::npos) {
2957 suffix = path.substr (dash+1);
2959 // Suffix is now everything after the dash. Now we need to eliminate
2960 // the nnnnn part, which is done by either finding a '%' or a '.'
2962 postfix = suffix.find_last_of ("%");
2963 if (postfix == string::npos) {
2964 postfix = suffix.find_last_of ('.');
2967 if (postfix != string::npos) {
2968 suffix = suffix.substr (postfix);
2970 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2974 const uint32_t limit = 10000;
2975 char buf[PATH_MAX+1];
2977 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2979 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2981 if (access (buf, F_OK) != 0) {
2989 error << "FATAL ERROR! Could not find a " << endl;
2997 /** Return the full path (in some session directory) for a new embedded source.
2998 * \a name must be a session-unique name that does not contain slashes
2999 * (e.g. as returned by new_*_source_name)
3002 Session::new_source_path_from_name (DataType type, const string& name)
3004 assert(name.find("/") == string::npos);
3006 SessionDirectory sdir(get_best_session_directory_for_new_source());
3009 if (type == DataType::AUDIO) {
3010 p = sdir.sound_path();
3011 } else if (type == DataType::MIDI) {
3012 p = sdir.midi_path();
3014 error << "Unknown source type, unable to create file path" << endmsg;
3019 return p.to_string();
3023 Session::peak_path (Glib::ustring base) const
3025 sys::path peakfile_path(_session_dir->peak_path());
3026 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3027 return peakfile_path.to_string();
3030 /** Return a unique name based on \a base for a new internal audio source */
3032 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3036 char buf[PATH_MAX+1];
3037 const uint32_t limit = 10000;
3041 legalized = legalize_for_path (base);
3043 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3044 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3046 vector<space_and_path>::iterator i;
3047 uint32_t existing = 0;
3049 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3051 SessionDirectory sdir((*i).path);
3053 spath = sdir.sound_path().to_string();
3058 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3059 spath.c_str(), cnt, legalized.c_str());
3060 } else if (nchan == 2) {
3062 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3063 spath.c_str(), cnt, legalized.c_str());
3065 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3066 spath.c_str(), cnt, legalized.c_str());
3068 } else if (nchan < 26) {
3069 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3070 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3072 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3073 spath.c_str(), cnt, legalized.c_str());
3082 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3083 } else if (nchan == 2) {
3085 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3087 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3089 } else if (nchan < 26) {
3090 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3092 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3096 if (sys::exists(buf)) {
3102 if (existing == 0) {
3107 error << string_compose(
3108 _("There are already %1 recordings for %2, which I consider too many."),
3109 limit, base) << endmsg;
3111 throw failed_constructor();
3115 return Glib::path_get_basename(buf);
3118 /** Create a new embedded audio source */
3119 boost::shared_ptr<AudioFileSource>
3120 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3122 const size_t n_chans = ds.n_channels().n_audio();
3123 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3124 const string path = new_source_path_from_name(DataType::AUDIO, name);
3125 return boost::dynamic_pointer_cast<AudioFileSource> (
3126 SourceFactory::createWritable (
3127 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3130 /** Return a unique name based on \a base for a new internal MIDI source */
3132 Session::new_midi_source_name (const string& base)
3135 char buf[PATH_MAX+1];
3136 const uint32_t limit = 10000;
3140 legalized = legalize_for_path (base);
3142 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3143 for (cnt = 1; cnt <= limit; ++cnt) {
3145 vector<space_and_path>::iterator i;
3146 uint32_t existing = 0;
3148 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3150 SessionDirectory sdir((*i).path);
3152 sys::path p = sdir.midi_path();
3155 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3157 if (sys::exists (buf)) {
3162 if (existing == 0) {
3167 error << string_compose(
3168 _("There are already %1 recordings for %2, which I consider too many."),
3169 limit, base) << endmsg;
3171 throw failed_constructor();
3175 return Glib::path_get_basename(buf);
3179 /** Create a new embedded MIDI source */
3180 boost::shared_ptr<MidiSource>
3181 Session::create_midi_source_for_session (MidiDiskstream& ds)
3183 const string name = new_midi_source_name (ds.name());
3184 const string path = new_source_path_from_name (DataType::MIDI, name);
3186 return boost::dynamic_pointer_cast<SMFSource> (
3187 SourceFactory::createWritable (
3188 DataType::MIDI, *this, path, true, false, frame_rate()));
3192 /* Playlist management */
3194 boost::shared_ptr<Playlist>
3195 Session::playlist_by_name (string name)
3197 Glib::Mutex::Lock lm (playlist_lock);
3198 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3199 if ((*i)->name() == name) {
3203 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3204 if ((*i)->name() == name) {
3209 return boost::shared_ptr<Playlist>();
3213 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3215 Glib::Mutex::Lock lm (playlist_lock);
3216 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3217 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3218 list.push_back (*i);
3221 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3222 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3223 list.push_back (*i);
3229 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3231 if (playlist->hidden()) {
3236 Glib::Mutex::Lock lm (playlist_lock);
3237 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3238 playlists.insert (playlists.begin(), playlist);
3239 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3240 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3245 playlist->release();
3250 PlaylistAdded (playlist); /* EMIT SIGNAL */
3254 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3257 Glib::Mutex::Lock lm (playlist_lock);
3258 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3261 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3268 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3270 boost::shared_ptr<Playlist> pl(wpl.lock());
3276 PlaylistList::iterator x;
3279 /* its not supposed to be visible */
3284 Glib::Mutex::Lock lm (playlist_lock);
3288 unused_playlists.insert (pl);
3290 if ((x = playlists.find (pl)) != playlists.end()) {
3291 playlists.erase (x);
3297 playlists.insert (pl);
3299 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3300 unused_playlists.erase (x);
3307 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3309 if (_state_of_the_state & Deletion) {
3313 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3320 Glib::Mutex::Lock lm (playlist_lock);
3322 PlaylistList::iterator i;
3324 i = find (playlists.begin(), playlists.end(), playlist);
3325 if (i != playlists.end()) {
3326 playlists.erase (i);
3329 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3330 if (i != unused_playlists.end()) {
3331 unused_playlists.erase (i);
3338 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3342 Session::set_audition (boost::shared_ptr<Region> r)
3344 pending_audition_region = r;
3345 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3346 schedule_butler_transport_work ();
3350 Session::audition_playlist ()
3352 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3353 ev->region.reset ();
3358 Session::non_realtime_set_audition ()
3360 if (!pending_audition_region) {
3361 auditioner->audition_current_playlist ();
3363 auditioner->audition_region (pending_audition_region);
3364 pending_audition_region.reset ();
3366 AuditionActive (true); /* EMIT SIGNAL */
3370 Session::audition_region (boost::shared_ptr<Region> r)
3372 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3378 Session::cancel_audition ()
3380 if (auditioner->active()) {
3381 auditioner->cancel_audition ();
3382 AuditionActive (false); /* EMIT SIGNAL */
3387 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3389 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3393 Session::remove_empty_sounds ()
3395 vector<string> audio_filenames;
3397 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3399 Glib::Mutex::Lock lm (source_lock);
3401 TapeFileMatcher tape_file_matcher;
3403 remove_if (audio_filenames.begin(), audio_filenames.end(),
3404 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3406 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3408 sys::path audio_file_path (_session_dir->sound_path());
3410 audio_file_path /= *i;
3412 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3416 sys::remove (audio_file_path);
3417 const string peakfile = peak_path (audio_file_path.to_string());
3418 sys::remove (peakfile);
3420 catch (const sys::filesystem_error& err)
3422 error << err.what() << endmsg;
3429 Session::is_auditioning () const
3431 /* can be called before we have an auditioner object */
3433 return auditioner->active();
3440 Session::set_all_solo (bool yn)
3442 shared_ptr<RouteList> r = routes.reader ();
3444 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3445 if (!(*i)->is_hidden()) {
3446 (*i)->set_solo (yn, this);
3454 Session::set_all_mute (bool yn)
3456 shared_ptr<RouteList> r = routes.reader ();
3458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3459 if (!(*i)->is_hidden()) {
3460 (*i)->set_mute (yn, this);
3468 Session::n_diskstreams () const
3472 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3474 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3475 if (!(*i)->hidden()) {
3483 Session::graph_reordered ()
3485 /* don't do this stuff if we are setting up connections
3486 from a set_state() call or creating new tracks.
3489 if (_state_of_the_state & InitialConnecting) {
3493 /* every track/bus asked for this to be handled but it was deferred because
3494 we were connecting. do it now.
3497 request_input_change_handling ();
3501 /* force all diskstreams to update their capture offset values to
3502 reflect any changes in latencies within the graph.
3505 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3507 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3508 (*i)->set_capture_offset ();
3513 Session::record_disenable_all ()
3515 record_enable_change_all (false);
3519 Session::record_enable_all ()
3521 record_enable_change_all (true);
3525 Session::record_enable_change_all (bool yn)
3527 shared_ptr<RouteList> r = routes.reader ();
3529 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3530 boost::shared_ptr<Track> t;
3532 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3533 t->set_record_enable (yn, this);
3537 /* since we don't keep rec-enable state, don't mark session dirty */
3541 Session::add_processor (Processor* processor)
3543 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3548 Session::remove_processor (Processor* processor)
3552 PortInsert* port_insert;
3554 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3555 insert_bitset[port_insert->bit_slot()] = false;
3556 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3557 send_bitset[send->bit_slot()] = false;
3558 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3559 return_bitset[send->bit_slot()] = false;
3566 Session::available_capture_duration ()
3568 float sample_bytes_on_disk = 4.0; // keep gcc happy
3570 switch (config.get_native_file_data_format()) {
3572 sample_bytes_on_disk = 4.0;
3576 sample_bytes_on_disk = 3.0;
3580 sample_bytes_on_disk = 2.0;
3584 /* impossible, but keep some gcc versions happy */
3585 fatal << string_compose (_("programming error: %1"),
3586 X_("illegal native file data format"))
3591 double scale = 4096.0 / sample_bytes_on_disk;
3593 if (_total_free_4k_blocks * scale > (double) max_frames) {
3597 return (nframes_t) floor (_total_free_4k_blocks * scale);
3601 Session::add_bundle (shared_ptr<Bundle> bundle)
3604 RCUWriter<BundleList> writer (_bundles);
3605 boost::shared_ptr<BundleList> b = writer.get_copy ();
3606 b->push_back (bundle);
3609 BundleAdded (bundle); /* EMIT SIGNAL */
3615 Session::remove_bundle (shared_ptr<Bundle> bundle)
3617 bool removed = false;
3620 RCUWriter<BundleList> writer (_bundles);
3621 boost::shared_ptr<BundleList> b = writer.get_copy ();
3622 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3624 if (i != b->end()) {
3631 BundleRemoved (bundle); /* EMIT SIGNAL */
3638 Session::bundle_by_name (string name) const
3640 boost::shared_ptr<BundleList> b = _bundles.reader ();
3642 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3643 if ((*i)->name() == name) {
3648 return boost::shared_ptr<Bundle> ();
3652 Session::tempo_map_changed (Change ignored)
3656 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3657 (*i)->update_after_tempo_map_change ();
3660 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3661 (*i)->update_after_tempo_map_change ();
3667 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3668 * the given count with the current block size.
3671 Session::ensure_buffers (ChanCount howmany)
3673 if (current_block_size == 0) {
3674 return; // too early? (is this ok?)
3677 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3678 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3679 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3680 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3681 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3684 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3688 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3690 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3691 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3696 Session::next_insert_id ()
3698 /* this doesn't really loop forever. just think about it */
3701 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3702 if (!insert_bitset[n]) {
3703 insert_bitset[n] = true;
3709 /* none available, so resize and try again */
3711 insert_bitset.resize (insert_bitset.size() + 16, false);
3716 Session::next_send_id ()
3718 /* this doesn't really loop forever. just think about it */
3721 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3722 if (!send_bitset[n]) {
3723 send_bitset[n] = true;
3729 /* none available, so resize and try again */
3731 send_bitset.resize (send_bitset.size() + 16, false);
3736 Session::next_return_id ()
3738 /* this doesn't really loop forever. just think about it */
3741 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3742 if (!return_bitset[n]) {
3743 return_bitset[n] = true;
3749 /* none available, so resize and try again */
3751 return_bitset.resize (return_bitset.size() + 16, false);
3756 Session::mark_send_id (uint32_t id)
3758 if (id >= send_bitset.size()) {
3759 send_bitset.resize (id+16, false);
3761 if (send_bitset[id]) {
3762 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3764 send_bitset[id] = true;
3768 Session::mark_return_id (uint32_t id)
3770 if (id >= return_bitset.size()) {
3771 return_bitset.resize (id+16, false);
3773 if (return_bitset[id]) {
3774 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3776 return_bitset[id] = true;
3780 Session::mark_insert_id (uint32_t id)
3782 if (id >= insert_bitset.size()) {
3783 insert_bitset.resize (id+16, false);
3785 if (insert_bitset[id]) {
3786 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3788 insert_bitset[id] = true;
3791 /* Named Selection management */
3794 Session::named_selection_by_name (string name)
3796 Glib::Mutex::Lock lm (named_selection_lock);
3797 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3798 if ((*i)->name == name) {
3806 Session::add_named_selection (NamedSelection* named_selection)
3809 Glib::Mutex::Lock lm (named_selection_lock);
3810 named_selections.insert (named_selections.begin(), named_selection);
3813 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3819 NamedSelectionAdded (); /* EMIT SIGNAL */
3823 Session::remove_named_selection (NamedSelection* named_selection)
3825 bool removed = false;
3828 Glib::Mutex::Lock lm (named_selection_lock);
3830 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3832 if (i != named_selections.end()) {
3834 named_selections.erase (i);
3841 NamedSelectionRemoved (); /* EMIT SIGNAL */
3846 Session::reset_native_file_format ()
3848 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3850 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3851 (*i)->reset_write_sources (false);
3856 Session::route_name_unique (string n) const
3858 shared_ptr<RouteList> r = routes.reader ();
3860 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3861 if ((*i)->name() == n) {
3870 Session::route_name_internal (string n) const
3872 if (auditioner && auditioner->name() == n) {
3876 if (_click_io && _click_io->name() == n) {
3884 Session::n_playlists () const
3886 Glib::Mutex::Lock lm (playlist_lock);
3887 return playlists.size();
3891 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3893 if (!force && howmany <= _npan_buffers) {
3897 if (_pan_automation_buffer) {
3899 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3900 delete [] _pan_automation_buffer[i];
3903 delete [] _pan_automation_buffer;
3906 _pan_automation_buffer = new pan_t*[howmany];
3908 for (uint32_t i = 0; i < howmany; ++i) {
3909 _pan_automation_buffer[i] = new pan_t[nframes];
3912 _npan_buffers = howmany;
3916 Session::freeze (InterThreadInfo& itt)
3918 shared_ptr<RouteList> r = routes.reader ();
3920 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3922 boost::shared_ptr<Track> t;
3924 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3925 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3935 boost::shared_ptr<Region>
3936 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3937 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
3938 InterThreadInfo& itt, bool enable_processing)
3940 boost::shared_ptr<Region> result;
3941 boost::shared_ptr<Playlist> playlist;
3942 boost::shared_ptr<AudioFileSource> fsource;
3944 char buf[PATH_MAX+1];
3945 ChanCount nchans(track.audio_diskstream()->n_channels());
3947 nframes_t this_chunk;
3950 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3951 const string sound_dir = sdir.sound_path().to_string();
3952 nframes_t len = end - start;
3955 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3956 end, start) << endmsg;
3960 // any bigger than this seems to cause stack overflows in called functions
3961 const nframes_t chunk_size = (128 * 1024)/4;
3963 // block all process callback handling
3965 block_processing ();
3967 /* call tree *MUST* hold route_lock */
3969 if ((playlist = track.diskstream()->playlist()) == 0) {
3973 /* external redirects will be a problem */
3975 if (track.has_external_redirects()) {
3979 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3981 for (x = 0; x < 99999; ++x) {
3982 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3983 if (access (buf, F_OK) != 0) {
3989 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3994 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3995 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
3998 catch (failed_constructor& err) {
3999 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4003 srcs.push_back (fsource);
4006 /* XXX need to flush all redirects */
4011 /* create a set of reasonably-sized buffers */
4012 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4013 buffers.set_count(nchans);
4015 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4016 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4018 afs->prepare_for_peakfile_writes ();
4021 while (to_do && !itt.cancel) {
4023 this_chunk = min (to_do, chunk_size);
4025 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4030 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4031 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4034 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4040 start += this_chunk;
4041 to_do -= this_chunk;
4043 itt.progress = (float) (1.0 - ((double) to_do / len));
4052 xnow = localtime (&now);
4054 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4055 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4058 afs->update_header (position, *xnow, now);
4059 afs->flush_header ();
4063 /* construct a region to represent the bounced material */
4065 result = RegionFactory::create (srcs, 0,
4066 srcs.front()->length(srcs.front()->timeline_position()),
4067 region_name_from_path (srcs.front()->name(), true));
4072 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4073 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4076 afs->mark_for_remove ();
4079 (*src)->drop_references ();
4083 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4084 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4087 afs->done_with_peakfile_writes ();
4091 unblock_processing ();
4097 Session::get_silent_buffers (ChanCount count)
4099 assert(_silent_buffers->available() >= count);
4100 _silent_buffers->set_count(count);
4102 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4103 for (size_t i= 0; i < count.get(*t); ++i) {
4104 _silent_buffers->get(*t, i).clear();
4108 return *_silent_buffers;
4112 Session::get_scratch_buffers (ChanCount count)
4114 if (count != ChanCount::ZERO) {
4115 assert(_scratch_buffers->available() >= count);
4116 _scratch_buffers->set_count(count);
4118 _scratch_buffers->set_count (_scratch_buffers->available());
4121 return *_scratch_buffers;
4125 Session::get_mix_buffers (ChanCount count)
4127 assert(_mix_buffers->available() >= count);
4128 _mix_buffers->set_count(count);
4129 return *_mix_buffers;
4133 Session::ntracks () const
4136 shared_ptr<RouteList> r = routes.reader ();
4138 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4139 if (boost::dynamic_pointer_cast<Track> (*i)) {
4148 Session::nbusses () const
4151 shared_ptr<RouteList> r = routes.reader ();
4153 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4154 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4163 Session::add_automation_list(AutomationList *al)
4165 automation_lists[al->id()] = al;
4169 Session::compute_initial_length ()
4171 return _engine.frame_rate() * 60 * 5;
4175 Session::sync_order_keys (const char* base)
4177 if (!Config->get_sync_all_route_ordering()) {
4178 /* leave order keys as they are */
4182 boost::shared_ptr<RouteList> r = routes.reader ();
4184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4185 (*i)->sync_order_keys (base);
4188 Route::SyncOrderKeys (base); // EMIT SIGNAL
4192 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4194 Session::have_rec_enabled_diskstream () const
4196 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4199 /** Update the state of our rec-enabled diskstreams flag */
4201 Session::update_have_rec_enabled_diskstream ()
4203 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4204 DiskstreamList::iterator i = dsl->begin ();
4205 while (i != dsl->end () && (*i)->record_enabled () == false) {
4209 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4211 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4213 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4214 RecordStateChanged (); /* EMIT SIGNAL */