2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_track.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/audioplaylist.h"
53 #include "ardour/audioregion.h"
54 #include "ardour/auditioner.h"
55 #include "ardour/buffer_set.h"
56 #include "ardour/bundle.h"
57 #include "ardour/click.h"
58 #include "ardour/configuration.h"
59 #include "ardour/crossfade.h"
60 #include "ardour/cycle_timer.h"
61 #include "ardour/data_type.h"
62 #include "ardour/filename_extensions.h"
63 #include "ardour/io_processor.h"
64 #include "ardour/midi_diskstream.h"
65 #include "ardour/midi_playlist.h"
66 #include "ardour/midi_region.h"
67 #include "ardour/midi_track.h"
68 #include "ardour/named_selection.h"
69 #include "ardour/playlist.h"
70 #include "ardour/plugin_insert.h"
71 #include "ardour/port_insert.h"
72 #include "ardour/processor.h"
73 #include "ardour/recent_sessions.h"
74 #include "ardour/region_factory.h"
75 #include "ardour/route_group.h"
76 #include "ardour/send.h"
77 #include "ardour/session.h"
78 #include "ardour/session_directory.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_metadata.h"
81 #include "ardour/slave.h"
82 #include "ardour/smf_source.h"
83 #include "ardour/source_factory.h"
84 #include "ardour/tape_file_matcher.h"
85 #include "ardour/tempo.h"
86 #include "ardour/utils.h"
91 using namespace ARDOUR;
93 using boost::shared_ptr;
95 bool Session::_disable_all_loaded_plugins = false;
97 sigc::signal<void,std::string> Session::Dialog;
98 sigc::signal<int> Session::AskAboutPendingState;
99 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
100 sigc::signal<void> Session::SendFeedback;
102 sigc::signal<void> Session::SMPTEOffsetChanged;
103 sigc::signal<void> Session::StartTimeChanged;
104 sigc::signal<void> Session::EndTimeChanged;
105 sigc::signal<void> Session::AutoBindingOn;
106 sigc::signal<void> Session::AutoBindingOff;
107 sigc::signal<void, std::string, std::string> Session::Exported;
109 Session::Session (AudioEngine &eng,
110 const string& fullpath,
111 const string& snapshot_name,
118 _requested_return_frame (-1),
119 _scratch_buffers(new BufferSet()),
120 _silent_buffers(new BufferSet()),
121 _mix_buffers(new BufferSet()),
123 _mmc_port (default_mmc_port),
124 _mtc_port (default_mtc_port),
125 _midi_port (default_midi_port),
126 _midi_clock_port (default_midi_clock_port),
127 _session_dir (new SessionDirectory(fullpath)),
128 pending_events (2048),
130 butler_mixdown_buffer (0),
131 butler_gain_buffer (0),
132 post_transport_work((PostTransportWork)0),
133 _send_smpte_update (false),
134 midi_thread (pthread_t (0)),
135 midi_requests (128), // the size of this should match the midi request pool size
136 diskstreams (new DiskstreamList),
137 routes (new RouteList),
138 auditioner ((Auditioner*) 0),
139 _total_free_4k_blocks (0),
140 _bundles (new BundleList),
141 _bundle_xml_node (0),
144 click_emphasis_data (0),
146 _metadata (new SessionMetadata()),
147 _have_rec_enabled_diskstream (false)
152 if (!eng.connected()) {
153 throw failed_constructor();
156 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
158 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
159 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
161 first_stage_init (fullpath, snapshot_name);
163 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
166 if (create (new_session, mix_template, compute_initial_length())) {
168 throw failed_constructor ();
172 if (second_stage_init (new_session)) {
174 throw failed_constructor ();
177 store_recent_sessions(_name, _path);
179 bool was_dirty = dirty();
181 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
183 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
186 DirtyChanged (); /* EMIT SIGNAL */
190 Session::Session (AudioEngine &eng,
192 string snapshot_name,
193 AutoConnectOption input_ac,
194 AutoConnectOption output_ac,
195 uint32_t control_out_channels,
196 uint32_t master_out_channels,
197 uint32_t requested_physical_in,
198 uint32_t requested_physical_out,
199 nframes_t initial_length)
205 _requested_return_frame (-1),
206 _scratch_buffers(new BufferSet()),
207 _silent_buffers(new BufferSet()),
208 _mix_buffers(new BufferSet()),
210 _mmc_port (default_mmc_port),
211 _mtc_port (default_mtc_port),
212 _midi_port (default_midi_port),
213 _midi_clock_port (default_midi_clock_port),
214 _session_dir ( new SessionDirectory(fullpath)),
215 pending_events (2048),
217 butler_mixdown_buffer (0),
218 butler_gain_buffer (0),
219 post_transport_work((PostTransportWork)0),
220 _send_smpte_update (false),
221 midi_thread (pthread_t (0)),
223 diskstreams (new DiskstreamList),
224 routes (new RouteList),
225 auditioner ((Auditioner *) 0),
226 _total_free_4k_blocks (0),
227 _bundles (new BundleList),
228 _bundle_xml_node (0),
229 _click_io ((IO *) 0),
231 click_emphasis_data (0),
233 _metadata (new SessionMetadata()),
234 _have_rec_enabled_diskstream (false)
238 if (!eng.connected()) {
239 throw failed_constructor();
242 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
244 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
245 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
247 if (n_physical_inputs) {
248 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
251 if (n_physical_outputs) {
252 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
255 first_stage_init (fullpath, snapshot_name);
257 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
260 if (create (new_session, string(), initial_length)) {
262 throw failed_constructor ();
267 /* set up Master Out and Control Out if necessary */
272 if (control_out_channels) {
273 ChanCount count(DataType::AUDIO, control_out_channels);
274 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut,
275 DataType::AUDIO, count, count));
276 r->set_remote_control_id (control_id++);
281 if (master_out_channels) {
282 ChanCount count(DataType::AUDIO, master_out_channels);
283 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut,
284 DataType::AUDIO, count, count));
285 r->set_remote_control_id (control_id);
289 /* prohibit auto-connect to master, because there isn't one */
290 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
294 add_routes (rl, false);
299 Config->set_input_auto_connect (input_ac);
300 Config->set_output_auto_connect (output_ac);
302 if (second_stage_init (new_session)) {
304 throw failed_constructor ();
307 store_recent_sessions (_name, _path);
309 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
311 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
322 /* if we got to here, leaving pending capture state around
326 remove_pending_capture_state ();
328 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
330 _engine.remove_session ();
332 GoingAway (); /* EMIT SIGNAL */
338 /* clear history so that no references to objects are held any more */
342 /* clear state tree so that no references to objects are held any more */
346 terminate_butler_thread ();
347 //terminate_midi_thread ();
349 if (click_data != default_click) {
350 delete [] click_data;
353 if (click_emphasis_data != default_click_emphasis) {
354 delete [] click_emphasis_data;
359 delete _scratch_buffers;
360 delete _silent_buffers;
363 AudioDiskstream::free_working_buffers();
365 Route::SyncOrderKeys.clear();
367 #undef TRACK_DESTRUCTION
368 #ifdef TRACK_DESTRUCTION
369 cerr << "delete named selections\n";
370 #endif /* TRACK_DESTRUCTION */
371 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
372 NamedSelectionList::iterator tmp;
381 #ifdef TRACK_DESTRUCTION
382 cerr << "delete playlists\n";
383 #endif /* TRACK_DESTRUCTION */
384 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
385 PlaylistList::iterator tmp;
390 (*i)->drop_references ();
395 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
396 PlaylistList::iterator tmp;
401 (*i)->drop_references ();
407 unused_playlists.clear ();
409 #ifdef TRACK_DESTRUCTION
410 cerr << "delete regions\n";
411 #endif /* TRACK_DESTRUCTION */
413 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
414 RegionList::iterator tmp;
419 i->second->drop_references ();
426 #ifdef TRACK_DESTRUCTION
427 cerr << "delete routes\n";
428 #endif /* TRACK_DESTRUCTION */
430 RCUWriter<RouteList> writer (routes);
431 boost::shared_ptr<RouteList> r = writer.get_copy ();
432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
433 (*i)->drop_references ();
436 /* writer goes out of scope and updates master */
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete diskstreams\n";
443 #endif /* TRACK_DESTRUCTION */
445 RCUWriter<DiskstreamList> dwriter (diskstreams);
446 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
447 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
448 (*i)->drop_references ();
452 diskstreams.flush ();
454 #ifdef TRACK_DESTRUCTION
455 cerr << "delete audio sources\n";
456 #endif /* TRACK_DESTRUCTION */
457 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
458 SourceMap::iterator tmp;
463 i->second->drop_references ();
469 #ifdef TRACK_DESTRUCTION
470 cerr << "delete mix groups\n";
471 #endif /* TRACK_DESTRUCTION */
472 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
473 list<RouteGroup*>::iterator tmp;
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete edit groups\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
487 list<RouteGroup*>::iterator tmp;
497 delete [] butler_mixdown_buffer;
498 delete [] butler_gain_buffer;
500 Crossfade::set_buffer_size (0);
506 Session::set_worst_io_latencies ()
508 _worst_output_latency = 0;
509 _worst_input_latency = 0;
511 if (!_engine.connected()) {
515 boost::shared_ptr<RouteList> r = routes.reader ();
517 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
518 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
519 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
524 Session::when_engine_running ()
526 string first_physical_output;
528 /* we don't want to run execute this again */
530 BootMessage (_("Set block size and sample rate"));
532 set_block_size (_engine.frames_per_cycle());
533 set_frame_rate (_engine.frame_rate());
535 BootMessage (_("Using configuration"));
537 Config->map_parameters (mem_fun (*this, &Session::config_changed));
539 /* every time we reconnect, recompute worst case output latencies */
541 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
543 if (synced_to_jack()) {
544 _engine.transport_stop ();
547 if (Config->get_jack_time_master()) {
548 _engine.transport_locate (_transport_frame);
556 _click_io.reset (new ClickIO (*this, "click"));
558 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
560 /* existing state for Click */
562 if (_click_io->set_state (*child->children().front()) == 0) {
564 _clicking = Config->get_clicking ();
568 error << _("could not setup Click I/O") << endmsg;
574 /* default state for Click: dual-mono to first 2 physical outputs */
576 for (int physport = 0; physport < 2; ++physport) {
577 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
579 if (physical_output.length()) {
580 if (_click_io->add_output_port (physical_output, this)) {
581 // relax, even though its an error
586 if (_click_io->n_outputs () > ChanCount::ZERO) {
587 _clicking = Config->get_clicking ();
592 catch (failed_constructor& err) {
593 error << _("cannot setup Click I/O") << endmsg;
596 BootMessage (_("Compute I/O Latencies"));
598 set_worst_io_latencies ();
601 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
604 BootMessage (_("Set up standard connections"));
606 /* Create a set of Bundle objects that map
607 to the physical I/O currently available. We create both
608 mono and stereo bundles, so that the common cases of mono
609 and stereo tracks get bundles to put in their mixer strip
610 in / out menus. There may be a nicer way of achieving that;
611 it doesn't really scale that well to higher channel counts */
613 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
615 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
617 shared_ptr<Bundle> c (new Bundle (buf, true));
618 c->add_channel (_("mono"));
619 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
624 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
625 if (np + 1 < n_physical_outputs) {
627 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
628 shared_ptr<Bundle> c (new Bundle (buf, true));
629 c->add_channel (_("L"));
630 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
631 c->add_channel (_("R"));
632 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
638 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
640 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
642 shared_ptr<Bundle> c (new Bundle (buf, false));
643 c->add_channel (_("mono"));
644 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
649 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
650 if (np + 1 < n_physical_inputs) {
652 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
654 shared_ptr<Bundle> c (new Bundle (buf, false));
655 c->add_channel (_("L"));
656 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
657 c->add_channel (_("R"));
658 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
666 /* create master/control ports */
669 /* force the master to ignore any later call to this */
670 if (_master_out->pending_state_node) {
671 _master_out->ports_became_legal();
674 /* no panner resets till we are through */
675 _master_out->defer_pan_reset ();
678 _master_out->set_input_minimum(ChanCount(DataType::AUDIO, n_physical_inputs));
679 _master_out->set_output_minimum(ChanCount(DataType::AUDIO, n_physical_outputs));
680 _master_out->ensure_io (
681 _master_out->input_minimum (), _master_out->output_minimum (),
684 _master_out->allow_pan_reset ();
689 BootMessage (_("Setup signal flow and plugins"));
693 /* catch up on send+insert cnts */
695 BootMessage (_("Catch up with send/insert state"));
699 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
702 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
703 if (id > insert_cnt) {
711 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
714 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
722 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
724 /* hook us up to the engine */
726 BootMessage (_("Connect to engine"));
728 _engine.set_session (this);
732 Session::hookup_io ()
734 /* stop graph reordering notifications from
735 causing resorts, etc.
738 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
741 if (auditioner == 0) {
743 /* we delay creating the auditioner till now because
744 it makes its own connections to ports.
745 the engine has to be running for this to work.
749 auditioner.reset (new Auditioner (*this));
752 catch (failed_constructor& err) {
753 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
757 /* Tell all IO objects to create their ports */
762 vector<string> cports;
764 _control_out->ensure_io(
765 _control_out->input_minimum(), _control_out->output_minimum(),
768 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
770 for (uint32_t n = 0; n < ni; ++n) {
771 cports.push_back (_control_out->input(n)->name());
774 boost::shared_ptr<RouteList> r = routes.reader ();
776 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
777 (*x)->set_control_outs (cports);
781 /* load bundles, which we may have postponed earlier on */
782 if (_bundle_xml_node) {
783 load_bundles (*_bundle_xml_node);
784 delete _bundle_xml_node;
787 /* Tell all IO objects to connect themselves together */
789 IO::enable_connecting ();
791 /* Now reset all panners */
793 IO::reset_panners ();
795 /* Anyone who cares about input state, wake up and do something */
797 IOConnectionsComplete (); /* EMIT SIGNAL */
799 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
802 /* now handle the whole enchilada as if it was one
808 /* update mixer solo state */
814 Session::playlist_length_changed ()
816 /* we can't just increase end_location->end() if pl->get_maximum_extent()
817 if larger. if the playlist used to be the longest playlist,
818 and its now shorter, we have to decrease end_location->end(). hence,
819 we have to iterate over all diskstreams and check the
820 playlists currently in use.
826 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
828 boost::shared_ptr<Playlist> playlist;
830 if ((playlist = dstream->playlist()) != 0) {
831 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
834 /* see comment in playlist_length_changed () */
839 Session::record_enabling_legal () const
841 /* this used to be in here, but survey says.... we don't need to restrict it */
842 // if (record_status() == Recording) {
846 if (Config->get_all_safe()) {
853 Session::reset_input_monitor_state ()
855 if (transport_rolling()) {
857 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
859 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
860 if ((*i)->record_enabled ()) {
861 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
862 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
866 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
868 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
869 if ((*i)->record_enabled ()) {
870 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
871 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
878 Session::auto_punch_start_changed (Location* location)
880 replace_event (Event::PunchIn, location->start());
882 if (get_record_enabled() && Config->get_punch_in()) {
883 /* capture start has been changed, so save new pending state */
884 save_state ("", true);
889 Session::auto_punch_end_changed (Location* location)
891 nframes_t when_to_stop = location->end();
892 // when_to_stop += _worst_output_latency + _worst_input_latency;
893 replace_event (Event::PunchOut, when_to_stop);
897 Session::auto_punch_changed (Location* location)
899 nframes_t when_to_stop = location->end();
901 replace_event (Event::PunchIn, location->start());
902 //when_to_stop += _worst_output_latency + _worst_input_latency;
903 replace_event (Event::PunchOut, when_to_stop);
907 Session::auto_loop_changed (Location* location)
909 replace_event (Event::AutoLoop, location->end(), location->start());
911 if (transport_rolling() && play_loop) {
913 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
915 if (_transport_frame > location->end()) {
916 // relocate to beginning of loop
917 clear_events (Event::LocateRoll);
919 request_locate (location->start(), true);
922 else if (Config->get_seamless_loop() && !loop_changing) {
924 // schedule a locate-roll to refill the diskstreams at the
926 loop_changing = true;
928 if (location->end() > last_loopend) {
929 clear_events (Event::LocateRoll);
930 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
937 last_loopend = location->end();
941 Session::set_auto_punch_location (Location* location)
945 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
946 auto_punch_start_changed_connection.disconnect();
947 auto_punch_end_changed_connection.disconnect();
948 auto_punch_changed_connection.disconnect();
949 existing->set_auto_punch (false, this);
950 remove_event (existing->start(), Event::PunchIn);
951 clear_events (Event::PunchOut);
952 auto_punch_location_changed (0);
961 if (location->end() <= location->start()) {
962 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
966 auto_punch_start_changed_connection.disconnect();
967 auto_punch_end_changed_connection.disconnect();
968 auto_punch_changed_connection.disconnect();
970 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
971 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
972 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
974 location->set_auto_punch (true, this);
977 auto_punch_changed (location);
979 auto_punch_location_changed (location);
983 Session::set_auto_loop_location (Location* location)
987 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
988 auto_loop_start_changed_connection.disconnect();
989 auto_loop_end_changed_connection.disconnect();
990 auto_loop_changed_connection.disconnect();
991 existing->set_auto_loop (false, this);
992 remove_event (existing->end(), Event::AutoLoop);
993 auto_loop_location_changed (0);
1002 if (location->end() <= location->start()) {
1003 error << _("Session: you can't use a mark for auto loop") << endmsg;
1007 last_loopend = location->end();
1009 auto_loop_start_changed_connection.disconnect();
1010 auto_loop_end_changed_connection.disconnect();
1011 auto_loop_changed_connection.disconnect();
1013 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1014 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1015 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1017 location->set_auto_loop (true, this);
1019 /* take care of our stuff first */
1021 auto_loop_changed (location);
1023 /* now tell everyone else */
1025 auto_loop_location_changed (location);
1029 Session::locations_added (Location* ignored)
1035 Session::locations_changed ()
1037 _locations.apply (*this, &Session::handle_locations_changed);
1041 Session::handle_locations_changed (Locations::LocationList& locations)
1043 Locations::LocationList::iterator i;
1045 bool set_loop = false;
1046 bool set_punch = false;
1048 for (i = locations.begin(); i != locations.end(); ++i) {
1052 if (location->is_auto_punch()) {
1053 set_auto_punch_location (location);
1056 if (location->is_auto_loop()) {
1057 set_auto_loop_location (location);
1061 if (location->is_start()) {
1062 start_location = location;
1064 if (location->is_end()) {
1065 end_location = location;
1070 set_auto_loop_location (0);
1073 set_auto_punch_location (0);
1080 Session::enable_record ()
1082 /* XXX really atomic compare+swap here */
1083 if (g_atomic_int_get (&_record_status) != Recording) {
1084 g_atomic_int_set (&_record_status, Recording);
1085 _last_record_location = _transport_frame;
1086 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1088 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1089 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1090 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1091 if ((*i)->record_enabled ()) {
1092 (*i)->monitor_input (true);
1097 RecordStateChanged ();
1102 Session::disable_record (bool rt_context, bool force)
1106 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1108 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1109 g_atomic_int_set (&_record_status, Disabled);
1111 if (rs == Recording) {
1112 g_atomic_int_set (&_record_status, Enabled);
1116 // FIXME: timestamp correct? [DR]
1117 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1118 // does this /need/ to be sent in all cases?
1120 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1122 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1123 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1125 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1126 if ((*i)->record_enabled ()) {
1127 (*i)->monitor_input (false);
1132 RecordStateChanged (); /* emit signal */
1135 remove_pending_capture_state ();
1141 Session::step_back_from_record ()
1143 /* XXX really atomic compare+swap here */
1144 if (g_atomic_int_get (&_record_status) == Recording) {
1145 g_atomic_int_set (&_record_status, Enabled);
1147 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1148 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1150 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1151 if ((*i)->record_enabled ()) {
1152 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1153 (*i)->monitor_input (false);
1161 Session::maybe_enable_record ()
1163 g_atomic_int_set (&_record_status, Enabled);
1165 /* this function is currently called from somewhere other than an RT thread.
1166 this save_state() call therefore doesn't impact anything.
1169 save_state ("", true);
1171 if (_transport_speed) {
1172 if (!Config->get_punch_in()) {
1176 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1177 RecordStateChanged (); /* EMIT SIGNAL */
1184 Session::audible_frame () const
1190 /* the first of these two possible settings for "offset"
1191 mean that the audible frame is stationary until
1192 audio emerges from the latency compensation
1195 the second means that the audible frame is stationary
1196 until audio would emerge from a physical port
1197 in the absence of any plugin latency compensation
1200 offset = _worst_output_latency;
1202 if (offset > current_block_size) {
1203 offset -= current_block_size;
1205 /* XXX is this correct? if we have no external
1206 physical connections and everything is internal
1207 then surely this is zero? still, how
1208 likely is that anyway?
1210 offset = current_block_size;
1213 if (synced_to_jack()) {
1214 tf = _engine.transport_frame();
1216 tf = _transport_frame;
1221 if (!non_realtime_work_pending()) {
1225 /* check to see if we have passed the first guaranteed
1226 audible frame past our last start position. if not,
1227 return that last start point because in terms
1228 of audible frames, we have not moved yet.
1231 if (_transport_speed > 0.0f) {
1233 if (!play_loop || !have_looped) {
1234 if (tf < _last_roll_location + offset) {
1235 return _last_roll_location;
1243 } else if (_transport_speed < 0.0f) {
1245 /* XXX wot? no backward looping? */
1247 if (tf > _last_roll_location - offset) {
1248 return _last_roll_location;
1260 Session::set_frame_rate (nframes_t frames_per_second)
1262 /** \fn void Session::set_frame_size(nframes_t)
1263 the AudioEngine object that calls this guarantees
1264 that it will not be called while we are also in
1265 ::process(). Its fine to do things that block
1269 _base_frame_rate = frames_per_second;
1273 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1277 // XXX we need some equivalent to this, somehow
1278 // SndFileSource::setup_standard_crossfades (frames_per_second);
1282 /* XXX need to reset/reinstantiate all LADSPA plugins */
1286 Session::set_block_size (nframes_t nframes)
1288 /* the AudioEngine guarantees
1289 that it will not be called while we are also in
1290 ::process(). It is therefore fine to do things that block
1295 current_block_size = nframes;
1297 ensure_buffers(_scratch_buffers->available());
1299 delete [] _gain_automation_buffer;
1300 _gain_automation_buffer = new gain_t[nframes];
1302 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1304 boost::shared_ptr<RouteList> r = routes.reader ();
1306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1307 (*i)->set_block_size (nframes);
1310 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1311 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1312 (*i)->set_block_size (nframes);
1315 set_worst_io_latencies ();
1320 Session::set_default_fade (float steepness, float fade_msecs)
1323 nframes_t fade_frames;
1325 /* Don't allow fade of less 1 frame */
1327 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1334 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1338 default_fade_msecs = fade_msecs;
1339 default_fade_steepness = steepness;
1342 // jlc, WTF is this!
1343 Glib::RWLock::ReaderLock lm (route_lock);
1344 AudioRegion::set_default_fade (steepness, fade_frames);
1349 /* XXX have to do this at some point */
1350 /* foreach region using default fade, reset, then
1351 refill_all_diskstream_buffers ();
1356 struct RouteSorter {
1357 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1358 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1360 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1363 if (r1->fed_by.empty()) {
1364 if (r2->fed_by.empty()) {
1365 /* no ardour-based connections inbound to either route. just use signal order */
1366 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1368 /* r2 has connections, r1 does not; run r1 early */
1372 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1379 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1381 shared_ptr<Route> r2;
1383 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1384 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1388 /* make a copy of the existing list of routes that feed r1 */
1390 set<shared_ptr<Route> > existing = r1->fed_by;
1392 /* for each route that feeds r1, recurse, marking it as feeding
1396 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1399 /* r2 is a route that feeds r1 which somehow feeds base. mark
1400 base as being fed by r2
1403 rbase->fed_by.insert (r2);
1407 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1411 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1415 /* now recurse, so that we can mark base as being fed by
1416 all routes that feed r2
1419 trace_terminal (r2, rbase);
1426 Session::resort_routes ()
1428 /* don't do anything here with signals emitted
1429 by Routes while we are being destroyed.
1432 if (_state_of_the_state & Deletion) {
1439 RCUWriter<RouteList> writer (routes);
1440 shared_ptr<RouteList> r = writer.get_copy ();
1441 resort_routes_using (r);
1442 /* writer goes out of scope and forces update */
1447 Session::resort_routes_using (shared_ptr<RouteList> r)
1449 RouteList::iterator i, j;
1451 for (i = r->begin(); i != r->end(); ++i) {
1453 (*i)->fed_by.clear ();
1455 for (j = r->begin(); j != r->end(); ++j) {
1457 /* although routes can feed themselves, it will
1458 cause an endless recursive descent if we
1459 detect it. so don't bother checking for
1467 if ((*j)->feeds (*i)) {
1468 (*i)->fed_by.insert (*j);
1473 for (i = r->begin(); i != r->end(); ++i) {
1474 trace_terminal (*i, *i);
1481 cerr << "finished route resort\n";
1483 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1484 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1491 list<boost::shared_ptr<MidiTrack> >
1492 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1494 char track_name[32];
1495 uint32_t track_id = 0;
1498 RouteList new_routes;
1499 list<boost::shared_ptr<MidiTrack> > ret;
1500 //uint32_t control_id;
1502 // FIXME: need physical I/O and autoconnect stuff for MIDI
1504 /* count existing midi tracks */
1507 shared_ptr<RouteList> r = routes.reader ();
1509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1510 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1511 if (!(*i)->is_hidden()) {
1513 //channels_used += (*i)->n_inputs().n_midi();
1519 vector<string> physinputs;
1520 vector<string> physoutputs;
1522 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1523 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1525 // control_id = ntracks() + nbusses();
1529 /* check for duplicate route names, since we might have pre-existing
1530 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1531 save, close,restart,add new route - first named route is now
1539 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1541 if (route_by_name (track_name) == 0) {
1545 } while (track_id < (UINT_MAX-1));
1547 shared_ptr<MidiTrack> track;
1550 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1552 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1553 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1559 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1563 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1564 port = physinputs[(channels_used+x)%nphysical_in];
1567 if (port.length() && track->connect_input (track->input (x), port, this)) {
1573 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1577 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1578 port = physoutputs[(channels_used+x)%nphysical_out];
1579 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1581 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1585 if (port.length() && track->connect_output (track->output (x), port, this)) {
1590 channels_used += track->n_inputs ().n_midi();
1594 track->midi_diskstream()->non_realtime_input_change();
1596 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1597 //track->set_remote_control_id (control_id);
1599 new_routes.push_back (track);
1600 ret.push_back (track);
1603 catch (failed_constructor &err) {
1604 error << _("Session: could not create new midi track.") << endmsg;
1607 /* we need to get rid of this, since the track failed to be created */
1608 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1611 RCUWriter<DiskstreamList> writer (diskstreams);
1612 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1613 ds->remove (track->midi_diskstream());
1620 catch (AudioEngine::PortRegistrationFailure& pfe) {
1622 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;
1625 /* we need to get rid of this, since the track failed to be created */
1626 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1629 RCUWriter<DiskstreamList> writer (diskstreams);
1630 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1631 ds->remove (track->midi_diskstream());
1642 if (!new_routes.empty()) {
1643 add_routes (new_routes, false);
1644 save_state (_current_snapshot_name);
1650 list<boost::shared_ptr<AudioTrack> >
1651 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1653 char track_name[32];
1654 uint32_t track_id = 0;
1656 uint32_t channels_used = 0;
1658 RouteList new_routes;
1659 list<boost::shared_ptr<AudioTrack> > ret;
1660 uint32_t control_id;
1662 /* count existing audio tracks */
1665 shared_ptr<RouteList> r = routes.reader ();
1667 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1668 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1669 if (!(*i)->is_hidden()) {
1671 channels_used += (*i)->n_inputs().n_audio();
1677 vector<string> physinputs;
1678 vector<string> physoutputs;
1680 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1681 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1683 control_id = ntracks() + nbusses() + 1;
1687 /* check for duplicate route names, since we might have pre-existing
1688 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1689 save, close,restart,add new route - first named route is now
1697 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1699 if (route_by_name (track_name) == 0) {
1703 } while (track_id < (UINT_MAX-1));
1705 shared_ptr<AudioTrack> track;
1708 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1710 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1711 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1712 input_channels, output_channels)
1717 if (!physinputs.empty()) {
1718 uint32_t nphysical_in = physinputs.size();
1720 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1724 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1725 port = physinputs[(channels_used+x)%nphysical_in];
1728 if (port.length() && track->connect_input (track->input (x), port, this)) {
1734 if (!physoutputs.empty()) {
1735 uint32_t nphysical_out = physoutputs.size();
1737 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1740 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1741 port = physoutputs[(channels_used+x)%nphysical_out];
1742 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1743 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1744 port = _master_out->input (x % _master_out->n_inputs().n_audio())->name();
1748 if (port.length() && track->connect_output (track->output (x), port, this)) {
1754 channels_used += track->n_inputs ().n_audio();
1756 track->audio_diskstream()->non_realtime_input_change();
1758 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1759 track->set_remote_control_id (control_id);
1762 new_routes.push_back (track);
1763 ret.push_back (track);
1766 catch (failed_constructor &err) {
1767 error << _("Session: could not create new audio track.") << endmsg;
1770 /* we need to get rid of this, since the track failed to be created */
1771 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1774 RCUWriter<DiskstreamList> writer (diskstreams);
1775 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1776 ds->remove (track->audio_diskstream());
1783 catch (AudioEngine::PortRegistrationFailure& pfe) {
1785 error << pfe.what() << endmsg;
1788 /* we need to get rid of this, since the track failed to be created */
1789 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1792 RCUWriter<DiskstreamList> writer (diskstreams);
1793 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1794 ds->remove (track->audio_diskstream());
1805 if (!new_routes.empty()) {
1806 add_routes (new_routes, true);
1813 Session::set_remote_control_ids ()
1815 RemoteModel m = Config->get_remote_model();
1817 shared_ptr<RouteList> r = routes.reader ();
1819 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1820 if ( MixerOrdered == m) {
1821 long order = (*i)->order_key(N_("signal"));
1822 (*i)->set_remote_control_id( order+1 );
1823 } else if ( EditorOrdered == m) {
1824 long order = (*i)->order_key(N_("editor"));
1825 (*i)->set_remote_control_id( order+1 );
1826 } else if ( UserOrdered == m) {
1827 //do nothing ... only changes to remote id's are initiated by user
1834 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1837 uint32_t bus_id = 1;
1839 uint32_t channels_used = 0;
1842 uint32_t control_id;
1844 /* count existing audio busses */
1847 shared_ptr<RouteList> r = routes.reader ();
1849 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1850 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1852 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1855 channels_used += (*i)->n_inputs().n_audio();
1861 vector<string> physinputs;
1862 vector<string> physoutputs;
1864 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1865 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1867 n_physical_audio_outputs = physoutputs.size();
1868 n_physical_audio_inputs = physinputs.size();
1870 control_id = ntracks() + nbusses() + 1;
1875 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1879 if (route_by_name (bus_name) == 0) {
1883 } while (bus_id < (UINT_MAX-1));
1886 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1888 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1889 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1890 input_channels, output_channels)
1898 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1902 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1903 port = physinputs[((n+x)%n_physical_audio_inputs)];
1906 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1912 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1915 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1916 port = physoutputs[((n+x)%n_physical_outputs)];
1917 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1919 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1923 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1928 channels_used += bus->n_inputs ().n_audio();
1930 bus->set_remote_control_id (control_id);
1933 ret.push_back (bus);
1937 catch (failed_constructor &err) {
1938 error << _("Session: could not create new audio route.") << endmsg;
1942 catch (AudioEngine::PortRegistrationFailure& pfe) {
1943 error << pfe.what() << endmsg;
1953 add_routes (ret, true);
1961 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1965 uint32_t control_id;
1968 if (!tree.read (template_path.c_str())) {
1972 XMLNode* node = tree.root();
1974 control_id = ntracks() + nbusses() + 1;
1978 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1980 std::string node_name = IO::name_from_state (*node_copy.children().front());
1982 if (route_by_name (node_name) != 0) {
1984 /* generate a new name by adding a number to the end of the template name */
1986 uint32_t number = 1;
1989 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
1993 if (route_by_name (name) == 0) {
1997 } while (number < UINT_MAX);
1999 if (number == UINT_MAX) {
2000 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2004 IO::set_name_in_state (*node_copy.children().front(), name);
2007 Track::zero_diskstream_id_in_xml (node_copy);
2010 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2013 error << _("Session: cannot create track/bus from template description") << endmsg;
2017 if (boost::dynamic_pointer_cast<Track>(route)) {
2018 /* force input/output change signals so that the new diskstream
2019 picks up the configuration of the route. During session
2020 loading this normally happens in a different way.
2022 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2023 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2026 route->set_remote_control_id (control_id);
2029 ret.push_back (route);
2032 catch (failed_constructor &err) {
2033 error << _("Session: could not create new route from template") << endmsg;
2037 catch (AudioEngine::PortRegistrationFailure& pfe) {
2038 error << pfe.what() << endmsg;
2047 add_routes (ret, true);
2054 Session::add_routes (RouteList& new_routes, bool save)
2057 RCUWriter<RouteList> writer (routes);
2058 shared_ptr<RouteList> r = writer.get_copy ();
2059 r->insert (r->end(), new_routes.begin(), new_routes.end());
2060 resort_routes_using (r);
2063 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2065 boost::weak_ptr<Route> wpr (*x);
2067 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2068 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2069 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2070 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2072 if ((*x)->is_master()) {
2076 if ((*x)->is_control()) {
2077 _control_out = (*x);
2081 if (_control_out && IO::connecting_legal) {
2083 vector<string> cports;
2084 uint32_t ni = _control_out->n_inputs().n_audio();
2086 for (uint32_t n = 0; n < ni; ++n) {
2087 cports.push_back (_control_out->input(n)->name());
2090 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2091 (*x)->set_control_outs (cports);
2098 save_state (_current_snapshot_name);
2101 RouteAdded (new_routes); /* EMIT SIGNAL */
2105 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2107 /* need to do this in case we're rolling at the time, to prevent false underruns */
2108 dstream->do_refill_with_alloc ();
2110 dstream->set_block_size (current_block_size);
2113 RCUWriter<DiskstreamList> writer (diskstreams);
2114 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2115 ds->push_back (dstream);
2116 /* writer goes out of scope, copies ds back to main */
2119 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2120 /* this will connect to future changes, and check the current length */
2121 diskstream_playlist_changed (dstream);
2123 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2125 dstream->prepare ();
2130 Session::remove_route (shared_ptr<Route> route)
2133 RCUWriter<RouteList> writer (routes);
2134 shared_ptr<RouteList> rs = writer.get_copy ();
2138 /* deleting the master out seems like a dumb
2139 idea, but its more of a UI policy issue
2143 if (route == _master_out) {
2144 _master_out = shared_ptr<Route> ();
2147 if (route == _control_out) {
2148 _control_out = shared_ptr<Route> ();
2150 /* cancel control outs for all routes */
2152 vector<string> empty;
2154 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2155 (*r)->set_control_outs (empty);
2159 update_route_solo_state ();
2161 /* writer goes out of scope, forces route list update */
2164 boost::shared_ptr<Track> t;
2165 boost::shared_ptr<Diskstream> ds;
2167 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2168 ds = t->diskstream();
2174 RCUWriter<DiskstreamList> dsl (diskstreams);
2175 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2180 find_current_end ();
2182 // We need to disconnect the routes inputs and outputs
2184 route->disconnect_inputs (0);
2185 route->disconnect_outputs (0);
2187 update_latency_compensation (false, false);
2190 /* get rid of it from the dead wood collection in the route list manager */
2192 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2196 /* try to cause everyone to drop their references */
2198 route->drop_references ();
2200 sync_order_keys (N_("session"));
2202 /* save the new state of the world */
2204 if (save_state (_current_snapshot_name)) {
2205 save_history (_current_snapshot_name);
2210 Session::route_mute_changed (void* src)
2216 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2218 if (solo_update_disabled) {
2224 boost::shared_ptr<Route> route = wpr.lock ();
2227 /* should not happen */
2228 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2232 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2234 shared_ptr<RouteList> r = routes.reader ();
2236 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2242 /* don't mess with busses */
2244 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
2250 /* don't mess with tracks */
2252 if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
2257 if ((*i) != route &&
2258 ((*i)->mix_group () == 0 ||
2259 (*i)->mix_group () != route->mix_group () ||
2260 !route->mix_group ()->is_active())) {
2262 if ((*i)->soloed()) {
2264 /* if its already soloed, and solo latching is enabled,
2265 then leave it as it is.
2268 if (Config->get_solo_latched()) {
2275 solo_update_disabled = true;
2276 (*i)->set_solo (false, src);
2277 solo_update_disabled = false;
2281 bool something_soloed = false;
2282 bool same_thing_soloed = false;
2283 bool signal = false;
2285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2286 if ((*i)->soloed()) {
2287 something_soloed = true;
2288 if (boost::dynamic_pointer_cast<Track>(*i)) {
2290 same_thing_soloed = true;
2295 same_thing_soloed = true;
2303 if (something_soloed != currently_soloing) {
2305 currently_soloing = something_soloed;
2308 modify_solo_mute (is_track, same_thing_soloed);
2311 SoloActive (currently_soloing); /* EMIT SIGNAL */
2314 SoloChanged (); /* EMIT SIGNAL */
2320 Session::update_route_solo_state ()
2323 bool is_track = false;
2324 bool signal = false;
2326 /* this is where we actually implement solo by changing
2327 the solo mute setting of each track.
2330 shared_ptr<RouteList> r = routes.reader ();
2332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2333 if ((*i)->soloed()) {
2335 if (boost::dynamic_pointer_cast<Track>(*i)) {
2342 if (mute != currently_soloing) {
2344 currently_soloing = mute;
2347 if (!is_track && !mute) {
2349 /* nothing is soloed */
2351 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2352 (*i)->set_solo_mute (false);
2362 modify_solo_mute (is_track, mute);
2365 SoloActive (currently_soloing);
2370 Session::modify_solo_mute (bool is_track, bool mute)
2372 shared_ptr<RouteList> r = routes.reader ();
2374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2378 /* only alter track solo mute */
2380 if (boost::dynamic_pointer_cast<Track>(*i)) {
2381 if ((*i)->soloed()) {
2382 (*i)->set_solo_mute (!mute);
2384 (*i)->set_solo_mute (mute);
2390 /* only alter bus solo mute */
2392 if (!boost::dynamic_pointer_cast<Track>(*i)) {
2394 if ((*i)->soloed()) {
2396 (*i)->set_solo_mute (false);
2400 /* don't mute master or control outs
2401 in response to another bus solo
2404 if ((*i) != _master_out &&
2405 (*i) != _control_out) {
2406 (*i)->set_solo_mute (mute);
2417 Session::catch_up_on_solo ()
2419 /* this is called after set_state() to catch the full solo
2420 state, which can't be correctly determined on a per-route
2421 basis, but needs the global overview that only the session
2424 update_route_solo_state();
2428 Session::catch_up_on_solo_mute_override ()
2430 if (Config->get_solo_model() != InverseMute) {
2434 /* this is called whenever the param solo-mute-override is
2437 shared_ptr<RouteList> r = routes.reader ();
2439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2440 (*i)->catch_up_on_solo_mute_override ();
2445 Session::route_by_name (string name)
2447 shared_ptr<RouteList> r = routes.reader ();
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 if ((*i)->name() == name) {
2455 return shared_ptr<Route> ((Route*) 0);
2459 Session::route_by_id (PBD::ID id)
2461 shared_ptr<RouteList> r = routes.reader ();
2463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2464 if ((*i)->id() == id) {
2469 return shared_ptr<Route> ((Route*) 0);
2473 Session::route_by_remote_id (uint32_t id)
2475 shared_ptr<RouteList> r = routes.reader ();
2477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2478 if ((*i)->remote_control_id() == id) {
2483 return shared_ptr<Route> ((Route*) 0);
2487 Session::find_current_end ()
2489 if (_state_of_the_state & Loading) {
2493 nframes_t max = get_maximum_extent ();
2495 if (max > end_location->end()) {
2496 end_location->set_end (max);
2498 DurationChanged(); /* EMIT SIGNAL */
2503 Session::get_maximum_extent () const
2508 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2510 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2511 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2513 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2514 if ((me = pl->get_maximum_extent()) > max) {
2522 boost::shared_ptr<Diskstream>
2523 Session::diskstream_by_name (string name)
2525 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2527 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2528 if ((*i)->name() == name) {
2533 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2536 boost::shared_ptr<Diskstream>
2537 Session::diskstream_by_id (const PBD::ID& id)
2539 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2541 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2542 if ((*i)->id() == id) {
2547 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2550 /* Region management */
2553 Session::new_region_name (string old)
2555 string::size_type last_period;
2557 string::size_type len = old.length() + 64;
2560 if ((last_period = old.find_last_of ('.')) == string::npos) {
2562 /* no period present - add one explicitly */
2565 last_period = old.length() - 1;
2570 number = atoi (old.substr (last_period+1).c_str());
2574 while (number < (UINT_MAX-1)) {
2576 RegionList::const_iterator i;
2581 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2584 for (i = regions.begin(); i != regions.end(); ++i) {
2585 if (i->second->name() == sbuf) {
2590 if (i == regions.end()) {
2595 if (number != (UINT_MAX-1)) {
2599 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2604 Session::region_name (string& result, string base, bool newlevel)
2609 if (base.find("/") != string::npos) {
2610 base = base.substr(base.find_last_of("/") + 1);
2615 Glib::Mutex::Lock lm (region_lock);
2617 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2626 string::size_type pos;
2628 pos = base.find_last_of ('.');
2630 /* pos may be npos, but then we just use entire base */
2632 subbase = base.substr (0, pos);
2637 Glib::Mutex::Lock lm (region_lock);
2639 map<string,uint32_t>::iterator x;
2643 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2645 region_name_map[subbase] = 1;
2648 snprintf (buf, sizeof (buf), ".%d", x->second);
2659 Session::add_region (boost::shared_ptr<Region> region)
2661 vector<boost::shared_ptr<Region> > v;
2662 v.push_back (region);
2667 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2672 Glib::Mutex::Lock lm (region_lock);
2674 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2676 boost::shared_ptr<Region> region = *ii;
2680 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2684 RegionList::iterator x;
2686 for (x = regions.begin(); x != regions.end(); ++x) {
2688 if (region->region_list_equivalent (x->second)) {
2693 if (x == regions.end()) {
2695 pair<RegionList::key_type,RegionList::mapped_type> entry;
2697 entry.first = region->id();
2698 entry.second = region;
2700 pair<RegionList::iterator,bool> x = regions.insert (entry);
2712 /* mark dirty because something has changed even if we didn't
2713 add the region to the region list.
2720 vector<boost::weak_ptr<Region> > v;
2721 boost::shared_ptr<Region> first_r;
2723 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2725 boost::shared_ptr<Region> region = *ii;
2729 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2732 v.push_back (region);
2739 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2740 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2742 update_region_name_map (region);
2746 RegionsAdded (v); /* EMIT SIGNAL */
2752 Session::update_region_name_map (boost::shared_ptr<Region> region)
2754 string::size_type last_period = region->name().find_last_of ('.');
2756 if (last_period != string::npos && last_period < region->name().length() - 1) {
2758 string base = region->name().substr (0, last_period);
2759 string number = region->name().substr (last_period+1);
2760 map<string,uint32_t>::iterator x;
2762 /* note that if there is no number, we get zero from atoi,
2766 region_name_map[base] = atoi (number);
2771 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2773 boost::shared_ptr<Region> region (weak_region.lock ());
2779 if (what_changed & Region::HiddenChanged) {
2780 /* relay hidden changes */
2781 RegionHiddenChange (region);
2784 if (what_changed & NameChanged) {
2785 update_region_name_map (region);
2790 Session::remove_region (boost::weak_ptr<Region> weak_region)
2792 RegionList::iterator i;
2793 boost::shared_ptr<Region> region (weak_region.lock ());
2799 bool removed = false;
2802 Glib::Mutex::Lock lm (region_lock);
2804 if ((i = regions.find (region->id())) != regions.end()) {
2810 /* mark dirty because something has changed even if we didn't
2811 remove the region from the region list.
2817 RegionRemoved(region); /* EMIT SIGNAL */
2821 boost::shared_ptr<Region>
2822 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2824 RegionList::iterator i;
2825 boost::shared_ptr<Region> region;
2827 Glib::Mutex::Lock lm (region_lock);
2829 for (i = regions.begin(); i != regions.end(); ++i) {
2833 if (region->whole_file()) {
2835 if (child->source_equivalent (region)) {
2841 return boost::shared_ptr<Region> ();
2845 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2847 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2848 (*i)->get_region_list_equivalent_regions (region, result);
2852 Session::destroy_region (boost::shared_ptr<Region> region)
2854 vector<boost::shared_ptr<Source> > srcs;
2857 if (region->playlist()) {
2858 region->playlist()->destroy_region (region);
2861 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2862 srcs.push_back (region->source (n));
2866 region->drop_references ();
2868 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2870 (*i)->mark_for_remove ();
2871 (*i)->drop_references ();
2873 cerr << "source was not used by any playlist\n";
2880 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2882 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2883 destroy_region (*i);
2889 Session::remove_last_capture ()
2891 list<boost::shared_ptr<Region> > r;
2893 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2895 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2896 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2899 r.insert (r.end(), l.begin(), l.end());
2904 destroy_regions (r);
2906 save_state (_current_snapshot_name);
2912 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2918 /* Source Management */
2921 Session::add_source (boost::shared_ptr<Source> source)
2923 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2924 pair<SourceMap::iterator,bool> result;
2926 entry.first = source->id();
2927 entry.second = source;
2930 Glib::Mutex::Lock lm (source_lock);
2931 result = sources.insert (entry);
2934 if (result.second) {
2935 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2939 boost::shared_ptr<AudioFileSource> afs;
2941 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2942 if (Config->get_auto_analyse_audio()) {
2943 Analyser::queue_source_for_analysis (source, false);
2949 Session::remove_source (boost::weak_ptr<Source> src)
2951 SourceMap::iterator i;
2952 boost::shared_ptr<Source> source = src.lock();
2959 Glib::Mutex::Lock lm (source_lock);
2961 if ((i = sources.find (source->id())) != sources.end()) {
2966 if (!_state_of_the_state & InCleanup) {
2968 /* save state so we don't end up with a session file
2969 referring to non-existent sources.
2972 save_state (_current_snapshot_name);
2976 boost::shared_ptr<Source>
2977 Session::source_by_id (const PBD::ID& id)
2979 Glib::Mutex::Lock lm (source_lock);
2980 SourceMap::iterator i;
2981 boost::shared_ptr<Source> source;
2983 if ((i = sources.find (id)) != sources.end()) {
2990 boost::shared_ptr<Source>
2991 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2993 Glib::Mutex::Lock lm (source_lock);
2995 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2996 cerr << "comparing " << path << " with " << i->second->name() << endl;
2997 boost::shared_ptr<AudioFileSource> afs
2998 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3000 if (afs && afs->path() == path && chn == afs->channel()) {
3004 return boost::shared_ptr<Source>();
3009 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3012 string old_basename = PBD::basename_nosuffix (oldname);
3013 string new_legalized = legalize_for_path (newname);
3015 /* note: we know (or assume) the old path is already valid */
3019 /* destructive file sources have a name of the form:
3021 /path/to/Tnnnn-NAME(%[LR])?.wav
3023 the task here is to replace NAME with the new name.
3026 /* find last slash */
3030 string::size_type slash;
3031 string::size_type dash;
3033 if ((slash = path.find_last_of ('/')) == string::npos) {
3037 dir = path.substr (0, slash+1);
3039 /* '-' is not a legal character for the NAME part of the path */
3041 if ((dash = path.find_last_of ('-')) == string::npos) {
3045 prefix = path.substr (slash+1, dash-(slash+1));
3050 path += new_legalized;
3051 path += ".wav"; /* XXX gag me with a spoon */
3055 /* non-destructive file sources have a name of the form:
3057 /path/to/NAME-nnnnn(%[LR])?.ext
3059 the task here is to replace NAME with the new name.
3064 string::size_type slash;
3065 string::size_type dash;
3066 string::size_type postfix;
3068 /* find last slash */
3070 if ((slash = path.find_last_of ('/')) == string::npos) {
3074 dir = path.substr (0, slash+1);
3076 /* '-' is not a legal character for the NAME part of the path */
3078 if ((dash = path.find_last_of ('-')) == string::npos) {
3082 suffix = path.substr (dash+1);
3084 // Suffix is now everything after the dash. Now we need to eliminate
3085 // the nnnnn part, which is done by either finding a '%' or a '.'
3087 postfix = suffix.find_last_of ("%");
3088 if (postfix == string::npos) {
3089 postfix = suffix.find_last_of ('.');
3092 if (postfix != string::npos) {
3093 suffix = suffix.substr (postfix);
3095 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3099 const uint32_t limit = 10000;
3100 char buf[PATH_MAX+1];
3102 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3104 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3106 if (access (buf, F_OK) != 0) {
3114 error << "FATAL ERROR! Could not find a " << endl;
3122 /** Return the full path (in some session directory) for a new embedded source.
3123 * \a name must be a session-unique name that does not contain slashes
3124 * (e.g. as returned by new_*_source_name)
3127 Session::new_source_path_from_name (DataType type, const string& name)
3129 assert(name.find("/") == string::npos);
3131 SessionDirectory sdir(get_best_session_directory_for_new_source());
3134 if (type == DataType::AUDIO) {
3135 p = sdir.sound_path();
3136 } else if (type == DataType::MIDI) {
3137 p = sdir.midi_path();
3139 error << "Unknown source type, unable to create file path" << endmsg;
3144 return p.to_string();
3148 Session::peak_path (Glib::ustring base) const
3150 sys::path peakfile_path(_session_dir->peak_path());
3151 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3152 return peakfile_path.to_string();
3155 /** Return a unique name based on \a base for a new internal audio source */
3157 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3161 char buf[PATH_MAX+1];
3162 const uint32_t limit = 10000;
3166 legalized = legalize_for_path (base);
3168 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3169 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3171 vector<space_and_path>::iterator i;
3172 uint32_t existing = 0;
3174 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3176 SessionDirectory sdir((*i).path);
3178 spath = sdir.sound_path().to_string();
3183 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3184 spath.c_str(), cnt, legalized.c_str());
3185 } else if (nchan == 2) {
3187 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3188 spath.c_str(), cnt, legalized.c_str());
3190 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3191 spath.c_str(), cnt, legalized.c_str());
3193 } else if (nchan < 26) {
3194 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3195 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3197 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3198 spath.c_str(), cnt, legalized.c_str());
3207 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3208 } else if (nchan == 2) {
3210 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3212 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3214 } else if (nchan < 26) {
3215 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3217 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3221 if (sys::exists(buf)) {
3227 if (existing == 0) {
3232 error << string_compose(
3233 _("There are already %1 recordings for %2, which I consider too many."),
3234 limit, base) << endmsg;
3236 throw failed_constructor();
3240 return Glib::path_get_basename(buf);
3243 /** Create a new embedded audio source */
3244 boost::shared_ptr<AudioFileSource>
3245 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3247 const size_t n_chans = ds.n_channels().n_audio();
3248 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3249 const string path = new_source_path_from_name(DataType::AUDIO, name);
3250 return boost::dynamic_pointer_cast<AudioFileSource> (
3251 SourceFactory::createWritable (
3252 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3255 /** Return a unique name based on \a base for a new internal MIDI source */
3257 Session::new_midi_source_name (const string& base)
3260 char buf[PATH_MAX+1];
3261 const uint32_t limit = 10000;
3265 legalized = legalize_for_path (base);
3267 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3268 for (cnt = 1; cnt <= limit; ++cnt) {
3270 vector<space_and_path>::iterator i;
3271 uint32_t existing = 0;
3273 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3275 SessionDirectory sdir((*i).path);
3277 sys::path p = sdir.midi_path();
3280 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3282 if (sys::exists (buf)) {
3287 if (existing == 0) {
3292 error << string_compose(
3293 _("There are already %1 recordings for %2, which I consider too many."),
3294 limit, base) << endmsg;
3296 throw failed_constructor();
3300 return Glib::path_get_basename(buf);
3304 /** Create a new embedded MIDI source */
3305 boost::shared_ptr<MidiSource>
3306 Session::create_midi_source_for_session (MidiDiskstream& ds)
3308 const string name = new_midi_source_name (ds.name());
3309 const string path = new_source_path_from_name (DataType::MIDI, name);
3311 return boost::dynamic_pointer_cast<SMFSource> (
3312 SourceFactory::createWritable (
3313 DataType::MIDI, *this, path, true, false, frame_rate()));
3317 /* Playlist management */
3319 boost::shared_ptr<Playlist>
3320 Session::playlist_by_name (string name)
3322 Glib::Mutex::Lock lm (playlist_lock);
3323 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3324 if ((*i)->name() == name) {
3328 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3329 if ((*i)->name() == name) {
3334 return boost::shared_ptr<Playlist>();
3338 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3340 Glib::Mutex::Lock lm (playlist_lock);
3341 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3342 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3343 list.push_back (*i);
3346 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3347 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3348 list.push_back (*i);
3354 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3356 if (playlist->hidden()) {
3361 Glib::Mutex::Lock lm (playlist_lock);
3362 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3363 playlists.insert (playlists.begin(), playlist);
3364 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3365 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3370 playlist->release();
3375 PlaylistAdded (playlist); /* EMIT SIGNAL */
3379 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3382 Glib::Mutex::Lock lm (playlist_lock);
3383 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3386 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3393 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3395 boost::shared_ptr<Playlist> pl(wpl.lock());
3401 PlaylistList::iterator x;
3404 /* its not supposed to be visible */
3409 Glib::Mutex::Lock lm (playlist_lock);
3413 unused_playlists.insert (pl);
3415 if ((x = playlists.find (pl)) != playlists.end()) {
3416 playlists.erase (x);
3422 playlists.insert (pl);
3424 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3425 unused_playlists.erase (x);
3432 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3434 if (_state_of_the_state & Deletion) {
3438 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3445 Glib::Mutex::Lock lm (playlist_lock);
3447 PlaylistList::iterator i;
3449 i = find (playlists.begin(), playlists.end(), playlist);
3450 if (i != playlists.end()) {
3451 playlists.erase (i);
3454 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3455 if (i != unused_playlists.end()) {
3456 unused_playlists.erase (i);
3463 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3467 Session::set_audition (boost::shared_ptr<Region> r)
3469 pending_audition_region = r;
3470 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3471 schedule_butler_transport_work ();
3475 Session::audition_playlist ()
3477 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3478 ev->region.reset ();
3483 Session::non_realtime_set_audition ()
3485 if (!pending_audition_region) {
3486 auditioner->audition_current_playlist ();
3488 auditioner->audition_region (pending_audition_region);
3489 pending_audition_region.reset ();
3491 AuditionActive (true); /* EMIT SIGNAL */
3495 Session::audition_region (boost::shared_ptr<Region> r)
3497 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3503 Session::cancel_audition ()
3505 if (auditioner->active()) {
3506 auditioner->cancel_audition ();
3507 AuditionActive (false); /* EMIT SIGNAL */
3512 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3514 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3518 Session::remove_empty_sounds ()
3520 vector<string> audio_filenames;
3522 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3524 Glib::Mutex::Lock lm (source_lock);
3526 TapeFileMatcher tape_file_matcher;
3528 remove_if (audio_filenames.begin(), audio_filenames.end(),
3529 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3531 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3533 sys::path audio_file_path (_session_dir->sound_path());
3535 audio_file_path /= *i;
3537 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3541 sys::remove (audio_file_path);
3542 const string peakfile = peak_path (audio_file_path.to_string());
3543 sys::remove (peakfile);
3545 catch (const sys::filesystem_error& err)
3547 error << err.what() << endmsg;
3554 Session::is_auditioning () const
3556 /* can be called before we have an auditioner object */
3558 return auditioner->active();
3565 Session::set_all_solo (bool yn)
3567 shared_ptr<RouteList> r = routes.reader ();
3569 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3570 if (!(*i)->is_hidden()) {
3571 (*i)->set_solo (yn, this);
3579 Session::set_all_mute (bool yn)
3581 shared_ptr<RouteList> r = routes.reader ();
3583 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3584 if (!(*i)->is_hidden()) {
3585 (*i)->set_mute (yn, this);
3593 Session::n_diskstreams () const
3597 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3599 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3600 if (!(*i)->hidden()) {
3608 Session::graph_reordered ()
3610 /* don't do this stuff if we are setting up connections
3611 from a set_state() call or creating new tracks.
3614 if (_state_of_the_state & InitialConnecting) {
3618 /* every track/bus asked for this to be handled but it was deferred because
3619 we were connecting. do it now.
3622 request_input_change_handling ();
3626 /* force all diskstreams to update their capture offset values to
3627 reflect any changes in latencies within the graph.
3630 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3632 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3633 (*i)->set_capture_offset ();
3638 Session::record_disenable_all ()
3640 record_enable_change_all (false);
3644 Session::record_enable_all ()
3646 record_enable_change_all (true);
3650 Session::record_enable_change_all (bool yn)
3652 shared_ptr<RouteList> r = routes.reader ();
3654 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3655 boost::shared_ptr<Track> t;
3657 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3658 t->set_record_enable (yn, this);
3662 /* since we don't keep rec-enable state, don't mark session dirty */
3666 Session::add_processor (Processor* processor)
3669 PortInsert* port_insert;
3670 PluginInsert* plugin_insert;
3672 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3673 _port_inserts.insert (_port_inserts.begin(), port_insert);
3674 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3675 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3676 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3677 _sends.insert (_sends.begin(), send);
3679 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3683 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3689 Session::remove_processor (Processor* processor)
3692 PortInsert* port_insert;
3693 PluginInsert* plugin_insert;
3695 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3696 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3697 if (x != _port_inserts.end()) {
3698 insert_bitset[port_insert->bit_slot()] = false;
3699 _port_inserts.erase (x);
3701 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3702 _plugin_inserts.remove (plugin_insert);
3703 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3704 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3705 if (x != _sends.end()) {
3706 send_bitset[send->bit_slot()] = false;
3710 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3718 Session::available_capture_duration ()
3720 float sample_bytes_on_disk = 4.0; // keep gcc happy
3722 switch (Config->get_native_file_data_format()) {
3724 sample_bytes_on_disk = 4.0;
3728 sample_bytes_on_disk = 3.0;
3732 sample_bytes_on_disk = 2.0;
3736 /* impossible, but keep some gcc versions happy */
3737 fatal << string_compose (_("programming error: %1"),
3738 X_("illegal native file data format"))
3743 double scale = 4096.0 / sample_bytes_on_disk;
3745 if (_total_free_4k_blocks * scale > (double) max_frames) {
3749 return (nframes_t) floor (_total_free_4k_blocks * scale);
3753 Session::add_bundle (shared_ptr<Bundle> bundle)
3756 RCUWriter<BundleList> writer (_bundles);
3757 boost::shared_ptr<BundleList> b = writer.get_copy ();
3758 b->push_back (bundle);
3761 BundleAdded (bundle); /* EMIT SIGNAL */
3767 Session::remove_bundle (shared_ptr<Bundle> bundle)
3769 bool removed = false;
3772 RCUWriter<BundleList> writer (_bundles);
3773 boost::shared_ptr<BundleList> b = writer.get_copy ();
3774 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3776 if (i != b->end()) {
3783 BundleRemoved (bundle); /* EMIT SIGNAL */
3790 Session::bundle_by_name (string name) const
3792 boost::shared_ptr<BundleList> b = _bundles.reader ();
3794 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3795 if ((*i)->name() == name) {
3800 return boost::shared_ptr<Bundle> ();
3804 Session::tempo_map_changed (Change ignored)
3808 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3809 (*i)->update_after_tempo_map_change ();
3812 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3813 (*i)->update_after_tempo_map_change ();
3819 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3820 * the given count with the current block size.
3823 Session::ensure_buffers (ChanCount howmany)
3825 if (current_block_size == 0) {
3826 return; // too early? (is this ok?)
3829 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3830 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3831 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3832 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3833 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3836 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3840 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3842 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3843 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3848 Session::next_insert_id ()
3850 /* this doesn't really loop forever. just think about it */
3853 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3854 if (!insert_bitset[n]) {
3855 insert_bitset[n] = true;
3861 /* none available, so resize and try again */
3863 insert_bitset.resize (insert_bitset.size() + 16, false);
3868 Session::next_send_id ()
3870 /* this doesn't really loop forever. just think about it */
3873 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3874 if (!send_bitset[n]) {
3875 send_bitset[n] = true;
3881 /* none available, so resize and try again */
3883 send_bitset.resize (send_bitset.size() + 16, false);
3888 Session::mark_send_id (uint32_t id)
3890 if (id >= send_bitset.size()) {
3891 send_bitset.resize (id+16, false);
3893 if (send_bitset[id]) {
3894 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3896 send_bitset[id] = true;
3900 Session::mark_insert_id (uint32_t id)
3902 if (id >= insert_bitset.size()) {
3903 insert_bitset.resize (id+16, false);
3905 if (insert_bitset[id]) {
3906 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3908 insert_bitset[id] = true;
3911 /* Named Selection management */
3914 Session::named_selection_by_name (string name)
3916 Glib::Mutex::Lock lm (named_selection_lock);
3917 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3918 if ((*i)->name == name) {
3926 Session::add_named_selection (NamedSelection* named_selection)
3929 Glib::Mutex::Lock lm (named_selection_lock);
3930 named_selections.insert (named_selections.begin(), named_selection);
3933 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3939 NamedSelectionAdded (); /* EMIT SIGNAL */
3943 Session::remove_named_selection (NamedSelection* named_selection)
3945 bool removed = false;
3948 Glib::Mutex::Lock lm (named_selection_lock);
3950 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3952 if (i != named_selections.end()) {
3954 named_selections.erase (i);
3961 NamedSelectionRemoved (); /* EMIT SIGNAL */
3966 Session::reset_native_file_format ()
3968 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3970 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3971 (*i)->reset_write_sources (false);
3976 Session::route_name_unique (string n) const
3978 shared_ptr<RouteList> r = routes.reader ();
3980 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3981 if ((*i)->name() == n) {
3990 Session::route_name_internal (string n) const
3992 if (auditioner && auditioner->name() == n) {
3996 if (_click_io && _click_io->name() == n) {
4004 Session::n_playlists () const
4006 Glib::Mutex::Lock lm (playlist_lock);
4007 return playlists.size();
4011 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4013 if (!force && howmany <= _npan_buffers) {
4017 if (_pan_automation_buffer) {
4019 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4020 delete [] _pan_automation_buffer[i];
4023 delete [] _pan_automation_buffer;
4026 _pan_automation_buffer = new pan_t*[howmany];
4028 for (uint32_t i = 0; i < howmany; ++i) {
4029 _pan_automation_buffer[i] = new pan_t[nframes];
4032 _npan_buffers = howmany;
4036 Session::freeze (InterThreadInfo& itt)
4038 shared_ptr<RouteList> r = routes.reader ();
4040 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4042 boost::shared_ptr<Track> t;
4044 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4045 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4055 boost::shared_ptr<Region>
4056 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4057 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4058 InterThreadInfo& itt, bool enable_processing)
4060 boost::shared_ptr<Region> result;
4061 boost::shared_ptr<Playlist> playlist;
4062 boost::shared_ptr<AudioFileSource> fsource;
4064 char buf[PATH_MAX+1];
4065 ChanCount nchans(track.audio_diskstream()->n_channels());
4067 nframes_t this_chunk;
4070 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4071 const string sound_dir = sdir.sound_path().to_string();
4072 nframes_t len = end - start;
4075 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4076 end, start) << endmsg;
4080 // any bigger than this seems to cause stack overflows in called functions
4081 const nframes_t chunk_size = (128 * 1024)/4;
4083 // block all process callback handling
4085 block_processing ();
4087 /* call tree *MUST* hold route_lock */
4089 if ((playlist = track.diskstream()->playlist()) == 0) {
4093 /* external redirects will be a problem */
4095 if (track.has_external_redirects()) {
4099 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4101 for (x = 0; x < 99999; ++x) {
4102 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4103 if (access (buf, F_OK) != 0) {
4109 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4114 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4115 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4118 catch (failed_constructor& err) {
4119 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4123 srcs.push_back (fsource);
4126 /* XXX need to flush all redirects */
4131 /* create a set of reasonably-sized buffers */
4132 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4133 buffers.set_count(nchans);
4135 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4136 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4138 afs->prepare_for_peakfile_writes ();
4141 while (to_do && !itt.cancel) {
4143 this_chunk = min (to_do, chunk_size);
4145 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4150 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4151 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4154 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4160 start += this_chunk;
4161 to_do -= this_chunk;
4163 itt.progress = (float) (1.0 - ((double) to_do / len));
4172 xnow = localtime (&now);
4174 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4175 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4178 afs->update_header (position, *xnow, now);
4179 afs->flush_header ();
4183 /* construct a region to represent the bounced material */
4185 result = RegionFactory::create (srcs, 0,
4186 srcs.front()->length(srcs.front()->timeline_position()),
4187 region_name_from_path (srcs.front()->name(), true));
4192 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4193 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4196 afs->mark_for_remove ();
4199 (*src)->drop_references ();
4203 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4204 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4207 afs->done_with_peakfile_writes ();
4211 unblock_processing ();
4217 Session::get_silent_buffers (ChanCount count)
4219 assert(_silent_buffers->available() >= count);
4220 _silent_buffers->set_count(count);
4222 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4223 for (size_t i= 0; i < count.get(*t); ++i) {
4224 _silent_buffers->get(*t, i).clear();
4228 return *_silent_buffers;
4232 Session::get_scratch_buffers (ChanCount count)
4234 if (count != ChanCount::ZERO) {
4235 assert(_scratch_buffers->available() >= count);
4236 _scratch_buffers->set_count(count);
4238 _scratch_buffers->set_count (_scratch_buffers->available());
4241 return *_scratch_buffers;
4245 Session::get_mix_buffers (ChanCount count)
4247 assert(_mix_buffers->available() >= count);
4248 _mix_buffers->set_count(count);
4249 return *_mix_buffers;
4253 Session::ntracks () const
4256 shared_ptr<RouteList> r = routes.reader ();
4258 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4259 if (boost::dynamic_pointer_cast<Track> (*i)) {
4268 Session::nbusses () const
4271 shared_ptr<RouteList> r = routes.reader ();
4273 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4274 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4283 Session::add_automation_list(AutomationList *al)
4285 automation_lists[al->id()] = al;
4289 Session::compute_initial_length ()
4291 return _engine.frame_rate() * 60 * 5;
4295 Session::sync_order_keys (const char* base)
4297 if (!Config->get_sync_all_route_ordering()) {
4298 /* leave order keys as they are */
4302 boost::shared_ptr<RouteList> r = routes.reader ();
4304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4305 (*i)->sync_order_keys (base);
4308 Route::SyncOrderKeys (base); // EMIT SIGNAL
4312 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4314 Session::have_rec_enabled_diskstream () const
4316 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4319 /** Update the state of our rec-enabled diskstreams flag */
4321 Session::update_have_rec_enabled_diskstream ()
4323 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4324 DiskstreamList::iterator i = dsl->begin ();
4325 while (i != dsl->end () && (*i)->record_enabled () == false) {
4329 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4331 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4333 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4334 RecordStateChanged (); /* EMIT SIGNAL */