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;
96 static const int CPU_CACHE_ALIGN = 64;
98 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
101 bool Session::_disable_all_loaded_plugins = false;
103 sigc::signal<void,std::string> Session::Dialog;
104 sigc::signal<int> Session::AskAboutPendingState;
105 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
106 sigc::signal<void> Session::SendFeedback;
108 sigc::signal<void> Session::SMPTEOffsetChanged;
109 sigc::signal<void> Session::StartTimeChanged;
110 sigc::signal<void> Session::EndTimeChanged;
111 sigc::signal<void> Session::AutoBindingOn;
112 sigc::signal<void> Session::AutoBindingOff;
113 sigc::signal<void, std::string, std::string> Session::Exported;
115 Session::Session (AudioEngine &eng,
116 const string& fullpath,
117 const string& snapshot_name,
121 _requested_return_frame (-1),
122 _scratch_buffers(new BufferSet()),
123 _silent_buffers(new BufferSet()),
124 _mix_buffers(new BufferSet()),
126 _mmc_port (default_mmc_port),
127 _mtc_port (default_mtc_port),
128 _midi_port (default_midi_port),
129 _midi_clock_port (default_midi_clock_port),
130 _session_dir (new SessionDirectory(fullpath)),
131 pending_events (2048),
133 butler_mixdown_buffer (0),
134 butler_gain_buffer (0),
135 post_transport_work((PostTransportWork)0),
136 _send_smpte_update (false),
137 midi_thread (pthread_t (0)),
138 midi_requests (128), // the size of this should match the midi request pool size
139 diskstreams (new DiskstreamList),
140 routes (new RouteList),
141 auditioner ((Auditioner*) 0),
142 _total_free_4k_blocks (0),
143 _bundles (new BundleList),
144 _bundle_xml_node (0),
147 click_emphasis_data (0),
149 _metadata (new SessionMetadata())
154 if (!eng.connected()) {
155 throw failed_constructor();
158 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
160 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
161 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
163 first_stage_init (fullpath, snapshot_name);
165 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
168 if (create (new_session, mix_template, compute_initial_length())) {
170 throw failed_constructor ();
174 if (second_stage_init (new_session)) {
176 throw failed_constructor ();
179 store_recent_sessions(_name, _path);
181 bool was_dirty = dirty();
183 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
185 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _requested_return_frame (-1),
205 _scratch_buffers(new BufferSet()),
206 _silent_buffers(new BufferSet()),
207 _mix_buffers(new BufferSet()),
209 _mmc_port (default_mmc_port),
210 _mtc_port (default_mtc_port),
211 _midi_port (default_midi_port),
212 _midi_clock_port (default_midi_clock_port),
213 _session_dir ( new SessionDirectory(fullpath)),
214 pending_events (2048),
216 butler_mixdown_buffer (0),
217 butler_gain_buffer (0),
218 post_transport_work((PostTransportWork)0),
219 _send_smpte_update (false),
220 midi_thread (pthread_t (0)),
222 diskstreams (new DiskstreamList),
223 routes (new RouteList),
224 auditioner ((Auditioner *) 0),
225 _total_free_4k_blocks (0),
226 _bundles (new BundleList),
227 _bundle_xml_node (0),
228 _click_io ((IO *) 0),
230 click_emphasis_data (0),
232 _metadata (new SessionMetadata())
236 if (!eng.connected()) {
237 throw failed_constructor();
240 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
242 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
243 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
245 if (n_physical_inputs) {
246 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
249 if (n_physical_outputs) {
250 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
253 first_stage_init (fullpath, snapshot_name);
255 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
258 if (create (new_session, string(), initial_length)) {
260 throw failed_constructor ();
265 /* set up Master Out and Control Out if necessary */
270 if (control_out_channels) {
271 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
272 r->set_remote_control_id (control_id++);
277 if (master_out_channels) {
278 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
279 r->set_remote_control_id (control_id);
283 /* prohibit auto-connect to master, because there isn't one */
284 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
288 add_routes (rl, false);
293 Config->set_input_auto_connect (input_ac);
294 Config->set_output_auto_connect (output_ac);
296 if (second_stage_init (new_session)) {
298 throw failed_constructor ();
301 store_recent_sessions (_name, _path);
303 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
305 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
316 /* if we got to here, leaving pending capture state around
320 remove_pending_capture_state ();
322 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
324 _engine.remove_session ();
326 GoingAway (); /* EMIT SIGNAL */
332 /* clear history so that no references to objects are held any more */
336 /* clear state tree so that no references to objects are held any more */
340 terminate_butler_thread ();
341 //terminate_midi_thread ();
343 if (click_data != default_click) {
344 delete [] click_data;
347 if (click_emphasis_data != default_click_emphasis) {
348 delete [] click_emphasis_data;
353 delete _scratch_buffers;
354 delete _silent_buffers;
357 AudioDiskstream::free_working_buffers();
359 Route::SyncOrderKeys.clear();
361 #undef TRACK_DESTRUCTION
362 #ifdef TRACK_DESTRUCTION
363 cerr << "delete named selections\n";
364 #endif /* TRACK_DESTRUCTION */
365 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
366 NamedSelectionList::iterator tmp;
375 #ifdef TRACK_DESTRUCTION
376 cerr << "delete playlists\n";
377 #endif /* TRACK_DESTRUCTION */
378 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
379 PlaylistList::iterator tmp;
384 (*i)->drop_references ();
389 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
390 PlaylistList::iterator tmp;
395 (*i)->drop_references ();
401 unused_playlists.clear ();
403 #ifdef TRACK_DESTRUCTION
404 cerr << "delete regions\n";
405 #endif /* TRACK_DESTRUCTION */
407 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
408 RegionList::iterator tmp;
413 i->second->drop_references ();
420 #ifdef TRACK_DESTRUCTION
421 cerr << "delete routes\n";
422 #endif /* TRACK_DESTRUCTION */
424 RCUWriter<RouteList> writer (routes);
425 boost::shared_ptr<RouteList> r = writer.get_copy ();
426 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
427 (*i)->drop_references ();
430 /* writer goes out of scope and updates master */
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete diskstreams\n";
437 #endif /* TRACK_DESTRUCTION */
439 RCUWriter<DiskstreamList> dwriter (diskstreams);
440 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
441 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
442 (*i)->drop_references ();
446 diskstreams.flush ();
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete audio sources\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
452 SourceMap::iterator tmp;
457 i->second->drop_references ();
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete mix groups\n";
465 #endif /* TRACK_DESTRUCTION */
466 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
467 list<RouteGroup*>::iterator tmp;
477 #ifdef TRACK_DESTRUCTION
478 cerr << "delete edit groups\n";
479 #endif /* TRACK_DESTRUCTION */
480 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
481 list<RouteGroup*>::iterator tmp;
491 delete [] butler_mixdown_buffer;
492 delete [] butler_gain_buffer;
494 Crossfade::set_buffer_size (0);
500 Session::set_worst_io_latencies ()
502 _worst_output_latency = 0;
503 _worst_input_latency = 0;
505 if (!_engine.connected()) {
509 boost::shared_ptr<RouteList> r = routes.reader ();
511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
512 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
513 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
518 Session::when_engine_running ()
520 string first_physical_output;
522 /* we don't want to run execute this again */
524 BootMessage (_("Set block size and sample rate"));
526 set_block_size (_engine.frames_per_cycle());
527 set_frame_rate (_engine.frame_rate());
529 BootMessage (_("Using configuration"));
531 Config->map_parameters (mem_fun (*this, &Session::config_changed));
533 /* every time we reconnect, recompute worst case output latencies */
535 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
537 if (synced_to_jack()) {
538 _engine.transport_stop ();
541 if (Config->get_jack_time_master()) {
542 _engine.transport_locate (_transport_frame);
550 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
552 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
554 /* existing state for Click */
556 if (_click_io->set_state (*child->children().front()) == 0) {
558 _clicking = Config->get_clicking ();
562 error << _("could not setup Click I/O") << endmsg;
568 /* default state for Click */
570 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
572 if (first_physical_output.length()) {
573 if (_click_io->add_output_port (first_physical_output, this)) {
574 // relax, even though its an error
576 _clicking = Config->get_clicking ();
582 catch (failed_constructor& err) {
583 error << _("cannot setup Click I/O") << endmsg;
586 BootMessage (_("Compute I/O Latencies"));
588 set_worst_io_latencies ();
591 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
594 BootMessage (_("Set up standard connections"));
596 /* Create a set of Bundle objects that map
597 to the physical I/O currently available. We create both
598 mono and stereo bundles, so that the common cases of mono
599 and stereo tracks get bundles to put in their mixer strip
600 in / out menus. There may be a nicer way of achieving that;
601 it doesn't really scale that well to higher channel counts */
603 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
605 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
607 shared_ptr<Bundle> c (new Bundle (buf, true));
608 c->add_channel (_("mono"));
609 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
614 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
615 if (np + 1 < n_physical_outputs) {
617 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
618 shared_ptr<Bundle> c (new Bundle (buf, true));
619 c->add_channel (_("L"));
620 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
621 c->add_channel (_("R"));
622 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
628 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
630 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
632 shared_ptr<Bundle> c (new Bundle (buf, false));
633 c->add_channel (_("mono"));
634 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
639 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
640 if (np + 1 < n_physical_inputs) {
642 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
644 shared_ptr<Bundle> c (new Bundle (buf, false));
645 c->add_channel (_("L"));
646 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
647 c->add_channel (_("R"));
648 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
656 /* create master/control ports */
661 /* force the master to ignore any later call to this */
663 if (_master_out->pending_state_node) {
664 _master_out->ports_became_legal();
667 /* no panner resets till we are through */
669 _master_out->defer_pan_reset ();
671 while (_master_out->n_inputs().n_audio()
672 < _master_out->input_maximum().n_audio()) {
673 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
674 error << _("cannot setup master inputs")
680 while (_master_out->n_outputs().n_audio()
681 < _master_out->output_maximum().n_audio()) {
682 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
683 error << _("cannot setup master outputs")
690 _master_out->allow_pan_reset ();
695 BootMessage (_("Setup signal flow and plugins"));
699 /* catch up on send+insert cnts */
701 BootMessage (_("Catch up with send/insert state"));
705 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
708 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
709 if (id > insert_cnt) {
717 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
720 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
728 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
730 /* hook us up to the engine */
732 BootMessage (_("Connect to engine"));
734 _engine.set_session (this);
738 Session::hookup_io ()
740 /* stop graph reordering notifications from
741 causing resorts, etc.
744 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
747 if (auditioner == 0) {
749 /* we delay creating the auditioner till now because
750 it makes its own connections to ports.
751 the engine has to be running for this to work.
755 auditioner.reset (new Auditioner (*this));
758 catch (failed_constructor& err) {
759 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
763 /* Tell all IO objects to create their ports */
769 vector<string> cports;
771 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
772 if (_control_out->add_input_port ("", this)) {
773 error << _("cannot setup control inputs")
779 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
780 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
781 error << _("cannot set up master outputs")
789 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
791 for (n = 0; n < ni; ++n) {
792 cports.push_back (_control_out->input(n)->name());
795 boost::shared_ptr<RouteList> r = routes.reader ();
797 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
798 (*x)->set_control_outs (cports);
802 /* load bundles, which we may have postponed earlier on */
803 if (_bundle_xml_node) {
804 load_bundles (*_bundle_xml_node);
805 delete _bundle_xml_node;
808 /* Tell all IO objects to connect themselves together */
810 IO::enable_connecting ();
812 /* Now reset all panners */
814 IO::reset_panners ();
816 /* Anyone who cares about input state, wake up and do something */
818 IOConnectionsComplete (); /* EMIT SIGNAL */
820 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
823 /* now handle the whole enchilada as if it was one
829 /* update mixer solo state */
835 Session::playlist_length_changed ()
837 /* we can't just increase end_location->end() if pl->get_maximum_extent()
838 if larger. if the playlist used to be the longest playlist,
839 and its now shorter, we have to decrease end_location->end(). hence,
840 we have to iterate over all diskstreams and check the
841 playlists currently in use.
847 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
849 boost::shared_ptr<Playlist> playlist;
851 if ((playlist = dstream->playlist()) != 0) {
852 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
855 /* see comment in playlist_length_changed () */
860 Session::record_enabling_legal () const
862 /* this used to be in here, but survey says.... we don't need to restrict it */
863 // if (record_status() == Recording) {
867 if (Config->get_all_safe()) {
874 Session::reset_input_monitor_state ()
876 if (transport_rolling()) {
878 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
880 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
881 if ((*i)->record_enabled ()) {
882 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
883 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
887 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
889 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
890 if ((*i)->record_enabled ()) {
891 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
892 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
899 Session::auto_punch_start_changed (Location* location)
901 replace_event (Event::PunchIn, location->start());
903 if (get_record_enabled() && Config->get_punch_in()) {
904 /* capture start has been changed, so save new pending state */
905 save_state ("", true);
910 Session::auto_punch_end_changed (Location* location)
912 nframes_t when_to_stop = location->end();
913 // when_to_stop += _worst_output_latency + _worst_input_latency;
914 replace_event (Event::PunchOut, when_to_stop);
918 Session::auto_punch_changed (Location* location)
920 nframes_t when_to_stop = location->end();
922 replace_event (Event::PunchIn, location->start());
923 //when_to_stop += _worst_output_latency + _worst_input_latency;
924 replace_event (Event::PunchOut, when_to_stop);
928 Session::auto_loop_changed (Location* location)
930 replace_event (Event::AutoLoop, location->end(), location->start());
932 if (transport_rolling() && play_loop) {
934 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
936 if (_transport_frame > location->end()) {
937 // relocate to beginning of loop
938 clear_events (Event::LocateRoll);
940 request_locate (location->start(), true);
943 else if (Config->get_seamless_loop() && !loop_changing) {
945 // schedule a locate-roll to refill the diskstreams at the
947 loop_changing = true;
949 if (location->end() > last_loopend) {
950 clear_events (Event::LocateRoll);
951 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
958 last_loopend = location->end();
962 Session::set_auto_punch_location (Location* location)
966 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
967 auto_punch_start_changed_connection.disconnect();
968 auto_punch_end_changed_connection.disconnect();
969 auto_punch_changed_connection.disconnect();
970 existing->set_auto_punch (false, this);
971 remove_event (existing->start(), Event::PunchIn);
972 clear_events (Event::PunchOut);
973 auto_punch_location_changed (0);
982 if (location->end() <= location->start()) {
983 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
987 auto_punch_start_changed_connection.disconnect();
988 auto_punch_end_changed_connection.disconnect();
989 auto_punch_changed_connection.disconnect();
991 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
992 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
993 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
995 location->set_auto_punch (true, this);
998 auto_punch_changed (location);
1000 auto_punch_location_changed (location);
1004 Session::set_auto_loop_location (Location* location)
1008 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1009 auto_loop_start_changed_connection.disconnect();
1010 auto_loop_end_changed_connection.disconnect();
1011 auto_loop_changed_connection.disconnect();
1012 existing->set_auto_loop (false, this);
1013 remove_event (existing->end(), Event::AutoLoop);
1014 auto_loop_location_changed (0);
1019 if (location == 0) {
1023 if (location->end() <= location->start()) {
1024 error << _("Session: you can't use a mark for auto loop") << endmsg;
1028 last_loopend = location->end();
1030 auto_loop_start_changed_connection.disconnect();
1031 auto_loop_end_changed_connection.disconnect();
1032 auto_loop_changed_connection.disconnect();
1034 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1035 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1036 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1038 location->set_auto_loop (true, this);
1040 /* take care of our stuff first */
1042 auto_loop_changed (location);
1044 /* now tell everyone else */
1046 auto_loop_location_changed (location);
1050 Session::locations_added (Location* ignored)
1056 Session::locations_changed ()
1058 _locations.apply (*this, &Session::handle_locations_changed);
1062 Session::handle_locations_changed (Locations::LocationList& locations)
1064 Locations::LocationList::iterator i;
1066 bool set_loop = false;
1067 bool set_punch = false;
1069 for (i = locations.begin(); i != locations.end(); ++i) {
1073 if (location->is_auto_punch()) {
1074 set_auto_punch_location (location);
1077 if (location->is_auto_loop()) {
1078 set_auto_loop_location (location);
1082 if (location->is_start()) {
1083 start_location = location;
1085 if (location->is_end()) {
1086 end_location = location;
1091 set_auto_loop_location (0);
1094 set_auto_punch_location (0);
1101 Session::enable_record ()
1103 /* XXX really atomic compare+swap here */
1104 if (g_atomic_int_get (&_record_status) != Recording) {
1105 g_atomic_int_set (&_record_status, Recording);
1106 _last_record_location = _transport_frame;
1107 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1109 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1110 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1111 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1112 if ((*i)->record_enabled ()) {
1113 (*i)->monitor_input (true);
1118 RecordStateChanged ();
1123 Session::disable_record (bool rt_context, bool force)
1127 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1129 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1130 g_atomic_int_set (&_record_status, Disabled);
1132 if (rs == Recording) {
1133 g_atomic_int_set (&_record_status, Enabled);
1137 // FIXME: timestamp correct? [DR]
1138 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1139 // does this /need/ to be sent in all cases?
1141 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1143 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1144 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1146 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1147 if ((*i)->record_enabled ()) {
1148 (*i)->monitor_input (false);
1153 RecordStateChanged (); /* emit signal */
1156 remove_pending_capture_state ();
1162 Session::step_back_from_record ()
1164 /* XXX really atomic compare+swap here */
1165 if (g_atomic_int_get (&_record_status) == Recording) {
1166 g_atomic_int_set (&_record_status, Enabled);
1168 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1169 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1171 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1172 if ((*i)->record_enabled ()) {
1173 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1174 (*i)->monitor_input (false);
1182 Session::maybe_enable_record ()
1184 g_atomic_int_set (&_record_status, Enabled);
1186 /* this function is currently called from somewhere other than an RT thread.
1187 this save_state() call therefore doesn't impact anything.
1190 save_state ("", true);
1192 if (_transport_speed) {
1193 if (!Config->get_punch_in()) {
1197 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1198 RecordStateChanged (); /* EMIT SIGNAL */
1205 Session::audible_frame () const
1211 /* the first of these two possible settings for "offset"
1212 mean that the audible frame is stationary until
1213 audio emerges from the latency compensation
1216 the second means that the audible frame is stationary
1217 until audio would emerge from a physical port
1218 in the absence of any plugin latency compensation
1221 offset = _worst_output_latency;
1223 if (offset > current_block_size) {
1224 offset -= current_block_size;
1226 /* XXX is this correct? if we have no external
1227 physical connections and everything is internal
1228 then surely this is zero? still, how
1229 likely is that anyway?
1231 offset = current_block_size;
1234 if (synced_to_jack()) {
1235 tf = _engine.transport_frame();
1237 tf = _transport_frame;
1242 if (!non_realtime_work_pending()) {
1246 /* check to see if we have passed the first guaranteed
1247 audible frame past our last start position. if not,
1248 return that last start point because in terms
1249 of audible frames, we have not moved yet.
1252 if (_transport_speed > 0.0f) {
1254 if (!play_loop || !have_looped) {
1255 if (tf < _last_roll_location + offset) {
1256 return _last_roll_location;
1264 } else if (_transport_speed < 0.0f) {
1266 /* XXX wot? no backward looping? */
1268 if (tf > _last_roll_location - offset) {
1269 return _last_roll_location;
1281 Session::set_frame_rate (nframes_t frames_per_second)
1283 /** \fn void Session::set_frame_size(nframes_t)
1284 the AudioEngine object that calls this guarantees
1285 that it will not be called while we are also in
1286 ::process(). Its fine to do things that block
1290 _base_frame_rate = frames_per_second;
1294 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1298 // XXX we need some equivalent to this, somehow
1299 // SndFileSource::setup_standard_crossfades (frames_per_second);
1303 /* XXX need to reset/reinstantiate all LADSPA plugins */
1307 Session::set_block_size (nframes_t nframes)
1309 /* the AudioEngine guarantees
1310 that it will not be called while we are also in
1311 ::process(). It is therefore fine to do things that block
1317 current_block_size = nframes;
1319 ensure_buffers(_scratch_buffers->available());
1321 delete [] _gain_automation_buffer;
1322 _gain_automation_buffer = new gain_t[nframes];
1324 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1326 boost::shared_ptr<RouteList> r = routes.reader ();
1328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1329 (*i)->set_block_size (nframes);
1332 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1333 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1334 (*i)->set_block_size (nframes);
1337 set_worst_io_latencies ();
1342 Session::set_default_fade (float steepness, float fade_msecs)
1345 nframes_t fade_frames;
1347 /* Don't allow fade of less 1 frame */
1349 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1356 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1360 default_fade_msecs = fade_msecs;
1361 default_fade_steepness = steepness;
1364 // jlc, WTF is this!
1365 Glib::RWLock::ReaderLock lm (route_lock);
1366 AudioRegion::set_default_fade (steepness, fade_frames);
1371 /* XXX have to do this at some point */
1372 /* foreach region using default fade, reset, then
1373 refill_all_diskstream_buffers ();
1378 struct RouteSorter {
1379 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1380 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1382 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1385 if (r1->fed_by.empty()) {
1386 if (r2->fed_by.empty()) {
1387 /* no ardour-based connections inbound to either route. just use signal order */
1388 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390 /* r2 has connections, r1 does not; run r1 early */
1394 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1401 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1403 shared_ptr<Route> r2;
1405 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1406 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1410 /* make a copy of the existing list of routes that feed r1 */
1412 set<shared_ptr<Route> > existing = r1->fed_by;
1414 /* for each route that feeds r1, recurse, marking it as feeding
1418 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1421 /* r2 is a route that feeds r1 which somehow feeds base. mark
1422 base as being fed by r2
1425 rbase->fed_by.insert (r2);
1429 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1433 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1437 /* now recurse, so that we can mark base as being fed by
1438 all routes that feed r2
1441 trace_terminal (r2, rbase);
1448 Session::resort_routes ()
1450 /* don't do anything here with signals emitted
1451 by Routes while we are being destroyed.
1454 if (_state_of_the_state & Deletion) {
1461 RCUWriter<RouteList> writer (routes);
1462 shared_ptr<RouteList> r = writer.get_copy ();
1463 resort_routes_using (r);
1464 /* writer goes out of scope and forces update */
1469 Session::resort_routes_using (shared_ptr<RouteList> r)
1471 RouteList::iterator i, j;
1473 for (i = r->begin(); i != r->end(); ++i) {
1475 (*i)->fed_by.clear ();
1477 for (j = r->begin(); j != r->end(); ++j) {
1479 /* although routes can feed themselves, it will
1480 cause an endless recursive descent if we
1481 detect it. so don't bother checking for
1489 if ((*j)->feeds (*i)) {
1490 (*i)->fed_by.insert (*j);
1495 for (i = r->begin(); i != r->end(); ++i) {
1496 trace_terminal (*i, *i);
1503 cerr << "finished route resort\n";
1505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1506 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1513 list<boost::shared_ptr<MidiTrack> >
1514 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1516 char track_name[32];
1517 uint32_t track_id = 0;
1520 RouteList new_routes;
1521 list<boost::shared_ptr<MidiTrack> > ret;
1522 //uint32_t control_id;
1524 // FIXME: need physical I/O and autoconnect stuff for MIDI
1526 /* count existing midi tracks */
1529 shared_ptr<RouteList> r = routes.reader ();
1531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1532 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1533 if (!(*i)->is_hidden()) {
1535 //channels_used += (*i)->n_inputs().n_midi();
1541 vector<string> physinputs;
1542 vector<string> physoutputs;
1544 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1545 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1547 // control_id = ntracks() + nbusses();
1551 /* check for duplicate route names, since we might have pre-existing
1552 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1553 save, close,restart,add new route - first named route is now
1561 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1563 if (route_by_name (track_name) == 0) {
1567 } while (track_id < (UINT_MAX-1));
1569 shared_ptr<MidiTrack> track;
1572 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1574 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1575 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1581 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1585 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1586 port = physinputs[(channels_used+x)%nphysical_in];
1589 if (port.length() && track->connect_input (track->input (x), port, this)) {
1595 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1599 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1600 port = physoutputs[(channels_used+x)%nphysical_out];
1601 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1603 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1607 if (port.length() && track->connect_output (track->output (x), port, this)) {
1612 channels_used += track->n_inputs ().n_midi();
1616 track->midi_diskstream()->non_realtime_input_change();
1618 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1619 //track->set_remote_control_id (control_id);
1621 new_routes.push_back (track);
1622 ret.push_back (track);
1625 catch (failed_constructor &err) {
1626 error << _("Session: could not create new midi track.") << endmsg;
1629 /* we need to get rid of this, since the track failed to be created */
1630 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1633 RCUWriter<DiskstreamList> writer (diskstreams);
1634 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1635 ds->remove (track->midi_diskstream());
1642 catch (AudioEngine::PortRegistrationFailure& pfe) {
1644 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;
1647 /* we need to get rid of this, since the track failed to be created */
1648 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1651 RCUWriter<DiskstreamList> writer (diskstreams);
1652 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1653 ds->remove (track->midi_diskstream());
1664 if (!new_routes.empty()) {
1665 add_routes (new_routes, false);
1666 save_state (_current_snapshot_name);
1672 list<boost::shared_ptr<AudioTrack> >
1673 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1675 char track_name[32];
1676 uint32_t track_id = 0;
1678 uint32_t channels_used = 0;
1680 RouteList new_routes;
1681 list<boost::shared_ptr<AudioTrack> > ret;
1682 uint32_t control_id;
1684 /* count existing audio tracks */
1687 shared_ptr<RouteList> r = routes.reader ();
1689 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1690 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1691 if (!(*i)->is_hidden()) {
1693 channels_used += (*i)->n_inputs().n_audio();
1699 vector<string> physinputs;
1700 vector<string> physoutputs;
1702 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1703 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1705 control_id = ntracks() + nbusses() + 1;
1709 /* check for duplicate route names, since we might have pre-existing
1710 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1711 save, close,restart,add new route - first named route is now
1719 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1721 if (route_by_name (track_name) == 0) {
1725 } while (track_id < (UINT_MAX-1));
1727 shared_ptr<AudioTrack> track;
1730 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1732 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1733 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1734 input_channels, output_channels)
1739 if (!physinputs.empty()) {
1740 uint32_t nphysical_in = physinputs.size();
1742 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1746 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1747 port = physinputs[(channels_used+x)%nphysical_in];
1750 if (port.length() && track->connect_input (track->input (x), port, this)) {
1756 if (!physoutputs.empty()) {
1757 uint32_t nphysical_out = physoutputs.size();
1759 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1763 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1764 port = physoutputs[(channels_used+x)%nphysical_out];
1765 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1767 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1771 if (port.length() && track->connect_output (track->output (x), port, this)) {
1777 channels_used += track->n_inputs ().n_audio();
1779 track->audio_diskstream()->non_realtime_input_change();
1781 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1782 track->set_remote_control_id (control_id);
1785 new_routes.push_back (track);
1786 ret.push_back (track);
1789 catch (failed_constructor &err) {
1790 error << _("Session: could not create new audio track.") << endmsg;
1793 /* we need to get rid of this, since the track failed to be created */
1794 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1797 RCUWriter<DiskstreamList> writer (diskstreams);
1798 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1799 ds->remove (track->audio_diskstream());
1806 catch (AudioEngine::PortRegistrationFailure& pfe) {
1808 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;
1811 /* we need to get rid of this, since the track failed to be created */
1812 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1815 RCUWriter<DiskstreamList> writer (diskstreams);
1816 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1817 ds->remove (track->audio_diskstream());
1828 if (!new_routes.empty()) {
1829 add_routes (new_routes, true);
1836 Session::set_remote_control_ids ()
1838 RemoteModel m = Config->get_remote_model();
1840 shared_ptr<RouteList> r = routes.reader ();
1842 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1843 if ( MixerOrdered == m) {
1844 long order = (*i)->order_key(N_("signal"));
1845 (*i)->set_remote_control_id( order+1 );
1846 } else if ( EditorOrdered == m) {
1847 long order = (*i)->order_key(N_("editor"));
1848 (*i)->set_remote_control_id( order+1 );
1849 } else if ( UserOrdered == m) {
1850 //do nothing ... only changes to remote id's are initiated by user
1857 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1860 uint32_t bus_id = 1;
1862 uint32_t channels_used = 0;
1865 uint32_t control_id;
1867 /* count existing audio busses */
1870 shared_ptr<RouteList> r = routes.reader ();
1872 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1873 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1875 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1878 channels_used += (*i)->n_inputs().n_audio();
1884 vector<string> physinputs;
1885 vector<string> physoutputs;
1887 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1888 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1890 n_physical_audio_outputs = physoutputs.size();
1891 n_physical_audio_inputs = physinputs.size();
1893 control_id = ntracks() + nbusses() + 1;
1898 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1902 if (route_by_name (bus_name) == 0) {
1906 } while (bus_id < (UINT_MAX-1));
1909 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1911 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1912 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1913 input_channels, output_channels)
1921 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1925 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1926 port = physinputs[((n+x)%n_physical_audio_inputs)];
1929 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1935 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1938 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1939 port = physoutputs[((n+x)%n_physical_outputs)];
1940 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1942 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1946 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1951 channels_used += bus->n_inputs ().n_audio();
1953 bus->set_remote_control_id (control_id);
1956 ret.push_back (bus);
1960 catch (failed_constructor &err) {
1961 error << _("Session: could not create new audio route.") << endmsg;
1965 catch (AudioEngine::PortRegistrationFailure& pfe) {
1966 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1976 add_routes (ret, true);
1984 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1988 uint32_t control_id;
1991 if (!tree.read (template_path.c_str())) {
1995 XMLNode* node = tree.root();
1997 control_id = ntracks() + nbusses() + 1;
2001 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2003 std::string node_name = IO::name_from_state (*node_copy.children().front());
2005 if (route_by_name (node_name) != 0) {
2007 /* generate a new name by adding a number to the end of the template name */
2009 uint32_t number = 1;
2012 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2016 if (route_by_name (name) == 0) {
2020 } while (number < UINT_MAX);
2022 if (number == UINT_MAX) {
2023 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2027 IO::set_name_in_state (node_copy, name);
2031 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2034 error << _("Session: cannot create track/bus from template description") << endmsg;
2038 route->set_remote_control_id (control_id);
2041 ret.push_back (route);
2044 catch (failed_constructor &err) {
2045 error << _("Session: could not create new route from template") << endmsg;
2049 catch (AudioEngine::PortRegistrationFailure& pfe) {
2050 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;
2059 add_routes (ret, true);
2066 Session::add_routes (RouteList& new_routes, bool save)
2069 RCUWriter<RouteList> writer (routes);
2070 shared_ptr<RouteList> r = writer.get_copy ();
2071 r->insert (r->end(), new_routes.begin(), new_routes.end());
2072 resort_routes_using (r);
2075 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2077 boost::weak_ptr<Route> wpr (*x);
2079 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2080 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2081 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2082 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2084 if ((*x)->is_master()) {
2088 if ((*x)->is_control()) {
2089 _control_out = (*x);
2093 if (_control_out && IO::connecting_legal) {
2095 vector<string> cports;
2096 uint32_t ni = _control_out->n_inputs().n_audio();
2098 for (uint32_t n = 0; n < ni; ++n) {
2099 cports.push_back (_control_out->input(n)->name());
2102 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2103 (*x)->set_control_outs (cports);
2110 save_state (_current_snapshot_name);
2113 RouteAdded (new_routes); /* EMIT SIGNAL */
2117 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2119 /* need to do this in case we're rolling at the time, to prevent false underruns */
2120 dstream->do_refill_with_alloc ();
2122 dstream->set_block_size (current_block_size);
2125 RCUWriter<DiskstreamList> writer (diskstreams);
2126 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2127 ds->push_back (dstream);
2128 /* writer goes out of scope, copies ds back to main */
2131 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2132 /* this will connect to future changes, and check the current length */
2133 diskstream_playlist_changed (dstream);
2135 dstream->prepare ();
2140 Session::remove_route (shared_ptr<Route> route)
2143 RCUWriter<RouteList> writer (routes);
2144 shared_ptr<RouteList> rs = writer.get_copy ();
2148 /* deleting the master out seems like a dumb
2149 idea, but its more of a UI policy issue
2153 if (route == _master_out) {
2154 _master_out = shared_ptr<Route> ();
2157 if (route == _control_out) {
2158 _control_out = shared_ptr<Route> ();
2160 /* cancel control outs for all routes */
2162 vector<string> empty;
2164 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2165 (*r)->set_control_outs (empty);
2169 update_route_solo_state ();
2171 /* writer goes out of scope, forces route list update */
2175 boost::shared_ptr<Diskstream> ds;
2177 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2178 ds = t->diskstream();
2184 RCUWriter<DiskstreamList> dsl (diskstreams);
2185 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2190 find_current_end ();
2192 // We need to disconnect the routes inputs and outputs
2194 route->disconnect_inputs (0);
2195 route->disconnect_outputs (0);
2197 update_latency_compensation (false, false);
2200 /* get rid of it from the dead wood collection in the route list manager */
2202 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2206 /* try to cause everyone to drop their references */
2208 route->drop_references ();
2210 sync_order_keys (N_("session"));
2212 /* save the new state of the world */
2214 if (save_state (_current_snapshot_name)) {
2215 save_history (_current_snapshot_name);
2220 Session::route_mute_changed (void* src)
2226 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2228 if (solo_update_disabled) {
2234 boost::shared_ptr<Route> route = wpr.lock ();
2237 /* should not happen */
2238 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2242 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2244 shared_ptr<RouteList> r = routes.reader ();
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2252 /* don't mess with busses */
2254 if (dynamic_cast<Track*>((*i).get()) == 0) {
2260 /* don't mess with tracks */
2262 if (dynamic_cast<Track*>((*i).get()) != 0) {
2267 if ((*i) != route &&
2268 ((*i)->mix_group () == 0 ||
2269 (*i)->mix_group () != route->mix_group () ||
2270 !route->mix_group ()->is_active())) {
2272 if ((*i)->soloed()) {
2274 /* if its already soloed, and solo latching is enabled,
2275 then leave it as it is.
2278 if (Config->get_solo_latched()) {
2285 solo_update_disabled = true;
2286 (*i)->set_solo (false, src);
2287 solo_update_disabled = false;
2291 bool something_soloed = false;
2292 bool same_thing_soloed = false;
2293 bool signal = false;
2295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2296 if ((*i)->soloed()) {
2297 something_soloed = true;
2298 if (dynamic_cast<Track*>((*i).get())) {
2300 same_thing_soloed = true;
2305 same_thing_soloed = true;
2313 if (something_soloed != currently_soloing) {
2315 currently_soloing = something_soloed;
2318 modify_solo_mute (is_track, same_thing_soloed);
2321 SoloActive (currently_soloing); /* EMIT SIGNAL */
2324 SoloChanged (); /* EMIT SIGNAL */
2330 Session::update_route_solo_state ()
2333 bool is_track = false;
2334 bool signal = false;
2336 /* this is where we actually implement solo by changing
2337 the solo mute setting of each track.
2340 shared_ptr<RouteList> r = routes.reader ();
2342 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2343 if ((*i)->soloed()) {
2345 if (dynamic_cast<Track*>((*i).get())) {
2352 if (mute != currently_soloing) {
2354 currently_soloing = mute;
2357 if (!is_track && !mute) {
2359 /* nothing is soloed */
2361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2362 (*i)->set_solo_mute (false);
2372 modify_solo_mute (is_track, mute);
2375 SoloActive (currently_soloing);
2380 Session::modify_solo_mute (bool is_track, bool mute)
2382 shared_ptr<RouteList> r = routes.reader ();
2384 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2388 /* only alter track solo mute */
2390 if (dynamic_cast<Track*>((*i).get())) {
2391 if ((*i)->soloed()) {
2392 (*i)->set_solo_mute (!mute);
2394 (*i)->set_solo_mute (mute);
2400 /* only alter bus solo mute */
2402 if (!dynamic_cast<Track*>((*i).get())) {
2404 if ((*i)->soloed()) {
2406 (*i)->set_solo_mute (false);
2410 /* don't mute master or control outs
2411 in response to another bus solo
2414 if ((*i) != _master_out &&
2415 (*i) != _control_out) {
2416 (*i)->set_solo_mute (mute);
2427 Session::catch_up_on_solo ()
2429 /* this is called after set_state() to catch the full solo
2430 state, which can't be correctly determined on a per-route
2431 basis, but needs the global overview that only the session
2434 update_route_solo_state();
2438 Session::catch_up_on_solo_mute_override ()
2440 if (Config->get_solo_model() != InverseMute) {
2444 /* this is called whenever the param solo-mute-override is
2447 shared_ptr<RouteList> r = routes.reader ();
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 (*i)->catch_up_on_solo_mute_override ();
2455 Session::route_by_name (string name)
2457 shared_ptr<RouteList> r = routes.reader ();
2459 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2460 if ((*i)->name() == name) {
2465 return shared_ptr<Route> ((Route*) 0);
2469 Session::route_by_id (PBD::ID id)
2471 shared_ptr<RouteList> r = routes.reader ();
2473 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2474 if ((*i)->id() == id) {
2479 return shared_ptr<Route> ((Route*) 0);
2483 Session::route_by_remote_id (uint32_t id)
2485 shared_ptr<RouteList> r = routes.reader ();
2487 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2488 if ((*i)->remote_control_id() == id) {
2493 return shared_ptr<Route> ((Route*) 0);
2497 Session::find_current_end ()
2499 if (_state_of_the_state & Loading) {
2503 nframes_t max = get_maximum_extent ();
2505 if (max > end_location->end()) {
2506 end_location->set_end (max);
2508 DurationChanged(); /* EMIT SIGNAL */
2513 Session::get_maximum_extent () const
2518 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2520 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2521 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2523 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2524 if ((me = pl->get_maximum_extent()) > max) {
2532 boost::shared_ptr<Diskstream>
2533 Session::diskstream_by_name (string name)
2535 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2537 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2538 if ((*i)->name() == name) {
2543 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2546 boost::shared_ptr<Diskstream>
2547 Session::diskstream_by_id (const PBD::ID& id)
2549 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2551 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2552 if ((*i)->id() == id) {
2557 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2560 /* Region management */
2563 Session::new_region_name (string old)
2565 string::size_type last_period;
2567 string::size_type len = old.length() + 64;
2570 if ((last_period = old.find_last_of ('.')) == string::npos) {
2572 /* no period present - add one explicitly */
2575 last_period = old.length() - 1;
2580 number = atoi (old.substr (last_period+1).c_str());
2584 while (number < (UINT_MAX-1)) {
2586 RegionList::const_iterator i;
2591 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2594 for (i = regions.begin(); i != regions.end(); ++i) {
2595 if (i->second->name() == sbuf) {
2600 if (i == regions.end()) {
2605 if (number != (UINT_MAX-1)) {
2609 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2614 Session::region_name (string& result, string base, bool newlevel)
2619 if (base.find("/") != string::npos) {
2620 base = base.substr(base.find_last_of("/") + 1);
2625 Glib::Mutex::Lock lm (region_lock);
2627 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2636 string::size_type pos;
2638 pos = base.find_last_of ('.');
2640 /* pos may be npos, but then we just use entire base */
2642 subbase = base.substr (0, pos);
2647 Glib::Mutex::Lock lm (region_lock);
2649 map<string,uint32_t>::iterator x;
2653 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2655 region_name_map[subbase] = 1;
2658 snprintf (buf, sizeof (buf), ".%d", x->second);
2669 Session::add_region (boost::shared_ptr<Region> region)
2671 vector<boost::shared_ptr<Region> > v;
2672 v.push_back (region);
2677 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2682 Glib::Mutex::Lock lm (region_lock);
2684 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2686 boost::shared_ptr<Region> region = *ii;
2690 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2694 RegionList::iterator x;
2696 for (x = regions.begin(); x != regions.end(); ++x) {
2698 if (region->region_list_equivalent (x->second)) {
2703 if (x == regions.end()) {
2705 pair<RegionList::key_type,RegionList::mapped_type> entry;
2707 entry.first = region->id();
2708 entry.second = region;
2710 pair<RegionList::iterator,bool> x = regions.insert (entry);
2722 /* mark dirty because something has changed even if we didn't
2723 add the region to the region list.
2730 vector<boost::weak_ptr<Region> > v;
2731 boost::shared_ptr<Region> first_r;
2733 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2735 boost::shared_ptr<Region> region = *ii;
2739 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2742 v.push_back (region);
2749 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2750 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2752 update_region_name_map (region);
2756 RegionsAdded (v); /* EMIT SIGNAL */
2762 Session::update_region_name_map (boost::shared_ptr<Region> region)
2764 string::size_type last_period = region->name().find_last_of ('.');
2766 if (last_period != string::npos && last_period < region->name().length() - 1) {
2768 string base = region->name().substr (0, last_period);
2769 string number = region->name().substr (last_period+1);
2770 map<string,uint32_t>::iterator x;
2772 /* note that if there is no number, we get zero from atoi,
2776 region_name_map[base] = atoi (number);
2781 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2783 boost::shared_ptr<Region> region (weak_region.lock ());
2789 if (what_changed & Region::HiddenChanged) {
2790 /* relay hidden changes */
2791 RegionHiddenChange (region);
2794 if (what_changed & NameChanged) {
2795 update_region_name_map (region);
2800 Session::remove_region (boost::weak_ptr<Region> weak_region)
2802 RegionList::iterator i;
2803 boost::shared_ptr<Region> region (weak_region.lock ());
2809 bool removed = false;
2812 Glib::Mutex::Lock lm (region_lock);
2814 if ((i = regions.find (region->id())) != regions.end()) {
2820 /* mark dirty because something has changed even if we didn't
2821 remove the region from the region list.
2827 RegionRemoved(region); /* EMIT SIGNAL */
2831 boost::shared_ptr<Region>
2832 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2834 RegionList::iterator i;
2835 boost::shared_ptr<Region> region;
2837 Glib::Mutex::Lock lm (region_lock);
2839 for (i = regions.begin(); i != regions.end(); ++i) {
2843 if (region->whole_file()) {
2845 if (child->source_equivalent (region)) {
2851 return boost::shared_ptr<Region> ();
2855 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2857 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2858 (*i)->get_region_list_equivalent_regions (region, result);
2862 Session::destroy_region (boost::shared_ptr<Region> region)
2864 vector<boost::shared_ptr<Source> > srcs;
2867 if (region->playlist()) {
2868 region->playlist()->destroy_region (region);
2871 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2872 srcs.push_back (region->source (n));
2876 region->drop_references ();
2878 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2880 (*i)->mark_for_remove ();
2881 (*i)->drop_references ();
2883 cerr << "source was not used by any playlist\n";
2890 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2892 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2893 destroy_region (*i);
2899 Session::remove_last_capture ()
2901 list<boost::shared_ptr<Region> > r;
2903 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2905 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2906 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2909 r.insert (r.end(), l.begin(), l.end());
2914 destroy_regions (r);
2916 save_state (_current_snapshot_name);
2922 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2928 /* Source Management */
2931 Session::add_source (boost::shared_ptr<Source> source)
2933 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2934 pair<SourceMap::iterator,bool> result;
2936 entry.first = source->id();
2937 entry.second = source;
2940 Glib::Mutex::Lock lm (source_lock);
2941 result = sources.insert (entry);
2944 if (result.second) {
2945 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2949 boost::shared_ptr<AudioFileSource> afs;
2951 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2952 if (Config->get_auto_analyse_audio()) {
2953 Analyser::queue_source_for_analysis (source, false);
2959 Session::remove_source (boost::weak_ptr<Source> src)
2961 SourceMap::iterator i;
2962 boost::shared_ptr<Source> source = src.lock();
2969 Glib::Mutex::Lock lm (source_lock);
2971 if ((i = sources.find (source->id())) != sources.end()) {
2976 if (!_state_of_the_state & InCleanup) {
2978 /* save state so we don't end up with a session file
2979 referring to non-existent sources.
2982 save_state (_current_snapshot_name);
2986 boost::shared_ptr<Source>
2987 Session::source_by_id (const PBD::ID& id)
2989 Glib::Mutex::Lock lm (source_lock);
2990 SourceMap::iterator i;
2991 boost::shared_ptr<Source> source;
2993 if ((i = sources.find (id)) != sources.end()) {
3000 boost::shared_ptr<Source>
3001 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3003 Glib::Mutex::Lock lm (source_lock);
3005 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3006 cerr << "comparing " << path << " with " << i->second->name() << endl;
3007 boost::shared_ptr<AudioFileSource> afs
3008 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3010 if (afs && afs->path() == path && chn == afs->channel()) {
3014 return boost::shared_ptr<Source>();
3019 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3022 string old_basename = PBD::basename_nosuffix (oldname);
3023 string new_legalized = legalize_for_path (newname);
3025 /* note: we know (or assume) the old path is already valid */
3029 /* destructive file sources have a name of the form:
3031 /path/to/Tnnnn-NAME(%[LR])?.wav
3033 the task here is to replace NAME with the new name.
3036 /* find last slash */
3040 string::size_type slash;
3041 string::size_type dash;
3043 if ((slash = path.find_last_of ('/')) == string::npos) {
3047 dir = path.substr (0, slash+1);
3049 /* '-' is not a legal character for the NAME part of the path */
3051 if ((dash = path.find_last_of ('-')) == string::npos) {
3055 prefix = path.substr (slash+1, dash-(slash+1));
3060 path += new_legalized;
3061 path += ".wav"; /* XXX gag me with a spoon */
3065 /* non-destructive file sources have a name of the form:
3067 /path/to/NAME-nnnnn(%[LR])?.ext
3069 the task here is to replace NAME with the new name.
3074 string::size_type slash;
3075 string::size_type dash;
3076 string::size_type postfix;
3078 /* find last slash */
3080 if ((slash = path.find_last_of ('/')) == string::npos) {
3084 dir = path.substr (0, slash+1);
3086 /* '-' is not a legal character for the NAME part of the path */
3088 if ((dash = path.find_last_of ('-')) == string::npos) {
3092 suffix = path.substr (dash+1);
3094 // Suffix is now everything after the dash. Now we need to eliminate
3095 // the nnnnn part, which is done by either finding a '%' or a '.'
3097 postfix = suffix.find_last_of ("%");
3098 if (postfix == string::npos) {
3099 postfix = suffix.find_last_of ('.');
3102 if (postfix != string::npos) {
3103 suffix = suffix.substr (postfix);
3105 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3109 const uint32_t limit = 10000;
3110 char buf[PATH_MAX+1];
3112 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3114 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3116 if (access (buf, F_OK) != 0) {
3124 error << "FATAL ERROR! Could not find a " << endl;
3132 /** Return the full path (in some session directory) for a new embedded source.
3133 * \a name must be a session-unique name that does not contain slashes
3134 * (e.g. as returned by new_*_source_name)
3137 Session::new_source_path_from_name (DataType type, const string& name)
3139 assert(name.find("/") == string::npos);
3141 SessionDirectory sdir(get_best_session_directory_for_new_source());
3144 if (type == DataType::AUDIO) {
3145 p = sdir.sound_path();
3146 } else if (type == DataType::MIDI) {
3147 p = sdir.midi_path();
3149 error << "Unknown source type, unable to create file path" << endmsg;
3154 return p.to_string();
3158 Session::peak_path (Glib::ustring base) const
3160 sys::path peakfile_path(_session_dir->peak_path());
3161 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3162 return peakfile_path.to_string();
3165 /** Return a unique name based on \a base for a new internal audio source */
3167 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3171 char buf[PATH_MAX+1];
3172 const uint32_t limit = 10000;
3176 legalized = legalize_for_path (base);
3178 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3179 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3181 vector<space_and_path>::iterator i;
3182 uint32_t existing = 0;
3184 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3186 SessionDirectory sdir((*i).path);
3188 spath = sdir.sound_path().to_string();
3193 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3194 spath.c_str(), cnt, legalized.c_str());
3195 } else if (nchan == 2) {
3197 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3198 spath.c_str(), cnt, legalized.c_str());
3200 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3201 spath.c_str(), cnt, legalized.c_str());
3203 } else if (nchan < 26) {
3204 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3205 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3207 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3208 spath.c_str(), cnt, legalized.c_str());
3217 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3218 } else if (nchan == 2) {
3220 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3222 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3224 } else if (nchan < 26) {
3225 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3227 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3231 if (sys::exists(buf)) {
3237 if (existing == 0) {
3242 error << string_compose(
3243 _("There are already %1 recordings for %2, which I consider too many."),
3244 limit, base) << endmsg;
3246 throw failed_constructor();
3250 return Glib::path_get_basename(buf);
3253 /** Create a new embedded audio source */
3254 boost::shared_ptr<AudioFileSource>
3255 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3257 const size_t n_chans = ds.n_channels().n_audio();
3258 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3259 const string path = new_source_path_from_name(DataType::AUDIO, name);
3260 return boost::dynamic_pointer_cast<AudioFileSource> (
3261 SourceFactory::createWritable (
3262 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3265 /** Return a unique name based on \a base for a new internal MIDI source */
3267 Session::new_midi_source_name (const string& base)
3270 char buf[PATH_MAX+1];
3271 const uint32_t limit = 10000;
3275 legalized = legalize_for_path (base);
3277 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3278 for (cnt = 1; cnt <= limit; ++cnt) {
3280 vector<space_and_path>::iterator i;
3281 uint32_t existing = 0;
3283 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3285 SessionDirectory sdir((*i).path);
3287 sys::path p = sdir.midi_path();
3290 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3292 if (sys::exists (buf)) {
3297 if (existing == 0) {
3302 error << string_compose(
3303 _("There are already %1 recordings for %2, which I consider too many."),
3304 limit, base) << endmsg;
3306 throw failed_constructor();
3310 return Glib::path_get_basename(buf);
3314 /** Create a new embedded MIDI source */
3315 boost::shared_ptr<MidiSource>
3316 Session::create_midi_source_for_session (MidiDiskstream& ds)
3318 const string name = new_midi_source_name (ds.name());
3319 const string path = new_source_path_from_name (DataType::MIDI, name);
3321 return boost::dynamic_pointer_cast<SMFSource> (
3322 SourceFactory::createWritable (
3323 DataType::MIDI, *this, path, true, false, frame_rate()));
3327 /* Playlist management */
3329 boost::shared_ptr<Playlist>
3330 Session::playlist_by_name (string name)
3332 Glib::Mutex::Lock lm (playlist_lock);
3333 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3334 if ((*i)->name() == name) {
3338 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3339 if ((*i)->name() == name) {
3344 return boost::shared_ptr<Playlist>();
3348 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3350 Glib::Mutex::Lock lm (playlist_lock);
3351 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3352 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3353 list.push_back (*i);
3356 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3357 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3358 list.push_back (*i);
3364 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3366 if (playlist->hidden()) {
3371 Glib::Mutex::Lock lm (playlist_lock);
3372 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3373 playlists.insert (playlists.begin(), playlist);
3374 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3375 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3380 playlist->release();
3385 PlaylistAdded (playlist); /* EMIT SIGNAL */
3389 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3392 Glib::Mutex::Lock lm (playlist_lock);
3393 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3396 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3403 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3405 boost::shared_ptr<Playlist> pl(wpl.lock());
3411 PlaylistList::iterator x;
3414 /* its not supposed to be visible */
3419 Glib::Mutex::Lock lm (playlist_lock);
3423 unused_playlists.insert (pl);
3425 if ((x = playlists.find (pl)) != playlists.end()) {
3426 playlists.erase (x);
3432 playlists.insert (pl);
3434 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3435 unused_playlists.erase (x);
3442 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3444 if (_state_of_the_state & Deletion) {
3448 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3455 Glib::Mutex::Lock lm (playlist_lock);
3457 PlaylistList::iterator i;
3459 i = find (playlists.begin(), playlists.end(), playlist);
3460 if (i != playlists.end()) {
3461 playlists.erase (i);
3464 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3465 if (i != unused_playlists.end()) {
3466 unused_playlists.erase (i);
3473 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3477 Session::set_audition (boost::shared_ptr<Region> r)
3479 pending_audition_region = r;
3480 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3481 schedule_butler_transport_work ();
3485 Session::audition_playlist ()
3487 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3488 ev->region.reset ();
3493 Session::non_realtime_set_audition ()
3495 if (!pending_audition_region) {
3496 auditioner->audition_current_playlist ();
3498 auditioner->audition_region (pending_audition_region);
3499 pending_audition_region.reset ();
3501 AuditionActive (true); /* EMIT SIGNAL */
3505 Session::audition_region (boost::shared_ptr<Region> r)
3507 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3513 Session::cancel_audition ()
3515 if (auditioner->active()) {
3516 auditioner->cancel_audition ();
3517 AuditionActive (false); /* EMIT SIGNAL */
3522 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3524 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3528 Session::remove_empty_sounds ()
3530 vector<string> audio_filenames;
3532 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3534 Glib::Mutex::Lock lm (source_lock);
3536 TapeFileMatcher tape_file_matcher;
3538 remove_if (audio_filenames.begin(), audio_filenames.end(),
3539 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3541 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3543 sys::path audio_file_path (_session_dir->sound_path());
3545 audio_file_path /= *i;
3547 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3551 sys::remove (audio_file_path);
3552 const string peakfile = peak_path (audio_file_path.to_string());
3553 sys::remove (peakfile);
3555 catch (const sys::filesystem_error& err)
3557 error << err.what() << endmsg;
3564 Session::is_auditioning () const
3566 /* can be called before we have an auditioner object */
3568 return auditioner->active();
3575 Session::set_all_solo (bool yn)
3577 shared_ptr<RouteList> r = routes.reader ();
3579 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3580 if (!(*i)->is_hidden()) {
3581 (*i)->set_solo (yn, this);
3589 Session::set_all_mute (bool yn)
3591 shared_ptr<RouteList> r = routes.reader ();
3593 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3594 if (!(*i)->is_hidden()) {
3595 (*i)->set_mute (yn, this);
3603 Session::n_diskstreams () const
3607 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3609 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3610 if (!(*i)->hidden()) {
3618 Session::graph_reordered ()
3620 /* don't do this stuff if we are setting up connections
3621 from a set_state() call or creating new tracks.
3624 if (_state_of_the_state & InitialConnecting) {
3628 /* every track/bus asked for this to be handled but it was deferred because
3629 we were connecting. do it now.
3632 request_input_change_handling ();
3636 /* force all diskstreams to update their capture offset values to
3637 reflect any changes in latencies within the graph.
3640 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3642 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3643 (*i)->set_capture_offset ();
3648 Session::record_disenable_all ()
3650 record_enable_change_all (false);
3654 Session::record_enable_all ()
3656 record_enable_change_all (true);
3660 Session::record_enable_change_all (bool yn)
3662 shared_ptr<RouteList> r = routes.reader ();
3664 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3667 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3668 at->set_record_enable (yn, this);
3672 /* since we don't keep rec-enable state, don't mark session dirty */
3676 Session::add_processor (Processor* processor)
3679 PortInsert* port_insert;
3680 PluginInsert* plugin_insert;
3682 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3683 _port_inserts.insert (_port_inserts.begin(), port_insert);
3684 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3685 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3686 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3687 _sends.insert (_sends.begin(), send);
3689 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3693 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3699 Session::remove_processor (Processor* processor)
3702 PortInsert* port_insert;
3703 PluginInsert* plugin_insert;
3705 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3706 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3707 if (x != _port_inserts.end()) {
3708 insert_bitset[port_insert->bit_slot()] = false;
3709 _port_inserts.erase (x);
3711 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3712 _plugin_inserts.remove (plugin_insert);
3713 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3714 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3715 if (x != _sends.end()) {
3716 send_bitset[send->bit_slot()] = false;
3720 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3728 Session::available_capture_duration ()
3730 float sample_bytes_on_disk = 4.0; // keep gcc happy
3732 switch (Config->get_native_file_data_format()) {
3734 sample_bytes_on_disk = 4.0;
3738 sample_bytes_on_disk = 3.0;
3742 sample_bytes_on_disk = 2.0;
3746 /* impossible, but keep some gcc versions happy */
3747 fatal << string_compose (_("programming error: %1"),
3748 X_("illegal native file data format"))
3753 double scale = 4096.0 / sample_bytes_on_disk;
3755 if (_total_free_4k_blocks * scale > (double) max_frames) {
3759 return (nframes_t) floor (_total_free_4k_blocks * scale);
3763 Session::add_bundle (shared_ptr<Bundle> bundle)
3766 RCUWriter<BundleList> writer (_bundles);
3767 boost::shared_ptr<BundleList> b = writer.get_copy ();
3768 b->push_back (bundle);
3771 BundleAdded (bundle); /* EMIT SIGNAL */
3777 Session::remove_bundle (shared_ptr<Bundle> bundle)
3779 bool removed = false;
3782 RCUWriter<BundleList> writer (_bundles);
3783 boost::shared_ptr<BundleList> b = writer.get_copy ();
3784 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3786 if (i != b->end()) {
3793 BundleRemoved (bundle); /* EMIT SIGNAL */
3800 Session::bundle_by_name (string name) const
3802 boost::shared_ptr<BundleList> b = _bundles.reader ();
3804 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3805 if ((*i)->name() == name) {
3810 return boost::shared_ptr<Bundle> ();
3814 Session::tempo_map_changed (Change ignored)
3818 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3819 (*i)->update_after_tempo_map_change ();
3822 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3823 (*i)->update_after_tempo_map_change ();
3829 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3830 * the given count with the current block size.
3833 Session::ensure_buffers (ChanCount howmany)
3835 if (current_block_size == 0)
3836 return; // too early? (is this ok?)
3838 // We need at least 2 MIDI scratch buffers to mix/merge
3839 if (howmany.n_midi() < 2)
3840 howmany.set_midi(2);
3842 // FIXME: JACK needs to tell us maximum MIDI buffer size
3843 // Using nasty assumption (max # events == nframes) for now
3844 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3845 _mix_buffers->ensure_buffers(howmany, current_block_size);
3846 _silent_buffers->ensure_buffers(howmany, current_block_size);
3848 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3852 Session::next_insert_id ()
3854 /* this doesn't really loop forever. just think about it */
3857 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3858 if (!insert_bitset[n]) {
3859 insert_bitset[n] = true;
3865 /* none available, so resize and try again */
3867 insert_bitset.resize (insert_bitset.size() + 16, false);
3872 Session::next_send_id ()
3874 /* this doesn't really loop forever. just think about it */
3877 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3878 if (!send_bitset[n]) {
3879 send_bitset[n] = true;
3885 /* none available, so resize and try again */
3887 send_bitset.resize (send_bitset.size() + 16, false);
3892 Session::mark_send_id (uint32_t id)
3894 if (id >= send_bitset.size()) {
3895 send_bitset.resize (id+16, false);
3897 if (send_bitset[id]) {
3898 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3900 send_bitset[id] = true;
3904 Session::mark_insert_id (uint32_t id)
3906 if (id >= insert_bitset.size()) {
3907 insert_bitset.resize (id+16, false);
3909 if (insert_bitset[id]) {
3910 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3912 insert_bitset[id] = true;
3915 /* Named Selection management */
3918 Session::named_selection_by_name (string name)
3920 Glib::Mutex::Lock lm (named_selection_lock);
3921 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3922 if ((*i)->name == name) {
3930 Session::add_named_selection (NamedSelection* named_selection)
3933 Glib::Mutex::Lock lm (named_selection_lock);
3934 named_selections.insert (named_selections.begin(), named_selection);
3937 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3943 NamedSelectionAdded (); /* EMIT SIGNAL */
3947 Session::remove_named_selection (NamedSelection* named_selection)
3949 bool removed = false;
3952 Glib::Mutex::Lock lm (named_selection_lock);
3954 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3956 if (i != named_selections.end()) {
3958 named_selections.erase (i);
3965 NamedSelectionRemoved (); /* EMIT SIGNAL */
3970 Session::reset_native_file_format ()
3972 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3974 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3975 (*i)->reset_write_sources (false);
3980 Session::route_name_unique (string n) const
3982 shared_ptr<RouteList> r = routes.reader ();
3984 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3985 if ((*i)->name() == n) {
3994 Session::n_playlists () const
3996 Glib::Mutex::Lock lm (playlist_lock);
3997 return playlists.size();
4001 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4003 if (!force && howmany <= _npan_buffers) {
4007 if (_pan_automation_buffer) {
4009 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4010 delete [] _pan_automation_buffer[i];
4013 delete [] _pan_automation_buffer;
4016 _pan_automation_buffer = new pan_t*[howmany];
4018 for (uint32_t i = 0; i < howmany; ++i) {
4019 _pan_automation_buffer[i] = new pan_t[nframes];
4022 _npan_buffers = howmany;
4026 Session::freeze (InterThreadInfo& itt)
4028 shared_ptr<RouteList> r = routes.reader ();
4030 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4034 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4035 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4045 boost::shared_ptr<Region>
4046 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4047 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4049 boost::shared_ptr<Region> result;
4050 boost::shared_ptr<Playlist> playlist;
4051 boost::shared_ptr<AudioFileSource> fsource;
4053 char buf[PATH_MAX+1];
4054 ChanCount nchans(track.audio_diskstream()->n_channels());
4056 nframes_t this_chunk;
4059 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4060 const string sound_dir = sdir.sound_path().to_string();
4061 nframes_t len = end - start;
4064 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4065 end, start) << endmsg;
4069 // any bigger than this seems to cause stack overflows in called functions
4070 const nframes_t chunk_size = (128 * 1024)/4;
4072 g_atomic_int_set (&processing_prohibited, 1);
4074 /* call tree *MUST* hold route_lock */
4076 if ((playlist = track.diskstream()->playlist()) == 0) {
4080 /* external redirects will be a problem */
4082 if (track.has_external_redirects()) {
4086 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4088 for (x = 0; x < 99999; ++x) {
4089 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4090 if (access (buf, F_OK) != 0) {
4096 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4101 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4102 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4105 catch (failed_constructor& err) {
4106 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4110 srcs.push_back (fsource);
4113 /* XXX need to flush all redirects */
4118 /* create a set of reasonably-sized buffers */
4119 buffers.ensure_buffers(nchans, chunk_size);
4120 buffers.set_count(nchans);
4122 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4123 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4125 afs->prepare_for_peakfile_writes ();
4128 while (to_do && !itt.cancel) {
4130 this_chunk = min (to_do, chunk_size);
4132 if (track.export_stuff (buffers, start, this_chunk)) {
4137 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4138 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4141 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4147 start += this_chunk;
4148 to_do -= this_chunk;
4150 itt.progress = (float) (1.0 - ((double) to_do / len));
4159 xnow = localtime (&now);
4161 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4162 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4165 afs->update_header (position, *xnow, now);
4166 afs->flush_header ();
4170 /* construct a region to represent the bounced material */
4172 result = RegionFactory::create (srcs, 0,
4173 srcs.front()->length(srcs.front()->timeline_position()),
4174 region_name_from_path (srcs.front()->name(), true));
4179 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4180 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4183 afs->mark_for_remove ();
4186 (*src)->drop_references ();
4190 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4191 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4194 afs->done_with_peakfile_writes ();
4198 g_atomic_int_set (&processing_prohibited, 0);
4204 Session::get_silent_buffers (ChanCount count)
4206 assert(_silent_buffers->available() >= count);
4207 _silent_buffers->set_count(count);
4209 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4210 for (size_t i= 0; i < count.get(*t); ++i) {
4211 _silent_buffers->get(*t, i).clear();
4215 return *_silent_buffers;
4219 Session::get_scratch_buffers (ChanCount count)
4221 if (count != ChanCount::ZERO) {
4222 assert(_scratch_buffers->available() >= count);
4223 _scratch_buffers->set_count(count);
4225 _scratch_buffers->set_count (_scratch_buffers->available());
4228 return *_scratch_buffers;
4232 Session::get_mix_buffers (ChanCount count)
4234 assert(_mix_buffers->available() >= count);
4235 _mix_buffers->set_count(count);
4236 return *_mix_buffers;
4240 Session::ntracks () const
4243 shared_ptr<RouteList> r = routes.reader ();
4245 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4246 if (dynamic_cast<Track*> ((*i).get())) {
4255 Session::nbusses () const
4258 shared_ptr<RouteList> r = routes.reader ();
4260 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4261 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4270 Session::add_automation_list(AutomationList *al)
4272 automation_lists[al->id()] = al;
4276 Session::compute_initial_length ()
4278 return _engine.frame_rate() * 60 * 5;
4282 Session::sync_order_keys (const char* base)
4284 if (!Config->get_sync_all_route_ordering()) {
4285 /* leave order keys as they are */
4289 boost::shared_ptr<RouteList> r = routes.reader ();
4291 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4292 (*i)->sync_order_keys (base);
4295 Route::SyncOrderKeys (base); // EMIT SIGNAL