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/click.h>
76 #include <ardour/data_type.h>
77 #include <ardour/buffer_set.h>
78 #include <ardour/source_factory.h>
79 #include <ardour/region_factory.h>
80 #include <ardour/filename_extensions.h>
81 #include <ardour/session_directory.h>
82 #include <ardour/tape_file_matcher.h>
83 #include <ardour/analyser.h>
84 #include <ardour/bundle.h>
87 #include <ardour/osc.h>
93 using namespace ARDOUR;
95 using boost::shared_ptr;
98 static const int CPU_CACHE_ALIGN = 64;
100 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
103 bool Session::_disable_all_loaded_plugins = false;
105 sigc::signal<void,std::string> Session::Dialog;
106 sigc::signal<int> Session::AskAboutPendingState;
107 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
108 sigc::signal<void> Session::SendFeedback;
110 sigc::signal<void> Session::SMPTEOffsetChanged;
111 sigc::signal<void> Session::StartTimeChanged;
112 sigc::signal<void> Session::EndTimeChanged;
113 sigc::signal<void> Session::AutoBindingOn;
114 sigc::signal<void> Session::AutoBindingOff;
115 sigc::signal<void, std::string, std::string> Session::Exported;
117 Session::Session (AudioEngine &eng,
118 const string& fullpath,
119 const string& snapshot_name,
123 _scratch_buffers(new BufferSet()),
124 _silent_buffers(new BufferSet()),
125 _mix_buffers(new BufferSet()),
127 _mmc_port (default_mmc_port),
128 _mtc_port (default_mtc_port),
129 _midi_port (default_midi_port),
130 _midi_clock_port (default_midi_clock_port),
131 _session_dir (new SessionDirectory(fullpath)),
132 pending_events (2048),
134 butler_mixdown_buffer (0),
135 butler_gain_buffer (0),
136 post_transport_work((PostTransportWork)0),
137 _send_smpte_update (false),
138 midi_thread (pthread_t (0)),
139 midi_requests (128), // the size of this should match the midi request pool size
140 diskstreams (new DiskstreamList),
141 routes (new RouteList),
142 auditioner ((Auditioner*) 0),
143 _total_free_4k_blocks (0),
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 _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 /* Create a set of Bundle objects that map
593 to the physical outputs currently available
596 BootMessage (_("Set up standard connections"));
600 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
602 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
604 shared_ptr<Bundle> c (new Bundle (buf, true));
605 c->set_nchannels (1);
606 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
611 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
613 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
615 shared_ptr<Bundle> c (new Bundle (buf, false));
616 c->set_nchannels (1);
617 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
624 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
626 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
628 shared_ptr<Bundle> c (new Bundle (buf, true));
629 c->set_nchannels (2);
630 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
631 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
636 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
638 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
640 shared_ptr<Bundle> c (new Bundle (buf, false));
641 c->set_nchannels (2);
642 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
643 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
652 /* create master/control ports */
657 /* force the master to ignore any later call to this */
659 if (_master_out->pending_state_node) {
660 _master_out->ports_became_legal();
663 /* no panner resets till we are through */
665 _master_out->defer_pan_reset ();
667 while (_master_out->n_inputs().n_audio()
668 < _master_out->input_maximum().n_audio()) {
669 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
670 error << _("cannot setup master inputs")
676 while (_master_out->n_outputs().n_audio()
677 < _master_out->output_maximum().n_audio()) {
678 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
679 error << _("cannot setup master outputs")
686 _master_out->allow_pan_reset ();
691 BootMessage (_("Setup signal flow and plugins"));
695 /* catch up on send+insert cnts */
697 BootMessage (_("Catch up with send/insert state"));
701 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
704 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
705 if (id > insert_cnt) {
713 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
716 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
724 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
726 /* hook us up to the engine */
728 BootMessage (_("Connect to engine"));
730 _engine.set_session (this);
735 BootMessage (_("OSC startup"));
737 osc->set_session (*this);
743 Session::hookup_io ()
745 /* stop graph reordering notifications from
746 causing resorts, etc.
749 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
752 if (auditioner == 0) {
754 /* we delay creating the auditioner till now because
755 it makes its own connections to ports.
756 the engine has to be running for this to work.
760 auditioner.reset (new Auditioner (*this));
763 catch (failed_constructor& err) {
764 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
768 /* Tell all IO objects to create their ports */
774 vector<string> cports;
776 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
777 if (_control_out->add_input_port ("", this)) {
778 error << _("cannot setup control inputs")
784 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
785 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
786 error << _("cannot set up master outputs")
794 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
796 for (n = 0; n < ni; ++n) {
797 cports.push_back (_control_out->input(n)->name());
800 boost::shared_ptr<RouteList> r = routes.reader ();
802 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
803 (*x)->set_control_outs (cports);
807 /* load bundles, which we may have postponed earlier on */
808 if (_bundle_xml_node) {
809 load_bundles (*_bundle_xml_node);
810 delete _bundle_xml_node;
813 /* Tell all IO objects to connect themselves together */
815 IO::enable_connecting ();
817 /* Now reset all panners */
819 IO::reset_panners ();
821 /* Anyone who cares about input state, wake up and do something */
823 IOConnectionsComplete (); /* EMIT SIGNAL */
825 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
828 /* now handle the whole enchilada as if it was one
834 /* update mixer solo state */
840 Session::playlist_length_changed ()
842 /* we can't just increase end_location->end() if pl->get_maximum_extent()
843 if larger. if the playlist used to be the longest playlist,
844 and its now shorter, we have to decrease end_location->end(). hence,
845 we have to iterate over all diskstreams and check the
846 playlists currently in use.
852 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
854 boost::shared_ptr<Playlist> playlist;
856 if ((playlist = dstream->playlist()) != 0) {
857 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
860 /* see comment in playlist_length_changed () */
865 Session::record_enabling_legal () const
867 /* this used to be in here, but survey says.... we don't need to restrict it */
868 // if (record_status() == Recording) {
872 if (Config->get_all_safe()) {
879 Session::reset_input_monitor_state ()
881 if (transport_rolling()) {
883 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
885 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
886 if ((*i)->record_enabled ()) {
887 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
888 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
892 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
894 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
895 if ((*i)->record_enabled ()) {
896 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
897 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
904 Session::auto_punch_start_changed (Location* location)
906 replace_event (Event::PunchIn, location->start());
908 if (get_record_enabled() && Config->get_punch_in()) {
909 /* capture start has been changed, so save new pending state */
910 save_state ("", true);
915 Session::auto_punch_end_changed (Location* location)
917 nframes_t when_to_stop = location->end();
918 // when_to_stop += _worst_output_latency + _worst_input_latency;
919 replace_event (Event::PunchOut, when_to_stop);
923 Session::auto_punch_changed (Location* location)
925 nframes_t when_to_stop = location->end();
927 replace_event (Event::PunchIn, location->start());
928 //when_to_stop += _worst_output_latency + _worst_input_latency;
929 replace_event (Event::PunchOut, when_to_stop);
933 Session::auto_loop_changed (Location* location)
935 replace_event (Event::AutoLoop, location->end(), location->start());
937 if (transport_rolling() && play_loop) {
939 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
941 if (_transport_frame > location->end()) {
942 // relocate to beginning of loop
943 clear_events (Event::LocateRoll);
945 request_locate (location->start(), true);
948 else if (Config->get_seamless_loop() && !loop_changing) {
950 // schedule a locate-roll to refill the diskstreams at the
952 loop_changing = true;
954 if (location->end() > last_loopend) {
955 clear_events (Event::LocateRoll);
956 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
963 last_loopend = location->end();
967 Session::set_auto_punch_location (Location* location)
971 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
972 auto_punch_start_changed_connection.disconnect();
973 auto_punch_end_changed_connection.disconnect();
974 auto_punch_changed_connection.disconnect();
975 existing->set_auto_punch (false, this);
976 remove_event (existing->start(), Event::PunchIn);
977 clear_events (Event::PunchOut);
978 auto_punch_location_changed (0);
987 if (location->end() <= location->start()) {
988 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
992 auto_punch_start_changed_connection.disconnect();
993 auto_punch_end_changed_connection.disconnect();
994 auto_punch_changed_connection.disconnect();
996 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
997 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
998 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1000 location->set_auto_punch (true, this);
1003 auto_punch_changed (location);
1005 auto_punch_location_changed (location);
1009 Session::set_auto_loop_location (Location* location)
1013 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1014 auto_loop_start_changed_connection.disconnect();
1015 auto_loop_end_changed_connection.disconnect();
1016 auto_loop_changed_connection.disconnect();
1017 existing->set_auto_loop (false, this);
1018 remove_event (existing->end(), Event::AutoLoop);
1019 auto_loop_location_changed (0);
1024 if (location == 0) {
1028 if (location->end() <= location->start()) {
1029 error << _("Session: you can't use a mark for auto loop") << endmsg;
1033 last_loopend = location->end();
1035 auto_loop_start_changed_connection.disconnect();
1036 auto_loop_end_changed_connection.disconnect();
1037 auto_loop_changed_connection.disconnect();
1039 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1040 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1041 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1043 location->set_auto_loop (true, this);
1045 /* take care of our stuff first */
1047 auto_loop_changed (location);
1049 /* now tell everyone else */
1051 auto_loop_location_changed (location);
1055 Session::locations_added (Location* ignored)
1061 Session::locations_changed ()
1063 _locations.apply (*this, &Session::handle_locations_changed);
1067 Session::handle_locations_changed (Locations::LocationList& locations)
1069 Locations::LocationList::iterator i;
1071 bool set_loop = false;
1072 bool set_punch = false;
1074 for (i = locations.begin(); i != locations.end(); ++i) {
1078 if (location->is_auto_punch()) {
1079 set_auto_punch_location (location);
1082 if (location->is_auto_loop()) {
1083 set_auto_loop_location (location);
1087 if (location->is_start()) {
1088 start_location = location;
1090 if (location->is_end()) {
1091 end_location = location;
1096 set_auto_loop_location (0);
1099 set_auto_punch_location (0);
1106 Session::enable_record ()
1108 /* XXX really atomic compare+swap here */
1109 if (g_atomic_int_get (&_record_status) != Recording) {
1110 g_atomic_int_set (&_record_status, Recording);
1111 _last_record_location = _transport_frame;
1112 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1114 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1116 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1117 if ((*i)->record_enabled ()) {
1118 (*i)->monitor_input (true);
1123 RecordStateChanged ();
1128 Session::disable_record (bool rt_context, bool force)
1132 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1134 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1135 g_atomic_int_set (&_record_status, Disabled);
1137 if (rs == Recording) {
1138 g_atomic_int_set (&_record_status, Enabled);
1142 // FIXME: timestamp correct? [DR]
1143 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1144 // does this /need/ to be sent in all cases?
1146 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1148 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1149 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1151 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1152 if ((*i)->record_enabled ()) {
1153 (*i)->monitor_input (false);
1158 RecordStateChanged (); /* emit signal */
1161 remove_pending_capture_state ();
1167 Session::step_back_from_record ()
1169 /* XXX really atomic compare+swap here */
1170 if (g_atomic_int_get (&_record_status) == Recording) {
1171 g_atomic_int_set (&_record_status, Enabled);
1173 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1174 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1176 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1177 if ((*i)->record_enabled ()) {
1178 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1179 (*i)->monitor_input (false);
1187 Session::maybe_enable_record ()
1189 g_atomic_int_set (&_record_status, Enabled);
1191 /* this function is currently called from somewhere other than an RT thread.
1192 this save_state() call therefore doesn't impact anything.
1195 save_state ("", true);
1197 if (_transport_speed) {
1198 if (!Config->get_punch_in()) {
1202 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1203 RecordStateChanged (); /* EMIT SIGNAL */
1210 Session::audible_frame () const
1216 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1217 return last_stop_frame;
1220 /* the first of these two possible settings for "offset"
1221 mean that the audible frame is stationary until
1222 audio emerges from the latency compensation
1225 the second means that the audible frame is stationary
1226 until audio would emerge from a physical port
1227 in the absence of any plugin latency compensation
1230 offset = _worst_output_latency;
1232 if (offset > current_block_size) {
1233 offset -= current_block_size;
1235 /* XXX is this correct? if we have no external
1236 physical connections and everything is internal
1237 then surely this is zero? still, how
1238 likely is that anyway?
1240 offset = current_block_size;
1243 if (synced_to_jack()) {
1244 tf = _engine.transport_frame();
1246 tf = _transport_frame;
1251 if (!non_realtime_work_pending()) {
1255 /* check to see if we have passed the first guaranteed
1256 audible frame past our last stopping position. if not,
1257 the return that last stopping point because in terms
1258 of audible frames, we have not moved yet.
1261 if (_transport_speed > 0.0f) {
1263 if (!play_loop || !have_looped) {
1264 if (tf < last_stop_frame + offset) {
1265 return last_stop_frame;
1274 } else if (_transport_speed < 0.0f) {
1276 /* XXX wot? no backward looping? */
1278 if (tf > last_stop_frame - offset) {
1279 return last_stop_frame;
1291 Session::set_frame_rate (nframes_t frames_per_second)
1293 /** \fn void Session::set_frame_size(nframes_t)
1294 the AudioEngine object that calls this guarantees
1295 that it will not be called while we are also in
1296 ::process(). Its fine to do things that block
1300 _base_frame_rate = frames_per_second;
1304 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1308 // XXX we need some equivalent to this, somehow
1309 // SndFileSource::setup_standard_crossfades (frames_per_second);
1313 /* XXX need to reset/reinstantiate all LADSPA plugins */
1317 Session::set_block_size (nframes_t nframes)
1319 /* the AudioEngine guarantees
1320 that it will not be called while we are also in
1321 ::process(). It is therefore fine to do things that block
1327 current_block_size = nframes;
1329 ensure_buffers(_scratch_buffers->available());
1331 delete [] _gain_automation_buffer;
1332 _gain_automation_buffer = new gain_t[nframes];
1334 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1336 boost::shared_ptr<RouteList> r = routes.reader ();
1338 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1339 (*i)->set_block_size (nframes);
1342 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1343 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1344 (*i)->set_block_size (nframes);
1347 set_worst_io_latencies ();
1352 Session::set_default_fade (float steepness, float fade_msecs)
1355 nframes_t fade_frames;
1357 /* Don't allow fade of less 1 frame */
1359 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1366 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1370 default_fade_msecs = fade_msecs;
1371 default_fade_steepness = steepness;
1374 // jlc, WTF is this!
1375 Glib::RWLock::ReaderLock lm (route_lock);
1376 AudioRegion::set_default_fade (steepness, fade_frames);
1381 /* XXX have to do this at some point */
1382 /* foreach region using default fade, reset, then
1383 refill_all_diskstream_buffers ();
1388 struct RouteSorter {
1389 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1390 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1392 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1395 if (r1->fed_by.empty()) {
1396 if (r2->fed_by.empty()) {
1397 /* no ardour-based connections inbound to either route. just use signal order */
1398 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1400 /* r2 has connections, r1 does not; run r1 early */
1404 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1411 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1413 shared_ptr<Route> r2;
1415 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1416 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1420 /* make a copy of the existing list of routes that feed r1 */
1422 set<shared_ptr<Route> > existing = r1->fed_by;
1424 /* for each route that feeds r1, recurse, marking it as feeding
1428 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1431 /* r2 is a route that feeds r1 which somehow feeds base. mark
1432 base as being fed by r2
1435 rbase->fed_by.insert (r2);
1439 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1443 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1447 /* now recurse, so that we can mark base as being fed by
1448 all routes that feed r2
1451 trace_terminal (r2, rbase);
1458 Session::resort_routes ()
1460 /* don't do anything here with signals emitted
1461 by Routes while we are being destroyed.
1464 if (_state_of_the_state & Deletion) {
1471 RCUWriter<RouteList> writer (routes);
1472 shared_ptr<RouteList> r = writer.get_copy ();
1473 resort_routes_using (r);
1474 /* writer goes out of scope and forces update */
1479 Session::resort_routes_using (shared_ptr<RouteList> r)
1481 RouteList::iterator i, j;
1483 for (i = r->begin(); i != r->end(); ++i) {
1485 (*i)->fed_by.clear ();
1487 for (j = r->begin(); j != r->end(); ++j) {
1489 /* although routes can feed themselves, it will
1490 cause an endless recursive descent if we
1491 detect it. so don't bother checking for
1499 if ((*j)->feeds (*i)) {
1500 (*i)->fed_by.insert (*j);
1505 for (i = r->begin(); i != r->end(); ++i) {
1506 trace_terminal (*i, *i);
1513 cerr << "finished route resort\n";
1515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1516 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1523 list<boost::shared_ptr<MidiTrack> >
1524 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1526 char track_name[32];
1527 uint32_t track_id = 0;
1530 RouteList new_routes;
1531 list<boost::shared_ptr<MidiTrack> > ret;
1532 //uint32_t control_id;
1534 // FIXME: need physical I/O and autoconnect stuff for MIDI
1536 /* count existing midi tracks */
1539 shared_ptr<RouteList> r = routes.reader ();
1541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1542 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1543 if (!(*i)->is_hidden()) {
1545 //channels_used += (*i)->n_inputs().n_midi();
1551 vector<string> physinputs;
1552 vector<string> physoutputs;
1554 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1555 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1557 // control_id = ntracks() + nbusses();
1561 /* check for duplicate route names, since we might have pre-existing
1562 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1563 save, close,restart,add new route - first named route is now
1571 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1573 if (route_by_name (track_name) == 0) {
1577 } while (track_id < (UINT_MAX-1));
1579 shared_ptr<MidiTrack> track;
1582 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1584 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1585 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1591 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1595 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1596 port = physinputs[(channels_used+x)%nphysical_in];
1599 if (port.length() && track->connect_input (track->input (x), port, this)) {
1605 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1609 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1610 port = physoutputs[(channels_used+x)%nphysical_out];
1611 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1613 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1617 if (port.length() && track->connect_output (track->output (x), port, this)) {
1622 channels_used += track->n_inputs ().n_midi();
1626 track->midi_diskstream()->non_realtime_input_change();
1628 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1629 //track->set_remote_control_id (control_id);
1631 new_routes.push_back (track);
1632 ret.push_back (track);
1635 catch (failed_constructor &err) {
1636 error << _("Session: could not create new midi track.") << endmsg;
1639 /* we need to get rid of this, since the track failed to be created */
1640 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1643 RCUWriter<DiskstreamList> writer (diskstreams);
1644 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1645 ds->remove (track->midi_diskstream());
1652 catch (AudioEngine::PortRegistrationFailure& pfe) {
1654 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;
1657 /* we need to get rid of this, since the track failed to be created */
1658 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1661 RCUWriter<DiskstreamList> writer (diskstreams);
1662 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1663 ds->remove (track->midi_diskstream());
1674 if (!new_routes.empty()) {
1675 add_routes (new_routes, false);
1676 save_state (_current_snapshot_name);
1682 list<boost::shared_ptr<AudioTrack> >
1683 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1685 char track_name[32];
1686 uint32_t track_id = 0;
1688 uint32_t channels_used = 0;
1690 RouteList new_routes;
1691 list<boost::shared_ptr<AudioTrack> > ret;
1692 uint32_t control_id;
1694 /* count existing audio tracks */
1697 shared_ptr<RouteList> r = routes.reader ();
1699 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1700 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1701 if (!(*i)->is_hidden()) {
1703 channels_used += (*i)->n_inputs().n_audio();
1709 vector<string> physinputs;
1710 vector<string> physoutputs;
1712 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1713 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1715 control_id = ntracks() + nbusses() + 1;
1719 /* check for duplicate route names, since we might have pre-existing
1720 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1721 save, close,restart,add new route - first named route is now
1729 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1731 if (route_by_name (track_name) == 0) {
1735 } while (track_id < (UINT_MAX-1));
1737 shared_ptr<AudioTrack> track;
1740 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1742 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1743 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1744 input_channels, output_channels)
1749 if (!physinputs.empty()) {
1750 uint32_t nphysical_in = physinputs.size();
1752 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1756 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1757 port = physinputs[(channels_used+x)%nphysical_in];
1760 if (port.length() && track->connect_input (track->input (x), port, this)) {
1766 if (!physoutputs.empty()) {
1767 uint32_t nphysical_out = physoutputs.size();
1769 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1773 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1774 port = physoutputs[(channels_used+x)%nphysical_out];
1775 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1777 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1781 if (port.length() && track->connect_output (track->output (x), port, this)) {
1787 channels_used += track->n_inputs ().n_audio();
1789 track->audio_diskstream()->non_realtime_input_change();
1791 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1792 track->set_remote_control_id (control_id);
1795 new_routes.push_back (track);
1796 ret.push_back (track);
1799 catch (failed_constructor &err) {
1800 error << _("Session: could not create new audio track.") << endmsg;
1803 /* we need to get rid of this, since the track failed to be created */
1804 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1807 RCUWriter<DiskstreamList> writer (diskstreams);
1808 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1809 ds->remove (track->audio_diskstream());
1816 catch (AudioEngine::PortRegistrationFailure& pfe) {
1818 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;
1821 /* we need to get rid of this, since the track failed to be created */
1822 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1825 RCUWriter<DiskstreamList> writer (diskstreams);
1826 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1827 ds->remove (track->audio_diskstream());
1838 if (!new_routes.empty()) {
1839 add_routes (new_routes, true);
1846 Session::set_remote_control_ids ()
1848 RemoteModel m = Config->get_remote_model();
1850 shared_ptr<RouteList> r = routes.reader ();
1852 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1853 if ( MixerOrdered == m) {
1854 long order = (*i)->order_key(N_("signal"));
1855 (*i)->set_remote_control_id( order+1 );
1856 } else if ( EditorOrdered == m) {
1857 long order = (*i)->order_key(N_("editor"));
1858 (*i)->set_remote_control_id( order+1 );
1859 } else if ( UserOrdered == m) {
1860 //do nothing ... only changes to remote id's are initiated by user
1867 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1870 uint32_t bus_id = 1;
1872 uint32_t channels_used = 0;
1875 uint32_t control_id;
1877 /* count existing audio busses */
1880 shared_ptr<RouteList> r = routes.reader ();
1882 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1883 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1885 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1888 channels_used += (*i)->n_inputs().n_audio();
1894 vector<string> physinputs;
1895 vector<string> physoutputs;
1897 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1898 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1900 n_physical_audio_outputs = physoutputs.size();
1901 n_physical_audio_inputs = physinputs.size();
1903 control_id = ntracks() + nbusses() + 1;
1908 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1912 if (route_by_name (bus_name) == 0) {
1916 } while (bus_id < (UINT_MAX-1));
1919 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1921 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1922 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1923 input_channels, output_channels)
1931 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1935 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1936 port = physinputs[((n+x)%n_physical_audio_inputs)];
1939 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1945 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1948 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1949 port = physoutputs[((n+x)%n_physical_outputs)];
1950 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1952 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1956 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1961 channels_used += bus->n_inputs ().n_audio();
1963 bus->set_remote_control_id (control_id);
1966 ret.push_back (bus);
1970 catch (failed_constructor &err) {
1971 error << _("Session: could not create new audio route.") << endmsg;
1975 catch (AudioEngine::PortRegistrationFailure& pfe) {
1976 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;
1986 add_routes (ret, true);
1994 Session::add_routes (RouteList& new_routes, bool save)
1997 RCUWriter<RouteList> writer (routes);
1998 shared_ptr<RouteList> r = writer.get_copy ();
1999 r->insert (r->end(), new_routes.begin(), new_routes.end());
2000 resort_routes_using (r);
2003 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2005 boost::weak_ptr<Route> wpr (*x);
2007 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2008 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2009 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2010 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2012 if ((*x)->is_master()) {
2016 if ((*x)->is_control()) {
2017 _control_out = (*x);
2020 /* only busses get automatic bundles formed */
2022 if (!boost::dynamic_pointer_cast<Track> (*x)) {
2023 add_bundle ((*x)->bundle_for_inputs());
2024 add_bundle ((*x)->bundle_for_outputs());
2028 if (_control_out && IO::connecting_legal) {
2030 vector<string> cports;
2031 uint32_t ni = _control_out->n_inputs().n_audio();
2033 for (uint32_t n = 0; n < ni; ++n) {
2034 cports.push_back (_control_out->input(n)->name());
2037 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2038 (*x)->set_control_outs (cports);
2045 save_state (_current_snapshot_name);
2048 RouteAdded (new_routes); /* EMIT SIGNAL */
2052 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2054 /* need to do this in case we're rolling at the time, to prevent false underruns */
2055 dstream->do_refill_with_alloc ();
2057 dstream->set_block_size (current_block_size);
2060 RCUWriter<DiskstreamList> writer (diskstreams);
2061 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2062 ds->push_back (dstream);
2063 /* writer goes out of scope, copies ds back to main */
2066 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2067 /* this will connect to future changes, and check the current length */
2068 diskstream_playlist_changed (dstream);
2070 dstream->prepare ();
2075 Session::remove_route (shared_ptr<Route> route)
2078 RCUWriter<RouteList> writer (routes);
2079 shared_ptr<RouteList> rs = writer.get_copy ();
2083 /* deleting the master out seems like a dumb
2084 idea, but its more of a UI policy issue
2088 if (route == _master_out) {
2089 _master_out = shared_ptr<Route> ();
2092 if (route == _control_out) {
2093 _control_out = shared_ptr<Route> ();
2095 /* cancel control outs for all routes */
2097 vector<string> empty;
2099 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2100 (*r)->set_control_outs (empty);
2104 update_route_solo_state ();
2106 /* writer goes out of scope, forces route list update */
2110 boost::shared_ptr<Diskstream> ds;
2112 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2113 ds = t->diskstream();
2119 RCUWriter<DiskstreamList> dsl (diskstreams);
2120 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2125 find_current_end ();
2127 // We need to disconnect the routes inputs and outputs
2129 route->disconnect_inputs (0);
2130 route->disconnect_outputs (0);
2132 update_latency_compensation (false, false);
2135 /* get rid of it from the dead wood collection in the route list manager */
2137 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2141 /* try to cause everyone to drop their references */
2143 route->drop_references ();
2145 sync_order_keys (N_("session"));
2147 /* save the new state of the world */
2149 if (save_state (_current_snapshot_name)) {
2150 save_history (_current_snapshot_name);
2155 Session::route_mute_changed (void* src)
2161 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2163 if (solo_update_disabled) {
2169 boost::shared_ptr<Route> route = wpr.lock ();
2172 /* should not happen */
2173 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2177 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2179 shared_ptr<RouteList> r = routes.reader ();
2181 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2183 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2187 /* don't mess with busses */
2189 if (dynamic_cast<Track*>((*i).get()) == 0) {
2195 /* don't mess with tracks */
2197 if (dynamic_cast<Track*>((*i).get()) != 0) {
2202 if ((*i) != route &&
2203 ((*i)->mix_group () == 0 ||
2204 (*i)->mix_group () != route->mix_group () ||
2205 !route->mix_group ()->is_active())) {
2207 if ((*i)->soloed()) {
2209 /* if its already soloed, and solo latching is enabled,
2210 then leave it as it is.
2213 if (Config->get_solo_latched()) {
2220 solo_update_disabled = true;
2221 (*i)->set_solo (false, src);
2222 solo_update_disabled = false;
2226 bool something_soloed = false;
2227 bool same_thing_soloed = false;
2228 bool signal = false;
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if ((*i)->soloed()) {
2232 something_soloed = true;
2233 if (dynamic_cast<Track*>((*i).get())) {
2235 same_thing_soloed = true;
2240 same_thing_soloed = true;
2248 if (something_soloed != currently_soloing) {
2250 currently_soloing = something_soloed;
2253 modify_solo_mute (is_track, same_thing_soloed);
2256 SoloActive (currently_soloing); /* EMIT SIGNAL */
2259 SoloChanged (); /* EMIT SIGNAL */
2265 Session::update_route_solo_state ()
2268 bool is_track = false;
2269 bool signal = false;
2271 /* this is where we actually implement solo by changing
2272 the solo mute setting of each track.
2275 shared_ptr<RouteList> r = routes.reader ();
2277 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2278 if ((*i)->soloed()) {
2280 if (dynamic_cast<Track*>((*i).get())) {
2287 if (mute != currently_soloing) {
2289 currently_soloing = mute;
2292 if (!is_track && !mute) {
2294 /* nothing is soloed */
2296 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2297 (*i)->set_solo_mute (false);
2307 modify_solo_mute (is_track, mute);
2310 SoloActive (currently_soloing);
2315 Session::modify_solo_mute (bool is_track, bool mute)
2317 shared_ptr<RouteList> r = routes.reader ();
2319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2323 /* only alter track solo mute */
2325 if (dynamic_cast<Track*>((*i).get())) {
2326 if ((*i)->soloed()) {
2327 (*i)->set_solo_mute (!mute);
2329 (*i)->set_solo_mute (mute);
2335 /* only alter bus solo mute */
2337 if (!dynamic_cast<Track*>((*i).get())) {
2339 if ((*i)->soloed()) {
2341 (*i)->set_solo_mute (false);
2345 /* don't mute master or control outs
2346 in response to another bus solo
2349 if ((*i) != _master_out &&
2350 (*i) != _control_out) {
2351 (*i)->set_solo_mute (mute);
2362 Session::catch_up_on_solo ()
2364 /* this is called after set_state() to catch the full solo
2365 state, which can't be correctly determined on a per-route
2366 basis, but needs the global overview that only the session
2369 update_route_solo_state();
2373 Session::catch_up_on_solo_mute_override ()
2375 if (Config->get_solo_model() != InverseMute) {
2379 /* this is called whenever the param solo-mute-override is
2382 shared_ptr<RouteList> r = routes.reader ();
2384 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2385 (*i)->catch_up_on_solo_mute_override ();
2390 Session::route_by_name (string name)
2392 shared_ptr<RouteList> r = routes.reader ();
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 if ((*i)->name() == name) {
2400 return shared_ptr<Route> ((Route*) 0);
2404 Session::route_by_id (PBD::ID id)
2406 shared_ptr<RouteList> r = routes.reader ();
2408 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2409 if ((*i)->id() == id) {
2414 return shared_ptr<Route> ((Route*) 0);
2418 Session::route_by_remote_id (uint32_t id)
2420 shared_ptr<RouteList> r = routes.reader ();
2422 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2423 if ((*i)->remote_control_id() == id) {
2428 return shared_ptr<Route> ((Route*) 0);
2432 Session::find_current_end ()
2434 if (_state_of_the_state & Loading) {
2438 nframes_t max = get_maximum_extent ();
2440 if (max > end_location->end()) {
2441 end_location->set_end (max);
2443 DurationChanged(); /* EMIT SIGNAL */
2448 Session::get_maximum_extent () const
2453 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2455 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2456 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2458 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2459 if ((me = pl->get_maximum_extent()) > max) {
2467 boost::shared_ptr<Diskstream>
2468 Session::diskstream_by_name (string name)
2470 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2472 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2473 if ((*i)->name() == name) {
2478 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2481 boost::shared_ptr<Diskstream>
2482 Session::diskstream_by_id (const PBD::ID& id)
2484 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2486 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2487 if ((*i)->id() == id) {
2492 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2495 /* Region management */
2498 Session::new_region_name (string old)
2500 string::size_type last_period;
2502 string::size_type len = old.length() + 64;
2505 if ((last_period = old.find_last_of ('.')) == string::npos) {
2507 /* no period present - add one explicitly */
2510 last_period = old.length() - 1;
2515 number = atoi (old.substr (last_period+1).c_str());
2519 while (number < (UINT_MAX-1)) {
2521 RegionList::const_iterator i;
2526 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2529 for (i = regions.begin(); i != regions.end(); ++i) {
2530 if (i->second->name() == sbuf) {
2535 if (i == regions.end()) {
2540 if (number != (UINT_MAX-1)) {
2544 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2549 Session::region_name (string& result, string base, bool newlevel)
2554 assert(base.find("/") == string::npos);
2558 Glib::Mutex::Lock lm (region_lock);
2560 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2569 string::size_type pos;
2571 pos = base.find_last_of ('.');
2573 /* pos may be npos, but then we just use entire base */
2575 subbase = base.substr (0, pos);
2580 Glib::Mutex::Lock lm (region_lock);
2582 map<string,uint32_t>::iterator x;
2586 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2588 region_name_map[subbase] = 1;
2591 snprintf (buf, sizeof (buf), ".%d", x->second);
2602 Session::add_region (boost::shared_ptr<Region> region)
2604 vector<boost::shared_ptr<Region> > v;
2605 v.push_back (region);
2610 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2615 Glib::Mutex::Lock lm (region_lock);
2617 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2619 boost::shared_ptr<Region> region = *ii;
2623 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2627 RegionList::iterator x;
2629 for (x = regions.begin(); x != regions.end(); ++x) {
2631 if (region->region_list_equivalent (x->second)) {
2636 if (x == regions.end()) {
2638 pair<RegionList::key_type,RegionList::mapped_type> entry;
2640 entry.first = region->id();
2641 entry.second = region;
2643 pair<RegionList::iterator,bool> x = regions.insert (entry);
2655 /* mark dirty because something has changed even if we didn't
2656 add the region to the region list.
2663 vector<boost::weak_ptr<Region> > v;
2664 boost::shared_ptr<Region> first_r;
2666 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2668 boost::shared_ptr<Region> region = *ii;
2672 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2675 v.push_back (region);
2682 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2683 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2685 update_region_name_map (region);
2689 RegionsAdded (v); /* EMIT SIGNAL */
2695 Session::update_region_name_map (boost::shared_ptr<Region> region)
2697 string::size_type last_period = region->name().find_last_of ('.');
2699 if (last_period != string::npos && last_period < region->name().length() - 1) {
2701 string base = region->name().substr (0, last_period);
2702 string number = region->name().substr (last_period+1);
2703 map<string,uint32_t>::iterator x;
2705 /* note that if there is no number, we get zero from atoi,
2709 region_name_map[base] = atoi (number);
2714 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2716 boost::shared_ptr<Region> region (weak_region.lock ());
2722 if (what_changed & Region::HiddenChanged) {
2723 /* relay hidden changes */
2724 RegionHiddenChange (region);
2727 if (what_changed & NameChanged) {
2728 update_region_name_map (region);
2733 Session::remove_region (boost::weak_ptr<Region> weak_region)
2735 RegionList::iterator i;
2736 boost::shared_ptr<Region> region (weak_region.lock ());
2742 bool removed = false;
2745 Glib::Mutex::Lock lm (region_lock);
2747 if ((i = regions.find (region->id())) != regions.end()) {
2753 /* mark dirty because something has changed even if we didn't
2754 remove the region from the region list.
2760 RegionRemoved(region); /* EMIT SIGNAL */
2764 boost::shared_ptr<Region>
2765 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2767 RegionList::iterator i;
2768 boost::shared_ptr<Region> region;
2770 Glib::Mutex::Lock lm (region_lock);
2772 for (i = regions.begin(); i != regions.end(); ++i) {
2776 if (region->whole_file()) {
2778 if (child->source_equivalent (region)) {
2784 return boost::shared_ptr<Region> ();
2788 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2790 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2791 (*i)->get_region_list_equivalent_regions (region, result);
2795 Session::destroy_region (boost::shared_ptr<Region> region)
2797 vector<boost::shared_ptr<Source> > srcs;
2800 if (region->playlist()) {
2801 region->playlist()->destroy_region (region);
2804 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2805 srcs.push_back (region->source (n));
2809 region->drop_references ();
2811 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2813 (*i)->mark_for_remove ();
2814 (*i)->drop_references ();
2816 cerr << "source was not used by any playlist\n";
2823 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2825 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2826 destroy_region (*i);
2832 Session::remove_last_capture ()
2834 list<boost::shared_ptr<Region> > r;
2836 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2838 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2839 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2842 r.insert (r.end(), l.begin(), l.end());
2847 destroy_regions (r);
2849 save_state (_current_snapshot_name);
2855 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2861 /* Source Management */
2863 Session::add_source (boost::shared_ptr<Source> source)
2865 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2866 pair<SourceMap::iterator,bool> result;
2868 entry.first = source->id();
2869 entry.second = source;
2872 Glib::Mutex::Lock lm (source_lock);
2873 result = sources.insert (entry);
2876 if (result.second) {
2877 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2881 boost::shared_ptr<AudioFileSource> afs;
2883 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2884 if (Config->get_auto_analyse_audio()) {
2885 Analyser::queue_source_for_analysis (source, false);
2891 Session::remove_source (boost::weak_ptr<Source> src)
2893 SourceMap::iterator i;
2894 boost::shared_ptr<Source> source = src.lock();
2901 Glib::Mutex::Lock lm (source_lock);
2903 if ((i = sources.find (source->id())) != sources.end()) {
2908 if (!_state_of_the_state & InCleanup) {
2910 /* save state so we don't end up with a session file
2911 referring to non-existent sources.
2914 save_state (_current_snapshot_name);
2918 boost::shared_ptr<Source>
2919 Session::source_by_id (const PBD::ID& id)
2921 Glib::Mutex::Lock lm (source_lock);
2922 SourceMap::iterator i;
2923 boost::shared_ptr<Source> source;
2925 if ((i = sources.find (id)) != sources.end()) {
2933 boost::shared_ptr<Source>
2934 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2936 Glib::Mutex::Lock lm (source_lock);
2938 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2939 cerr << "comparing " << path << " with " << i->second->name() << endl;
2940 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2942 if (afs && afs->path() == path && chn == afs->channel()) {
2947 return boost::shared_ptr<Source>();
2951 Session::peak_path (Glib::ustring base) const
2953 sys::path peakfile_path(_session_dir->peak_path());
2954 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2955 return peakfile_path.to_string();
2959 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2962 string old_basename = PBD::basename_nosuffix (oldname);
2963 string new_legalized = legalize_for_path (newname);
2965 /* note: we know (or assume) the old path is already valid */
2969 /* destructive file sources have a name of the form:
2971 /path/to/Tnnnn-NAME(%[LR])?.wav
2973 the task here is to replace NAME with the new name.
2976 /* find last slash */
2980 string::size_type slash;
2981 string::size_type dash;
2983 if ((slash = path.find_last_of ('/')) == string::npos) {
2987 dir = path.substr (0, slash+1);
2989 /* '-' is not a legal character for the NAME part of the path */
2991 if ((dash = path.find_last_of ('-')) == string::npos) {
2995 prefix = path.substr (slash+1, dash-(slash+1));
3000 path += new_legalized;
3001 path += ".wav"; /* XXX gag me with a spoon */
3005 /* non-destructive file sources have a name of the form:
3007 /path/to/NAME-nnnnn(%[LR])?.wav
3009 the task here is to replace NAME with the new name.
3014 string::size_type slash;
3015 string::size_type dash;
3016 string::size_type postfix;
3018 /* find last slash */
3020 if ((slash = path.find_last_of ('/')) == string::npos) {
3024 dir = path.substr (0, slash+1);
3026 /* '-' is not a legal character for the NAME part of the path */
3028 if ((dash = path.find_last_of ('-')) == string::npos) {
3032 suffix = path.substr (dash+1);
3034 // Suffix is now everything after the dash. Now we need to eliminate
3035 // the nnnnn part, which is done by either finding a '%' or a '.'
3037 postfix = suffix.find_last_of ("%");
3038 if (postfix == string::npos) {
3039 postfix = suffix.find_last_of ('.');
3042 if (postfix != string::npos) {
3043 suffix = suffix.substr (postfix);
3045 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3049 const uint32_t limit = 10000;
3050 char buf[PATH_MAX+1];
3052 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3054 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3056 if (access (buf, F_OK) != 0) {
3064 error << "FATAL ERROR! Could not find a " << endl;
3073 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3077 char buf[PATH_MAX+1];
3078 const uint32_t limit = 10000;
3082 legalized = legalize_for_path (name);
3084 /* find a "version" of the file name that doesn't exist in
3085 any of the possible directories.
3088 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3090 vector<space_and_path>::iterator i;
3091 uint32_t existing = 0;
3093 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3095 SessionDirectory sdir((*i).path);
3097 spath = sdir.sound_path().to_string();
3101 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3102 } else if (nchan == 2) {
3104 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3106 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3108 } else if (nchan < 26) {
3109 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3111 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3120 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3121 } else if (nchan == 2) {
3123 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3125 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3127 } else if (nchan < 26) {
3128 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3130 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3134 if (sys::exists(buf)) {
3140 if (existing == 0) {
3145 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3147 throw failed_constructor();
3151 /* we now have a unique name for the file, but figure out where to
3157 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3159 spath = sdir.sound_path().to_string();
3162 string::size_type pos = foo.find_last_of ('/');
3164 if (pos == string::npos) {
3167 spath += foo.substr (pos + 1);
3173 boost::shared_ptr<AudioFileSource>
3174 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3176 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3177 return boost::dynamic_pointer_cast<AudioFileSource> (
3178 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3181 // FIXME: _terrible_ code duplication
3183 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3186 string old_basename = PBD::basename_nosuffix (oldname);
3187 string new_legalized = legalize_for_path (newname);
3189 /* note: we know (or assume) the old path is already valid */
3193 /* destructive file sources have a name of the form:
3195 /path/to/Tnnnn-NAME(%[LR])?.wav
3197 the task here is to replace NAME with the new name.
3200 /* find last slash */
3204 string::size_type slash;
3205 string::size_type dash;
3207 if ((slash = path.find_last_of ('/')) == string::npos) {
3211 dir = path.substr (0, slash+1);
3213 /* '-' is not a legal character for the NAME part of the path */
3215 if ((dash = path.find_last_of ('-')) == string::npos) {
3219 prefix = path.substr (slash+1, dash-(slash+1));
3224 path += new_legalized;
3225 path += ".mid"; /* XXX gag me with a spoon */
3229 /* non-destructive file sources have a name of the form:
3231 /path/to/NAME-nnnnn(%[LR])?.wav
3233 the task here is to replace NAME with the new name.
3238 string::size_type slash;
3239 string::size_type dash;
3240 string::size_type postfix;
3242 /* find last slash */
3244 if ((slash = path.find_last_of ('/')) == string::npos) {
3248 dir = path.substr (0, slash+1);
3250 /* '-' is not a legal character for the NAME part of the path */
3252 if ((dash = path.find_last_of ('-')) == string::npos) {
3256 suffix = path.substr (dash+1);
3258 // Suffix is now everything after the dash. Now we need to eliminate
3259 // the nnnnn part, which is done by either finding a '%' or a '.'
3261 postfix = suffix.find_last_of ("%");
3262 if (postfix == string::npos) {
3263 postfix = suffix.find_last_of ('.');
3266 if (postfix != string::npos) {
3267 suffix = suffix.substr (postfix);
3269 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3273 const uint32_t limit = 10000;
3274 char buf[PATH_MAX+1];
3276 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3278 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3280 if (access (buf, F_OK) != 0) {
3288 error << "FATAL ERROR! Could not find a " << endl;
3297 Session::midi_path_from_name (string name)
3301 char buf[PATH_MAX+1];
3302 const uint32_t limit = 10000;
3306 legalized = legalize_for_path (name);
3308 /* find a "version" of the file name that doesn't exist in
3309 any of the possible directories.
3312 for (cnt = 1; cnt <= limit; ++cnt) {
3314 vector<space_and_path>::iterator i;
3315 uint32_t existing = 0;
3317 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3319 SessionDirectory sdir((*i).path);
3321 sys::path p = sdir.midi_path();
3325 spath = p.to_string();
3327 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3329 if (sys::exists (buf)) {
3334 if (existing == 0) {
3339 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3340 throw failed_constructor();
3344 /* we now have a unique name for the file, but figure out where to
3350 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3352 spath = sdir.midi_path().to_string();
3355 string::size_type pos = foo.find_last_of ('/');
3357 if (pos == string::npos) {
3360 spath += foo.substr (pos + 1);
3366 boost::shared_ptr<MidiSource>
3367 Session::create_midi_source_for_session (MidiDiskstream& ds)
3369 string mpath = midi_path_from_name (ds.name());
3371 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3375 /* Playlist management */
3377 boost::shared_ptr<Playlist>
3378 Session::playlist_by_name (string name)
3380 Glib::Mutex::Lock lm (playlist_lock);
3381 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3382 if ((*i)->name() == name) {
3386 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3387 if ((*i)->name() == name) {
3392 return boost::shared_ptr<Playlist>();
3396 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3398 Glib::Mutex::Lock lm (playlist_lock);
3399 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3400 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3401 list.push_back (*i);
3404 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3405 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3406 list.push_back (*i);
3412 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3414 if (playlist->hidden()) {
3419 Glib::Mutex::Lock lm (playlist_lock);
3420 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3421 playlists.insert (playlists.begin(), playlist);
3422 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3423 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3428 playlist->release();
3433 PlaylistAdded (playlist); /* EMIT SIGNAL */
3437 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3440 Glib::Mutex::Lock lm (playlist_lock);
3441 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3444 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3451 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3453 boost::shared_ptr<Playlist> pl(wpl.lock());
3459 PlaylistList::iterator x;
3462 /* its not supposed to be visible */
3467 Glib::Mutex::Lock lm (playlist_lock);
3471 unused_playlists.insert (pl);
3473 if ((x = playlists.find (pl)) != playlists.end()) {
3474 playlists.erase (x);
3480 playlists.insert (pl);
3482 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3483 unused_playlists.erase (x);
3490 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3492 if (_state_of_the_state & Deletion) {
3496 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3503 Glib::Mutex::Lock lm (playlist_lock);
3505 PlaylistList::iterator i;
3507 i = find (playlists.begin(), playlists.end(), playlist);
3508 if (i != playlists.end()) {
3509 playlists.erase (i);
3512 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3513 if (i != unused_playlists.end()) {
3514 unused_playlists.erase (i);
3521 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3525 Session::set_audition (boost::shared_ptr<Region> r)
3527 pending_audition_region = r;
3528 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3529 schedule_butler_transport_work ();
3533 Session::audition_playlist ()
3535 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3536 ev->region.reset ();
3541 Session::non_realtime_set_audition ()
3543 if (!pending_audition_region) {
3544 auditioner->audition_current_playlist ();
3546 auditioner->audition_region (pending_audition_region);
3547 pending_audition_region.reset ();
3549 AuditionActive (true); /* EMIT SIGNAL */
3553 Session::audition_region (boost::shared_ptr<Region> r)
3555 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3561 Session::cancel_audition ()
3563 if (auditioner->active()) {
3564 auditioner->cancel_audition ();
3565 AuditionActive (false); /* EMIT SIGNAL */
3570 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3572 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3576 Session::remove_empty_sounds ()
3578 vector<string> audio_filenames;
3580 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3582 Glib::Mutex::Lock lm (source_lock);
3584 TapeFileMatcher tape_file_matcher;
3586 remove_if (audio_filenames.begin(), audio_filenames.end(),
3587 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3589 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3591 sys::path audio_file_path (_session_dir->sound_path());
3593 audio_file_path /= *i;
3595 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3599 sys::remove (audio_file_path);
3600 const string peakfile = peak_path (audio_file_path.to_string());
3601 sys::remove (peakfile);
3603 catch (const sys::filesystem_error& err)
3605 error << err.what() << endmsg;
3612 Session::is_auditioning () const
3614 /* can be called before we have an auditioner object */
3616 return auditioner->active();
3623 Session::set_all_solo (bool yn)
3625 shared_ptr<RouteList> r = routes.reader ();
3627 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3628 if (!(*i)->is_hidden()) {
3629 (*i)->set_solo (yn, this);
3637 Session::set_all_mute (bool yn)
3639 shared_ptr<RouteList> r = routes.reader ();
3641 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3642 if (!(*i)->is_hidden()) {
3643 (*i)->set_mute (yn, this);
3651 Session::n_diskstreams () const
3655 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3657 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3658 if (!(*i)->hidden()) {
3666 Session::graph_reordered ()
3668 /* don't do this stuff if we are setting up connections
3669 from a set_state() call or creating new tracks.
3672 if (_state_of_the_state & InitialConnecting) {
3676 /* every track/bus asked for this to be handled but it was deferred because
3677 we were connecting. do it now.
3680 request_input_change_handling ();
3684 /* force all diskstreams to update their capture offset values to
3685 reflect any changes in latencies within the graph.
3688 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3690 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3691 (*i)->set_capture_offset ();
3696 Session::record_disenable_all ()
3698 record_enable_change_all (false);
3702 Session::record_enable_all ()
3704 record_enable_change_all (true);
3708 Session::record_enable_change_all (bool yn)
3710 shared_ptr<RouteList> r = routes.reader ();
3712 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3715 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3716 at->set_record_enable (yn, this);
3720 /* since we don't keep rec-enable state, don't mark session dirty */
3724 Session::add_processor (Processor* processor)
3727 PortInsert* port_insert;
3728 PluginInsert* plugin_insert;
3730 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3731 _port_inserts.insert (_port_inserts.begin(), port_insert);
3732 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3733 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3734 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3735 _sends.insert (_sends.begin(), send);
3737 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3741 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3747 Session::remove_processor (Processor* processor)
3750 PortInsert* port_insert;
3751 PluginInsert* plugin_insert;
3753 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3754 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3755 if (x != _port_inserts.end()) {
3756 insert_bitset[port_insert->bit_slot()] = false;
3757 _port_inserts.erase (x);
3759 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3760 _plugin_inserts.remove (plugin_insert);
3761 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3762 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3763 if (x != _sends.end()) {
3764 send_bitset[send->bit_slot()] = false;
3768 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3776 Session::available_capture_duration ()
3778 float sample_bytes_on_disk = 4.0; // keep gcc happy
3780 switch (Config->get_native_file_data_format()) {
3782 sample_bytes_on_disk = 4.0;
3786 sample_bytes_on_disk = 3.0;
3790 sample_bytes_on_disk = 2.0;
3794 /* impossible, but keep some gcc versions happy */
3795 fatal << string_compose (_("programming error: %1"),
3796 X_("illegal native file data format"))
3801 double scale = 4096.0 / sample_bytes_on_disk;
3803 if (_total_free_4k_blocks * scale > (double) max_frames) {
3807 return (nframes_t) floor (_total_free_4k_blocks * scale);
3811 Session::add_bundle (shared_ptr<Bundle> bundle)
3814 Glib::Mutex::Lock guard (bundle_lock);
3815 _bundles.push_back (bundle);
3818 BundleAdded (bundle); /* EMIT SIGNAL */
3824 Session::remove_bundle (shared_ptr<Bundle> bundle)
3826 bool removed = false;
3829 Glib::Mutex::Lock guard (bundle_lock);
3830 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3832 if (i != _bundles.end()) {
3839 BundleRemoved (bundle); /* EMIT SIGNAL */
3846 Session::bundle_by_name (string name) const
3848 Glib::Mutex::Lock lm (bundle_lock);
3850 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3851 if ((*i)->name() == name) {
3856 return boost::shared_ptr<Bundle> ();
3860 Session::tempo_map_changed (Change ignored)
3864 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3865 (*i)->update_after_tempo_map_change ();
3868 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3869 (*i)->update_after_tempo_map_change ();
3875 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3876 * the given count with the current block size.
3879 Session::ensure_buffers (ChanCount howmany)
3881 if (current_block_size == 0)
3882 return; // too early? (is this ok?)
3884 // We need at least 2 MIDI scratch buffers to mix/merge
3885 if (howmany.n_midi() < 2)
3886 howmany.set_midi(2);
3888 // FIXME: JACK needs to tell us maximum MIDI buffer size
3889 // Using nasty assumption (max # events == nframes) for now
3890 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3891 _mix_buffers->ensure_buffers(howmany, current_block_size);
3892 _silent_buffers->ensure_buffers(howmany, current_block_size);
3894 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3898 Session::next_insert_id ()
3900 /* this doesn't really loop forever. just think about it */
3903 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3904 if (!insert_bitset[n]) {
3905 insert_bitset[n] = true;
3911 /* none available, so resize and try again */
3913 insert_bitset.resize (insert_bitset.size() + 16, false);
3918 Session::next_send_id ()
3920 /* this doesn't really loop forever. just think about it */
3923 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3924 if (!send_bitset[n]) {
3925 send_bitset[n] = true;
3931 /* none available, so resize and try again */
3933 send_bitset.resize (send_bitset.size() + 16, false);
3938 Session::mark_send_id (uint32_t id)
3940 if (id >= send_bitset.size()) {
3941 send_bitset.resize (id+16, false);
3943 if (send_bitset[id]) {
3944 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3946 send_bitset[id] = true;
3950 Session::mark_insert_id (uint32_t id)
3952 if (id >= insert_bitset.size()) {
3953 insert_bitset.resize (id+16, false);
3955 if (insert_bitset[id]) {
3956 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3958 insert_bitset[id] = true;
3961 /* Named Selection management */
3964 Session::named_selection_by_name (string name)
3966 Glib::Mutex::Lock lm (named_selection_lock);
3967 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3968 if ((*i)->name == name) {
3976 Session::add_named_selection (NamedSelection* named_selection)
3979 Glib::Mutex::Lock lm (named_selection_lock);
3980 named_selections.insert (named_selections.begin(), named_selection);
3983 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3989 NamedSelectionAdded (); /* EMIT SIGNAL */
3993 Session::remove_named_selection (NamedSelection* named_selection)
3995 bool removed = false;
3998 Glib::Mutex::Lock lm (named_selection_lock);
4000 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4002 if (i != named_selections.end()) {
4004 named_selections.erase (i);
4011 NamedSelectionRemoved (); /* EMIT SIGNAL */
4016 Session::reset_native_file_format ()
4018 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4020 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4021 (*i)->reset_write_sources (false);
4026 Session::route_name_unique (string n) const
4028 shared_ptr<RouteList> r = routes.reader ();
4030 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4031 if ((*i)->name() == n) {
4040 Session::n_playlists () const
4042 Glib::Mutex::Lock lm (playlist_lock);
4043 return playlists.size();
4047 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4049 if (!force && howmany <= _npan_buffers) {
4053 if (_pan_automation_buffer) {
4055 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4056 delete [] _pan_automation_buffer[i];
4059 delete [] _pan_automation_buffer;
4062 _pan_automation_buffer = new pan_t*[howmany];
4064 for (uint32_t i = 0; i < howmany; ++i) {
4065 _pan_automation_buffer[i] = new pan_t[nframes];
4068 _npan_buffers = howmany;
4072 Session::freeze (InterThreadInfo& itt)
4074 shared_ptr<RouteList> r = routes.reader ();
4076 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4080 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4081 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4091 boost::shared_ptr<Region>
4092 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4093 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4095 boost::shared_ptr<Region> result;
4096 boost::shared_ptr<Playlist> playlist;
4097 boost::shared_ptr<AudioFileSource> fsource;
4099 char buf[PATH_MAX+1];
4100 ChanCount nchans(track.audio_diskstream()->n_channels());
4102 nframes_t this_chunk;
4105 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4106 const string sound_dir = sdir.sound_path().to_string();
4107 nframes_t len = end - start;
4110 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4111 end, start) << endmsg;
4115 // any bigger than this seems to cause stack overflows in called functions
4116 const nframes_t chunk_size = (128 * 1024)/4;
4118 g_atomic_int_set (&processing_prohibited, 1);
4120 /* call tree *MUST* hold route_lock */
4122 if ((playlist = track.diskstream()->playlist()) == 0) {
4126 /* external redirects will be a problem */
4128 if (track.has_external_redirects()) {
4132 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4134 for (x = 0; x < 99999; ++x) {
4135 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4136 if (access (buf, F_OK) != 0) {
4142 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4147 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4148 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4151 catch (failed_constructor& err) {
4152 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4156 srcs.push_back (fsource);
4159 /* XXX need to flush all redirects */
4164 /* create a set of reasonably-sized buffers */
4165 buffers.ensure_buffers(nchans, chunk_size);
4166 buffers.set_count(nchans);
4168 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4169 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4171 afs->prepare_for_peakfile_writes ();
4174 while (to_do && !itt.cancel) {
4176 this_chunk = min (to_do, chunk_size);
4178 if (track.export_stuff (buffers, start, this_chunk)) {
4183 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4184 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4187 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4193 start += this_chunk;
4194 to_do -= this_chunk;
4196 itt.progress = (float) (1.0 - ((double) to_do / len));
4205 xnow = localtime (&now);
4207 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4208 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4211 afs->update_header (position, *xnow, now);
4212 afs->flush_header ();
4216 /* construct a region to represent the bounced material */
4218 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4219 region_name_from_path (srcs.front()->name(), true));
4224 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4225 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4228 afs->mark_for_remove ();
4231 (*src)->drop_references ();
4235 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4236 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4239 afs->done_with_peakfile_writes ();
4243 g_atomic_int_set (&processing_prohibited, 0);
4249 Session::get_silent_buffers (ChanCount count)
4251 assert(_silent_buffers->available() >= count);
4252 _silent_buffers->set_count(count);
4254 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4255 for (size_t i= 0; i < count.get(*t); ++i) {
4256 _silent_buffers->get(*t, i).clear();
4260 return *_silent_buffers;
4264 Session::get_scratch_buffers (ChanCount count)
4266 if (count != ChanCount::ZERO) {
4267 assert(_scratch_buffers->available() >= count);
4268 _scratch_buffers->set_count(count);
4270 _scratch_buffers->set_count (_scratch_buffers->available());
4273 return *_scratch_buffers;
4277 Session::get_mix_buffers (ChanCount count)
4279 assert(_mix_buffers->available() >= count);
4280 _mix_buffers->set_count(count);
4281 return *_mix_buffers;
4285 Session::ntracks () const
4288 shared_ptr<RouteList> r = routes.reader ();
4290 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4291 if (dynamic_cast<Track*> ((*i).get())) {
4300 Session::nbusses () const
4303 shared_ptr<RouteList> r = routes.reader ();
4305 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4306 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4315 Session::add_automation_list(AutomationList *al)
4317 automation_lists[al->id()] = al;
4321 Session::compute_initial_length ()
4323 return _engine.frame_rate() * 60 * 5;
4327 Session::sync_order_keys (const char* base)
4329 if (!Config->get_sync_all_route_ordering()) {
4330 /* leave order keys as they are */
4334 boost::shared_ptr<RouteList> r = routes.reader ();
4336 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4337 (*i)->sync_order_keys (base);
4340 Route::SyncOrderKeys (base); // EMIT SIGNAL
4344 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4346 Glib::Mutex::Lock lm (bundle_lock);
4347 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {