2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
44 #include <pbd/file_utils.h>
46 #include <ardour/analyser.h>
47 #include <ardour/audio_buffer.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audio_track.h>
50 #include <ardour/audioengine.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/auditioner.h>
55 #include <ardour/buffer_set.h>
56 #include <ardour/bundle.h>
57 #include <ardour/click.h>
58 #include <ardour/configuration.h>
59 #include <ardour/crossfade.h>
60 #include <ardour/cycle_timer.h>
61 #include <ardour/data_type.h>
62 #include <ardour/filename_extensions.h>
63 #include <ardour/internal_send.h>
64 #include <ardour/io_processor.h>
65 #include <ardour/midi_diskstream.h>
66 #include <ardour/midi_playlist.h>
67 #include <ardour/midi_region.h>
68 #include <ardour/midi_track.h>
69 #include <ardour/named_selection.h>
70 #include <ardour/playlist.h>
71 #include <ardour/plugin_insert.h>
72 #include <ardour/port_insert.h>
73 #include <ardour/processor.h>
74 #include <ardour/recent_sessions.h>
75 #include <ardour/region_factory.h>
76 #include <ardour/route_group.h>
77 #include <ardour/send.h>
78 #include <ardour/session.h>
79 #include <ardour/session_directory.h>
80 #include <ardour/session_directory.h>
81 #include <ardour/session_metadata.h>
82 #include <ardour/slave.h>
83 #include <ardour/smf_source.h>
84 #include <ardour/source_factory.h>
85 #include <ardour/tape_file_matcher.h>
86 #include <ardour/tempo.h>
87 #include <ardour/utils.h>
92 using namespace ARDOUR;
94 using boost::shared_ptr;
97 static const int CPU_CACHE_ALIGN = 64;
99 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
102 bool Session::_disable_all_loaded_plugins = false;
104 sigc::signal<void,std::string> Session::Dialog;
105 sigc::signal<int> Session::AskAboutPendingState;
106 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
107 sigc::signal<void> Session::SendFeedback;
109 sigc::signal<void> Session::SMPTEOffsetChanged;
110 sigc::signal<void> Session::StartTimeChanged;
111 sigc::signal<void> Session::EndTimeChanged;
112 sigc::signal<void> Session::AutoBindingOn;
113 sigc::signal<void> Session::AutoBindingOff;
114 sigc::signal<void, std::string, std::string> Session::Exported;
116 Session::Session (AudioEngine &eng,
117 const string& fullpath,
118 const string& snapshot_name,
122 _scratch_buffers(new BufferSet()),
123 _silent_buffers(new BufferSet()),
124 _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),
133 butler_mixdown_buffer (0),
134 butler_gain_buffer (0),
135 post_transport_work((PostTransportWork)0),
136 _send_smpte_update (false),
137 midi_thread (pthread_t (0)),
138 midi_requests (128), // the size of this should match the midi request pool size
139 diskstreams (new DiskstreamList),
140 routes (new RouteList),
141 auditioner ((Auditioner*) 0),
142 _total_free_4k_blocks (0),
143 _bundles (new BundleList),
144 _bundle_xml_node (0),
147 click_emphasis_data (0),
149 _metadata (new SessionMetadata())
154 if (!eng.connected()) {
155 throw failed_constructor();
158 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
160 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
161 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
163 first_stage_init (fullpath, snapshot_name);
165 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
168 if (create (new_session, mix_template, compute_initial_length())) {
170 throw failed_constructor ();
174 if (second_stage_init (new_session)) {
176 throw failed_constructor ();
179 store_recent_sessions(_name, _path);
181 bool was_dirty = dirty();
183 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
185 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _scratch_buffers(new BufferSet()),
205 _silent_buffers(new BufferSet()),
206 _mix_buffers(new BufferSet()),
208 _mmc_port (default_mmc_port),
209 _mtc_port (default_mtc_port),
210 _midi_port (default_midi_port),
211 _midi_clock_port (default_midi_clock_port),
212 _session_dir ( new SessionDirectory(fullpath)),
213 pending_events (2048),
215 butler_mixdown_buffer (0),
216 butler_gain_buffer (0),
217 post_transport_work((PostTransportWork)0),
218 _send_smpte_update (false),
219 midi_thread (pthread_t (0)),
221 diskstreams (new DiskstreamList),
222 routes (new RouteList),
223 auditioner ((Auditioner *) 0),
224 _total_free_4k_blocks (0),
225 _bundles (new BundleList),
226 _bundle_xml_node (0),
227 _click_io ((IO *) 0),
229 click_emphasis_data (0),
231 _metadata (new SessionMetadata())
235 if (!eng.connected()) {
236 throw failed_constructor();
239 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
241 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
242 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
244 if (n_physical_inputs) {
245 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
248 if (n_physical_outputs) {
249 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
252 first_stage_init (fullpath, snapshot_name);
254 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
257 if (create (new_session, string(), initial_length)) {
259 throw failed_constructor ();
264 /* set up Master Out and Control Out if necessary */
269 if (control_out_channels) {
270 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
271 r->set_remote_control_id (control_id++);
276 if (master_out_channels) {
277 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
278 r->set_remote_control_id (control_id);
282 /* prohibit auto-connect to master, because there isn't one */
283 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
287 add_routes (rl, false);
292 Config->set_input_auto_connect (input_ac);
293 Config->set_output_auto_connect (output_ac);
295 if (second_stage_init (new_session)) {
297 throw failed_constructor ();
300 store_recent_sessions (_name, _path);
302 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
304 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
315 /* if we got to here, leaving pending capture state around
319 remove_pending_capture_state ();
321 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
323 _engine.remove_session ();
325 GoingAway (); /* EMIT SIGNAL */
331 /* clear history so that no references to objects are held any more */
335 /* clear state tree so that no references to objects are held any more */
339 terminate_butler_thread ();
340 //terminate_midi_thread ();
342 if (click_data != default_click) {
343 delete [] click_data;
346 if (click_emphasis_data != default_click_emphasis) {
347 delete [] click_emphasis_data;
352 delete _scratch_buffers;
353 delete _silent_buffers;
356 AudioDiskstream::free_working_buffers();
358 Route::SyncOrderKeys.clear();
360 #undef TRACK_DESTRUCTION
361 #ifdef TRACK_DESTRUCTION
362 cerr << "delete named selections\n";
363 #endif /* TRACK_DESTRUCTION */
364 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
365 NamedSelectionList::iterator tmp;
374 #ifdef TRACK_DESTRUCTION
375 cerr << "delete playlists\n";
376 #endif /* TRACK_DESTRUCTION */
377 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
378 PlaylistList::iterator tmp;
383 (*i)->drop_references ();
388 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
389 PlaylistList::iterator tmp;
394 (*i)->drop_references ();
400 unused_playlists.clear ();
402 #ifdef TRACK_DESTRUCTION
403 cerr << "delete regions\n";
404 #endif /* TRACK_DESTRUCTION */
406 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
407 RegionList::iterator tmp;
412 i->second->drop_references ();
419 #ifdef TRACK_DESTRUCTION
420 cerr << "delete routes\n";
421 #endif /* TRACK_DESTRUCTION */
423 RCUWriter<RouteList> writer (routes);
424 boost::shared_ptr<RouteList> r = writer.get_copy ();
425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
426 (*i)->drop_references ();
429 /* writer goes out of scope and updates master */
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete diskstreams\n";
436 #endif /* TRACK_DESTRUCTION */
438 RCUWriter<DiskstreamList> dwriter (diskstreams);
439 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
440 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
441 (*i)->drop_references ();
445 diskstreams.flush ();
447 #ifdef TRACK_DESTRUCTION
448 cerr << "delete audio sources\n";
449 #endif /* TRACK_DESTRUCTION */
450 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
451 SourceMap::iterator tmp;
456 i->second->drop_references ();
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete mix groups\n";
464 #endif /* TRACK_DESTRUCTION */
465 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
466 list<RouteGroup*>::iterator tmp;
476 #ifdef TRACK_DESTRUCTION
477 cerr << "delete edit groups\n";
478 #endif /* TRACK_DESTRUCTION */
479 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
480 list<RouteGroup*>::iterator tmp;
490 delete [] butler_mixdown_buffer;
491 delete [] butler_gain_buffer;
493 Crossfade::set_buffer_size (0);
499 Session::set_worst_io_latencies ()
501 _worst_output_latency = 0;
502 _worst_input_latency = 0;
504 if (!_engine.connected()) {
508 boost::shared_ptr<RouteList> r = routes.reader ();
510 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
511 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
512 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
517 Session::when_engine_running ()
519 string first_physical_output;
521 /* we don't want to run execute this again */
523 BootMessage (_("Set block size and sample rate"));
525 set_block_size (_engine.frames_per_cycle());
526 set_frame_rate (_engine.frame_rate());
528 BootMessage (_("Using configuration"));
530 Config->map_parameters (mem_fun (*this, &Session::config_changed));
532 /* every time we reconnect, recompute worst case output latencies */
534 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
536 if (synced_to_jack()) {
537 _engine.transport_stop ();
540 if (Config->get_jack_time_master()) {
541 _engine.transport_locate (_transport_frame);
549 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
551 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
553 /* existing state for Click */
555 if (_click_io->set_state (*child->children().front()) == 0) {
557 _clicking = Config->get_clicking ();
561 error << _("could not setup Click I/O") << endmsg;
567 /* default state for Click */
569 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
571 if (first_physical_output.length()) {
572 if (_click_io->add_output_port (first_physical_output, this)) {
573 // relax, even though its an error
575 _clicking = Config->get_clicking ();
581 catch (failed_constructor& err) {
582 error << _("cannot setup Click I/O") << endmsg;
585 BootMessage (_("Compute I/O Latencies"));
587 set_worst_io_latencies ();
590 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
593 BootMessage (_("Set up standard connections"));
595 /* Create a set of Bundle objects that map
596 to the physical I/O currently available */
598 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
600 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
602 shared_ptr<Bundle> c (new Bundle (buf, true));
603 c->add_channel (_("mono"));
604 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
609 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
611 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
613 shared_ptr<Bundle> c (new Bundle (buf, false));
614 c->add_channel (_("mono"));
615 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
622 /* create master/control ports */
627 /* force the master to ignore any later call to this */
629 if (_master_out->pending_state_node) {
630 _master_out->ports_became_legal();
633 /* no panner resets till we are through */
635 _master_out->defer_pan_reset ();
637 while (_master_out->n_inputs().n_audio()
638 < _master_out->input_maximum().n_audio()) {
639 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
640 error << _("cannot setup master inputs")
646 while (_master_out->n_outputs().n_audio()
647 < _master_out->output_maximum().n_audio()) {
648 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
649 error << _("cannot setup master outputs")
656 _master_out->allow_pan_reset ();
661 BootMessage (_("Setup signal flow and plugins"));
665 /* catch up on send+insert cnts */
667 BootMessage (_("Catch up with send/insert state"));
671 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
674 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
675 if (id > insert_cnt) {
683 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
686 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
694 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
696 /* hook us up to the engine */
698 BootMessage (_("Connect to engine"));
700 _engine.set_session (this);
704 Session::hookup_io ()
706 /* stop graph reordering notifications from
707 causing resorts, etc.
710 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
713 if (auditioner == 0) {
715 /* we delay creating the auditioner till now because
716 it makes its own connections to ports.
717 the engine has to be running for this to work.
721 auditioner.reset (new Auditioner (*this));
724 catch (failed_constructor& err) {
725 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
729 /* Tell all IO objects to create their ports */
735 vector<string> cports;
737 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
738 if (_control_out->add_input_port ("", this)) {
739 error << _("cannot setup control inputs")
745 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
746 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
747 error << _("cannot set up master outputs")
755 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
757 for (n = 0; n < ni; ++n) {
758 cports.push_back (_control_out->input(n)->name());
761 boost::shared_ptr<RouteList> r = routes.reader ();
763 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
764 (*x)->set_control_outs (cports);
768 /* load bundles, which we may have postponed earlier on */
769 if (_bundle_xml_node) {
770 load_bundles (*_bundle_xml_node);
771 delete _bundle_xml_node;
774 /* Tell all IO objects to connect themselves together */
776 IO::enable_connecting ();
778 /* Now reset all panners */
780 IO::reset_panners ();
782 /* Anyone who cares about input state, wake up and do something */
784 IOConnectionsComplete (); /* EMIT SIGNAL */
786 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
789 /* now handle the whole enchilada as if it was one
795 /* update mixer solo state */
801 Session::playlist_length_changed ()
803 /* we can't just increase end_location->end() if pl->get_maximum_extent()
804 if larger. if the playlist used to be the longest playlist,
805 and its now shorter, we have to decrease end_location->end(). hence,
806 we have to iterate over all diskstreams and check the
807 playlists currently in use.
813 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
815 boost::shared_ptr<Playlist> playlist;
817 if ((playlist = dstream->playlist()) != 0) {
818 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
821 /* see comment in playlist_length_changed () */
826 Session::record_enabling_legal () const
828 /* this used to be in here, but survey says.... we don't need to restrict it */
829 // if (record_status() == Recording) {
833 if (Config->get_all_safe()) {
840 Session::reset_input_monitor_state ()
842 if (transport_rolling()) {
844 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
846 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
847 if ((*i)->record_enabled ()) {
848 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
849 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
853 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
855 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
856 if ((*i)->record_enabled ()) {
857 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
858 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
865 Session::auto_punch_start_changed (Location* location)
867 replace_event (Event::PunchIn, location->start());
869 if (get_record_enabled() && Config->get_punch_in()) {
870 /* capture start has been changed, so save new pending state */
871 save_state ("", true);
876 Session::auto_punch_end_changed (Location* location)
878 nframes_t when_to_stop = location->end();
879 // when_to_stop += _worst_output_latency + _worst_input_latency;
880 replace_event (Event::PunchOut, when_to_stop);
884 Session::auto_punch_changed (Location* location)
886 nframes_t when_to_stop = location->end();
888 replace_event (Event::PunchIn, location->start());
889 //when_to_stop += _worst_output_latency + _worst_input_latency;
890 replace_event (Event::PunchOut, when_to_stop);
894 Session::auto_loop_changed (Location* location)
896 replace_event (Event::AutoLoop, location->end(), location->start());
898 if (transport_rolling() && play_loop) {
900 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
902 if (_transport_frame > location->end()) {
903 // relocate to beginning of loop
904 clear_events (Event::LocateRoll);
906 request_locate (location->start(), true);
909 else if (Config->get_seamless_loop() && !loop_changing) {
911 // schedule a locate-roll to refill the diskstreams at the
913 loop_changing = true;
915 if (location->end() > last_loopend) {
916 clear_events (Event::LocateRoll);
917 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
924 last_loopend = location->end();
928 Session::set_auto_punch_location (Location* location)
932 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
933 auto_punch_start_changed_connection.disconnect();
934 auto_punch_end_changed_connection.disconnect();
935 auto_punch_changed_connection.disconnect();
936 existing->set_auto_punch (false, this);
937 remove_event (existing->start(), Event::PunchIn);
938 clear_events (Event::PunchOut);
939 auto_punch_location_changed (0);
948 if (location->end() <= location->start()) {
949 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
953 auto_punch_start_changed_connection.disconnect();
954 auto_punch_end_changed_connection.disconnect();
955 auto_punch_changed_connection.disconnect();
957 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
958 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
959 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
961 location->set_auto_punch (true, this);
964 auto_punch_changed (location);
966 auto_punch_location_changed (location);
970 Session::set_auto_loop_location (Location* location)
974 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
975 auto_loop_start_changed_connection.disconnect();
976 auto_loop_end_changed_connection.disconnect();
977 auto_loop_changed_connection.disconnect();
978 existing->set_auto_loop (false, this);
979 remove_event (existing->end(), Event::AutoLoop);
980 auto_loop_location_changed (0);
989 if (location->end() <= location->start()) {
990 error << _("Session: you can't use a mark for auto loop") << endmsg;
994 last_loopend = location->end();
996 auto_loop_start_changed_connection.disconnect();
997 auto_loop_end_changed_connection.disconnect();
998 auto_loop_changed_connection.disconnect();
1000 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1001 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1002 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1004 location->set_auto_loop (true, this);
1006 /* take care of our stuff first */
1008 auto_loop_changed (location);
1010 /* now tell everyone else */
1012 auto_loop_location_changed (location);
1016 Session::locations_added (Location* ignored)
1022 Session::locations_changed ()
1024 _locations.apply (*this, &Session::handle_locations_changed);
1028 Session::handle_locations_changed (Locations::LocationList& locations)
1030 Locations::LocationList::iterator i;
1032 bool set_loop = false;
1033 bool set_punch = false;
1035 for (i = locations.begin(); i != locations.end(); ++i) {
1039 if (location->is_auto_punch()) {
1040 set_auto_punch_location (location);
1043 if (location->is_auto_loop()) {
1044 set_auto_loop_location (location);
1048 if (location->is_start()) {
1049 start_location = location;
1051 if (location->is_end()) {
1052 end_location = location;
1057 set_auto_loop_location (0);
1060 set_auto_punch_location (0);
1067 Session::enable_record ()
1069 /* XXX really atomic compare+swap here */
1070 if (g_atomic_int_get (&_record_status) != Recording) {
1071 g_atomic_int_set (&_record_status, Recording);
1072 _last_record_location = _transport_frame;
1073 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1075 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1076 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1077 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1078 if ((*i)->record_enabled ()) {
1079 (*i)->monitor_input (true);
1084 RecordStateChanged ();
1089 Session::disable_record (bool rt_context, bool force)
1093 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1095 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1096 g_atomic_int_set (&_record_status, Disabled);
1098 if (rs == Recording) {
1099 g_atomic_int_set (&_record_status, Enabled);
1103 // FIXME: timestamp correct? [DR]
1104 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1105 // does this /need/ to be sent in all cases?
1107 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1109 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1110 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1112 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1113 if ((*i)->record_enabled ()) {
1114 (*i)->monitor_input (false);
1119 RecordStateChanged (); /* emit signal */
1122 remove_pending_capture_state ();
1128 Session::step_back_from_record ()
1130 /* XXX really atomic compare+swap here */
1131 if (g_atomic_int_get (&_record_status) == Recording) {
1132 g_atomic_int_set (&_record_status, Enabled);
1134 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1135 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1137 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1138 if ((*i)->record_enabled ()) {
1139 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1140 (*i)->monitor_input (false);
1148 Session::maybe_enable_record ()
1150 g_atomic_int_set (&_record_status, Enabled);
1152 /* this function is currently called from somewhere other than an RT thread.
1153 this save_state() call therefore doesn't impact anything.
1156 save_state ("", true);
1158 if (_transport_speed) {
1159 if (!Config->get_punch_in()) {
1163 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1164 RecordStateChanged (); /* EMIT SIGNAL */
1171 Session::audible_frame () const
1177 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1178 return last_stop_frame;
1181 /* the first of these two possible settings for "offset"
1182 mean that the audible frame is stationary until
1183 audio emerges from the latency compensation
1186 the second means that the audible frame is stationary
1187 until audio would emerge from a physical port
1188 in the absence of any plugin latency compensation
1191 offset = _worst_output_latency;
1193 if (offset > current_block_size) {
1194 offset -= current_block_size;
1196 /* XXX is this correct? if we have no external
1197 physical connections and everything is internal
1198 then surely this is zero? still, how
1199 likely is that anyway?
1201 offset = current_block_size;
1204 if (synced_to_jack()) {
1205 tf = _engine.transport_frame();
1207 tf = _transport_frame;
1212 if (!non_realtime_work_pending()) {
1216 /* check to see if we have passed the first guaranteed
1217 audible frame past our last stopping position. if not,
1218 the return that last stopping point because in terms
1219 of audible frames, we have not moved yet.
1222 if (_transport_speed > 0.0f) {
1224 if (!play_loop || !have_looped) {
1225 if (tf < last_stop_frame + offset) {
1226 return last_stop_frame;
1235 } else if (_transport_speed < 0.0f) {
1237 /* XXX wot? no backward looping? */
1239 if (tf > last_stop_frame - offset) {
1240 return last_stop_frame;
1252 Session::set_frame_rate (nframes_t frames_per_second)
1254 /** \fn void Session::set_frame_size(nframes_t)
1255 the AudioEngine object that calls this guarantees
1256 that it will not be called while we are also in
1257 ::process(). Its fine to do things that block
1261 _base_frame_rate = frames_per_second;
1265 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1269 // XXX we need some equivalent to this, somehow
1270 // SndFileSource::setup_standard_crossfades (frames_per_second);
1274 /* XXX need to reset/reinstantiate all LADSPA plugins */
1278 Session::set_block_size (nframes_t nframes)
1280 /* the AudioEngine guarantees
1281 that it will not be called while we are also in
1282 ::process(). It is therefore fine to do things that block
1288 current_block_size = nframes;
1290 ensure_buffers(_scratch_buffers->available());
1292 delete [] _gain_automation_buffer;
1293 _gain_automation_buffer = new gain_t[nframes];
1295 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1297 boost::shared_ptr<RouteList> r = routes.reader ();
1299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1300 (*i)->set_block_size (nframes);
1303 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1304 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1305 (*i)->set_block_size (nframes);
1308 set_worst_io_latencies ();
1313 Session::set_default_fade (float steepness, float fade_msecs)
1316 nframes_t fade_frames;
1318 /* Don't allow fade of less 1 frame */
1320 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1327 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1331 default_fade_msecs = fade_msecs;
1332 default_fade_steepness = steepness;
1335 // jlc, WTF is this!
1336 Glib::RWLock::ReaderLock lm (route_lock);
1337 AudioRegion::set_default_fade (steepness, fade_frames);
1342 /* XXX have to do this at some point */
1343 /* foreach region using default fade, reset, then
1344 refill_all_diskstream_buffers ();
1349 struct RouteSorter {
1350 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1351 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1353 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1356 if (r1->fed_by.empty()) {
1357 if (r2->fed_by.empty()) {
1358 /* no ardour-based connections inbound to either route. just use signal order */
1359 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1361 /* r2 has connections, r1 does not; run r1 early */
1365 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1372 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1374 shared_ptr<Route> r2;
1376 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1377 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1381 /* make a copy of the existing list of routes that feed r1 */
1383 set<shared_ptr<Route> > existing = r1->fed_by;
1385 /* for each route that feeds r1, recurse, marking it as feeding
1389 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1392 /* r2 is a route that feeds r1 which somehow feeds base. mark
1393 base as being fed by r2
1396 rbase->fed_by.insert (r2);
1400 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1404 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1408 /* now recurse, so that we can mark base as being fed by
1409 all routes that feed r2
1412 trace_terminal (r2, rbase);
1419 Session::resort_routes ()
1421 /* don't do anything here with signals emitted
1422 by Routes while we are being destroyed.
1425 if (_state_of_the_state & Deletion) {
1432 RCUWriter<RouteList> writer (routes);
1433 shared_ptr<RouteList> r = writer.get_copy ();
1434 resort_routes_using (r);
1435 /* writer goes out of scope and forces update */
1440 Session::resort_routes_using (shared_ptr<RouteList> r)
1442 RouteList::iterator i, j;
1444 for (i = r->begin(); i != r->end(); ++i) {
1446 (*i)->fed_by.clear ();
1448 for (j = r->begin(); j != r->end(); ++j) {
1450 /* although routes can feed themselves, it will
1451 cause an endless recursive descent if we
1452 detect it. so don't bother checking for
1460 if ((*j)->feeds (*i)) {
1461 (*i)->fed_by.insert (*j);
1466 for (i = r->begin(); i != r->end(); ++i) {
1467 trace_terminal (*i, *i);
1474 cerr << "finished route resort\n";
1476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1477 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1484 list<boost::shared_ptr<MidiTrack> >
1485 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1487 char track_name[32];
1488 uint32_t track_id = 0;
1491 RouteList new_routes;
1492 list<boost::shared_ptr<MidiTrack> > ret;
1493 //uint32_t control_id;
1495 // FIXME: need physical I/O and autoconnect stuff for MIDI
1497 /* count existing midi tracks */
1500 shared_ptr<RouteList> r = routes.reader ();
1502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1503 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1504 if (!(*i)->is_hidden()) {
1506 //channels_used += (*i)->n_inputs().n_midi();
1512 vector<string> physinputs;
1513 vector<string> physoutputs;
1515 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1516 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1518 // control_id = ntracks() + nbusses();
1522 /* check for duplicate route names, since we might have pre-existing
1523 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1524 save, close,restart,add new route - first named route is now
1532 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1534 if (route_by_name (track_name) == 0) {
1538 } while (track_id < (UINT_MAX-1));
1540 shared_ptr<MidiTrack> track;
1543 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1545 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1546 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1552 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1556 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1557 port = physinputs[(channels_used+x)%nphysical_in];
1560 if (port.length() && track->connect_input (track->input (x), port, this)) {
1566 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1570 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1571 port = physoutputs[(channels_used+x)%nphysical_out];
1572 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1574 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1578 if (port.length() && track->connect_output (track->output (x), port, this)) {
1583 channels_used += track->n_inputs ().n_midi();
1587 track->midi_diskstream()->non_realtime_input_change();
1589 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1590 //track->set_remote_control_id (control_id);
1592 new_routes.push_back (track);
1593 ret.push_back (track);
1596 catch (failed_constructor &err) {
1597 error << _("Session: could not create new midi track.") << endmsg;
1600 /* we need to get rid of this, since the track failed to be created */
1601 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1604 RCUWriter<DiskstreamList> writer (diskstreams);
1605 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1606 ds->remove (track->midi_diskstream());
1613 catch (AudioEngine::PortRegistrationFailure& pfe) {
1615 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;
1618 /* we need to get rid of this, since the track failed to be created */
1619 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1622 RCUWriter<DiskstreamList> writer (diskstreams);
1623 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1624 ds->remove (track->midi_diskstream());
1635 if (!new_routes.empty()) {
1636 add_routes (new_routes, false);
1637 save_state (_current_snapshot_name);
1643 list<boost::shared_ptr<AudioTrack> >
1644 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1646 char track_name[32];
1647 uint32_t track_id = 0;
1649 uint32_t channels_used = 0;
1651 RouteList new_routes;
1652 list<boost::shared_ptr<AudioTrack> > ret;
1653 uint32_t control_id;
1655 /* count existing audio tracks */
1658 shared_ptr<RouteList> r = routes.reader ();
1660 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1661 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1662 if (!(*i)->is_hidden()) {
1664 channels_used += (*i)->n_inputs().n_audio();
1670 vector<string> physinputs;
1671 vector<string> physoutputs;
1673 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1674 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1676 control_id = ntracks() + nbusses() + 1;
1680 /* check for duplicate route names, since we might have pre-existing
1681 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1682 save, close,restart,add new route - first named route is now
1690 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1692 if (route_by_name (track_name) == 0) {
1696 } while (track_id < (UINT_MAX-1));
1698 shared_ptr<AudioTrack> track;
1701 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1703 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1704 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1705 input_channels, output_channels)
1710 if (!physinputs.empty()) {
1711 uint32_t nphysical_in = physinputs.size();
1713 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1717 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1718 port = physinputs[(channels_used+x)%nphysical_in];
1721 if (port.length() && track->connect_input (track->input (x), port, this)) {
1727 if (!physoutputs.empty()) {
1728 uint32_t nphysical_out = physoutputs.size();
1730 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1734 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1735 port = physoutputs[(channels_used+x)%nphysical_out];
1736 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1738 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1742 if (port.length() && track->connect_output (track->output (x), port, this)) {
1748 channels_used += track->n_inputs ().n_audio();
1750 track->audio_diskstream()->non_realtime_input_change();
1752 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1753 track->set_remote_control_id (control_id);
1756 new_routes.push_back (track);
1757 ret.push_back (track);
1760 catch (failed_constructor &err) {
1761 error << _("Session: could not create new audio track.") << endmsg;
1764 /* we need to get rid of this, since the track failed to be created */
1765 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1768 RCUWriter<DiskstreamList> writer (diskstreams);
1769 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1770 ds->remove (track->audio_diskstream());
1777 catch (AudioEngine::PortRegistrationFailure& pfe) {
1779 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;
1782 /* we need to get rid of this, since the track failed to be created */
1783 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1786 RCUWriter<DiskstreamList> writer (diskstreams);
1787 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1788 ds->remove (track->audio_diskstream());
1799 if (!new_routes.empty()) {
1800 add_routes (new_routes, true);
1807 Session::set_remote_control_ids ()
1809 RemoteModel m = Config->get_remote_model();
1811 shared_ptr<RouteList> r = routes.reader ();
1813 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1814 if ( MixerOrdered == m) {
1815 long order = (*i)->order_key(N_("signal"));
1816 (*i)->set_remote_control_id( order+1 );
1817 } else if ( EditorOrdered == m) {
1818 long order = (*i)->order_key(N_("editor"));
1819 (*i)->set_remote_control_id( order+1 );
1820 } else if ( UserOrdered == m) {
1821 //do nothing ... only changes to remote id's are initiated by user
1828 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1831 uint32_t bus_id = 1;
1833 uint32_t channels_used = 0;
1836 uint32_t control_id;
1838 /* count existing audio busses */
1841 shared_ptr<RouteList> r = routes.reader ();
1843 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1844 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1846 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1849 channels_used += (*i)->n_inputs().n_audio();
1855 vector<string> physinputs;
1856 vector<string> physoutputs;
1858 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1859 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1861 n_physical_audio_outputs = physoutputs.size();
1862 n_physical_audio_inputs = physinputs.size();
1864 control_id = ntracks() + nbusses() + 1;
1869 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1873 if (route_by_name (bus_name) == 0) {
1877 } while (bus_id < (UINT_MAX-1));
1880 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1882 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1883 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1884 input_channels, output_channels)
1892 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1896 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1897 port = physinputs[((n+x)%n_physical_audio_inputs)];
1900 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1906 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1909 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1910 port = physoutputs[((n+x)%n_physical_outputs)];
1911 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1913 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1917 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1922 channels_used += bus->n_inputs ().n_audio();
1924 bus->set_remote_control_id (control_id);
1927 ret.push_back (bus);
1931 catch (failed_constructor &err) {
1932 error << _("Session: could not create new audio route.") << endmsg;
1936 catch (AudioEngine::PortRegistrationFailure& pfe) {
1937 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;
1947 add_routes (ret, true);
1955 Session::add_routes (RouteList& new_routes, bool save)
1958 RCUWriter<RouteList> writer (routes);
1959 shared_ptr<RouteList> r = writer.get_copy ();
1960 r->insert (r->end(), new_routes.begin(), new_routes.end());
1961 resort_routes_using (r);
1964 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1966 boost::weak_ptr<Route> wpr (*x);
1968 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1969 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1970 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1971 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1973 if ((*x)->is_master()) {
1977 if ((*x)->is_control()) {
1978 _control_out = (*x);
1982 if (_control_out && IO::connecting_legal) {
1984 vector<string> cports;
1985 uint32_t ni = _control_out->n_inputs().n_audio();
1987 for (uint32_t n = 0; n < ni; ++n) {
1988 cports.push_back (_control_out->input(n)->name());
1991 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1992 (*x)->set_control_outs (cports);
1999 save_state (_current_snapshot_name);
2002 RouteAdded (new_routes); /* EMIT SIGNAL */
2006 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2008 /* need to do this in case we're rolling at the time, to prevent false underruns */
2009 dstream->do_refill_with_alloc ();
2011 dstream->set_block_size (current_block_size);
2014 RCUWriter<DiskstreamList> writer (diskstreams);
2015 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2016 ds->push_back (dstream);
2017 /* writer goes out of scope, copies ds back to main */
2020 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2021 /* this will connect to future changes, and check the current length */
2022 diskstream_playlist_changed (dstream);
2024 dstream->prepare ();
2029 Session::remove_route (shared_ptr<Route> route)
2032 RCUWriter<RouteList> writer (routes);
2033 shared_ptr<RouteList> rs = writer.get_copy ();
2037 /* deleting the master out seems like a dumb
2038 idea, but its more of a UI policy issue
2042 if (route == _master_out) {
2043 _master_out = shared_ptr<Route> ();
2046 if (route == _control_out) {
2047 _control_out = shared_ptr<Route> ();
2049 /* cancel control outs for all routes */
2051 vector<string> empty;
2053 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2054 (*r)->set_control_outs (empty);
2058 update_route_solo_state ();
2060 /* writer goes out of scope, forces route list update */
2064 boost::shared_ptr<Diskstream> ds;
2066 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2067 ds = t->diskstream();
2073 RCUWriter<DiskstreamList> dsl (diskstreams);
2074 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2079 find_current_end ();
2081 // We need to disconnect the routes inputs and outputs
2083 route->disconnect_inputs (0);
2084 route->disconnect_outputs (0);
2086 update_latency_compensation (false, false);
2089 /* get rid of it from the dead wood collection in the route list manager */
2091 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2095 /* try to cause everyone to drop their references */
2097 route->drop_references ();
2099 sync_order_keys (N_("session"));
2101 /* save the new state of the world */
2103 if (save_state (_current_snapshot_name)) {
2104 save_history (_current_snapshot_name);
2109 Session::route_mute_changed (void* src)
2115 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2117 if (solo_update_disabled) {
2123 boost::shared_ptr<Route> route = wpr.lock ();
2126 /* should not happen */
2127 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2131 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2133 shared_ptr<RouteList> r = routes.reader ();
2135 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2137 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2141 /* don't mess with busses */
2143 if (dynamic_cast<Track*>((*i).get()) == 0) {
2149 /* don't mess with tracks */
2151 if (dynamic_cast<Track*>((*i).get()) != 0) {
2156 if ((*i) != route &&
2157 ((*i)->mix_group () == 0 ||
2158 (*i)->mix_group () != route->mix_group () ||
2159 !route->mix_group ()->is_active())) {
2161 if ((*i)->soloed()) {
2163 /* if its already soloed, and solo latching is enabled,
2164 then leave it as it is.
2167 if (Config->get_solo_latched()) {
2174 solo_update_disabled = true;
2175 (*i)->set_solo (false, src);
2176 solo_update_disabled = false;
2180 bool something_soloed = false;
2181 bool same_thing_soloed = false;
2182 bool signal = false;
2184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2185 if ((*i)->soloed()) {
2186 something_soloed = true;
2187 if (dynamic_cast<Track*>((*i).get())) {
2189 same_thing_soloed = true;
2194 same_thing_soloed = true;
2202 if (something_soloed != currently_soloing) {
2204 currently_soloing = something_soloed;
2207 modify_solo_mute (is_track, same_thing_soloed);
2210 SoloActive (currently_soloing); /* EMIT SIGNAL */
2213 SoloChanged (); /* EMIT SIGNAL */
2219 Session::update_route_solo_state ()
2222 bool is_track = false;
2223 bool signal = false;
2225 /* this is where we actually implement solo by changing
2226 the solo mute setting of each track.
2229 shared_ptr<RouteList> r = routes.reader ();
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if ((*i)->soloed()) {
2234 if (dynamic_cast<Track*>((*i).get())) {
2241 if (mute != currently_soloing) {
2243 currently_soloing = mute;
2246 if (!is_track && !mute) {
2248 /* nothing is soloed */
2250 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2251 (*i)->set_solo_mute (false);
2261 modify_solo_mute (is_track, mute);
2264 SoloActive (currently_soloing);
2269 Session::modify_solo_mute (bool is_track, bool mute)
2271 shared_ptr<RouteList> r = routes.reader ();
2273 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2277 /* only alter track solo mute */
2279 if (dynamic_cast<Track*>((*i).get())) {
2280 if ((*i)->soloed()) {
2281 (*i)->set_solo_mute (!mute);
2283 (*i)->set_solo_mute (mute);
2289 /* only alter bus solo mute */
2291 if (!dynamic_cast<Track*>((*i).get())) {
2293 if ((*i)->soloed()) {
2295 (*i)->set_solo_mute (false);
2299 /* don't mute master or control outs
2300 in response to another bus solo
2303 if ((*i) != _master_out &&
2304 (*i) != _control_out) {
2305 (*i)->set_solo_mute (mute);
2316 Session::catch_up_on_solo ()
2318 /* this is called after set_state() to catch the full solo
2319 state, which can't be correctly determined on a per-route
2320 basis, but needs the global overview that only the session
2323 update_route_solo_state();
2327 Session::catch_up_on_solo_mute_override ()
2329 if (Config->get_solo_model() != InverseMute) {
2333 /* this is called whenever the param solo-mute-override is
2336 shared_ptr<RouteList> r = routes.reader ();
2338 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2339 (*i)->catch_up_on_solo_mute_override ();
2344 Session::route_by_name (string name)
2346 shared_ptr<RouteList> r = routes.reader ();
2348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2349 if ((*i)->name() == name) {
2354 return shared_ptr<Route> ((Route*) 0);
2358 Session::route_by_id (PBD::ID id)
2360 shared_ptr<RouteList> r = routes.reader ();
2362 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2363 if ((*i)->id() == id) {
2368 return shared_ptr<Route> ((Route*) 0);
2372 Session::route_by_remote_id (uint32_t id)
2374 shared_ptr<RouteList> r = routes.reader ();
2376 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2377 if ((*i)->remote_control_id() == id) {
2382 return shared_ptr<Route> ((Route*) 0);
2386 Session::find_current_end ()
2388 if (_state_of_the_state & Loading) {
2392 nframes_t max = get_maximum_extent ();
2394 if (max > end_location->end()) {
2395 end_location->set_end (max);
2397 DurationChanged(); /* EMIT SIGNAL */
2402 Session::get_maximum_extent () const
2407 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2409 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2410 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2412 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2413 if ((me = pl->get_maximum_extent()) > max) {
2421 boost::shared_ptr<Diskstream>
2422 Session::diskstream_by_name (string name)
2424 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2426 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2427 if ((*i)->name() == name) {
2432 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2435 boost::shared_ptr<Diskstream>
2436 Session::diskstream_by_id (const PBD::ID& id)
2438 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2440 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2441 if ((*i)->id() == id) {
2446 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2449 /* Region management */
2452 Session::new_region_name (string old)
2454 string::size_type last_period;
2456 string::size_type len = old.length() + 64;
2459 if ((last_period = old.find_last_of ('.')) == string::npos) {
2461 /* no period present - add one explicitly */
2464 last_period = old.length() - 1;
2469 number = atoi (old.substr (last_period+1).c_str());
2473 while (number < (UINT_MAX-1)) {
2475 RegionList::const_iterator i;
2480 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2483 for (i = regions.begin(); i != regions.end(); ++i) {
2484 if (i->second->name() == sbuf) {
2489 if (i == regions.end()) {
2494 if (number != (UINT_MAX-1)) {
2498 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2503 Session::region_name (string& result, string base, bool newlevel)
2508 assert(base.find("/") == string::npos);
2512 Glib::Mutex::Lock lm (region_lock);
2514 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2523 string::size_type pos;
2525 pos = base.find_last_of ('.');
2527 /* pos may be npos, but then we just use entire base */
2529 subbase = base.substr (0, pos);
2534 Glib::Mutex::Lock lm (region_lock);
2536 map<string,uint32_t>::iterator x;
2540 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2542 region_name_map[subbase] = 1;
2545 snprintf (buf, sizeof (buf), ".%d", x->second);
2556 Session::add_region (boost::shared_ptr<Region> region)
2558 vector<boost::shared_ptr<Region> > v;
2559 v.push_back (region);
2564 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2569 Glib::Mutex::Lock lm (region_lock);
2571 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2573 boost::shared_ptr<Region> region = *ii;
2577 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2581 RegionList::iterator x;
2583 for (x = regions.begin(); x != regions.end(); ++x) {
2585 if (region->region_list_equivalent (x->second)) {
2590 if (x == regions.end()) {
2592 pair<RegionList::key_type,RegionList::mapped_type> entry;
2594 entry.first = region->id();
2595 entry.second = region;
2597 pair<RegionList::iterator,bool> x = regions.insert (entry);
2609 /* mark dirty because something has changed even if we didn't
2610 add the region to the region list.
2617 vector<boost::weak_ptr<Region> > v;
2618 boost::shared_ptr<Region> first_r;
2620 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2622 boost::shared_ptr<Region> region = *ii;
2626 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2629 v.push_back (region);
2636 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2637 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2639 update_region_name_map (region);
2643 RegionsAdded (v); /* EMIT SIGNAL */
2649 Session::update_region_name_map (boost::shared_ptr<Region> region)
2651 string::size_type last_period = region->name().find_last_of ('.');
2653 if (last_period != string::npos && last_period < region->name().length() - 1) {
2655 string base = region->name().substr (0, last_period);
2656 string number = region->name().substr (last_period+1);
2657 map<string,uint32_t>::iterator x;
2659 /* note that if there is no number, we get zero from atoi,
2663 region_name_map[base] = atoi (number);
2668 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2670 boost::shared_ptr<Region> region (weak_region.lock ());
2676 if (what_changed & Region::HiddenChanged) {
2677 /* relay hidden changes */
2678 RegionHiddenChange (region);
2681 if (what_changed & NameChanged) {
2682 update_region_name_map (region);
2687 Session::remove_region (boost::weak_ptr<Region> weak_region)
2689 RegionList::iterator i;
2690 boost::shared_ptr<Region> region (weak_region.lock ());
2696 bool removed = false;
2699 Glib::Mutex::Lock lm (region_lock);
2701 if ((i = regions.find (region->id())) != regions.end()) {
2707 /* mark dirty because something has changed even if we didn't
2708 remove the region from the region list.
2714 RegionRemoved(region); /* EMIT SIGNAL */
2718 boost::shared_ptr<Region>
2719 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2721 RegionList::iterator i;
2722 boost::shared_ptr<Region> region;
2724 Glib::Mutex::Lock lm (region_lock);
2726 for (i = regions.begin(); i != regions.end(); ++i) {
2730 if (region->whole_file()) {
2732 if (child->source_equivalent (region)) {
2738 return boost::shared_ptr<Region> ();
2742 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2744 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2745 (*i)->get_region_list_equivalent_regions (region, result);
2749 Session::destroy_region (boost::shared_ptr<Region> region)
2751 vector<boost::shared_ptr<Source> > srcs;
2754 if (region->playlist()) {
2755 region->playlist()->destroy_region (region);
2758 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2759 srcs.push_back (region->source (n));
2763 region->drop_references ();
2765 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2767 (*i)->mark_for_remove ();
2768 (*i)->drop_references ();
2770 cerr << "source was not used by any playlist\n";
2777 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2779 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2780 destroy_region (*i);
2786 Session::remove_last_capture ()
2788 list<boost::shared_ptr<Region> > r;
2790 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2792 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2793 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2796 r.insert (r.end(), l.begin(), l.end());
2801 destroy_regions (r);
2803 save_state (_current_snapshot_name);
2809 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2815 /* Source Management */
2817 Session::add_source (boost::shared_ptr<Source> source)
2819 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2820 pair<SourceMap::iterator,bool> result;
2822 entry.first = source->id();
2823 entry.second = source;
2826 Glib::Mutex::Lock lm (source_lock);
2827 result = sources.insert (entry);
2830 if (result.second) {
2831 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2835 boost::shared_ptr<AudioFileSource> afs;
2837 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2838 if (Config->get_auto_analyse_audio()) {
2839 Analyser::queue_source_for_analysis (source, false);
2845 Session::remove_source (boost::weak_ptr<Source> src)
2847 SourceMap::iterator i;
2848 boost::shared_ptr<Source> source = src.lock();
2855 Glib::Mutex::Lock lm (source_lock);
2857 if ((i = sources.find (source->id())) != sources.end()) {
2862 if (!_state_of_the_state & InCleanup) {
2864 /* save state so we don't end up with a session file
2865 referring to non-existent sources.
2868 save_state (_current_snapshot_name);
2872 boost::shared_ptr<Source>
2873 Session::source_by_id (const PBD::ID& id)
2875 Glib::Mutex::Lock lm (source_lock);
2876 SourceMap::iterator i;
2877 boost::shared_ptr<Source> source;
2879 if ((i = sources.find (id)) != sources.end()) {
2887 boost::shared_ptr<Source>
2888 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2890 Glib::Mutex::Lock lm (source_lock);
2892 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2893 cerr << "comparing " << path << " with " << i->second->name() << endl;
2894 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2896 if (afs && afs->path() == path && chn == afs->channel()) {
2901 return boost::shared_ptr<Source>();
2905 Session::peak_path (Glib::ustring base) const
2907 sys::path peakfile_path(_session_dir->peak_path());
2908 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2909 return peakfile_path.to_string();
2913 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2916 string old_basename = PBD::basename_nosuffix (oldname);
2917 string new_legalized = legalize_for_path (newname);
2919 /* note: we know (or assume) the old path is already valid */
2923 /* destructive file sources have a name of the form:
2925 /path/to/Tnnnn-NAME(%[LR])?.wav
2927 the task here is to replace NAME with the new name.
2930 /* find last slash */
2934 string::size_type slash;
2935 string::size_type dash;
2937 if ((slash = path.find_last_of ('/')) == string::npos) {
2941 dir = path.substr (0, slash+1);
2943 /* '-' is not a legal character for the NAME part of the path */
2945 if ((dash = path.find_last_of ('-')) == string::npos) {
2949 prefix = path.substr (slash+1, dash-(slash+1));
2954 path += new_legalized;
2955 path += ".wav"; /* XXX gag me with a spoon */
2959 /* non-destructive file sources have a name of the form:
2961 /path/to/NAME-nnnnn(%[LR])?.wav
2963 the task here is to replace NAME with the new name.
2968 string::size_type slash;
2969 string::size_type dash;
2970 string::size_type postfix;
2972 /* find last slash */
2974 if ((slash = path.find_last_of ('/')) == string::npos) {
2978 dir = path.substr (0, slash+1);
2980 /* '-' is not a legal character for the NAME part of the path */
2982 if ((dash = path.find_last_of ('-')) == string::npos) {
2986 suffix = path.substr (dash+1);
2988 // Suffix is now everything after the dash. Now we need to eliminate
2989 // the nnnnn part, which is done by either finding a '%' or a '.'
2991 postfix = suffix.find_last_of ("%");
2992 if (postfix == string::npos) {
2993 postfix = suffix.find_last_of ('.');
2996 if (postfix != string::npos) {
2997 suffix = suffix.substr (postfix);
2999 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3003 const uint32_t limit = 10000;
3004 char buf[PATH_MAX+1];
3006 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3008 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3010 if (access (buf, F_OK) != 0) {
3018 error << "FATAL ERROR! Could not find a " << endl;
3027 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3031 char buf[PATH_MAX+1];
3032 const uint32_t limit = 10000;
3036 legalized = legalize_for_path (name);
3038 /* find a "version" of the file name that doesn't exist in
3039 any of the possible directories.
3042 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3044 vector<space_and_path>::iterator i;
3045 uint32_t existing = 0;
3047 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3049 SessionDirectory sdir((*i).path);
3051 spath = sdir.sound_path().to_string();
3055 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3056 } else if (nchan == 2) {
3058 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3060 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3062 } else if (nchan < 26) {
3063 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3065 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3074 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3075 } else if (nchan == 2) {
3077 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3079 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3081 } else if (nchan < 26) {
3082 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3084 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3088 if (sys::exists(buf)) {
3094 if (existing == 0) {
3099 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3101 throw failed_constructor();
3105 /* we now have a unique name for the file, but figure out where to
3111 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3113 spath = sdir.sound_path().to_string();
3116 string::size_type pos = foo.find_last_of ('/');
3118 if (pos == string::npos) {
3121 spath += foo.substr (pos + 1);
3127 boost::shared_ptr<AudioFileSource>
3128 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3130 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3131 return boost::dynamic_pointer_cast<AudioFileSource> (
3132 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3135 // FIXME: _terrible_ code duplication
3137 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3140 string old_basename = PBD::basename_nosuffix (oldname);
3141 string new_legalized = legalize_for_path (newname);
3143 /* note: we know (or assume) the old path is already valid */
3147 /* destructive file sources have a name of the form:
3149 /path/to/Tnnnn-NAME(%[LR])?.wav
3151 the task here is to replace NAME with the new name.
3154 /* find last slash */
3158 string::size_type slash;
3159 string::size_type dash;
3161 if ((slash = path.find_last_of ('/')) == string::npos) {
3165 dir = path.substr (0, slash+1);
3167 /* '-' is not a legal character for the NAME part of the path */
3169 if ((dash = path.find_last_of ('-')) == string::npos) {
3173 prefix = path.substr (slash+1, dash-(slash+1));
3178 path += new_legalized;
3179 path += ".mid"; /* XXX gag me with a spoon */
3183 /* non-destructive file sources have a name of the form:
3185 /path/to/NAME-nnnnn(%[LR])?.wav
3187 the task here is to replace NAME with the new name.
3192 string::size_type slash;
3193 string::size_type dash;
3194 string::size_type postfix;
3196 /* find last slash */
3198 if ((slash = path.find_last_of ('/')) == string::npos) {
3202 dir = path.substr (0, slash+1);
3204 /* '-' is not a legal character for the NAME part of the path */
3206 if ((dash = path.find_last_of ('-')) == string::npos) {
3210 suffix = path.substr (dash+1);
3212 // Suffix is now everything after the dash. Now we need to eliminate
3213 // the nnnnn part, which is done by either finding a '%' or a '.'
3215 postfix = suffix.find_last_of ("%");
3216 if (postfix == string::npos) {
3217 postfix = suffix.find_last_of ('.');
3220 if (postfix != string::npos) {
3221 suffix = suffix.substr (postfix);
3223 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3227 const uint32_t limit = 10000;
3228 char buf[PATH_MAX+1];
3230 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3232 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3234 if (access (buf, F_OK) != 0) {
3242 error << "FATAL ERROR! Could not find a " << endl;
3251 Session::midi_path_from_name (string name)
3255 char buf[PATH_MAX+1];
3256 const uint32_t limit = 10000;
3260 legalized = legalize_for_path (name);
3262 /* find a "version" of the file name that doesn't exist in
3263 any of the possible directories.
3266 for (cnt = 1; cnt <= limit; ++cnt) {
3268 vector<space_and_path>::iterator i;
3269 uint32_t existing = 0;
3271 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3273 SessionDirectory sdir((*i).path);
3275 sys::path p = sdir.midi_path();
3279 spath = p.to_string();
3281 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3283 if (sys::exists (buf)) {
3288 if (existing == 0) {
3293 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3294 throw failed_constructor();
3298 /* we now have a unique name for the file, but figure out where to
3304 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3306 spath = sdir.midi_path().to_string();
3309 string::size_type pos = foo.find_last_of ('/');
3311 if (pos == string::npos) {
3314 spath += foo.substr (pos + 1);
3320 boost::shared_ptr<MidiSource>
3321 Session::create_midi_source_for_session (MidiDiskstream& ds)
3323 string mpath = midi_path_from_name (ds.name());
3325 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3329 /* Playlist management */
3331 boost::shared_ptr<Playlist>
3332 Session::playlist_by_name (string name)
3334 Glib::Mutex::Lock lm (playlist_lock);
3335 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3336 if ((*i)->name() == name) {
3340 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3341 if ((*i)->name() == name) {
3346 return boost::shared_ptr<Playlist>();
3350 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3352 Glib::Mutex::Lock lm (playlist_lock);
3353 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3354 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3355 list.push_back (*i);
3358 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3359 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3360 list.push_back (*i);
3366 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3368 if (playlist->hidden()) {
3373 Glib::Mutex::Lock lm (playlist_lock);
3374 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3375 playlists.insert (playlists.begin(), playlist);
3376 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3377 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3382 playlist->release();
3387 PlaylistAdded (playlist); /* EMIT SIGNAL */
3391 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3394 Glib::Mutex::Lock lm (playlist_lock);
3395 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3398 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3405 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3407 boost::shared_ptr<Playlist> pl(wpl.lock());
3413 PlaylistList::iterator x;
3416 /* its not supposed to be visible */
3421 Glib::Mutex::Lock lm (playlist_lock);
3425 unused_playlists.insert (pl);
3427 if ((x = playlists.find (pl)) != playlists.end()) {
3428 playlists.erase (x);
3434 playlists.insert (pl);
3436 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3437 unused_playlists.erase (x);
3444 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3446 if (_state_of_the_state & Deletion) {
3450 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3457 Glib::Mutex::Lock lm (playlist_lock);
3459 PlaylistList::iterator i;
3461 i = find (playlists.begin(), playlists.end(), playlist);
3462 if (i != playlists.end()) {
3463 playlists.erase (i);
3466 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3467 if (i != unused_playlists.end()) {
3468 unused_playlists.erase (i);
3475 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3479 Session::set_audition (boost::shared_ptr<Region> r)
3481 pending_audition_region = r;
3482 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3483 schedule_butler_transport_work ();
3487 Session::audition_playlist ()
3489 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3490 ev->region.reset ();
3495 Session::non_realtime_set_audition ()
3497 if (!pending_audition_region) {
3498 auditioner->audition_current_playlist ();
3500 auditioner->audition_region (pending_audition_region);
3501 pending_audition_region.reset ();
3503 AuditionActive (true); /* EMIT SIGNAL */
3507 Session::audition_region (boost::shared_ptr<Region> r)
3509 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3515 Session::cancel_audition ()
3517 if (auditioner->active()) {
3518 auditioner->cancel_audition ();
3519 AuditionActive (false); /* EMIT SIGNAL */
3524 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3526 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3530 Session::remove_empty_sounds ()
3532 vector<string> audio_filenames;
3534 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3536 Glib::Mutex::Lock lm (source_lock);
3538 TapeFileMatcher tape_file_matcher;
3540 remove_if (audio_filenames.begin(), audio_filenames.end(),
3541 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3543 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3545 sys::path audio_file_path (_session_dir->sound_path());
3547 audio_file_path /= *i;
3549 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3553 sys::remove (audio_file_path);
3554 const string peakfile = peak_path (audio_file_path.to_string());
3555 sys::remove (peakfile);
3557 catch (const sys::filesystem_error& err)
3559 error << err.what() << endmsg;
3566 Session::is_auditioning () const
3568 /* can be called before we have an auditioner object */
3570 return auditioner->active();
3577 Session::set_all_solo (bool yn)
3579 shared_ptr<RouteList> r = routes.reader ();
3581 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3582 if (!(*i)->is_hidden()) {
3583 (*i)->set_solo (yn, this);
3591 Session::set_all_mute (bool yn)
3593 shared_ptr<RouteList> r = routes.reader ();
3595 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3596 if (!(*i)->is_hidden()) {
3597 (*i)->set_mute (yn, this);
3605 Session::n_diskstreams () const
3609 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3611 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3612 if (!(*i)->hidden()) {
3620 Session::graph_reordered ()
3622 /* don't do this stuff if we are setting up connections
3623 from a set_state() call or creating new tracks.
3626 if (_state_of_the_state & InitialConnecting) {
3630 /* every track/bus asked for this to be handled but it was deferred because
3631 we were connecting. do it now.
3634 request_input_change_handling ();
3638 /* force all diskstreams to update their capture offset values to
3639 reflect any changes in latencies within the graph.
3642 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3644 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3645 (*i)->set_capture_offset ();
3650 Session::record_disenable_all ()
3652 record_enable_change_all (false);
3656 Session::record_enable_all ()
3658 record_enable_change_all (true);
3662 Session::record_enable_change_all (bool yn)
3664 shared_ptr<RouteList> r = routes.reader ();
3666 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3669 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3670 at->set_record_enable (yn, this);
3674 /* since we don't keep rec-enable state, don't mark session dirty */
3678 Session::add_processor (Processor* processor)
3681 PortInsert* port_insert;
3682 PluginInsert* plugin_insert;
3684 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3685 _port_inserts.insert (_port_inserts.begin(), port_insert);
3686 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3687 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3688 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3689 _sends.insert (_sends.begin(), send);
3690 } else if (dynamic_cast<InternalSend *> (processor) != 0) {
3693 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3697 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3703 Session::remove_processor (Processor* processor)
3706 PortInsert* port_insert;
3707 PluginInsert* plugin_insert;
3709 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3710 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3711 if (x != _port_inserts.end()) {
3712 insert_bitset[port_insert->bit_slot()] = false;
3713 _port_inserts.erase (x);
3715 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3716 _plugin_inserts.remove (plugin_insert);
3717 } else if (dynamic_cast<InternalSend *> (processor) != 0) {
3719 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3720 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3721 if (x != _sends.end()) {
3722 send_bitset[send->bit_slot()] = false;
3726 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3734 Session::available_capture_duration ()
3736 float sample_bytes_on_disk = 4.0; // keep gcc happy
3738 switch (Config->get_native_file_data_format()) {
3740 sample_bytes_on_disk = 4.0;
3744 sample_bytes_on_disk = 3.0;
3748 sample_bytes_on_disk = 2.0;
3752 /* impossible, but keep some gcc versions happy */
3753 fatal << string_compose (_("programming error: %1"),
3754 X_("illegal native file data format"))
3759 double scale = 4096.0 / sample_bytes_on_disk;
3761 if (_total_free_4k_blocks * scale > (double) max_frames) {
3765 return (nframes_t) floor (_total_free_4k_blocks * scale);
3769 Session::add_bundle (shared_ptr<Bundle> bundle)
3772 RCUWriter<BundleList> writer (_bundles);
3773 boost::shared_ptr<BundleList> b = writer.get_copy ();
3774 b->push_back (bundle);
3777 BundleAdded (bundle); /* EMIT SIGNAL */
3783 Session::remove_bundle (shared_ptr<Bundle> bundle)
3785 bool removed = false;
3788 RCUWriter<BundleList> writer (_bundles);
3789 boost::shared_ptr<BundleList> b = writer.get_copy ();
3790 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3792 if (i != b->end()) {
3799 BundleRemoved (bundle); /* EMIT SIGNAL */
3806 Session::bundle_by_name (string name) const
3808 boost::shared_ptr<BundleList> b = _bundles.reader ();
3810 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3811 if ((*i)->name() == name) {
3816 return boost::shared_ptr<Bundle> ();
3820 Session::tempo_map_changed (Change ignored)
3824 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3825 (*i)->update_after_tempo_map_change ();
3828 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3829 (*i)->update_after_tempo_map_change ();
3835 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3836 * the given count with the current block size.
3839 Session::ensure_buffers (ChanCount howmany)
3841 if (current_block_size == 0)
3842 return; // too early? (is this ok?)
3844 // We need at least 2 MIDI scratch buffers to mix/merge
3845 if (howmany.n_midi() < 2)
3846 howmany.set_midi(2);
3848 // FIXME: JACK needs to tell us maximum MIDI buffer size
3849 // Using nasty assumption (max # events == nframes) for now
3850 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3851 _mix_buffers->ensure_buffers(howmany, current_block_size);
3852 _silent_buffers->ensure_buffers(howmany, current_block_size);
3854 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3858 Session::next_insert_id ()
3860 /* this doesn't really loop forever. just think about it */
3863 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3864 if (!insert_bitset[n]) {
3865 insert_bitset[n] = true;
3871 /* none available, so resize and try again */
3873 insert_bitset.resize (insert_bitset.size() + 16, false);
3878 Session::next_send_id ()
3880 /* this doesn't really loop forever. just think about it */
3883 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3884 if (!send_bitset[n]) {
3885 send_bitset[n] = true;
3891 /* none available, so resize and try again */
3893 send_bitset.resize (send_bitset.size() + 16, false);
3898 Session::mark_send_id (uint32_t id)
3900 if (id >= send_bitset.size()) {
3901 send_bitset.resize (id+16, false);
3903 if (send_bitset[id]) {
3904 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3906 send_bitset[id] = true;
3910 Session::mark_insert_id (uint32_t id)
3912 if (id >= insert_bitset.size()) {
3913 insert_bitset.resize (id+16, false);
3915 if (insert_bitset[id]) {
3916 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3918 insert_bitset[id] = true;
3921 /* Named Selection management */
3924 Session::named_selection_by_name (string name)
3926 Glib::Mutex::Lock lm (named_selection_lock);
3927 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3928 if ((*i)->name == name) {
3936 Session::add_named_selection (NamedSelection* named_selection)
3939 Glib::Mutex::Lock lm (named_selection_lock);
3940 named_selections.insert (named_selections.begin(), named_selection);
3943 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3949 NamedSelectionAdded (); /* EMIT SIGNAL */
3953 Session::remove_named_selection (NamedSelection* named_selection)
3955 bool removed = false;
3958 Glib::Mutex::Lock lm (named_selection_lock);
3960 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3962 if (i != named_selections.end()) {
3964 named_selections.erase (i);
3971 NamedSelectionRemoved (); /* EMIT SIGNAL */
3976 Session::reset_native_file_format ()
3978 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3980 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3981 (*i)->reset_write_sources (false);
3986 Session::route_name_unique (string n) const
3988 shared_ptr<RouteList> r = routes.reader ();
3990 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3991 if ((*i)->name() == n) {
4000 Session::n_playlists () const
4002 Glib::Mutex::Lock lm (playlist_lock);
4003 return playlists.size();
4007 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4009 if (!force && howmany <= _npan_buffers) {
4013 if (_pan_automation_buffer) {
4015 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4016 delete [] _pan_automation_buffer[i];
4019 delete [] _pan_automation_buffer;
4022 _pan_automation_buffer = new pan_t*[howmany];
4024 for (uint32_t i = 0; i < howmany; ++i) {
4025 _pan_automation_buffer[i] = new pan_t[nframes];
4028 _npan_buffers = howmany;
4032 Session::freeze (InterThreadInfo& itt)
4034 shared_ptr<RouteList> r = routes.reader ();
4036 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4040 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4041 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4051 boost::shared_ptr<Region>
4052 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4053 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4055 boost::shared_ptr<Region> result;
4056 boost::shared_ptr<Playlist> playlist;
4057 boost::shared_ptr<AudioFileSource> fsource;
4059 char buf[PATH_MAX+1];
4060 ChanCount nchans(track.audio_diskstream()->n_channels());
4062 nframes_t this_chunk;
4065 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4066 const string sound_dir = sdir.sound_path().to_string();
4067 nframes_t len = end - start;
4070 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4071 end, start) << endmsg;
4075 // any bigger than this seems to cause stack overflows in called functions
4076 const nframes_t chunk_size = (128 * 1024)/4;
4078 g_atomic_int_set (&processing_prohibited, 1);
4080 /* call tree *MUST* hold route_lock */
4082 if ((playlist = track.diskstream()->playlist()) == 0) {
4086 /* external redirects will be a problem */
4088 if (track.has_external_redirects()) {
4092 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4094 for (x = 0; x < 99999; ++x) {
4095 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4096 if (access (buf, F_OK) != 0) {
4102 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4107 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4108 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4111 catch (failed_constructor& err) {
4112 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4116 srcs.push_back (fsource);
4119 /* XXX need to flush all redirects */
4124 /* create a set of reasonably-sized buffers */
4125 buffers.ensure_buffers(nchans, chunk_size);
4126 buffers.set_count(nchans);
4128 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4129 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4131 afs->prepare_for_peakfile_writes ();
4134 while (to_do && !itt.cancel) {
4136 this_chunk = min (to_do, chunk_size);
4138 if (track.export_stuff (buffers, start, this_chunk)) {
4143 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4144 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4147 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4153 start += this_chunk;
4154 to_do -= this_chunk;
4156 itt.progress = (float) (1.0 - ((double) to_do / len));
4165 xnow = localtime (&now);
4167 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4168 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4171 afs->update_header (position, *xnow, now);
4172 afs->flush_header ();
4176 /* construct a region to represent the bounced material */
4178 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4179 region_name_from_path (srcs.front()->name(), true));
4184 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4185 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4188 afs->mark_for_remove ();
4191 (*src)->drop_references ();
4195 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4196 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4199 afs->done_with_peakfile_writes ();
4203 g_atomic_int_set (&processing_prohibited, 0);
4209 Session::get_silent_buffers (ChanCount count)
4211 assert(_silent_buffers->available() >= count);
4212 _silent_buffers->set_count(count);
4214 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4215 for (size_t i= 0; i < count.get(*t); ++i) {
4216 _silent_buffers->get(*t, i).clear();
4220 return *_silent_buffers;
4224 Session::get_scratch_buffers (ChanCount count)
4226 if (count != ChanCount::ZERO) {
4227 assert(_scratch_buffers->available() >= count);
4228 _scratch_buffers->set_count(count);
4230 _scratch_buffers->set_count (_scratch_buffers->available());
4233 return *_scratch_buffers;
4237 Session::get_mix_buffers (ChanCount count)
4239 assert(_mix_buffers->available() >= count);
4240 _mix_buffers->set_count(count);
4241 return *_mix_buffers;
4245 Session::ntracks () const
4248 shared_ptr<RouteList> r = routes.reader ();
4250 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4251 if (dynamic_cast<Track*> ((*i).get())) {
4260 Session::nbusses () const
4263 shared_ptr<RouteList> r = routes.reader ();
4265 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4266 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4275 Session::add_automation_list(AutomationList *al)
4277 automation_lists[al->id()] = al;
4281 Session::compute_initial_length ()
4283 return _engine.frame_rate() * 60 * 5;
4287 Session::sync_order_keys (const char* base)
4289 if (!Config->get_sync_all_route_ordering()) {
4290 /* leave order keys as they are */
4294 boost::shared_ptr<RouteList> r = routes.reader ();
4296 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4297 (*i)->sync_order_keys (base);
4300 Route::SyncOrderKeys (base); // EMIT SIGNAL