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/slave.h>
68 #include <ardour/tempo.h>
69 #include <ardour/audio_track.h>
70 #include <ardour/midi_track.h>
71 #include <ardour/cycle_timer.h>
72 #include <ardour/named_selection.h>
73 #include <ardour/crossfade.h>
74 #include <ardour/playlist.h>
75 #include <ardour/internal_send.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>
85 #include <ardour/audio_buffer.h>
86 #include <ardour/bundle.h>
91 using namespace ARDOUR;
93 using boost::shared_ptr;
96 static const int CPU_CACHE_ALIGN = 64;
98 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
101 bool Session::_disable_all_loaded_plugins = false;
103 sigc::signal<void,std::string> Session::Dialog;
104 sigc::signal<int> Session::AskAboutPendingState;
105 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
106 sigc::signal<void> Session::SendFeedback;
108 sigc::signal<void> Session::SMPTEOffsetChanged;
109 sigc::signal<void> Session::StartTimeChanged;
110 sigc::signal<void> Session::EndTimeChanged;
111 sigc::signal<void> Session::AutoBindingOn;
112 sigc::signal<void> Session::AutoBindingOff;
113 sigc::signal<void, std::string, std::string> Session::Exported;
115 Session::Session (AudioEngine &eng,
116 const string& fullpath,
117 const string& snapshot_name,
121 _scratch_buffers(new BufferSet()),
122 _silent_buffers(new BufferSet()),
123 _mix_buffers(new BufferSet()),
125 _mmc_port (default_mmc_port),
126 _mtc_port (default_mtc_port),
127 _midi_port (default_midi_port),
128 _midi_clock_port (default_midi_clock_port),
129 _session_dir (new SessionDirectory(fullpath)),
130 pending_events (2048),
132 butler_mixdown_buffer (0),
133 butler_gain_buffer (0),
134 post_transport_work((PostTransportWork)0),
135 _send_smpte_update (false),
136 midi_thread (pthread_t (0)),
137 midi_requests (128), // the size of this should match the midi request pool size
138 diskstreams (new DiskstreamList),
139 routes (new RouteList),
140 auditioner ((Auditioner*) 0),
141 _total_free_4k_blocks (0),
142 _bundles (new BundleList),
143 _bundle_xml_node (0),
146 click_emphasis_data (0),
148 _metadata (new SessionMetadata())
153 if (!eng.connected()) {
154 throw failed_constructor();
157 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
159 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
160 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
162 first_stage_init (fullpath, snapshot_name);
164 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
167 if (create (new_session, mix_template, compute_initial_length())) {
169 throw failed_constructor ();
173 if (second_stage_init (new_session)) {
175 throw failed_constructor ();
178 store_recent_sessions(_name, _path);
180 bool was_dirty = dirty();
182 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
184 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
187 DirtyChanged (); /* EMIT SIGNAL */
191 Session::Session (AudioEngine &eng,
193 string snapshot_name,
194 AutoConnectOption input_ac,
195 AutoConnectOption output_ac,
196 uint32_t control_out_channels,
197 uint32_t master_out_channels,
198 uint32_t requested_physical_in,
199 uint32_t requested_physical_out,
200 nframes_t initial_length)
203 _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 auditioner ((Auditioner *) 0),
223 _total_free_4k_blocks (0),
224 _bundles (new BundleList),
225 _bundle_xml_node (0),
226 _click_io ((IO *) 0),
228 click_emphasis_data (0),
230 _metadata (new SessionMetadata())
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 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
270 r->set_remote_control_id (control_id++);
275 if (master_out_channels) {
276 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
277 r->set_remote_control_id (control_id);
281 /* prohibit auto-connect to master, because there isn't one */
282 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
286 add_routes (rl, false);
291 Config->set_input_auto_connect (input_ac);
292 Config->set_output_auto_connect (output_ac);
294 if (second_stage_init (new_session)) {
296 throw failed_constructor ();
299 store_recent_sessions (_name, _path);
301 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
303 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
314 /* if we got to here, leaving pending capture state around
318 remove_pending_capture_state ();
320 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
322 _engine.remove_session ();
324 GoingAway (); /* EMIT SIGNAL */
330 /* clear history so that no references to objects are held any more */
334 /* clear state tree so that no references to objects are held any more */
338 terminate_butler_thread ();
339 //terminate_midi_thread ();
341 if (click_data != default_click) {
342 delete [] click_data;
345 if (click_emphasis_data != default_click_emphasis) {
346 delete [] click_emphasis_data;
351 delete _scratch_buffers;
352 delete _silent_buffers;
355 AudioDiskstream::free_working_buffers();
357 Route::SyncOrderKeys.clear();
359 #undef TRACK_DESTRUCTION
360 #ifdef TRACK_DESTRUCTION
361 cerr << "delete named selections\n";
362 #endif /* TRACK_DESTRUCTION */
363 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
364 NamedSelectionList::iterator tmp;
373 #ifdef TRACK_DESTRUCTION
374 cerr << "delete playlists\n";
375 #endif /* TRACK_DESTRUCTION */
376 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
377 PlaylistList::iterator tmp;
382 (*i)->drop_references ();
387 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
388 PlaylistList::iterator tmp;
393 (*i)->drop_references ();
399 unused_playlists.clear ();
401 #ifdef TRACK_DESTRUCTION
402 cerr << "delete regions\n";
403 #endif /* TRACK_DESTRUCTION */
405 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
406 RegionList::iterator tmp;
411 i->second->drop_references ();
418 #ifdef TRACK_DESTRUCTION
419 cerr << "delete routes\n";
420 #endif /* TRACK_DESTRUCTION */
422 RCUWriter<RouteList> writer (routes);
423 boost::shared_ptr<RouteList> r = writer.get_copy ();
424 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
425 (*i)->drop_references ();
428 /* writer goes out of scope and updates master */
433 #ifdef TRACK_DESTRUCTION
434 cerr << "delete diskstreams\n";
435 #endif /* TRACK_DESTRUCTION */
437 RCUWriter<DiskstreamList> dwriter (diskstreams);
438 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
439 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
440 (*i)->drop_references ();
444 diskstreams.flush ();
446 #ifdef TRACK_DESTRUCTION
447 cerr << "delete audio sources\n";
448 #endif /* TRACK_DESTRUCTION */
449 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
450 SourceMap::iterator tmp;
455 i->second->drop_references ();
461 #ifdef TRACK_DESTRUCTION
462 cerr << "delete mix groups\n";
463 #endif /* TRACK_DESTRUCTION */
464 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
465 list<RouteGroup*>::iterator tmp;
475 #ifdef TRACK_DESTRUCTION
476 cerr << "delete edit groups\n";
477 #endif /* TRACK_DESTRUCTION */
478 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
479 list<RouteGroup*>::iterator tmp;
489 delete [] butler_mixdown_buffer;
490 delete [] butler_gain_buffer;
492 Crossfade::set_buffer_size (0);
498 Session::set_worst_io_latencies ()
500 _worst_output_latency = 0;
501 _worst_input_latency = 0;
503 if (!_engine.connected()) {
507 boost::shared_ptr<RouteList> r = routes.reader ();
509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
510 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
511 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
516 Session::when_engine_running ()
518 string first_physical_output;
520 /* we don't want to run execute this again */
522 BootMessage (_("Set block size and sample rate"));
524 set_block_size (_engine.frames_per_cycle());
525 set_frame_rate (_engine.frame_rate());
527 BootMessage (_("Using configuration"));
529 Config->map_parameters (mem_fun (*this, &Session::config_changed));
531 /* every time we reconnect, recompute worst case output latencies */
533 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
535 if (synced_to_jack()) {
536 _engine.transport_stop ();
539 if (Config->get_jack_time_master()) {
540 _engine.transport_locate (_transport_frame);
548 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
550 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
552 /* existing state for Click */
554 if (_click_io->set_state (*child->children().front()) == 0) {
556 _clicking = Config->get_clicking ();
560 error << _("could not setup Click I/O") << endmsg;
566 /* default state for Click */
568 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
570 if (first_physical_output.length()) {
571 if (_click_io->add_output_port (first_physical_output, this)) {
572 // relax, even though its an error
574 _clicking = Config->get_clicking ();
580 catch (failed_constructor& err) {
581 error << _("cannot setup Click I/O") << endmsg;
584 BootMessage (_("Compute I/O Latencies"));
586 set_worst_io_latencies ();
589 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
592 BootMessage (_("Set up standard connections"));
594 /* Create a set of Bundle objects that map
595 to the physical I/O currently available */
597 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
599 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
601 shared_ptr<Bundle> c (new Bundle (buf, true));
602 c->add_channel (_("mono"));
603 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
608 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
610 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
612 shared_ptr<Bundle> c (new Bundle (buf, false));
613 c->add_channel (_("mono"));
614 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
621 /* create master/control ports */
626 /* force the master to ignore any later call to this */
628 if (_master_out->pending_state_node) {
629 _master_out->ports_became_legal();
632 /* no panner resets till we are through */
634 _master_out->defer_pan_reset ();
636 while (_master_out->n_inputs().n_audio()
637 < _master_out->input_maximum().n_audio()) {
638 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
639 error << _("cannot setup master inputs")
645 while (_master_out->n_outputs().n_audio()
646 < _master_out->output_maximum().n_audio()) {
647 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
648 error << _("cannot setup master outputs")
655 _master_out->allow_pan_reset ();
660 BootMessage (_("Setup signal flow and plugins"));
664 /* catch up on send+insert cnts */
666 BootMessage (_("Catch up with send/insert state"));
670 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
673 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
674 if (id > insert_cnt) {
682 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
685 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
693 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
695 /* hook us up to the engine */
697 BootMessage (_("Connect to engine"));
699 _engine.set_session (this);
703 Session::hookup_io ()
705 /* stop graph reordering notifications from
706 causing resorts, etc.
709 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
712 if (auditioner == 0) {
714 /* we delay creating the auditioner till now because
715 it makes its own connections to ports.
716 the engine has to be running for this to work.
720 auditioner.reset (new Auditioner (*this));
723 catch (failed_constructor& err) {
724 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
728 /* Tell all IO objects to create their ports */
734 vector<string> cports;
736 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
737 if (_control_out->add_input_port ("", this)) {
738 error << _("cannot setup control inputs")
744 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
745 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
746 error << _("cannot set up master outputs")
754 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
756 for (n = 0; n < ni; ++n) {
757 cports.push_back (_control_out->input(n)->name());
760 boost::shared_ptr<RouteList> r = routes.reader ();
762 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
763 (*x)->set_control_outs (cports);
767 /* load bundles, which we may have postponed earlier on */
768 if (_bundle_xml_node) {
769 load_bundles (*_bundle_xml_node);
770 delete _bundle_xml_node;
773 /* Tell all IO objects to connect themselves together */
775 IO::enable_connecting ();
777 /* Now reset all panners */
779 IO::reset_panners ();
781 /* Anyone who cares about input state, wake up and do something */
783 IOConnectionsComplete (); /* EMIT SIGNAL */
785 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
788 /* now handle the whole enchilada as if it was one
794 /* update mixer solo state */
800 Session::playlist_length_changed ()
802 /* we can't just increase end_location->end() if pl->get_maximum_extent()
803 if larger. if the playlist used to be the longest playlist,
804 and its now shorter, we have to decrease end_location->end(). hence,
805 we have to iterate over all diskstreams and check the
806 playlists currently in use.
812 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
814 boost::shared_ptr<Playlist> playlist;
816 if ((playlist = dstream->playlist()) != 0) {
817 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
820 /* see comment in playlist_length_changed () */
825 Session::record_enabling_legal () const
827 /* this used to be in here, but survey says.... we don't need to restrict it */
828 // if (record_status() == Recording) {
832 if (Config->get_all_safe()) {
839 Session::reset_input_monitor_state ()
841 if (transport_rolling()) {
843 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
845 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
846 if ((*i)->record_enabled ()) {
847 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
848 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
852 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
854 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
855 if ((*i)->record_enabled ()) {
856 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
857 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
864 Session::auto_punch_start_changed (Location* location)
866 replace_event (Event::PunchIn, location->start());
868 if (get_record_enabled() && Config->get_punch_in()) {
869 /* capture start has been changed, so save new pending state */
870 save_state ("", true);
875 Session::auto_punch_end_changed (Location* location)
877 nframes_t when_to_stop = location->end();
878 // when_to_stop += _worst_output_latency + _worst_input_latency;
879 replace_event (Event::PunchOut, when_to_stop);
883 Session::auto_punch_changed (Location* location)
885 nframes_t when_to_stop = location->end();
887 replace_event (Event::PunchIn, location->start());
888 //when_to_stop += _worst_output_latency + _worst_input_latency;
889 replace_event (Event::PunchOut, when_to_stop);
893 Session::auto_loop_changed (Location* location)
895 replace_event (Event::AutoLoop, location->end(), location->start());
897 if (transport_rolling() && play_loop) {
899 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
901 if (_transport_frame > location->end()) {
902 // relocate to beginning of loop
903 clear_events (Event::LocateRoll);
905 request_locate (location->start(), true);
908 else if (Config->get_seamless_loop() && !loop_changing) {
910 // schedule a locate-roll to refill the diskstreams at the
912 loop_changing = true;
914 if (location->end() > last_loopend) {
915 clear_events (Event::LocateRoll);
916 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
923 last_loopend = location->end();
927 Session::set_auto_punch_location (Location* location)
931 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
932 auto_punch_start_changed_connection.disconnect();
933 auto_punch_end_changed_connection.disconnect();
934 auto_punch_changed_connection.disconnect();
935 existing->set_auto_punch (false, this);
936 remove_event (existing->start(), Event::PunchIn);
937 clear_events (Event::PunchOut);
938 auto_punch_location_changed (0);
947 if (location->end() <= location->start()) {
948 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
952 auto_punch_start_changed_connection.disconnect();
953 auto_punch_end_changed_connection.disconnect();
954 auto_punch_changed_connection.disconnect();
956 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
957 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
958 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
960 location->set_auto_punch (true, this);
963 auto_punch_changed (location);
965 auto_punch_location_changed (location);
969 Session::set_auto_loop_location (Location* location)
973 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
974 auto_loop_start_changed_connection.disconnect();
975 auto_loop_end_changed_connection.disconnect();
976 auto_loop_changed_connection.disconnect();
977 existing->set_auto_loop (false, this);
978 remove_event (existing->end(), Event::AutoLoop);
979 auto_loop_location_changed (0);
988 if (location->end() <= location->start()) {
989 error << _("Session: you can't use a mark for auto loop") << endmsg;
993 last_loopend = location->end();
995 auto_loop_start_changed_connection.disconnect();
996 auto_loop_end_changed_connection.disconnect();
997 auto_loop_changed_connection.disconnect();
999 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1000 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1001 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1003 location->set_auto_loop (true, this);
1005 /* take care of our stuff first */
1007 auto_loop_changed (location);
1009 /* now tell everyone else */
1011 auto_loop_location_changed (location);
1015 Session::locations_added (Location* ignored)
1021 Session::locations_changed ()
1023 _locations.apply (*this, &Session::handle_locations_changed);
1027 Session::handle_locations_changed (Locations::LocationList& locations)
1029 Locations::LocationList::iterator i;
1031 bool set_loop = false;
1032 bool set_punch = false;
1034 for (i = locations.begin(); i != locations.end(); ++i) {
1038 if (location->is_auto_punch()) {
1039 set_auto_punch_location (location);
1042 if (location->is_auto_loop()) {
1043 set_auto_loop_location (location);
1047 if (location->is_start()) {
1048 start_location = location;
1050 if (location->is_end()) {
1051 end_location = location;
1056 set_auto_loop_location (0);
1059 set_auto_punch_location (0);
1066 Session::enable_record ()
1068 /* XXX really atomic compare+swap here */
1069 if (g_atomic_int_get (&_record_status) != Recording) {
1070 g_atomic_int_set (&_record_status, Recording);
1071 _last_record_location = _transport_frame;
1072 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1074 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1075 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1076 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1077 if ((*i)->record_enabled ()) {
1078 (*i)->monitor_input (true);
1083 RecordStateChanged ();
1088 Session::disable_record (bool rt_context, bool force)
1092 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1094 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1095 g_atomic_int_set (&_record_status, Disabled);
1097 if (rs == Recording) {
1098 g_atomic_int_set (&_record_status, Enabled);
1102 // FIXME: timestamp correct? [DR]
1103 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1104 // does this /need/ to be sent in all cases?
1106 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1108 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1109 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1111 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1112 if ((*i)->record_enabled ()) {
1113 (*i)->monitor_input (false);
1118 RecordStateChanged (); /* emit signal */
1121 remove_pending_capture_state ();
1127 Session::step_back_from_record ()
1129 /* XXX really atomic compare+swap here */
1130 if (g_atomic_int_get (&_record_status) == Recording) {
1131 g_atomic_int_set (&_record_status, Enabled);
1133 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1134 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1136 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1137 if ((*i)->record_enabled ()) {
1138 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1139 (*i)->monitor_input (false);
1147 Session::maybe_enable_record ()
1149 g_atomic_int_set (&_record_status, Enabled);
1151 /* this function is currently called from somewhere other than an RT thread.
1152 this save_state() call therefore doesn't impact anything.
1155 save_state ("", true);
1157 if (_transport_speed) {
1158 if (!Config->get_punch_in()) {
1162 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1163 RecordStateChanged (); /* EMIT SIGNAL */
1170 Session::audible_frame () const
1176 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1177 return last_stop_frame;
1180 /* the first of these two possible settings for "offset"
1181 mean that the audible frame is stationary until
1182 audio emerges from the latency compensation
1185 the second means that the audible frame is stationary
1186 until audio would emerge from a physical port
1187 in the absence of any plugin latency compensation
1190 offset = _worst_output_latency;
1192 if (offset > current_block_size) {
1193 offset -= current_block_size;
1195 /* XXX is this correct? if we have no external
1196 physical connections and everything is internal
1197 then surely this is zero? still, how
1198 likely is that anyway?
1200 offset = current_block_size;
1203 if (synced_to_jack()) {
1204 tf = _engine.transport_frame();
1206 tf = _transport_frame;
1211 if (!non_realtime_work_pending()) {
1215 /* check to see if we have passed the first guaranteed
1216 audible frame past our last stopping position. if not,
1217 the return that last stopping point because in terms
1218 of audible frames, we have not moved yet.
1221 if (_transport_speed > 0.0f) {
1223 if (!play_loop || !have_looped) {
1224 if (tf < last_stop_frame + offset) {
1225 return last_stop_frame;
1234 } else if (_transport_speed < 0.0f) {
1236 /* XXX wot? no backward looping? */
1238 if (tf > last_stop_frame - offset) {
1239 return last_stop_frame;
1251 Session::set_frame_rate (nframes_t frames_per_second)
1253 /** \fn void Session::set_frame_size(nframes_t)
1254 the AudioEngine object that calls this guarantees
1255 that it will not be called while we are also in
1256 ::process(). Its fine to do things that block
1260 _base_frame_rate = frames_per_second;
1264 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1268 // XXX we need some equivalent to this, somehow
1269 // SndFileSource::setup_standard_crossfades (frames_per_second);
1273 /* XXX need to reset/reinstantiate all LADSPA plugins */
1277 Session::set_block_size (nframes_t nframes)
1279 /* the AudioEngine guarantees
1280 that it will not be called while we are also in
1281 ::process(). It is therefore fine to do things that block
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 (dynamic_cast<MidiTrack*>((*i).get()) != 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->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1545 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1551 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1555 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1556 port = physinputs[(channels_used+x)%nphysical_in];
1559 if (port.length() && track->connect_input (track->input (x), port, this)) {
1565 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1569 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1570 port = physoutputs[(channels_used+x)%nphysical_out];
1571 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1573 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1577 if (port.length() && track->connect_output (track->output (x), port, this)) {
1582 channels_used += track->n_inputs ().n_midi();
1586 track->midi_diskstream()->non_realtime_input_change();
1588 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1589 //track->set_remote_control_id (control_id);
1591 new_routes.push_back (track);
1592 ret.push_back (track);
1595 catch (failed_constructor &err) {
1596 error << _("Session: could not create new midi track.") << endmsg;
1599 /* we need to get rid of this, since the track failed to be created */
1600 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1603 RCUWriter<DiskstreamList> writer (diskstreams);
1604 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1605 ds->remove (track->midi_diskstream());
1612 catch (AudioEngine::PortRegistrationFailure& pfe) {
1614 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;
1617 /* we need to get rid of this, since the track failed to be created */
1618 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1621 RCUWriter<DiskstreamList> writer (diskstreams);
1622 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1623 ds->remove (track->midi_diskstream());
1634 if (!new_routes.empty()) {
1635 add_routes (new_routes, false);
1636 save_state (_current_snapshot_name);
1642 list<boost::shared_ptr<AudioTrack> >
1643 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1645 char track_name[32];
1646 uint32_t track_id = 0;
1648 uint32_t channels_used = 0;
1650 RouteList new_routes;
1651 list<boost::shared_ptr<AudioTrack> > ret;
1652 uint32_t control_id;
1654 /* count existing audio tracks */
1657 shared_ptr<RouteList> r = routes.reader ();
1659 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1660 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1661 if (!(*i)->is_hidden()) {
1663 channels_used += (*i)->n_inputs().n_audio();
1669 vector<string> physinputs;
1670 vector<string> physoutputs;
1672 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1673 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1675 control_id = ntracks() + nbusses() + 1;
1679 /* check for duplicate route names, since we might have pre-existing
1680 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1681 save, close,restart,add new route - first named route is now
1689 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1691 if (route_by_name (track_name) == 0) {
1695 } while (track_id < (UINT_MAX-1));
1697 shared_ptr<AudioTrack> track;
1700 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1702 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1703 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1704 input_channels, output_channels)
1709 if (!physinputs.empty()) {
1710 uint32_t nphysical_in = physinputs.size();
1712 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1716 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1717 port = physinputs[(channels_used+x)%nphysical_in];
1720 if (port.length() && track->connect_input (track->input (x), port, this)) {
1726 if (!physoutputs.empty()) {
1727 uint32_t nphysical_out = physoutputs.size();
1729 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1733 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1734 port = physoutputs[(channels_used+x)%nphysical_out];
1735 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1737 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1741 if (port.length() && track->connect_output (track->output (x), port, this)) {
1747 channels_used += track->n_inputs ().n_audio();
1749 track->audio_diskstream()->non_realtime_input_change();
1751 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1752 track->set_remote_control_id (control_id);
1755 new_routes.push_back (track);
1756 ret.push_back (track);
1759 catch (failed_constructor &err) {
1760 error << _("Session: could not create new audio track.") << endmsg;
1763 /* we need to get rid of this, since the track failed to be created */
1764 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1767 RCUWriter<DiskstreamList> writer (diskstreams);
1768 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1769 ds->remove (track->audio_diskstream());
1776 catch (AudioEngine::PortRegistrationFailure& pfe) {
1778 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;
1781 /* we need to get rid of this, since the track failed to be created */
1782 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1785 RCUWriter<DiskstreamList> writer (diskstreams);
1786 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1787 ds->remove (track->audio_diskstream());
1798 if (!new_routes.empty()) {
1799 add_routes (new_routes, true);
1806 Session::set_remote_control_ids ()
1808 RemoteModel m = Config->get_remote_model();
1810 shared_ptr<RouteList> r = routes.reader ();
1812 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1813 if ( MixerOrdered == m) {
1814 long order = (*i)->order_key(N_("signal"));
1815 (*i)->set_remote_control_id( order+1 );
1816 } else if ( EditorOrdered == m) {
1817 long order = (*i)->order_key(N_("editor"));
1818 (*i)->set_remote_control_id( order+1 );
1819 } else if ( UserOrdered == m) {
1820 //do nothing ... only changes to remote id's are initiated by user
1827 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1830 uint32_t bus_id = 1;
1832 uint32_t channels_used = 0;
1835 uint32_t control_id;
1837 /* count existing audio busses */
1840 shared_ptr<RouteList> r = routes.reader ();
1842 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1843 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1845 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1848 channels_used += (*i)->n_inputs().n_audio();
1854 vector<string> physinputs;
1855 vector<string> physoutputs;
1857 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1858 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1860 n_physical_audio_outputs = physoutputs.size();
1861 n_physical_audio_inputs = physinputs.size();
1863 control_id = ntracks() + nbusses() + 1;
1868 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1872 if (route_by_name (bus_name) == 0) {
1876 } while (bus_id < (UINT_MAX-1));
1879 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1881 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1882 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1883 input_channels, output_channels)
1891 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1895 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1896 port = physinputs[((n+x)%n_physical_audio_inputs)];
1899 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1905 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1908 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1909 port = physoutputs[((n+x)%n_physical_outputs)];
1910 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1912 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1916 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1921 channels_used += bus->n_inputs ().n_audio();
1923 bus->set_remote_control_id (control_id);
1926 ret.push_back (bus);
1930 catch (failed_constructor &err) {
1931 error << _("Session: could not create new audio route.") << endmsg;
1935 catch (AudioEngine::PortRegistrationFailure& pfe) {
1936 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;
1946 add_routes (ret, true);
1954 Session::add_routes (RouteList& new_routes, bool save)
1957 RCUWriter<RouteList> writer (routes);
1958 shared_ptr<RouteList> r = writer.get_copy ();
1959 r->insert (r->end(), new_routes.begin(), new_routes.end());
1960 resort_routes_using (r);
1963 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1965 boost::weak_ptr<Route> wpr (*x);
1967 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1968 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1969 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1970 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1972 if ((*x)->is_master()) {
1976 if ((*x)->is_control()) {
1977 _control_out = (*x);
1981 if (_control_out && IO::connecting_legal) {
1983 vector<string> cports;
1984 uint32_t ni = _control_out->n_inputs().n_audio();
1986 for (uint32_t n = 0; n < ni; ++n) {
1987 cports.push_back (_control_out->input(n)->name());
1990 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1991 (*x)->set_control_outs (cports);
1998 save_state (_current_snapshot_name);
2001 RouteAdded (new_routes); /* EMIT SIGNAL */
2005 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2007 /* need to do this in case we're rolling at the time, to prevent false underruns */
2008 dstream->do_refill_with_alloc ();
2010 dstream->set_block_size (current_block_size);
2013 RCUWriter<DiskstreamList> writer (diskstreams);
2014 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2015 ds->push_back (dstream);
2016 /* writer goes out of scope, copies ds back to main */
2019 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2020 /* this will connect to future changes, and check the current length */
2021 diskstream_playlist_changed (dstream);
2023 dstream->prepare ();
2028 Session::remove_route (shared_ptr<Route> route)
2031 RCUWriter<RouteList> writer (routes);
2032 shared_ptr<RouteList> rs = writer.get_copy ();
2036 /* deleting the master out seems like a dumb
2037 idea, but its more of a UI policy issue
2041 if (route == _master_out) {
2042 _master_out = shared_ptr<Route> ();
2045 if (route == _control_out) {
2046 _control_out = shared_ptr<Route> ();
2048 /* cancel control outs for all routes */
2050 vector<string> empty;
2052 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2053 (*r)->set_control_outs (empty);
2057 update_route_solo_state ();
2059 /* writer goes out of scope, forces route list update */
2063 boost::shared_ptr<Diskstream> ds;
2065 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2066 ds = t->diskstream();
2072 RCUWriter<DiskstreamList> dsl (diskstreams);
2073 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2078 find_current_end ();
2080 // We need to disconnect the routes inputs and outputs
2082 route->disconnect_inputs (0);
2083 route->disconnect_outputs (0);
2085 update_latency_compensation (false, false);
2088 /* get rid of it from the dead wood collection in the route list manager */
2090 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2094 /* try to cause everyone to drop their references */
2096 route->drop_references ();
2098 sync_order_keys (N_("session"));
2100 /* save the new state of the world */
2102 if (save_state (_current_snapshot_name)) {
2103 save_history (_current_snapshot_name);
2108 Session::route_mute_changed (void* src)
2114 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2116 if (solo_update_disabled) {
2122 boost::shared_ptr<Route> route = wpr.lock ();
2125 /* should not happen */
2126 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2130 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2132 shared_ptr<RouteList> r = routes.reader ();
2134 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2136 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2140 /* don't mess with busses */
2142 if (dynamic_cast<Track*>((*i).get()) == 0) {
2148 /* don't mess with tracks */
2150 if (dynamic_cast<Track*>((*i).get()) != 0) {
2155 if ((*i) != route &&
2156 ((*i)->mix_group () == 0 ||
2157 (*i)->mix_group () != route->mix_group () ||
2158 !route->mix_group ()->is_active())) {
2160 if ((*i)->soloed()) {
2162 /* if its already soloed, and solo latching is enabled,
2163 then leave it as it is.
2166 if (Config->get_solo_latched()) {
2173 solo_update_disabled = true;
2174 (*i)->set_solo (false, src);
2175 solo_update_disabled = false;
2179 bool something_soloed = false;
2180 bool same_thing_soloed = false;
2181 bool signal = false;
2183 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2184 if ((*i)->soloed()) {
2185 something_soloed = true;
2186 if (dynamic_cast<Track*>((*i).get())) {
2188 same_thing_soloed = true;
2193 same_thing_soloed = true;
2201 if (something_soloed != currently_soloing) {
2203 currently_soloing = something_soloed;
2206 modify_solo_mute (is_track, same_thing_soloed);
2209 SoloActive (currently_soloing); /* EMIT SIGNAL */
2212 SoloChanged (); /* EMIT SIGNAL */
2218 Session::update_route_solo_state ()
2221 bool is_track = false;
2222 bool signal = false;
2224 /* this is where we actually implement solo by changing
2225 the solo mute setting of each track.
2228 shared_ptr<RouteList> r = routes.reader ();
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if ((*i)->soloed()) {
2233 if (dynamic_cast<Track*>((*i).get())) {
2240 if (mute != currently_soloing) {
2242 currently_soloing = mute;
2245 if (!is_track && !mute) {
2247 /* nothing is soloed */
2249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2250 (*i)->set_solo_mute (false);
2260 modify_solo_mute (is_track, mute);
2263 SoloActive (currently_soloing);
2268 Session::modify_solo_mute (bool is_track, bool mute)
2270 shared_ptr<RouteList> r = routes.reader ();
2272 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2276 /* only alter track solo mute */
2278 if (dynamic_cast<Track*>((*i).get())) {
2279 if ((*i)->soloed()) {
2280 (*i)->set_solo_mute (!mute);
2282 (*i)->set_solo_mute (mute);
2288 /* only alter bus solo mute */
2290 if (!dynamic_cast<Track*>((*i).get())) {
2292 if ((*i)->soloed()) {
2294 (*i)->set_solo_mute (false);
2298 /* don't mute master or control outs
2299 in response to another bus solo
2302 if ((*i) != _master_out &&
2303 (*i) != _control_out) {
2304 (*i)->set_solo_mute (mute);
2315 Session::catch_up_on_solo ()
2317 /* this is called after set_state() to catch the full solo
2318 state, which can't be correctly determined on a per-route
2319 basis, but needs the global overview that only the session
2322 update_route_solo_state();
2326 Session::catch_up_on_solo_mute_override ()
2328 if (Config->get_solo_model() != InverseMute) {
2332 /* this is called whenever the param solo-mute-override is
2335 shared_ptr<RouteList> r = routes.reader ();
2337 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2338 (*i)->catch_up_on_solo_mute_override ();
2343 Session::route_by_name (string name)
2345 shared_ptr<RouteList> r = routes.reader ();
2347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2348 if ((*i)->name() == name) {
2353 return shared_ptr<Route> ((Route*) 0);
2357 Session::route_by_id (PBD::ID id)
2359 shared_ptr<RouteList> r = routes.reader ();
2361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2362 if ((*i)->id() == id) {
2367 return shared_ptr<Route> ((Route*) 0);
2371 Session::route_by_remote_id (uint32_t id)
2373 shared_ptr<RouteList> r = routes.reader ();
2375 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2376 if ((*i)->remote_control_id() == id) {
2381 return shared_ptr<Route> ((Route*) 0);
2385 Session::find_current_end ()
2387 if (_state_of_the_state & Loading) {
2391 nframes_t max = get_maximum_extent ();
2393 if (max > end_location->end()) {
2394 end_location->set_end (max);
2396 DurationChanged(); /* EMIT SIGNAL */
2401 Session::get_maximum_extent () const
2406 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2408 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2409 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2411 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2412 if ((me = pl->get_maximum_extent()) > max) {
2420 boost::shared_ptr<Diskstream>
2421 Session::diskstream_by_name (string name)
2423 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2425 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2426 if ((*i)->name() == name) {
2431 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2434 boost::shared_ptr<Diskstream>
2435 Session::diskstream_by_id (const PBD::ID& id)
2437 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2439 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2440 if ((*i)->id() == id) {
2445 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2448 /* Region management */
2451 Session::new_region_name (string old)
2453 string::size_type last_period;
2455 string::size_type len = old.length() + 64;
2458 if ((last_period = old.find_last_of ('.')) == string::npos) {
2460 /* no period present - add one explicitly */
2463 last_period = old.length() - 1;
2468 number = atoi (old.substr (last_period+1).c_str());
2472 while (number < (UINT_MAX-1)) {
2474 RegionList::const_iterator i;
2479 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2482 for (i = regions.begin(); i != regions.end(); ++i) {
2483 if (i->second->name() == sbuf) {
2488 if (i == regions.end()) {
2493 if (number != (UINT_MAX-1)) {
2497 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2502 Session::region_name (string& result, string base, bool newlevel)
2507 assert(base.find("/") == string::npos);
2511 Glib::Mutex::Lock lm (region_lock);
2513 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2522 string::size_type pos;
2524 pos = base.find_last_of ('.');
2526 /* pos may be npos, but then we just use entire base */
2528 subbase = base.substr (0, pos);
2533 Glib::Mutex::Lock lm (region_lock);
2535 map<string,uint32_t>::iterator x;
2539 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2541 region_name_map[subbase] = 1;
2544 snprintf (buf, sizeof (buf), ".%d", x->second);
2555 Session::add_region (boost::shared_ptr<Region> region)
2557 vector<boost::shared_ptr<Region> > v;
2558 v.push_back (region);
2563 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2568 Glib::Mutex::Lock lm (region_lock);
2570 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2572 boost::shared_ptr<Region> region = *ii;
2576 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2580 RegionList::iterator x;
2582 for (x = regions.begin(); x != regions.end(); ++x) {
2584 if (region->region_list_equivalent (x->second)) {
2589 if (x == regions.end()) {
2591 pair<RegionList::key_type,RegionList::mapped_type> entry;
2593 entry.first = region->id();
2594 entry.second = region;
2596 pair<RegionList::iterator,bool> x = regions.insert (entry);
2608 /* mark dirty because something has changed even if we didn't
2609 add the region to the region list.
2616 vector<boost::weak_ptr<Region> > v;
2617 boost::shared_ptr<Region> first_r;
2619 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2621 boost::shared_ptr<Region> region = *ii;
2625 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2628 v.push_back (region);
2635 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2636 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2638 update_region_name_map (region);
2642 RegionsAdded (v); /* EMIT SIGNAL */
2648 Session::update_region_name_map (boost::shared_ptr<Region> region)
2650 string::size_type last_period = region->name().find_last_of ('.');
2652 if (last_period != string::npos && last_period < region->name().length() - 1) {
2654 string base = region->name().substr (0, last_period);
2655 string number = region->name().substr (last_period+1);
2656 map<string,uint32_t>::iterator x;
2658 /* note that if there is no number, we get zero from atoi,
2662 region_name_map[base] = atoi (number);
2667 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2669 boost::shared_ptr<Region> region (weak_region.lock ());
2675 if (what_changed & Region::HiddenChanged) {
2676 /* relay hidden changes */
2677 RegionHiddenChange (region);
2680 if (what_changed & NameChanged) {
2681 update_region_name_map (region);
2686 Session::remove_region (boost::weak_ptr<Region> weak_region)
2688 RegionList::iterator i;
2689 boost::shared_ptr<Region> region (weak_region.lock ());
2695 bool removed = false;
2698 Glib::Mutex::Lock lm (region_lock);
2700 if ((i = regions.find (region->id())) != regions.end()) {
2706 /* mark dirty because something has changed even if we didn't
2707 remove the region from the region list.
2713 RegionRemoved(region); /* EMIT SIGNAL */
2717 boost::shared_ptr<Region>
2718 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2720 RegionList::iterator i;
2721 boost::shared_ptr<Region> region;
2723 Glib::Mutex::Lock lm (region_lock);
2725 for (i = regions.begin(); i != regions.end(); ++i) {
2729 if (region->whole_file()) {
2731 if (child->source_equivalent (region)) {
2737 return boost::shared_ptr<Region> ();
2741 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2743 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2744 (*i)->get_region_list_equivalent_regions (region, result);
2748 Session::destroy_region (boost::shared_ptr<Region> region)
2750 vector<boost::shared_ptr<Source> > srcs;
2753 if (region->playlist()) {
2754 region->playlist()->destroy_region (region);
2757 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2758 srcs.push_back (region->source (n));
2762 region->drop_references ();
2764 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2766 (*i)->mark_for_remove ();
2767 (*i)->drop_references ();
2769 cerr << "source was not used by any playlist\n";
2776 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2778 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2779 destroy_region (*i);
2785 Session::remove_last_capture ()
2787 list<boost::shared_ptr<Region> > r;
2789 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2791 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2792 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2795 r.insert (r.end(), l.begin(), l.end());
2800 destroy_regions (r);
2802 save_state (_current_snapshot_name);
2808 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2814 /* Source Management */
2816 Session::add_source (boost::shared_ptr<Source> source)
2818 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2819 pair<SourceMap::iterator,bool> result;
2821 entry.first = source->id();
2822 entry.second = source;
2825 Glib::Mutex::Lock lm (source_lock);
2826 result = sources.insert (entry);
2829 if (result.second) {
2830 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2834 boost::shared_ptr<AudioFileSource> afs;
2836 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2837 if (Config->get_auto_analyse_audio()) {
2838 Analyser::queue_source_for_analysis (source, false);
2844 Session::remove_source (boost::weak_ptr<Source> src)
2846 SourceMap::iterator i;
2847 boost::shared_ptr<Source> source = src.lock();
2854 Glib::Mutex::Lock lm (source_lock);
2856 if ((i = sources.find (source->id())) != sources.end()) {
2861 if (!_state_of_the_state & InCleanup) {
2863 /* save state so we don't end up with a session file
2864 referring to non-existent sources.
2867 save_state (_current_snapshot_name);
2871 boost::shared_ptr<Source>
2872 Session::source_by_id (const PBD::ID& id)
2874 Glib::Mutex::Lock lm (source_lock);
2875 SourceMap::iterator i;
2876 boost::shared_ptr<Source> source;
2878 if ((i = sources.find (id)) != sources.end()) {
2886 boost::shared_ptr<Source>
2887 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2889 Glib::Mutex::Lock lm (source_lock);
2891 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2892 cerr << "comparing " << path << " with " << i->second->name() << endl;
2893 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2895 if (afs && afs->path() == path && chn == afs->channel()) {
2900 return boost::shared_ptr<Source>();
2904 Session::peak_path (Glib::ustring base) const
2906 sys::path peakfile_path(_session_dir->peak_path());
2907 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2908 return peakfile_path.to_string();
2912 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2915 string old_basename = PBD::basename_nosuffix (oldname);
2916 string new_legalized = legalize_for_path (newname);
2918 /* note: we know (or assume) the old path is already valid */
2922 /* destructive file sources have a name of the form:
2924 /path/to/Tnnnn-NAME(%[LR])?.wav
2926 the task here is to replace NAME with the new name.
2929 /* find last slash */
2933 string::size_type slash;
2934 string::size_type dash;
2936 if ((slash = path.find_last_of ('/')) == string::npos) {
2940 dir = path.substr (0, slash+1);
2942 /* '-' is not a legal character for the NAME part of the path */
2944 if ((dash = path.find_last_of ('-')) == string::npos) {
2948 prefix = path.substr (slash+1, dash-(slash+1));
2953 path += new_legalized;
2954 path += ".wav"; /* XXX gag me with a spoon */
2958 /* non-destructive file sources have a name of the form:
2960 /path/to/NAME-nnnnn(%[LR])?.wav
2962 the task here is to replace NAME with the new name.
2967 string::size_type slash;
2968 string::size_type dash;
2969 string::size_type postfix;
2971 /* find last slash */
2973 if ((slash = path.find_last_of ('/')) == string::npos) {
2977 dir = path.substr (0, slash+1);
2979 /* '-' is not a legal character for the NAME part of the path */
2981 if ((dash = path.find_last_of ('-')) == string::npos) {
2985 suffix = path.substr (dash+1);
2987 // Suffix is now everything after the dash. Now we need to eliminate
2988 // the nnnnn part, which is done by either finding a '%' or a '.'
2990 postfix = suffix.find_last_of ("%");
2991 if (postfix == string::npos) {
2992 postfix = suffix.find_last_of ('.');
2995 if (postfix != string::npos) {
2996 suffix = suffix.substr (postfix);
2998 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3002 const uint32_t limit = 10000;
3003 char buf[PATH_MAX+1];
3005 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3007 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3009 if (access (buf, F_OK) != 0) {
3017 error << "FATAL ERROR! Could not find a " << endl;
3026 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3030 char buf[PATH_MAX+1];
3031 const uint32_t limit = 10000;
3035 legalized = legalize_for_path (name);
3037 /* find a "version" of the file name that doesn't exist in
3038 any of the possible directories.
3041 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3043 vector<space_and_path>::iterator i;
3044 uint32_t existing = 0;
3046 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3048 SessionDirectory sdir((*i).path);
3050 spath = sdir.sound_path().to_string();
3054 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3055 } else if (nchan == 2) {
3057 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3059 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3061 } else if (nchan < 26) {
3062 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3064 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3073 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3074 } else if (nchan == 2) {
3076 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3078 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3080 } else if (nchan < 26) {
3081 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3083 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3087 if (sys::exists(buf)) {
3093 if (existing == 0) {
3098 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3100 throw failed_constructor();
3104 /* we now have a unique name for the file, but figure out where to
3110 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3112 spath = sdir.sound_path().to_string();
3115 string::size_type pos = foo.find_last_of ('/');
3117 if (pos == string::npos) {
3120 spath += foo.substr (pos + 1);
3126 boost::shared_ptr<AudioFileSource>
3127 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3129 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3130 return boost::dynamic_pointer_cast<AudioFileSource> (
3131 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3134 // FIXME: _terrible_ code duplication
3136 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3139 string old_basename = PBD::basename_nosuffix (oldname);
3140 string new_legalized = legalize_for_path (newname);
3142 /* note: we know (or assume) the old path is already valid */
3146 /* destructive file sources have a name of the form:
3148 /path/to/Tnnnn-NAME(%[LR])?.wav
3150 the task here is to replace NAME with the new name.
3153 /* find last slash */
3157 string::size_type slash;
3158 string::size_type dash;
3160 if ((slash = path.find_last_of ('/')) == string::npos) {
3164 dir = path.substr (0, slash+1);
3166 /* '-' is not a legal character for the NAME part of the path */
3168 if ((dash = path.find_last_of ('-')) == string::npos) {
3172 prefix = path.substr (slash+1, dash-(slash+1));
3177 path += new_legalized;
3178 path += ".mid"; /* XXX gag me with a spoon */
3182 /* non-destructive file sources have a name of the form:
3184 /path/to/NAME-nnnnn(%[LR])?.wav
3186 the task here is to replace NAME with the new name.
3191 string::size_type slash;
3192 string::size_type dash;
3193 string::size_type postfix;
3195 /* find last slash */
3197 if ((slash = path.find_last_of ('/')) == string::npos) {
3201 dir = path.substr (0, slash+1);
3203 /* '-' is not a legal character for the NAME part of the path */
3205 if ((dash = path.find_last_of ('-')) == string::npos) {
3209 suffix = path.substr (dash+1);
3211 // Suffix is now everything after the dash. Now we need to eliminate
3212 // the nnnnn part, which is done by either finding a '%' or a '.'
3214 postfix = suffix.find_last_of ("%");
3215 if (postfix == string::npos) {
3216 postfix = suffix.find_last_of ('.');
3219 if (postfix != string::npos) {
3220 suffix = suffix.substr (postfix);
3222 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3226 const uint32_t limit = 10000;
3227 char buf[PATH_MAX+1];
3229 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3231 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3233 if (access (buf, F_OK) != 0) {
3241 error << "FATAL ERROR! Could not find a " << endl;
3250 Session::midi_path_from_name (string name)
3254 char buf[PATH_MAX+1];
3255 const uint32_t limit = 10000;
3259 legalized = legalize_for_path (name);
3261 /* find a "version" of the file name that doesn't exist in
3262 any of the possible directories.
3265 for (cnt = 1; cnt <= limit; ++cnt) {
3267 vector<space_and_path>::iterator i;
3268 uint32_t existing = 0;
3270 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3272 SessionDirectory sdir((*i).path);
3274 sys::path p = sdir.midi_path();
3278 spath = p.to_string();
3280 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3282 if (sys::exists (buf)) {
3287 if (existing == 0) {
3292 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3293 throw failed_constructor();
3297 /* we now have a unique name for the file, but figure out where to
3303 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3305 spath = sdir.midi_path().to_string();
3308 string::size_type pos = foo.find_last_of ('/');
3310 if (pos == string::npos) {
3313 spath += foo.substr (pos + 1);
3319 boost::shared_ptr<MidiSource>
3320 Session::create_midi_source_for_session (MidiDiskstream& ds)
3322 string mpath = midi_path_from_name (ds.name());
3324 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3328 /* Playlist management */
3330 boost::shared_ptr<Playlist>
3331 Session::playlist_by_name (string name)
3333 Glib::Mutex::Lock lm (playlist_lock);
3334 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3335 if ((*i)->name() == name) {
3339 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3340 if ((*i)->name() == name) {
3345 return boost::shared_ptr<Playlist>();
3349 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3351 Glib::Mutex::Lock lm (playlist_lock);
3352 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3353 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3354 list.push_back (*i);
3357 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3358 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3359 list.push_back (*i);
3365 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3367 if (playlist->hidden()) {
3372 Glib::Mutex::Lock lm (playlist_lock);
3373 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3374 playlists.insert (playlists.begin(), playlist);
3375 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3376 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3381 playlist->release();
3386 PlaylistAdded (playlist); /* EMIT SIGNAL */
3390 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3393 Glib::Mutex::Lock lm (playlist_lock);
3394 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3397 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3404 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3406 boost::shared_ptr<Playlist> pl(wpl.lock());
3412 PlaylistList::iterator x;
3415 /* its not supposed to be visible */
3420 Glib::Mutex::Lock lm (playlist_lock);
3424 unused_playlists.insert (pl);
3426 if ((x = playlists.find (pl)) != playlists.end()) {
3427 playlists.erase (x);
3433 playlists.insert (pl);
3435 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3436 unused_playlists.erase (x);
3443 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3445 if (_state_of_the_state & Deletion) {
3449 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3456 Glib::Mutex::Lock lm (playlist_lock);
3458 PlaylistList::iterator i;
3460 i = find (playlists.begin(), playlists.end(), playlist);
3461 if (i != playlists.end()) {
3462 playlists.erase (i);
3465 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3466 if (i != unused_playlists.end()) {
3467 unused_playlists.erase (i);
3474 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3478 Session::set_audition (boost::shared_ptr<Region> r)
3480 pending_audition_region = r;
3481 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3482 schedule_butler_transport_work ();
3486 Session::audition_playlist ()
3488 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3489 ev->region.reset ();
3494 Session::non_realtime_set_audition ()
3496 if (!pending_audition_region) {
3497 auditioner->audition_current_playlist ();
3499 auditioner->audition_region (pending_audition_region);
3500 pending_audition_region.reset ();
3502 AuditionActive (true); /* EMIT SIGNAL */
3506 Session::audition_region (boost::shared_ptr<Region> r)
3508 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3514 Session::cancel_audition ()
3516 if (auditioner->active()) {
3517 auditioner->cancel_audition ();
3518 AuditionActive (false); /* EMIT SIGNAL */
3523 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3525 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3529 Session::remove_empty_sounds ()
3531 vector<string> audio_filenames;
3533 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3535 Glib::Mutex::Lock lm (source_lock);
3537 TapeFileMatcher tape_file_matcher;
3539 remove_if (audio_filenames.begin(), audio_filenames.end(),
3540 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3542 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3544 sys::path audio_file_path (_session_dir->sound_path());
3546 audio_file_path /= *i;
3548 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3552 sys::remove (audio_file_path);
3553 const string peakfile = peak_path (audio_file_path.to_string());
3554 sys::remove (peakfile);
3556 catch (const sys::filesystem_error& err)
3558 error << err.what() << endmsg;
3565 Session::is_auditioning () const
3567 /* can be called before we have an auditioner object */
3569 return auditioner->active();
3576 Session::set_all_solo (bool yn)
3578 shared_ptr<RouteList> r = routes.reader ();
3580 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3581 if (!(*i)->is_hidden()) {
3582 (*i)->set_solo (yn, this);
3590 Session::set_all_mute (bool yn)
3592 shared_ptr<RouteList> r = routes.reader ();
3594 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3595 if (!(*i)->is_hidden()) {
3596 (*i)->set_mute (yn, this);
3604 Session::n_diskstreams () const
3608 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3610 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3611 if (!(*i)->hidden()) {
3619 Session::graph_reordered ()
3621 /* don't do this stuff if we are setting up connections
3622 from a set_state() call or creating new tracks.
3625 if (_state_of_the_state & InitialConnecting) {
3629 /* every track/bus asked for this to be handled but it was deferred because
3630 we were connecting. do it now.
3633 request_input_change_handling ();
3637 /* force all diskstreams to update their capture offset values to
3638 reflect any changes in latencies within the graph.
3641 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3643 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3644 (*i)->set_capture_offset ();
3649 Session::record_disenable_all ()
3651 record_enable_change_all (false);
3655 Session::record_enable_all ()
3657 record_enable_change_all (true);
3661 Session::record_enable_change_all (bool yn)
3663 shared_ptr<RouteList> r = routes.reader ();
3665 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3668 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3669 at->set_record_enable (yn, this);
3673 /* since we don't keep rec-enable state, don't mark session dirty */
3677 Session::add_processor (Processor* processor)
3680 PortInsert* port_insert;
3681 PluginInsert* plugin_insert;
3683 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3684 _port_inserts.insert (_port_inserts.begin(), port_insert);
3685 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3686 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3687 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3688 _sends.insert (_sends.begin(), send);
3689 } else if (dynamic_cast<InternalSend *> (processor) != 0) {
3692 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3696 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3702 Session::remove_processor (Processor* processor)
3705 PortInsert* port_insert;
3706 PluginInsert* plugin_insert;
3708 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3709 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3710 if (x != _port_inserts.end()) {
3711 insert_bitset[port_insert->bit_slot()] = false;
3712 _port_inserts.erase (x);
3714 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3715 _plugin_inserts.remove (plugin_insert);
3716 } else if (dynamic_cast<InternalSend *> (processor) != 0) {
3718 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3719 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3720 if (x != _sends.end()) {
3721 send_bitset[send->bit_slot()] = false;
3725 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3733 Session::available_capture_duration ()
3735 float sample_bytes_on_disk = 4.0; // keep gcc happy
3737 switch (Config->get_native_file_data_format()) {
3739 sample_bytes_on_disk = 4.0;
3743 sample_bytes_on_disk = 3.0;
3747 sample_bytes_on_disk = 2.0;
3751 /* impossible, but keep some gcc versions happy */
3752 fatal << string_compose (_("programming error: %1"),
3753 X_("illegal native file data format"))
3758 double scale = 4096.0 / sample_bytes_on_disk;
3760 if (_total_free_4k_blocks * scale > (double) max_frames) {
3764 return (nframes_t) floor (_total_free_4k_blocks * scale);
3768 Session::add_bundle (shared_ptr<Bundle> bundle)
3771 RCUWriter<BundleList> writer (_bundles);
3772 boost::shared_ptr<BundleList> b = writer.get_copy ();
3773 b->push_back (bundle);
3776 BundleAdded (bundle); /* EMIT SIGNAL */
3782 Session::remove_bundle (shared_ptr<Bundle> bundle)
3784 bool removed = false;
3787 RCUWriter<BundleList> writer (_bundles);
3788 boost::shared_ptr<BundleList> b = writer.get_copy ();
3789 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3791 if (i != b->end()) {
3798 BundleRemoved (bundle); /* EMIT SIGNAL */
3805 Session::bundle_by_name (string name) const
3807 boost::shared_ptr<BundleList> b = _bundles.reader ();
3809 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3810 if ((*i)->name() == name) {
3815 return boost::shared_ptr<Bundle> ();
3819 Session::tempo_map_changed (Change ignored)
3823 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3824 (*i)->update_after_tempo_map_change ();
3827 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3828 (*i)->update_after_tempo_map_change ();
3834 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3835 * the given count with the current block size.
3838 Session::ensure_buffers (ChanCount howmany)
3840 if (current_block_size == 0)
3841 return; // too early? (is this ok?)
3843 // We need at least 2 MIDI scratch buffers to mix/merge
3844 if (howmany.n_midi() < 2)
3845 howmany.set_midi(2);
3847 // FIXME: JACK needs to tell us maximum MIDI buffer size
3848 // Using nasty assumption (max # events == nframes) for now
3849 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3850 _mix_buffers->ensure_buffers(howmany, current_block_size);
3851 _silent_buffers->ensure_buffers(howmany, current_block_size);
3853 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3857 Session::next_insert_id ()
3859 /* this doesn't really loop forever. just think about it */
3862 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3863 if (!insert_bitset[n]) {
3864 insert_bitset[n] = true;
3870 /* none available, so resize and try again */
3872 insert_bitset.resize (insert_bitset.size() + 16, false);
3877 Session::next_send_id ()
3879 /* this doesn't really loop forever. just think about it */
3882 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3883 if (!send_bitset[n]) {
3884 send_bitset[n] = true;
3890 /* none available, so resize and try again */
3892 send_bitset.resize (send_bitset.size() + 16, false);
3897 Session::mark_send_id (uint32_t id)
3899 if (id >= send_bitset.size()) {
3900 send_bitset.resize (id+16, false);
3902 if (send_bitset[id]) {
3903 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3905 send_bitset[id] = true;
3909 Session::mark_insert_id (uint32_t id)
3911 if (id >= insert_bitset.size()) {
3912 insert_bitset.resize (id+16, false);
3914 if (insert_bitset[id]) {
3915 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3917 insert_bitset[id] = true;
3920 /* Named Selection management */
3923 Session::named_selection_by_name (string name)
3925 Glib::Mutex::Lock lm (named_selection_lock);
3926 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3927 if ((*i)->name == name) {
3935 Session::add_named_selection (NamedSelection* named_selection)
3938 Glib::Mutex::Lock lm (named_selection_lock);
3939 named_selections.insert (named_selections.begin(), named_selection);
3942 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3948 NamedSelectionAdded (); /* EMIT SIGNAL */
3952 Session::remove_named_selection (NamedSelection* named_selection)
3954 bool removed = false;
3957 Glib::Mutex::Lock lm (named_selection_lock);
3959 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3961 if (i != named_selections.end()) {
3963 named_selections.erase (i);
3970 NamedSelectionRemoved (); /* EMIT SIGNAL */
3975 Session::reset_native_file_format ()
3977 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3979 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3980 (*i)->reset_write_sources (false);
3985 Session::route_name_unique (string n) const
3987 shared_ptr<RouteList> r = routes.reader ();
3989 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3990 if ((*i)->name() == n) {
3999 Session::n_playlists () const
4001 Glib::Mutex::Lock lm (playlist_lock);
4002 return playlists.size();
4006 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4008 if (!force && howmany <= _npan_buffers) {
4012 if (_pan_automation_buffer) {
4014 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4015 delete [] _pan_automation_buffer[i];
4018 delete [] _pan_automation_buffer;
4021 _pan_automation_buffer = new pan_t*[howmany];
4023 for (uint32_t i = 0; i < howmany; ++i) {
4024 _pan_automation_buffer[i] = new pan_t[nframes];
4027 _npan_buffers = howmany;
4031 Session::freeze (InterThreadInfo& itt)
4033 shared_ptr<RouteList> r = routes.reader ();
4035 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4039 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4040 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4050 boost::shared_ptr<Region>
4051 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4052 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4054 boost::shared_ptr<Region> result;
4055 boost::shared_ptr<Playlist> playlist;
4056 boost::shared_ptr<AudioFileSource> fsource;
4058 char buf[PATH_MAX+1];
4059 ChanCount nchans(track.audio_diskstream()->n_channels());
4061 nframes_t this_chunk;
4064 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4065 const string sound_dir = sdir.sound_path().to_string();
4066 nframes_t len = end - start;
4069 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4070 end, start) << endmsg;
4074 // any bigger than this seems to cause stack overflows in called functions
4075 const nframes_t chunk_size = (128 * 1024)/4;
4077 g_atomic_int_set (&processing_prohibited, 1);
4079 /* call tree *MUST* hold route_lock */
4081 if ((playlist = track.diskstream()->playlist()) == 0) {
4085 /* external redirects will be a problem */
4087 if (track.has_external_redirects()) {
4091 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4093 for (x = 0; x < 99999; ++x) {
4094 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4095 if (access (buf, F_OK) != 0) {
4101 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4106 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4107 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4110 catch (failed_constructor& err) {
4111 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4115 srcs.push_back (fsource);
4118 /* XXX need to flush all redirects */
4123 /* create a set of reasonably-sized buffers */
4124 buffers.ensure_buffers(nchans, chunk_size);
4125 buffers.set_count(nchans);
4127 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4128 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4130 afs->prepare_for_peakfile_writes ();
4133 while (to_do && !itt.cancel) {
4135 this_chunk = min (to_do, chunk_size);
4137 if (track.export_stuff (buffers, start, this_chunk)) {
4142 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4143 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4146 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4152 start += this_chunk;
4153 to_do -= this_chunk;
4155 itt.progress = (float) (1.0 - ((double) to_do / len));
4164 xnow = localtime (&now);
4166 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4167 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4170 afs->update_header (position, *xnow, now);
4171 afs->flush_header ();
4175 /* construct a region to represent the bounced material */
4177 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4178 region_name_from_path (srcs.front()->name(), true));
4183 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4184 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4187 afs->mark_for_remove ();
4190 (*src)->drop_references ();
4194 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4195 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4198 afs->done_with_peakfile_writes ();
4202 g_atomic_int_set (&processing_prohibited, 0);
4208 Session::get_silent_buffers (ChanCount count)
4210 assert(_silent_buffers->available() >= count);
4211 _silent_buffers->set_count(count);
4213 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4214 for (size_t i= 0; i < count.get(*t); ++i) {
4215 _silent_buffers->get(*t, i).clear();
4219 return *_silent_buffers;
4223 Session::get_scratch_buffers (ChanCount count)
4225 if (count != ChanCount::ZERO) {
4226 assert(_scratch_buffers->available() >= count);
4227 _scratch_buffers->set_count(count);
4229 _scratch_buffers->set_count (_scratch_buffers->available());
4232 return *_scratch_buffers;
4236 Session::get_mix_buffers (ChanCount count)
4238 assert(_mix_buffers->available() >= count);
4239 _mix_buffers->set_count(count);
4240 return *_mix_buffers;
4244 Session::ntracks () const
4247 shared_ptr<RouteList> r = routes.reader ();
4249 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4250 if (dynamic_cast<Track*> ((*i).get())) {
4259 Session::nbusses () const
4262 shared_ptr<RouteList> r = routes.reader ();
4264 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4265 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4274 Session::add_automation_list(AutomationList *al)
4276 automation_lists[al->id()] = al;
4280 Session::compute_initial_length ()
4282 return _engine.frame_rate() * 60 * 5;
4286 Session::sync_order_keys (const char* base)
4288 if (!Config->get_sync_all_route_ordering()) {
4289 /* leave order keys as they are */
4293 boost::shared_ptr<RouteList> r = routes.reader ();
4295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4296 (*i)->sync_order_keys (base);
4299 Route::SyncOrderKeys (base); // EMIT SIGNAL