2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
44 #include <pbd/file_utils.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/session_directory.h>
50 #include <ardour/session_metadata.h>
51 #include <ardour/utils.h>
52 #include <ardour/audio_diskstream.h>
53 #include <ardour/audioplaylist.h>
54 #include <ardour/audioregion.h>
55 #include <ardour/audiofilesource.h>
56 #include <ardour/midi_diskstream.h>
57 #include <ardour/midi_playlist.h>
58 #include <ardour/midi_region.h>
59 #include <ardour/smf_source.h>
60 #include <ardour/auditioner.h>
61 #include <ardour/recent_sessions.h>
62 #include <ardour/io_processor.h>
63 #include <ardour/send.h>
64 #include <ardour/processor.h>
65 #include <ardour/plugin_insert.h>
66 #include <ardour/port_insert.h>
67 #include <ardour/auto_bundle.h>
68 #include <ardour/slave.h>
69 #include <ardour/tempo.h>
70 #include <ardour/audio_track.h>
71 #include <ardour/midi_track.h>
72 #include <ardour/cycle_timer.h>
73 #include <ardour/named_selection.h>
74 #include <ardour/crossfade.h>
75 #include <ardour/playlist.h>
76 #include <ardour/click.h>
77 #include <ardour/data_type.h>
78 #include <ardour/buffer_set.h>
79 #include <ardour/source_factory.h>
80 #include <ardour/region_factory.h>
81 #include <ardour/filename_extensions.h>
82 #include <ardour/session_directory.h>
83 #include <ardour/tape_file_matcher.h>
84 #include <ardour/analyser.h>
87 #include <ardour/osc.h>
93 using namespace ARDOUR;
95 using boost::shared_ptr;
98 static const int CPU_CACHE_ALIGN = 64;
100 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
103 bool Session::_disable_all_loaded_plugins = false;
105 sigc::signal<void,std::string> Session::Dialog;
106 sigc::signal<int> Session::AskAboutPendingState;
107 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
108 sigc::signal<void> Session::SendFeedback;
110 sigc::signal<void> Session::SMPTEOffsetChanged;
111 sigc::signal<void> Session::StartTimeChanged;
112 sigc::signal<void> Session::EndTimeChanged;
113 sigc::signal<void> Session::AutoBindingOn;
114 sigc::signal<void> Session::AutoBindingOff;
115 sigc::signal<void, std::string, std::string> Session::Exported;
117 Session::Session (AudioEngine &eng,
118 const string& fullpath,
119 const string& snapshot_name,
123 _scratch_buffers(new BufferSet()),
124 _silent_buffers(new BufferSet()),
125 _mix_buffers(new BufferSet()),
126 _mmc_port (default_mmc_port),
127 _mtc_port (default_mtc_port),
128 _midi_port (default_midi_port),
129 _midi_clock_port (default_midi_clock_port),
130 _session_dir (new SessionDirectory(fullpath)),
131 pending_events (2048),
132 post_transport_work((PostTransportWork)0),
133 _send_smpte_update (false),
135 diskstreams (new DiskstreamList),
136 routes (new RouteList),
137 auditioner ((Auditioner*) 0),
138 _total_free_4k_blocks (0),
139 _bundle_xml_node (0),
142 _metadata (new SessionMetadata())
146 if (!eng.connected()) {
147 throw failed_constructor();
150 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
152 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
153 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
155 first_stage_init (fullpath, snapshot_name);
157 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
160 if (create (new_session, mix_template, compute_initial_length())) {
162 throw failed_constructor ();
166 if (second_stage_init (new_session)) {
168 throw failed_constructor ();
171 store_recent_sessions(_name, _path);
173 bool was_dirty = dirty();
175 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
177 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
180 DirtyChanged (); /* EMIT SIGNAL */
184 Session::Session (AudioEngine &eng,
186 string snapshot_name,
187 AutoConnectOption input_ac,
188 AutoConnectOption output_ac,
189 uint32_t control_out_channels,
190 uint32_t master_out_channels,
191 uint32_t requested_physical_in,
192 uint32_t requested_physical_out,
193 nframes_t initial_length)
196 _scratch_buffers(new BufferSet()),
197 _silent_buffers(new BufferSet()),
198 _mix_buffers(new BufferSet()),
199 _mmc_port (default_mmc_port),
200 _mtc_port (default_mtc_port),
201 _midi_port (default_midi_port),
202 _midi_clock_port (default_midi_clock_port),
203 _session_dir ( new SessionDirectory(fullpath)),
204 pending_events (2048),
205 post_transport_work((PostTransportWork)0),
206 _send_smpte_update (false),
208 diskstreams (new DiskstreamList),
209 routes (new RouteList),
210 _total_free_4k_blocks (0),
211 _bundle_xml_node (0),
217 if (!eng.connected()) {
218 throw failed_constructor();
221 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
223 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
224 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
226 if (n_physical_inputs) {
227 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
230 if (n_physical_outputs) {
231 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
234 first_stage_init (fullpath, snapshot_name);
236 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
239 if (create (new_session, string(), initial_length)) {
241 throw failed_constructor ();
246 /* set up Master Out and Control Out if necessary */
251 if (control_out_channels) {
252 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
253 r->set_remote_control_id (control_id++);
258 if (master_out_channels) {
259 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
260 r->set_remote_control_id (control_id);
264 /* prohibit auto-connect to master, because there isn't one */
265 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
269 add_routes (rl, false);
274 Config->set_input_auto_connect (input_ac);
275 Config->set_output_auto_connect (output_ac);
277 if (second_stage_init (new_session)) {
279 throw failed_constructor ();
282 store_recent_sessions (_name, _path);
284 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
286 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
297 /* if we got to here, leaving pending capture state around
301 remove_pending_capture_state ();
303 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
305 _engine.remove_session ();
307 GoingAway (); /* EMIT SIGNAL */
313 /* clear history so that no references to objects are held any more */
317 /* clear state tree so that no references to objects are held any more */
323 terminate_butler_thread ();
324 //terminate_midi_thread ();
326 if (click_data && click_data != default_click) {
327 delete [] click_data;
330 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
331 delete [] click_emphasis_data;
336 delete _scratch_buffers;
337 delete _silent_buffers;
340 AudioDiskstream::free_working_buffers();
342 Route::SyncOrderKeys.clear();
344 #undef TRACK_DESTRUCTION
345 #ifdef TRACK_DESTRUCTION
346 cerr << "delete named selections\n";
347 #endif /* TRACK_DESTRUCTION */
348 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
349 NamedSelectionList::iterator tmp;
358 #ifdef TRACK_DESTRUCTION
359 cerr << "delete playlists\n";
360 #endif /* TRACK_DESTRUCTION */
361 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
362 PlaylistList::iterator tmp;
367 (*i)->drop_references ();
372 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
373 PlaylistList::iterator tmp;
378 (*i)->drop_references ();
384 unused_playlists.clear ();
386 #ifdef TRACK_DESTRUCTION
387 cerr << "delete regions\n";
388 #endif /* TRACK_DESTRUCTION */
390 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
391 RegionList::iterator tmp;
396 i->second->drop_references ();
403 #ifdef TRACK_DESTRUCTION
404 cerr << "delete routes\n";
405 #endif /* TRACK_DESTRUCTION */
407 RCUWriter<RouteList> writer (routes);
408 boost::shared_ptr<RouteList> r = writer.get_copy ();
409 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
410 (*i)->drop_references ();
413 /* writer goes out of scope and updates master */
418 #ifdef TRACK_DESTRUCTION
419 cerr << "delete diskstreams\n";
420 #endif /* TRACK_DESTRUCTION */
422 RCUWriter<DiskstreamList> dwriter (diskstreams);
423 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
424 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
425 (*i)->drop_references ();
429 diskstreams.flush ();
431 #ifdef TRACK_DESTRUCTION
432 cerr << "delete audio sources\n";
433 #endif /* TRACK_DESTRUCTION */
434 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
435 SourceMap::iterator tmp;
440 i->second->drop_references ();
446 #ifdef TRACK_DESTRUCTION
447 cerr << "delete mix groups\n";
448 #endif /* TRACK_DESTRUCTION */
449 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
450 list<RouteGroup*>::iterator tmp;
460 #ifdef TRACK_DESTRUCTION
461 cerr << "delete edit groups\n";
462 #endif /* TRACK_DESTRUCTION */
463 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
464 list<RouteGroup*>::iterator tmp;
474 if (butler_mixdown_buffer) {
475 delete [] butler_mixdown_buffer;
478 if (butler_gain_buffer) {
479 delete [] butler_gain_buffer;
482 Crossfade::set_buffer_size (0);
490 Session::set_worst_io_latencies ()
492 _worst_output_latency = 0;
493 _worst_input_latency = 0;
495 if (!_engine.connected()) {
499 boost::shared_ptr<RouteList> r = routes.reader ();
501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
502 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
503 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
508 Session::when_engine_running ()
510 string first_physical_output;
512 /* we don't want to run execute this again */
514 BootMessage (_("Set block size and sample rate"));
516 set_block_size (_engine.frames_per_cycle());
517 set_frame_rate (_engine.frame_rate());
519 BootMessage (_("Using configuration"));
521 Config->map_parameters (mem_fun (*this, &Session::config_changed));
523 /* every time we reconnect, recompute worst case output latencies */
525 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
527 if (synced_to_jack()) {
528 _engine.transport_stop ();
531 if (Config->get_jack_time_master()) {
532 _engine.transport_locate (_transport_frame);
540 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
542 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
544 /* existing state for Click */
546 if (_click_io->set_state (*child->children().front()) == 0) {
548 _clicking = Config->get_clicking ();
552 error << _("could not setup Click I/O") << endmsg;
558 /* default state for Click */
560 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
562 if (first_physical_output.length()) {
563 if (_click_io->add_output_port (first_physical_output, this)) {
564 // relax, even though its an error
566 _clicking = Config->get_clicking ();
572 catch (failed_constructor& err) {
573 error << _("cannot setup Click I/O") << endmsg;
576 BootMessage (_("Compute I/O Latencies"));
578 set_worst_io_latencies ();
581 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
584 /* Create a set of Bundle objects that map
585 to the physical outputs currently available
588 BootMessage (_("Set up standard connections"));
592 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
594 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
596 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
598 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
603 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
605 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
607 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
609 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
616 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
618 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
620 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
622 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
623 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
628 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
630 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
632 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
634 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
635 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
644 /* create master/control ports */
649 /* force the master to ignore any later call to this */
651 if (_master_out->pending_state_node) {
652 _master_out->ports_became_legal();
655 /* no panner resets till we are through */
657 _master_out->defer_pan_reset ();
659 while (_master_out->n_inputs().n_audio()
660 < _master_out->input_maximum().n_audio()) {
661 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
662 error << _("cannot setup master inputs")
668 while (_master_out->n_outputs().n_audio()
669 < _master_out->output_maximum().n_audio()) {
670 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
671 error << _("cannot setup master outputs")
678 _master_out->allow_pan_reset ();
682 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
684 c->set_channels (_master_out->n_inputs().n_total());
685 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
686 c->set_port (n, _master_out->input(n)->name());
691 BootMessage (_("Setup signal flow and plugins"));
695 /* catch up on send+insert cnts */
697 BootMessage (_("Catch up with send/insert state"));
701 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
704 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
705 if (id > insert_cnt) {
713 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
716 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
724 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
726 /* hook us up to the engine */
728 BootMessage (_("Connect to engine"));
730 _engine.set_session (this);
735 BootMessage (_("OSC startup"));
737 osc->set_session (*this);
743 Session::hookup_io ()
745 /* stop graph reordering notifications from
746 causing resorts, etc.
749 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
752 if (auditioner == 0) {
754 /* we delay creating the auditioner till now because
755 it makes its own connections to ports.
756 the engine has to be running for this to work.
760 auditioner.reset (new Auditioner (*this));
763 catch (failed_constructor& err) {
764 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
768 /* Tell all IO objects to create their ports */
774 vector<string> cports;
776 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
777 if (_control_out->add_input_port ("", this)) {
778 error << _("cannot setup control inputs")
784 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
785 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
786 error << _("cannot set up master outputs")
794 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
796 for (n = 0; n < ni; ++n) {
797 cports.push_back (_control_out->input(n)->name());
800 boost::shared_ptr<RouteList> r = routes.reader ();
802 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
803 (*x)->set_control_outs (cports);
807 /* load bundles, which we may have postponed earlier on */
808 if (_bundle_xml_node) {
809 load_bundles (*_bundle_xml_node);
810 delete _bundle_xml_node;
813 /* Tell all IO objects to connect themselves together */
815 IO::enable_connecting ();
817 /* Now reset all panners */
819 IO::reset_panners ();
821 /* Anyone who cares about input state, wake up and do something */
823 IOConnectionsComplete (); /* EMIT SIGNAL */
825 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
828 /* now handle the whole enchilada as if it was one
834 /* update mixer solo state */
840 Session::playlist_length_changed ()
842 /* we can't just increase end_location->end() if pl->get_maximum_extent()
843 if larger. if the playlist used to be the longest playlist,
844 and its now shorter, we have to decrease end_location->end(). hence,
845 we have to iterate over all diskstreams and check the
846 playlists currently in use.
852 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
854 boost::shared_ptr<Playlist> playlist;
856 if ((playlist = dstream->playlist()) != 0) {
857 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
860 /* see comment in playlist_length_changed () */
865 Session::record_enabling_legal () const
867 /* this used to be in here, but survey says.... we don't need to restrict it */
868 // if (record_status() == Recording) {
872 if (Config->get_all_safe()) {
879 Session::reset_input_monitor_state ()
881 if (transport_rolling()) {
883 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
885 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
886 if ((*i)->record_enabled ()) {
887 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
888 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
892 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
894 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
895 if ((*i)->record_enabled ()) {
896 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
897 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
904 Session::auto_punch_start_changed (Location* location)
906 replace_event (Event::PunchIn, location->start());
908 if (get_record_enabled() && Config->get_punch_in()) {
909 /* capture start has been changed, so save new pending state */
910 save_state ("", true);
915 Session::auto_punch_end_changed (Location* location)
917 nframes_t when_to_stop = location->end();
918 // when_to_stop += _worst_output_latency + _worst_input_latency;
919 replace_event (Event::PunchOut, when_to_stop);
923 Session::auto_punch_changed (Location* location)
925 nframes_t when_to_stop = location->end();
927 replace_event (Event::PunchIn, location->start());
928 //when_to_stop += _worst_output_latency + _worst_input_latency;
929 replace_event (Event::PunchOut, when_to_stop);
933 Session::auto_loop_changed (Location* location)
935 replace_event (Event::AutoLoop, location->end(), location->start());
937 if (transport_rolling() && play_loop) {
939 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
941 if (_transport_frame > location->end()) {
942 // relocate to beginning of loop
943 clear_events (Event::LocateRoll);
945 request_locate (location->start(), true);
948 else if (Config->get_seamless_loop() && !loop_changing) {
950 // schedule a locate-roll to refill the diskstreams at the
952 loop_changing = true;
954 if (location->end() > last_loopend) {
955 clear_events (Event::LocateRoll);
956 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
963 last_loopend = location->end();
967 Session::set_auto_punch_location (Location* location)
971 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
972 auto_punch_start_changed_connection.disconnect();
973 auto_punch_end_changed_connection.disconnect();
974 auto_punch_changed_connection.disconnect();
975 existing->set_auto_punch (false, this);
976 remove_event (existing->start(), Event::PunchIn);
977 clear_events (Event::PunchOut);
978 auto_punch_location_changed (0);
987 if (location->end() <= location->start()) {
988 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
992 auto_punch_start_changed_connection.disconnect();
993 auto_punch_end_changed_connection.disconnect();
994 auto_punch_changed_connection.disconnect();
996 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
997 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
998 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1000 location->set_auto_punch (true, this);
1003 auto_punch_changed (location);
1005 auto_punch_location_changed (location);
1009 Session::set_auto_loop_location (Location* location)
1013 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1014 auto_loop_start_changed_connection.disconnect();
1015 auto_loop_end_changed_connection.disconnect();
1016 auto_loop_changed_connection.disconnect();
1017 existing->set_auto_loop (false, this);
1018 remove_event (existing->end(), Event::AutoLoop);
1019 auto_loop_location_changed (0);
1024 if (location == 0) {
1028 if (location->end() <= location->start()) {
1029 error << _("Session: you can't use a mark for auto loop") << endmsg;
1033 last_loopend = location->end();
1035 auto_loop_start_changed_connection.disconnect();
1036 auto_loop_end_changed_connection.disconnect();
1037 auto_loop_changed_connection.disconnect();
1039 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1040 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1041 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1043 location->set_auto_loop (true, this);
1045 /* take care of our stuff first */
1047 auto_loop_changed (location);
1049 /* now tell everyone else */
1051 auto_loop_location_changed (location);
1055 Session::locations_added (Location* ignored)
1061 Session::locations_changed ()
1063 _locations.apply (*this, &Session::handle_locations_changed);
1067 Session::handle_locations_changed (Locations::LocationList& locations)
1069 Locations::LocationList::iterator i;
1071 bool set_loop = false;
1072 bool set_punch = false;
1074 for (i = locations.begin(); i != locations.end(); ++i) {
1078 if (location->is_auto_punch()) {
1079 set_auto_punch_location (location);
1082 if (location->is_auto_loop()) {
1083 set_auto_loop_location (location);
1087 if (location->is_start()) {
1088 start_location = location;
1090 if (location->is_end()) {
1091 end_location = location;
1096 set_auto_loop_location (0);
1099 set_auto_punch_location (0);
1106 Session::enable_record ()
1108 /* XXX really atomic compare+swap here */
1109 if (g_atomic_int_get (&_record_status) != Recording) {
1110 g_atomic_int_set (&_record_status, Recording);
1111 _last_record_location = _transport_frame;
1112 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1114 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1116 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1117 if ((*i)->record_enabled ()) {
1118 (*i)->monitor_input (true);
1123 RecordStateChanged ();
1128 Session::disable_record (bool rt_context, bool force)
1132 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1134 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1135 g_atomic_int_set (&_record_status, Disabled);
1137 if (rs == Recording) {
1138 g_atomic_int_set (&_record_status, Enabled);
1142 // FIXME: timestamp correct? [DR]
1143 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1144 // does this /need/ to be sent in all cases?
1146 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1148 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1149 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1151 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1152 if ((*i)->record_enabled ()) {
1153 (*i)->monitor_input (false);
1158 RecordStateChanged (); /* emit signal */
1161 remove_pending_capture_state ();
1167 Session::step_back_from_record ()
1169 /* XXX really atomic compare+swap here */
1170 if (g_atomic_int_get (&_record_status) == Recording) {
1171 g_atomic_int_set (&_record_status, Enabled);
1173 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1174 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1176 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1177 if ((*i)->record_enabled ()) {
1178 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1179 (*i)->monitor_input (false);
1187 Session::maybe_enable_record ()
1189 g_atomic_int_set (&_record_status, Enabled);
1191 /* this function is currently called from somewhere other than an RT thread.
1192 this save_state() call therefore doesn't impact anything.
1195 save_state ("", true);
1197 if (_transport_speed) {
1198 if (!Config->get_punch_in()) {
1202 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1203 RecordStateChanged (); /* EMIT SIGNAL */
1210 Session::audible_frame () const
1216 /* the first of these two possible settings for "offset"
1217 mean that the audible frame is stationary until
1218 audio emerges from the latency compensation
1221 the second means that the audible frame is stationary
1222 until audio would emerge from a physical port
1223 in the absence of any plugin latency compensation
1226 offset = _worst_output_latency;
1228 if (offset > current_block_size) {
1229 offset -= current_block_size;
1231 /* XXX is this correct? if we have no external
1232 physical connections and everything is internal
1233 then surely this is zero? still, how
1234 likely is that anyway?
1236 offset = current_block_size;
1239 if (synced_to_jack()) {
1240 tf = _engine.transport_frame();
1242 tf = _transport_frame;
1245 if (_transport_speed == 0) {
1255 if (!non_realtime_work_pending()) {
1259 /* take latency into account */
1268 Session::set_frame_rate (nframes_t frames_per_second)
1270 /** \fn void Session::set_frame_size(nframes_t)
1271 the AudioEngine object that calls this guarantees
1272 that it will not be called while we are also in
1273 ::process(). Its fine to do things that block
1277 _base_frame_rate = frames_per_second;
1281 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1285 // XXX we need some equivalent to this, somehow
1286 // SndFileSource::setup_standard_crossfades (frames_per_second);
1290 /* XXX need to reset/reinstantiate all LADSPA plugins */
1294 Session::set_block_size (nframes_t nframes)
1296 /* the AudioEngine guarantees
1297 that it will not be called while we are also in
1298 ::process(). It is therefore fine to do things that block
1304 current_block_size = nframes;
1306 ensure_buffers(_scratch_buffers->available());
1308 if (_gain_automation_buffer) {
1309 delete [] _gain_automation_buffer;
1311 _gain_automation_buffer = new gain_t[nframes];
1313 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1315 boost::shared_ptr<RouteList> r = routes.reader ();
1317 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1318 (*i)->set_block_size (nframes);
1321 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1322 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1323 (*i)->set_block_size (nframes);
1326 set_worst_io_latencies ();
1331 Session::set_default_fade (float steepness, float fade_msecs)
1334 nframes_t fade_frames;
1336 /* Don't allow fade of less 1 frame */
1338 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1345 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1349 default_fade_msecs = fade_msecs;
1350 default_fade_steepness = steepness;
1353 // jlc, WTF is this!
1354 Glib::RWLock::ReaderLock lm (route_lock);
1355 AudioRegion::set_default_fade (steepness, fade_frames);
1360 /* XXX have to do this at some point */
1361 /* foreach region using default fade, reset, then
1362 refill_all_diskstream_buffers ();
1367 struct RouteSorter {
1368 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1369 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1371 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1374 if (r1->fed_by.empty()) {
1375 if (r2->fed_by.empty()) {
1376 /* no ardour-based connections inbound to either route. just use signal order */
1377 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1379 /* r2 has connections, r1 does not; run r1 early */
1383 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1392 shared_ptr<Route> r2;
1394 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1395 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1399 /* make a copy of the existing list of routes that feed r1 */
1401 set<shared_ptr<Route> > existing = r1->fed_by;
1403 /* for each route that feeds r1, recurse, marking it as feeding
1407 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1410 /* r2 is a route that feeds r1 which somehow feeds base. mark
1411 base as being fed by r2
1414 rbase->fed_by.insert (r2);
1418 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1422 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1426 /* now recurse, so that we can mark base as being fed by
1427 all routes that feed r2
1430 trace_terminal (r2, rbase);
1437 Session::resort_routes ()
1439 /* don't do anything here with signals emitted
1440 by Routes while we are being destroyed.
1443 if (_state_of_the_state & Deletion) {
1450 RCUWriter<RouteList> writer (routes);
1451 shared_ptr<RouteList> r = writer.get_copy ();
1452 resort_routes_using (r);
1453 /* writer goes out of scope and forces update */
1458 Session::resort_routes_using (shared_ptr<RouteList> r)
1460 RouteList::iterator i, j;
1462 for (i = r->begin(); i != r->end(); ++i) {
1464 (*i)->fed_by.clear ();
1466 for (j = r->begin(); j != r->end(); ++j) {
1468 /* although routes can feed themselves, it will
1469 cause an endless recursive descent if we
1470 detect it. so don't bother checking for
1478 if ((*j)->feeds (*i)) {
1479 (*i)->fed_by.insert (*j);
1484 for (i = r->begin(); i != r->end(); ++i) {
1485 trace_terminal (*i, *i);
1492 cerr << "finished route resort\n";
1494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1495 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1502 list<boost::shared_ptr<MidiTrack> >
1503 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1505 char track_name[32];
1506 uint32_t track_id = 0;
1509 RouteList new_routes;
1510 list<boost::shared_ptr<MidiTrack> > ret;
1511 //uint32_t control_id;
1513 // FIXME: need physical I/O and autoconnect stuff for MIDI
1515 /* count existing midi tracks */
1518 shared_ptr<RouteList> r = routes.reader ();
1520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1521 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1522 if (!(*i)->is_hidden()) {
1524 //channels_used += (*i)->n_inputs().n_midi();
1531 vector<string> physinputs;
1532 vector<string> physoutputs;
1534 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1535 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1536 uint32_t nphysical_in;
1537 uint32_t nphysical_out;
1538 control_id = ntracks() + nbusses();
1543 /* check for duplicate route names, since we might have pre-existing
1544 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1545 save, close,restart,add new route - first named route is now
1553 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1555 if (route_by_name (track_name) == 0) {
1559 } while (track_id < (UINT_MAX-1));
1562 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1563 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1568 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1569 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1575 shared_ptr<MidiTrack> track;
1578 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1580 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1581 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1587 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1591 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1592 port = physinputs[(channels_used+x)%nphysical_in];
1595 if (port.length() && track->connect_input (track->input (x), port, this)) {
1601 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1605 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1606 port = physoutputs[(channels_used+x)%nphysical_out];
1607 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1609 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1613 if (port.length() && track->connect_output (track->output (x), port, this)) {
1618 channels_used += track->n_inputs ().n_midi();
1622 track->midi_diskstream()->non_realtime_input_change();
1624 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1625 //track->set_remote_control_id (control_id);
1627 new_routes.push_back (track);
1628 ret.push_back (track);
1631 catch (failed_constructor &err) {
1632 error << _("Session: could not create new midi track.") << endmsg;
1635 /* we need to get rid of this, since the track failed to be created */
1636 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1639 RCUWriter<DiskstreamList> writer (diskstreams);
1640 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1641 ds->remove (track->midi_diskstream());
1648 catch (AudioEngine::PortRegistrationFailure& pfe) {
1650 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;
1653 /* we need to get rid of this, since the track failed to be created */
1654 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1657 RCUWriter<DiskstreamList> writer (diskstreams);
1658 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1659 ds->remove (track->midi_diskstream());
1670 if (!new_routes.empty()) {
1671 add_routes (new_routes, false);
1672 save_state (_current_snapshot_name);
1678 list<boost::shared_ptr<AudioTrack> >
1679 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1681 char track_name[32];
1682 uint32_t track_id = 0;
1684 uint32_t channels_used = 0;
1686 RouteList new_routes;
1687 list<boost::shared_ptr<AudioTrack> > ret;
1688 uint32_t control_id;
1690 /* count existing audio tracks */
1693 shared_ptr<RouteList> r = routes.reader ();
1695 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1696 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1697 if (!(*i)->is_hidden()) {
1699 channels_used += (*i)->n_inputs().n_audio();
1705 vector<string> physinputs;
1706 vector<string> physoutputs;
1707 uint32_t nphysical_in;
1708 uint32_t nphysical_out;
1710 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1711 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1712 control_id = ntracks() + nbusses() + 1;
1716 /* check for duplicate route names, since we might have pre-existing
1717 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1718 save, close,restart,add new route - first named route is now
1726 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1728 if (route_by_name (track_name) == 0) {
1732 } while (track_id < (UINT_MAX-1));
1734 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1735 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1740 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1741 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1746 shared_ptr<AudioTrack> track;
1749 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1751 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1752 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1753 input_channels, output_channels)
1759 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1763 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1764 port = physinputs[(channels_used+x)%nphysical_in];
1767 if (port.length() && track->connect_input (track->input (x), port, this)) {
1773 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1777 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1778 port = physoutputs[(channels_used+x)%nphysical_out];
1779 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1781 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1785 if (port.length() && track->connect_output (track->output (x), port, this)) {
1790 channels_used += track->n_inputs ().n_audio();
1792 track->audio_diskstream()->non_realtime_input_change();
1794 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1795 track->set_remote_control_id (control_id);
1798 new_routes.push_back (track);
1799 ret.push_back (track);
1802 catch (failed_constructor &err) {
1803 error << _("Session: could not create new audio track.") << endmsg;
1806 /* we need to get rid of this, since the track failed to be created */
1807 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1810 RCUWriter<DiskstreamList> writer (diskstreams);
1811 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1812 ds->remove (track->audio_diskstream());
1819 catch (AudioEngine::PortRegistrationFailure& pfe) {
1821 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;
1824 /* we need to get rid of this, since the track failed to be created */
1825 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1828 RCUWriter<DiskstreamList> writer (diskstreams);
1829 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1830 ds->remove (track->audio_diskstream());
1841 if (!new_routes.empty()) {
1842 add_routes (new_routes, true);
1849 Session::set_remote_control_ids ()
1851 RemoteModel m = Config->get_remote_model();
1853 shared_ptr<RouteList> r = routes.reader ();
1855 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1856 if ( MixerOrdered == m) {
1857 long order = (*i)->order_key(N_("signal"));
1858 (*i)->set_remote_control_id( order+1 );
1859 } else if ( EditorOrdered == m) {
1860 long order = (*i)->order_key(N_("editor"));
1861 (*i)->set_remote_control_id( order+1 );
1862 } else if ( UserOrdered == m) {
1863 //do nothing ... only changes to remote id's are initiated by user
1870 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1873 uint32_t bus_id = 1;
1877 uint32_t control_id;
1879 /* count existing audio busses */
1882 shared_ptr<RouteList> r = routes.reader ();
1884 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1885 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1886 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1893 vector<string> physinputs;
1894 vector<string> physoutputs;
1896 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1897 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1898 control_id = ntracks() + nbusses() + 1;
1903 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1907 if (route_by_name (bus_name) == 0) {
1911 } while (bus_id < (UINT_MAX-1));
1914 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1916 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1917 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1918 input_channels, output_channels)
1923 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1927 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1928 port = physinputs[((n+x)%n_physical_inputs)];
1931 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1936 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1940 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1941 port = physoutputs[((n+x)%n_physical_outputs)];
1942 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1944 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1948 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1953 bus->set_remote_control_id (control_id);
1956 ret.push_back (bus);
1960 catch (failed_constructor &err) {
1961 error << _("Session: could not create new audio route.") << endmsg;
1965 catch (AudioEngine::PortRegistrationFailure& pfe) {
1966 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1976 add_routes (ret, true);
1984 Session::add_routes (RouteList& new_routes, bool save)
1987 RCUWriter<RouteList> writer (routes);
1988 shared_ptr<RouteList> r = writer.get_copy ();
1989 r->insert (r->end(), new_routes.begin(), new_routes.end());
1990 resort_routes_using (r);
1993 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1995 boost::weak_ptr<Route> wpr (*x);
1997 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1998 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1999 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2000 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2002 if ((*x)->is_master()) {
2006 if ((*x)->is_control()) {
2007 _control_out = (*x);
2010 add_bundle ((*x)->bundle_for_inputs());
2011 add_bundle ((*x)->bundle_for_outputs());
2014 if (_control_out && IO::connecting_legal) {
2016 vector<string> cports;
2017 uint32_t ni = _control_out->n_inputs().n_audio();
2019 for (uint32_t n = 0; n < ni; ++n) {
2020 cports.push_back (_control_out->input(n)->name());
2023 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2024 (*x)->set_control_outs (cports);
2031 save_state (_current_snapshot_name);
2034 RouteAdded (new_routes); /* EMIT SIGNAL */
2038 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2040 /* need to do this in case we're rolling at the time, to prevent false underruns */
2041 dstream->do_refill_with_alloc ();
2043 dstream->set_block_size (current_block_size);
2046 RCUWriter<DiskstreamList> writer (diskstreams);
2047 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2048 ds->push_back (dstream);
2049 /* writer goes out of scope, copies ds back to main */
2052 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2053 /* this will connect to future changes, and check the current length */
2054 diskstream_playlist_changed (dstream);
2056 dstream->prepare ();
2061 Session::remove_route (shared_ptr<Route> route)
2064 RCUWriter<RouteList> writer (routes);
2065 shared_ptr<RouteList> rs = writer.get_copy ();
2069 /* deleting the master out seems like a dumb
2070 idea, but its more of a UI policy issue
2074 if (route == _master_out) {
2075 _master_out = shared_ptr<Route> ();
2078 if (route == _control_out) {
2079 _control_out = shared_ptr<Route> ();
2081 /* cancel control outs for all routes */
2083 vector<string> empty;
2085 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2086 (*r)->set_control_outs (empty);
2090 update_route_solo_state ();
2092 /* writer goes out of scope, forces route list update */
2096 boost::shared_ptr<Diskstream> ds;
2098 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2099 ds = t->diskstream();
2105 RCUWriter<DiskstreamList> dsl (diskstreams);
2106 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2111 find_current_end ();
2113 // We need to disconnect the routes inputs and outputs
2115 route->disconnect_inputs (0);
2116 route->disconnect_outputs (0);
2118 update_latency_compensation (false, false);
2121 /* get rid of it from the dead wood collection in the route list manager */
2123 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2127 /* try to cause everyone to drop their references */
2129 route->drop_references ();
2131 /* save the new state of the world */
2133 if (save_state (_current_snapshot_name)) {
2134 save_history (_current_snapshot_name);
2139 Session::route_mute_changed (void* src)
2145 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2147 if (solo_update_disabled) {
2153 boost::shared_ptr<Route> route = wpr.lock ();
2156 /* should not happen */
2157 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2161 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2163 shared_ptr<RouteList> r = routes.reader ();
2165 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2167 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2171 /* don't mess with busses */
2173 if (dynamic_cast<Track*>((*i).get()) == 0) {
2179 /* don't mess with tracks */
2181 if (dynamic_cast<Track*>((*i).get()) != 0) {
2186 if ((*i) != route &&
2187 ((*i)->mix_group () == 0 ||
2188 (*i)->mix_group () != route->mix_group () ||
2189 !route->mix_group ()->is_active())) {
2191 if ((*i)->soloed()) {
2193 /* if its already soloed, and solo latching is enabled,
2194 then leave it as it is.
2197 if (Config->get_solo_latched()) {
2204 solo_update_disabled = true;
2205 (*i)->set_solo (false, src);
2206 solo_update_disabled = false;
2210 bool something_soloed = false;
2211 bool same_thing_soloed = false;
2212 bool signal = false;
2214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2215 if ((*i)->soloed()) {
2216 something_soloed = true;
2217 if (dynamic_cast<Track*>((*i).get())) {
2219 same_thing_soloed = true;
2224 same_thing_soloed = true;
2232 if (something_soloed != currently_soloing) {
2234 currently_soloing = something_soloed;
2237 modify_solo_mute (is_track, same_thing_soloed);
2240 SoloActive (currently_soloing); /* EMIT SIGNAL */
2243 SoloChanged (); /* EMIT SIGNAL */
2249 Session::update_route_solo_state ()
2252 bool is_track = false;
2253 bool signal = false;
2255 /* caller must hold RouteLock */
2257 /* this is where we actually implement solo by changing
2258 the solo mute setting of each track.
2261 shared_ptr<RouteList> r = routes.reader ();
2263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2264 if ((*i)->soloed()) {
2266 if (dynamic_cast<Track*>((*i).get())) {
2273 if (mute != currently_soloing) {
2275 currently_soloing = mute;
2278 if (!is_track && !mute) {
2280 /* nothing is soloed */
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 (*i)->set_solo_mute (false);
2293 modify_solo_mute (is_track, mute);
2296 SoloActive (currently_soloing);
2301 Session::modify_solo_mute (bool is_track, bool mute)
2303 shared_ptr<RouteList> r = routes.reader ();
2305 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2309 /* only alter track solo mute */
2311 if (dynamic_cast<Track*>((*i).get())) {
2312 if ((*i)->soloed()) {
2313 (*i)->set_solo_mute (!mute);
2315 (*i)->set_solo_mute (mute);
2321 /* only alter bus solo mute */
2323 if (!dynamic_cast<Track*>((*i).get())) {
2325 if ((*i)->soloed()) {
2327 (*i)->set_solo_mute (false);
2331 /* don't mute master or control outs
2332 in response to another bus solo
2335 if ((*i) != _master_out &&
2336 (*i) != _control_out) {
2337 (*i)->set_solo_mute (mute);
2348 Session::catch_up_on_solo ()
2350 /* this is called after set_state() to catch the full solo
2351 state, which can't be correctly determined on a per-route
2352 basis, but needs the global overview that only the session
2355 update_route_solo_state();
2359 Session::route_by_name (string name)
2361 shared_ptr<RouteList> r = routes.reader ();
2363 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2364 if ((*i)->name() == name) {
2369 return shared_ptr<Route> ((Route*) 0);
2373 Session::route_by_id (PBD::ID id)
2375 shared_ptr<RouteList> r = routes.reader ();
2377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2378 if ((*i)->id() == id) {
2383 return shared_ptr<Route> ((Route*) 0);
2387 Session::route_by_remote_id (uint32_t id)
2389 shared_ptr<RouteList> r = routes.reader ();
2391 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2392 if ((*i)->remote_control_id() == id) {
2397 return shared_ptr<Route> ((Route*) 0);
2401 Session::find_current_end ()
2403 if (_state_of_the_state & Loading) {
2407 nframes_t max = get_maximum_extent ();
2409 if (max > end_location->end()) {
2410 end_location->set_end (max);
2412 DurationChanged(); /* EMIT SIGNAL */
2417 Session::get_maximum_extent () const
2422 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2424 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2425 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2427 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2428 if ((me = pl->get_maximum_extent()) > max) {
2436 boost::shared_ptr<Diskstream>
2437 Session::diskstream_by_name (string name)
2439 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2441 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2442 if ((*i)->name() == name) {
2447 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2450 boost::shared_ptr<Diskstream>
2451 Session::diskstream_by_id (const PBD::ID& id)
2453 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2455 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2456 if ((*i)->id() == id) {
2461 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2464 /* Region management */
2467 Session::new_region_name (string old)
2469 string::size_type last_period;
2471 string::size_type len = old.length() + 64;
2474 if ((last_period = old.find_last_of ('.')) == string::npos) {
2476 /* no period present - add one explicitly */
2479 last_period = old.length() - 1;
2484 number = atoi (old.substr (last_period+1).c_str());
2488 while (number < (UINT_MAX-1)) {
2490 RegionList::const_iterator i;
2495 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2498 for (i = regions.begin(); i != regions.end(); ++i) {
2499 if (i->second->name() == sbuf) {
2504 if (i == regions.end()) {
2509 if (number != (UINT_MAX-1)) {
2513 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2518 Session::region_name (string& result, string base, bool newlevel)
2523 assert(base.find("/") == string::npos);
2527 Glib::Mutex::Lock lm (region_lock);
2529 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2538 string::size_type pos;
2540 pos = base.find_last_of ('.');
2542 /* pos may be npos, but then we just use entire base */
2544 subbase = base.substr (0, pos);
2549 Glib::Mutex::Lock lm (region_lock);
2551 map<string,uint32_t>::iterator x;
2555 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2557 region_name_map[subbase] = 1;
2560 snprintf (buf, sizeof (buf), ".%d", x->second);
2571 Session::add_region (boost::shared_ptr<Region> region)
2573 vector<boost::shared_ptr<Region> > v;
2574 v.push_back (region);
2579 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2584 Glib::Mutex::Lock lm (region_lock);
2586 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2588 boost::shared_ptr<Region> region = *ii;
2592 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2596 RegionList::iterator x;
2598 for (x = regions.begin(); x != regions.end(); ++x) {
2600 if (region->region_list_equivalent (x->second)) {
2605 if (x == regions.end()) {
2607 pair<RegionList::key_type,RegionList::mapped_type> entry;
2609 entry.first = region->id();
2610 entry.second = region;
2612 pair<RegionList::iterator,bool> x = regions.insert (entry);
2624 /* mark dirty because something has changed even if we didn't
2625 add the region to the region list.
2632 vector<boost::weak_ptr<Region> > v;
2633 boost::shared_ptr<Region> first_r;
2635 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2637 boost::shared_ptr<Region> region = *ii;
2641 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2644 v.push_back (region);
2651 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2652 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2654 update_region_name_map (region);
2658 RegionsAdded (v); /* EMIT SIGNAL */
2664 Session::update_region_name_map (boost::shared_ptr<Region> region)
2666 string::size_type last_period = region->name().find_last_of ('.');
2668 if (last_period != string::npos && last_period < region->name().length() - 1) {
2670 string base = region->name().substr (0, last_period);
2671 string number = region->name().substr (last_period+1);
2672 map<string,uint32_t>::iterator x;
2674 /* note that if there is no number, we get zero from atoi,
2678 region_name_map[base] = atoi (number);
2683 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2685 boost::shared_ptr<Region> region (weak_region.lock ());
2691 if (what_changed & Region::HiddenChanged) {
2692 /* relay hidden changes */
2693 RegionHiddenChange (region);
2696 if (what_changed & NameChanged) {
2697 update_region_name_map (region);
2702 Session::remove_region (boost::weak_ptr<Region> weak_region)
2704 RegionList::iterator i;
2705 boost::shared_ptr<Region> region (weak_region.lock ());
2711 bool removed = false;
2714 Glib::Mutex::Lock lm (region_lock);
2716 if ((i = regions.find (region->id())) != regions.end()) {
2722 /* mark dirty because something has changed even if we didn't
2723 remove the region from the region list.
2729 RegionRemoved(region); /* EMIT SIGNAL */
2733 boost::shared_ptr<Region>
2734 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2736 RegionList::iterator i;
2737 boost::shared_ptr<Region> region;
2739 Glib::Mutex::Lock lm (region_lock);
2741 for (i = regions.begin(); i != regions.end(); ++i) {
2745 if (region->whole_file()) {
2747 if (child->source_equivalent (region)) {
2753 return boost::shared_ptr<Region> ();
2757 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2759 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2760 (*i)->get_region_list_equivalent_regions (region, result);
2764 Session::destroy_region (boost::shared_ptr<Region> region)
2766 vector<boost::shared_ptr<Source> > srcs;
2769 if (region->playlist()) {
2770 region->playlist()->destroy_region (region);
2773 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2774 srcs.push_back (region->source (n));
2778 region->drop_references ();
2780 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2782 (*i)->mark_for_remove ();
2783 (*i)->drop_references ();
2785 cerr << "source was not used by any playlist\n";
2792 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2794 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2795 destroy_region (*i);
2801 Session::remove_last_capture ()
2803 list<boost::shared_ptr<Region> > r;
2805 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2807 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2808 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2811 r.insert (r.end(), l.begin(), l.end());
2816 destroy_regions (r);
2818 save_state (_current_snapshot_name);
2824 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2830 /* Source Management */
2832 Session::add_source (boost::shared_ptr<Source> source)
2834 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2835 pair<SourceMap::iterator,bool> result;
2837 entry.first = source->id();
2838 entry.second = source;
2841 Glib::Mutex::Lock lm (source_lock);
2842 result = sources.insert (entry);
2845 if (result.second) {
2846 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2850 boost::shared_ptr<AudioFileSource> afs;
2852 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2853 if (Config->get_auto_analyse_audio()) {
2854 Analyser::queue_source_for_analysis (source, false);
2860 Session::remove_source (boost::weak_ptr<Source> src)
2862 SourceMap::iterator i;
2863 boost::shared_ptr<Source> source = src.lock();
2870 Glib::Mutex::Lock lm (source_lock);
2872 if ((i = sources.find (source->id())) != sources.end()) {
2877 if (!_state_of_the_state & InCleanup) {
2879 /* save state so we don't end up with a session file
2880 referring to non-existent sources.
2883 save_state (_current_snapshot_name);
2887 boost::shared_ptr<Source>
2888 Session::source_by_id (const PBD::ID& id)
2890 Glib::Mutex::Lock lm (source_lock);
2891 SourceMap::iterator i;
2892 boost::shared_ptr<Source> source;
2894 if ((i = sources.find (id)) != sources.end()) {
2902 boost::shared_ptr<Source>
2903 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2905 Glib::Mutex::Lock lm (source_lock);
2907 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2908 cerr << "comparing " << path << " with " << i->second->name() << endl;
2909 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2911 if (afs && afs->path() == path && chn == afs->channel()) {
2916 return boost::shared_ptr<Source>();
2920 Session::peak_path (Glib::ustring base) const
2922 sys::path peakfile_path(_session_dir->peak_path());
2923 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2924 return peakfile_path.to_string();
2928 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2931 string old_basename = PBD::basename_nosuffix (oldname);
2932 string new_legalized = legalize_for_path (newname);
2934 /* note: we know (or assume) the old path is already valid */
2938 /* destructive file sources have a name of the form:
2940 /path/to/Tnnnn-NAME(%[LR])?.wav
2942 the task here is to replace NAME with the new name.
2945 /* find last slash */
2949 string::size_type slash;
2950 string::size_type dash;
2952 if ((slash = path.find_last_of ('/')) == string::npos) {
2956 dir = path.substr (0, slash+1);
2958 /* '-' is not a legal character for the NAME part of the path */
2960 if ((dash = path.find_last_of ('-')) == string::npos) {
2964 prefix = path.substr (slash+1, dash-(slash+1));
2969 path += new_legalized;
2970 path += ".wav"; /* XXX gag me with a spoon */
2974 /* non-destructive file sources have a name of the form:
2976 /path/to/NAME-nnnnn(%[LR])?.wav
2978 the task here is to replace NAME with the new name.
2983 string::size_type slash;
2984 string::size_type dash;
2985 string::size_type postfix;
2987 /* find last slash */
2989 if ((slash = path.find_last_of ('/')) == string::npos) {
2993 dir = path.substr (0, slash+1);
2995 /* '-' is not a legal character for the NAME part of the path */
2997 if ((dash = path.find_last_of ('-')) == string::npos) {
3001 suffix = path.substr (dash+1);
3003 // Suffix is now everything after the dash. Now we need to eliminate
3004 // the nnnnn part, which is done by either finding a '%' or a '.'
3006 postfix = suffix.find_last_of ("%");
3007 if (postfix == string::npos) {
3008 postfix = suffix.find_last_of ('.');
3011 if (postfix != string::npos) {
3012 suffix = suffix.substr (postfix);
3014 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3018 const uint32_t limit = 10000;
3019 char buf[PATH_MAX+1];
3021 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3023 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3025 if (access (buf, F_OK) != 0) {
3033 error << "FATAL ERROR! Could not find a " << endl;
3042 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3046 char buf[PATH_MAX+1];
3047 const uint32_t limit = 10000;
3051 legalized = legalize_for_path (name);
3053 /* find a "version" of the file name that doesn't exist in
3054 any of the possible directories.
3057 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3059 vector<space_and_path>::iterator i;
3060 uint32_t existing = 0;
3062 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3064 SessionDirectory sdir((*i).path);
3066 spath = sdir.sound_path().to_string();
3070 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3071 } else if (nchan == 2) {
3073 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3075 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3077 } else if (nchan < 26) {
3078 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3080 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3089 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3090 } else if (nchan == 2) {
3092 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3094 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3096 } else if (nchan < 26) {
3097 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3099 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3103 if (sys::exists(buf)) {
3109 if (existing == 0) {
3114 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3116 throw failed_constructor();
3120 /* we now have a unique name for the file, but figure out where to
3126 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3128 spath = sdir.sound_path().to_string();
3131 string::size_type pos = foo.find_last_of ('/');
3133 if (pos == string::npos) {
3136 spath += foo.substr (pos + 1);
3142 boost::shared_ptr<AudioFileSource>
3143 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3145 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3146 return boost::dynamic_pointer_cast<AudioFileSource> (
3147 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3150 // FIXME: _terrible_ code duplication
3152 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3155 string old_basename = PBD::basename_nosuffix (oldname);
3156 string new_legalized = legalize_for_path (newname);
3158 /* note: we know (or assume) the old path is already valid */
3162 /* destructive file sources have a name of the form:
3164 /path/to/Tnnnn-NAME(%[LR])?.wav
3166 the task here is to replace NAME with the new name.
3169 /* find last slash */
3173 string::size_type slash;
3174 string::size_type dash;
3176 if ((slash = path.find_last_of ('/')) == string::npos) {
3180 dir = path.substr (0, slash+1);
3182 /* '-' is not a legal character for the NAME part of the path */
3184 if ((dash = path.find_last_of ('-')) == string::npos) {
3188 prefix = path.substr (slash+1, dash-(slash+1));
3193 path += new_legalized;
3194 path += ".mid"; /* XXX gag me with a spoon */
3198 /* non-destructive file sources have a name of the form:
3200 /path/to/NAME-nnnnn(%[LR])?.wav
3202 the task here is to replace NAME with the new name.
3207 string::size_type slash;
3208 string::size_type dash;
3209 string::size_type postfix;
3211 /* find last slash */
3213 if ((slash = path.find_last_of ('/')) == string::npos) {
3217 dir = path.substr (0, slash+1);
3219 /* '-' is not a legal character for the NAME part of the path */
3221 if ((dash = path.find_last_of ('-')) == string::npos) {
3225 suffix = path.substr (dash+1);
3227 // Suffix is now everything after the dash. Now we need to eliminate
3228 // the nnnnn part, which is done by either finding a '%' or a '.'
3230 postfix = suffix.find_last_of ("%");
3231 if (postfix == string::npos) {
3232 postfix = suffix.find_last_of ('.');
3235 if (postfix != string::npos) {
3236 suffix = suffix.substr (postfix);
3238 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3242 const uint32_t limit = 10000;
3243 char buf[PATH_MAX+1];
3245 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3247 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3249 if (access (buf, F_OK) != 0) {
3257 error << "FATAL ERROR! Could not find a " << endl;
3266 Session::midi_path_from_name (string name)
3270 char buf[PATH_MAX+1];
3271 const uint32_t limit = 10000;
3275 legalized = legalize_for_path (name);
3277 /* find a "version" of the file name that doesn't exist in
3278 any of the possible directories.
3281 for (cnt = 1; cnt <= limit; ++cnt) {
3283 vector<space_and_path>::iterator i;
3284 uint32_t existing = 0;
3286 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3288 SessionDirectory sdir((*i).path);
3290 sys::path p = sdir.midi_path();
3294 spath = p.to_string();
3296 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3298 if (sys::exists (buf)) {
3303 if (existing == 0) {
3308 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3309 throw failed_constructor();
3313 /* we now have a unique name for the file, but figure out where to
3319 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3321 spath = sdir.midi_path().to_string();
3324 string::size_type pos = foo.find_last_of ('/');
3326 if (pos == string::npos) {
3329 spath += foo.substr (pos + 1);
3335 boost::shared_ptr<MidiSource>
3336 Session::create_midi_source_for_session (MidiDiskstream& ds)
3338 string mpath = midi_path_from_name (ds.name());
3340 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3344 /* Playlist management */
3346 boost::shared_ptr<Playlist>
3347 Session::playlist_by_name (string name)
3349 Glib::Mutex::Lock lm (playlist_lock);
3350 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3351 if ((*i)->name() == name) {
3355 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3356 if ((*i)->name() == name) {
3361 return boost::shared_ptr<Playlist>();
3365 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3367 Glib::Mutex::Lock lm (playlist_lock);
3368 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3369 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3370 list.push_back (*i);
3373 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3374 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3375 list.push_back (*i);
3381 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3383 if (playlist->hidden()) {
3388 Glib::Mutex::Lock lm (playlist_lock);
3389 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3390 playlists.insert (playlists.begin(), playlist);
3391 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3392 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3397 playlist->release();
3402 PlaylistAdded (playlist); /* EMIT SIGNAL */
3406 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3409 Glib::Mutex::Lock lm (playlist_lock);
3410 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3413 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3420 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3422 boost::shared_ptr<Playlist> pl(wpl.lock());
3428 PlaylistList::iterator x;
3431 /* its not supposed to be visible */
3436 Glib::Mutex::Lock lm (playlist_lock);
3440 unused_playlists.insert (pl);
3442 if ((x = playlists.find (pl)) != playlists.end()) {
3443 playlists.erase (x);
3449 playlists.insert (pl);
3451 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3452 unused_playlists.erase (x);
3459 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3461 if (_state_of_the_state & Deletion) {
3465 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3472 Glib::Mutex::Lock lm (playlist_lock);
3474 PlaylistList::iterator i;
3476 i = find (playlists.begin(), playlists.end(), playlist);
3477 if (i != playlists.end()) {
3478 playlists.erase (i);
3481 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3482 if (i != unused_playlists.end()) {
3483 unused_playlists.erase (i);
3490 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3494 Session::set_audition (boost::shared_ptr<Region> r)
3496 pending_audition_region = r;
3497 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3498 schedule_butler_transport_work ();
3502 Session::audition_playlist ()
3504 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3505 ev->region.reset ();
3510 Session::non_realtime_set_audition ()
3512 if (!pending_audition_region) {
3513 auditioner->audition_current_playlist ();
3515 auditioner->audition_region (pending_audition_region);
3516 pending_audition_region.reset ();
3518 AuditionActive (true); /* EMIT SIGNAL */
3522 Session::audition_region (boost::shared_ptr<Region> r)
3524 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3530 Session::cancel_audition ()
3532 if (auditioner->active()) {
3533 auditioner->cancel_audition ();
3534 AuditionActive (false); /* EMIT SIGNAL */
3539 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3541 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3545 Session::remove_empty_sounds ()
3547 vector<string> audio_filenames;
3549 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3551 Glib::Mutex::Lock lm (source_lock);
3553 TapeFileMatcher tape_file_matcher;
3555 remove_if (audio_filenames.begin(), audio_filenames.end(),
3556 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3558 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3560 sys::path audio_file_path (_session_dir->sound_path());
3562 audio_file_path /= *i;
3564 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3568 sys::remove (audio_file_path);
3569 const string peakfile = peak_path (audio_file_path.to_string());
3570 sys::remove (peakfile);
3572 catch (const sys::filesystem_error& err)
3574 error << err.what() << endmsg;
3581 Session::is_auditioning () const
3583 /* can be called before we have an auditioner object */
3585 return auditioner->active();
3592 Session::set_all_solo (bool yn)
3594 shared_ptr<RouteList> r = routes.reader ();
3596 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3597 if (!(*i)->is_hidden()) {
3598 (*i)->set_solo (yn, this);
3606 Session::set_all_mute (bool yn)
3608 shared_ptr<RouteList> r = routes.reader ();
3610 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3611 if (!(*i)->is_hidden()) {
3612 (*i)->set_mute (yn, this);
3620 Session::n_diskstreams () const
3624 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3626 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3627 if (!(*i)->hidden()) {
3635 Session::graph_reordered ()
3637 /* don't do this stuff if we are setting up connections
3638 from a set_state() call or creating new tracks.
3641 if (_state_of_the_state & InitialConnecting) {
3645 /* every track/bus asked for this to be handled but it was deferred because
3646 we were connecting. do it now.
3649 request_input_change_handling ();
3653 /* force all diskstreams to update their capture offset values to
3654 reflect any changes in latencies within the graph.
3657 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3659 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3660 (*i)->set_capture_offset ();
3665 Session::record_disenable_all ()
3667 record_enable_change_all (false);
3671 Session::record_enable_all ()
3673 record_enable_change_all (true);
3677 Session::record_enable_change_all (bool yn)
3679 shared_ptr<RouteList> r = routes.reader ();
3681 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3684 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3685 at->set_record_enable (yn, this);
3689 /* since we don't keep rec-enable state, don't mark session dirty */
3693 Session::add_processor (Processor* processor)
3696 PortInsert* port_insert;
3697 PluginInsert* plugin_insert;
3699 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3700 _port_inserts.insert (_port_inserts.begin(), port_insert);
3701 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3702 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3703 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3704 _sends.insert (_sends.begin(), send);
3706 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3710 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3716 Session::remove_processor (Processor* processor)
3719 PortInsert* port_insert;
3720 PluginInsert* plugin_insert;
3722 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3723 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3724 if (x != _port_inserts.end()) {
3725 insert_bitset[port_insert->bit_slot()] = false;
3726 _port_inserts.erase (x);
3728 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3729 _plugin_inserts.remove (plugin_insert);
3730 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3731 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3732 if (x != _sends.end()) {
3733 send_bitset[send->bit_slot()] = false;
3737 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3745 Session::available_capture_duration ()
3747 float sample_bytes_on_disk = 4.0; // keep gcc happy
3749 switch (Config->get_native_file_data_format()) {
3751 sample_bytes_on_disk = 4.0;
3755 sample_bytes_on_disk = 3.0;
3759 sample_bytes_on_disk = 2.0;
3763 /* impossible, but keep some gcc versions happy */
3764 fatal << string_compose (_("programming error: %1"),
3765 X_("illegal native file data format"))
3770 double scale = 4096.0 / sample_bytes_on_disk;
3772 if (_total_free_4k_blocks * scale > (double) max_frames) {
3776 return (nframes_t) floor (_total_free_4k_blocks * scale);
3780 Session::add_bundle (shared_ptr<Bundle> bundle)
3783 Glib::Mutex::Lock guard (bundle_lock);
3784 _bundles.push_back (bundle);
3787 BundleAdded (bundle); /* EMIT SIGNAL */
3793 Session::remove_bundle (shared_ptr<Bundle> bundle)
3795 bool removed = false;
3798 Glib::Mutex::Lock guard (bundle_lock);
3799 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3801 if (i != _bundles.end()) {
3808 BundleRemoved (bundle); /* EMIT SIGNAL */
3815 Session::bundle_by_name (string name) const
3817 Glib::Mutex::Lock lm (bundle_lock);
3819 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3820 if ((*i)->name() == name) {
3825 return boost::shared_ptr<Bundle> ();
3829 Session::tempo_map_changed (Change ignored)
3833 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3834 (*i)->update_after_tempo_map_change ();
3837 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3838 (*i)->update_after_tempo_map_change ();
3844 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3845 * the given count with the current block size.
3848 Session::ensure_buffers (ChanCount howmany)
3850 if (current_block_size == 0)
3851 return; // too early? (is this ok?)
3853 // We need at least 2 MIDI scratch buffers to mix/merge
3854 if (howmany.n_midi() < 2)
3855 howmany.set_midi(2);
3857 // FIXME: JACK needs to tell us maximum MIDI buffer size
3858 // Using nasty assumption (max # events == nframes) for now
3859 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3860 _mix_buffers->ensure_buffers(howmany, current_block_size);
3861 _silent_buffers->ensure_buffers(howmany, current_block_size);
3863 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3867 Session::next_insert_id ()
3869 /* this doesn't really loop forever. just think about it */
3872 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3873 if (!insert_bitset[n]) {
3874 insert_bitset[n] = true;
3880 /* none available, so resize and try again */
3882 insert_bitset.resize (insert_bitset.size() + 16, false);
3887 Session::next_send_id ()
3889 /* this doesn't really loop forever. just think about it */
3892 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3893 if (!send_bitset[n]) {
3894 send_bitset[n] = true;
3900 /* none available, so resize and try again */
3902 send_bitset.resize (send_bitset.size() + 16, false);
3907 Session::mark_send_id (uint32_t id)
3909 if (id >= send_bitset.size()) {
3910 send_bitset.resize (id+16, false);
3912 if (send_bitset[id]) {
3913 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3915 send_bitset[id] = true;
3919 Session::mark_insert_id (uint32_t id)
3921 if (id >= insert_bitset.size()) {
3922 insert_bitset.resize (id+16, false);
3924 if (insert_bitset[id]) {
3925 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3927 insert_bitset[id] = true;
3930 /* Named Selection management */
3933 Session::named_selection_by_name (string name)
3935 Glib::Mutex::Lock lm (named_selection_lock);
3936 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3937 if ((*i)->name == name) {
3945 Session::add_named_selection (NamedSelection* named_selection)
3948 Glib::Mutex::Lock lm (named_selection_lock);
3949 named_selections.insert (named_selections.begin(), named_selection);
3952 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3958 NamedSelectionAdded (); /* EMIT SIGNAL */
3962 Session::remove_named_selection (NamedSelection* named_selection)
3964 bool removed = false;
3967 Glib::Mutex::Lock lm (named_selection_lock);
3969 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3971 if (i != named_selections.end()) {
3973 named_selections.erase (i);
3980 NamedSelectionRemoved (); /* EMIT SIGNAL */
3985 Session::reset_native_file_format ()
3987 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3989 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3990 (*i)->reset_write_sources (false);
3995 Session::route_name_unique (string n) const
3997 shared_ptr<RouteList> r = routes.reader ();
3999 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4000 if ((*i)->name() == n) {
4009 Session::n_playlists () const
4011 Glib::Mutex::Lock lm (playlist_lock);
4012 return playlists.size();
4016 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4018 if (!force && howmany <= _npan_buffers) {
4022 if (_pan_automation_buffer) {
4024 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4025 delete [] _pan_automation_buffer[i];
4028 delete [] _pan_automation_buffer;
4031 _pan_automation_buffer = new pan_t*[howmany];
4033 for (uint32_t i = 0; i < howmany; ++i) {
4034 _pan_automation_buffer[i] = new pan_t[nframes];
4037 _npan_buffers = howmany;
4041 Session::freeze (InterThreadInfo& itt)
4043 shared_ptr<RouteList> r = routes.reader ();
4045 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4049 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4050 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4060 boost::shared_ptr<Region>
4061 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4062 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4064 boost::shared_ptr<Region> result;
4065 boost::shared_ptr<Playlist> playlist;
4066 boost::shared_ptr<AudioFileSource> fsource;
4068 char buf[PATH_MAX+1];
4069 ChanCount nchans(track.audio_diskstream()->n_channels());
4071 nframes_t this_chunk;
4074 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4075 const string sound_dir = sdir.sound_path().to_string();
4076 nframes_t len = end - start;
4079 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4080 end, start) << endmsg;
4084 // any bigger than this seems to cause stack overflows in called functions
4085 const nframes_t chunk_size = (128 * 1024)/4;
4087 g_atomic_int_set (&processing_prohibited, 1);
4089 /* call tree *MUST* hold route_lock */
4091 if ((playlist = track.diskstream()->playlist()) == 0) {
4095 /* external redirects will be a problem */
4097 if (track.has_external_redirects()) {
4101 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4103 for (x = 0; x < 99999; ++x) {
4104 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4105 if (access (buf, F_OK) != 0) {
4111 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4116 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4117 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4120 catch (failed_constructor& err) {
4121 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4125 srcs.push_back (fsource);
4128 /* XXX need to flush all redirects */
4133 /* create a set of reasonably-sized buffers */
4134 buffers.ensure_buffers(nchans, chunk_size);
4135 buffers.set_count(nchans);
4137 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4138 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4140 afs->prepare_for_peakfile_writes ();
4143 while (to_do && !itt.cancel) {
4145 this_chunk = min (to_do, chunk_size);
4147 if (track.export_stuff (buffers, start, this_chunk)) {
4152 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4153 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4156 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4162 start += this_chunk;
4163 to_do -= this_chunk;
4165 itt.progress = (float) (1.0 - ((double) to_do / len));
4174 xnow = localtime (&now);
4176 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4177 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4180 afs->update_header (position, *xnow, now);
4181 afs->flush_header ();
4185 /* construct a region to represent the bounced material */
4187 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4188 region_name_from_path (srcs.front()->name(), true));
4193 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4194 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4197 afs->mark_for_remove ();
4200 (*src)->drop_references ();
4204 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4205 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4208 afs->done_with_peakfile_writes ();
4212 g_atomic_int_set (&processing_prohibited, 0);
4218 Session::get_silent_buffers (ChanCount count)
4220 assert(_silent_buffers->available() >= count);
4221 _silent_buffers->set_count(count);
4223 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4224 for (size_t i= 0; i < count.get(*t); ++i) {
4225 _silent_buffers->get(*t, i).clear();
4229 return *_silent_buffers;
4233 Session::get_scratch_buffers (ChanCount count)
4235 assert(_scratch_buffers->available() >= count);
4236 _scratch_buffers->set_count(count);
4237 return *_scratch_buffers;
4241 Session::get_mix_buffers (ChanCount count)
4243 assert(_mix_buffers->available() >= count);
4244 _mix_buffers->set_count(count);
4245 return *_mix_buffers;
4249 Session::ntracks () const
4252 shared_ptr<RouteList> r = routes.reader ();
4254 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4255 if (dynamic_cast<Track*> ((*i).get())) {
4264 Session::nbusses () const
4267 shared_ptr<RouteList> r = routes.reader ();
4269 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4270 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4279 Session::add_automation_list(AutomationList *al)
4281 automation_lists[al->id()] = al;
4285 Session::compute_initial_length ()
4287 return _engine.frame_rate() * 60 * 5;
4291 Session::sync_order_keys ()
4293 if (!Config->get_sync_all_route_ordering()) {
4294 /* leave order keys as they are */
4298 boost::shared_ptr<RouteList> r = routes.reader ();
4300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4301 (*i)->sync_order_keys ();
4304 Route::SyncOrderKeys (); // EMIT SIGNAL
4308 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4310 Glib::Mutex::Lock lm (bundle_lock);
4311 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {