2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
44 #include <pbd/file_utils.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/session_directory.h>
50 #include <ardour/utils.h>
51 #include <ardour/audio_diskstream.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/audiofilesource.h>
55 #include <ardour/midi_diskstream.h>
56 #include <ardour/midi_playlist.h>
57 #include <ardour/midi_region.h>
58 #include <ardour/smf_source.h>
59 #include <ardour/auditioner.h>
60 #include <ardour/recent_sessions.h>
61 #include <ardour/io_processor.h>
62 #include <ardour/send.h>
63 #include <ardour/processor.h>
64 #include <ardour/plugin_insert.h>
65 #include <ardour/port_insert.h>
66 #include <ardour/auto_bundle.h>
67 #include <ardour/slave.h>
68 #include <ardour/tempo.h>
69 #include <ardour/audio_track.h>
70 #include <ardour/midi_track.h>
71 #include <ardour/cycle_timer.h>
72 #include <ardour/named_selection.h>
73 #include <ardour/crossfade.h>
74 #include <ardour/playlist.h>
75 #include <ardour/click.h>
76 #include <ardour/data_type.h>
77 #include <ardour/buffer_set.h>
78 #include <ardour/source_factory.h>
79 #include <ardour/region_factory.h>
80 #include <ardour/filename_extensions.h>
81 #include <ardour/session_directory.h>
82 #include <ardour/tape_file_matcher.h>
83 #include <ardour/analyser.h>
86 #include <ardour/osc.h>
92 using namespace ARDOUR;
94 using boost::shared_ptr;
97 static const int CPU_CACHE_ALIGN = 64;
99 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
102 bool Session::_disable_all_loaded_plugins = false;
104 Session::compute_peak_t Session::compute_peak = 0;
105 Session::find_peaks_t Session::find_peaks = 0;
106 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
107 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
108 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
110 sigc::signal<int> Session::AskAboutPendingState;
111 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
112 sigc::signal<void> Session::SendFeedback;
114 sigc::signal<void> Session::SMPTEOffsetChanged;
115 sigc::signal<void> Session::StartTimeChanged;
116 sigc::signal<void> Session::EndTimeChanged;
118 Session::Session (AudioEngine &eng,
119 const string& fullpath,
120 const string& snapshot_name,
124 _scratch_buffers(new BufferSet()),
125 _silent_buffers(new BufferSet()),
126 _mix_buffers(new BufferSet()),
127 _mmc_port (default_mmc_port),
128 _mtc_port (default_mtc_port),
129 _midi_port (default_midi_port),
130 _session_dir (new SessionDirectory(fullpath)),
131 pending_events (2048),
132 //midi_requests (128), // the size of this should match the midi request pool size
133 _send_smpte_update (false),
134 diskstreams (new DiskstreamList),
135 routes (new RouteList),
136 auditioner ((Auditioner*) 0),
137 _bundle_xml_node (0),
143 if (!eng.connected()) {
144 throw failed_constructor();
147 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
149 n_physical_outputs = _engine.n_physical_outputs();
150 n_physical_inputs = _engine.n_physical_inputs();
152 first_stage_init (fullpath, snapshot_name);
154 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
157 if (create (new_session, mix_template, compute_initial_length())) {
159 throw failed_constructor ();
163 if (second_stage_init (new_session)) {
165 throw failed_constructor ();
168 store_recent_sessions(_name, _path);
170 bool was_dirty = dirty();
172 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
174 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
177 DirtyChanged (); /* EMIT SIGNAL */
181 Session::Session (AudioEngine &eng,
183 string snapshot_name,
184 AutoConnectOption input_ac,
185 AutoConnectOption output_ac,
186 uint32_t control_out_channels,
187 uint32_t master_out_channels,
188 uint32_t requested_physical_in,
189 uint32_t requested_physical_out,
190 nframes_t initial_length)
193 _scratch_buffers(new BufferSet()),
194 _silent_buffers(new BufferSet()),
195 _mix_buffers(new BufferSet()),
196 _mmc_port (default_mmc_port),
197 _mtc_port (default_mtc_port),
198 _midi_port (default_midi_port),
199 _session_dir ( new SessionDirectory(fullpath)),
200 pending_events (2048),
201 //midi_requests (16),
202 _send_smpte_update (false),
203 diskstreams (new DiskstreamList),
204 routes (new RouteList),
205 _bundle_xml_node (0),
211 if (!eng.connected()) {
212 throw failed_constructor();
215 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
217 n_physical_outputs = _engine.n_physical_outputs();
218 n_physical_inputs = _engine.n_physical_inputs();
220 if (n_physical_inputs) {
221 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
224 if (n_physical_outputs) {
225 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
228 first_stage_init (fullpath, snapshot_name);
230 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
233 if (create (new_session, string(), initial_length)) {
235 throw failed_constructor ();
240 /* set up Master Out and Control Out if necessary */
245 if (control_out_channels) {
246 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
247 r->set_remote_control_id (control_id++);
252 if (master_out_channels) {
253 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
254 r->set_remote_control_id (control_id);
258 /* prohibit auto-connect to master, because there isn't one */
259 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
263 add_routes (rl, false);
268 Config->set_input_auto_connect (input_ac);
269 Config->set_output_auto_connect (output_ac);
271 if (second_stage_init (new_session)) {
273 throw failed_constructor ();
276 store_recent_sessions (_name, _path);
278 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
280 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
291 /* if we got to here, leaving pending capture state around
295 remove_pending_capture_state ();
297 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
299 _engine.remove_session ();
301 GoingAway (); /* EMIT SIGNAL */
307 /* clear history so that no references to objects are held any more */
311 /* clear state tree so that no references to objects are held any more */
317 terminate_butler_thread ();
318 //terminate_midi_thread ();
320 if (click_data && click_data != default_click) {
321 delete [] click_data;
324 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
325 delete [] click_emphasis_data;
330 delete _scratch_buffers;
331 delete _silent_buffers;
334 AudioDiskstream::free_working_buffers();
336 #undef TRACK_DESTRUCTION
337 #ifdef TRACK_DESTRUCTION
338 cerr << "delete named selections\n";
339 #endif /* TRACK_DESTRUCTION */
340 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
341 NamedSelectionList::iterator tmp;
350 #ifdef TRACK_DESTRUCTION
351 cerr << "delete playlists\n";
352 #endif /* TRACK_DESTRUCTION */
353 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
354 PlaylistList::iterator tmp;
359 (*i)->drop_references ();
364 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
365 PlaylistList::iterator tmp;
370 (*i)->drop_references ();
376 unused_playlists.clear ();
378 #ifdef TRACK_DESTRUCTION
379 cerr << "delete regions\n";
380 #endif /* TRACK_DESTRUCTION */
382 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
383 RegionList::iterator tmp;
388 i->second->drop_references ();
395 #ifdef TRACK_DESTRUCTION
396 cerr << "delete routes\n";
397 #endif /* TRACK_DESTRUCTION */
399 RCUWriter<RouteList> writer (routes);
400 boost::shared_ptr<RouteList> r = writer.get_copy ();
401 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
402 (*i)->drop_references ();
405 /* writer goes out of scope and updates master */
410 #ifdef TRACK_DESTRUCTION
411 cerr << "delete diskstreams\n";
412 #endif /* TRACK_DESTRUCTION */
414 RCUWriter<DiskstreamList> dwriter (diskstreams);
415 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
416 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
417 (*i)->drop_references ();
421 diskstreams.flush ();
423 #ifdef TRACK_DESTRUCTION
424 cerr << "delete audio sources\n";
425 #endif /* TRACK_DESTRUCTION */
426 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
427 SourceMap::iterator tmp;
432 i->second->drop_references ();
439 #ifdef TRACK_DESTRUCTION
440 cerr << "delete mix groups\n";
441 #endif /* TRACK_DESTRUCTION */
442 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
443 list<RouteGroup*>::iterator tmp;
453 #ifdef TRACK_DESTRUCTION
454 cerr << "delete edit groups\n";
455 #endif /* TRACK_DESTRUCTION */
456 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
457 list<RouteGroup*>::iterator tmp;
467 if (butler_mixdown_buffer) {
468 delete [] butler_mixdown_buffer;
471 if (butler_gain_buffer) {
472 delete [] butler_gain_buffer;
475 Crossfade::set_buffer_size (0);
483 Session::set_worst_io_latencies ()
485 _worst_output_latency = 0;
486 _worst_input_latency = 0;
488 if (!_engine.connected()) {
492 boost::shared_ptr<RouteList> r = routes.reader ();
494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
495 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
496 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
501 Session::when_engine_running ()
503 string first_physical_output;
505 /* we don't want to run execute this again */
507 BootMessage (_("Set block size and sample rate"));
509 set_block_size (_engine.frames_per_cycle());
510 set_frame_rate (_engine.frame_rate());
512 BootMessage (_("Using configuration"));
514 Config->map_parameters (mem_fun (*this, &Session::config_changed));
516 /* every time we reconnect, recompute worst case output latencies */
518 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
520 if (synced_to_jack()) {
521 _engine.transport_stop ();
524 if (Config->get_jack_time_master()) {
525 _engine.transport_locate (_transport_frame);
533 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
535 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
537 /* existing state for Click */
539 if (_click_io->set_state (*child->children().front()) == 0) {
541 _clicking = Config->get_clicking ();
545 error << _("could not setup Click I/O") << endmsg;
551 /* default state for Click */
553 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
555 if (first_physical_output.length()) {
556 if (_click_io->add_output_port (first_physical_output, this)) {
557 // relax, even though its an error
559 _clicking = Config->get_clicking ();
565 catch (failed_constructor& err) {
566 error << _("cannot setup Click I/O") << endmsg;
569 BootMessage (_("Compute I/O Latencies"));
571 set_worst_io_latencies ();
574 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
577 /* Create a set of Bundle objects that map
578 to the physical outputs currently available
581 BootMessage (_("Set up standard connections"));
585 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
587 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
589 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
591 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
596 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
598 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
600 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
602 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
609 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
611 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
613 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
615 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
616 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
621 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
623 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
625 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
627 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
628 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
637 /* create master/control ports */
642 /* force the master to ignore any later call to this */
644 if (_master_out->pending_state_node) {
645 _master_out->ports_became_legal();
648 /* no panner resets till we are through */
650 _master_out->defer_pan_reset ();
652 while (_master_out->n_inputs().n_audio()
653 < _master_out->input_maximum().n_audio()) {
654 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
655 error << _("cannot setup master inputs")
661 while (_master_out->n_outputs().n_audio()
662 < _master_out->output_maximum().n_audio()) {
663 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
664 error << _("cannot setup master outputs")
671 _master_out->allow_pan_reset ();
675 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
677 c->set_channels (_master_out->n_inputs().n_total());
678 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
679 c->set_port (n, _master_out->input(n)->name());
684 BootMessage (_("Connect ports"));
688 /* catch up on send+insert cnts */
690 BootMessage (_("Catch up with send/insert state"));
694 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
697 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
698 if (id > insert_cnt) {
706 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
709 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
717 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
719 /* hook us up to the engine */
721 BootMessage (_("Connect to engine"));
723 _engine.set_session (this);
728 BootMessage (_("OSC startup"));
730 osc->set_session (*this);
736 Session::hookup_io ()
738 /* stop graph reordering notifications from
739 causing resorts, etc.
742 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
745 if (auditioner == 0) {
747 /* we delay creating the auditioner till now because
748 it makes its own connections to ports.
749 the engine has to be running for this to work.
753 auditioner.reset (new Auditioner (*this));
756 catch (failed_constructor& err) {
757 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
761 /* Tell all IO objects to create their ports */
767 vector<string> cports;
769 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
770 if (_control_out->add_input_port ("", this)) {
771 error << _("cannot setup control inputs")
777 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
778 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
779 error << _("cannot set up master outputs")
787 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
789 for (n = 0; n < ni; ++n) {
790 cports.push_back (_control_out->input(n)->name());
793 boost::shared_ptr<RouteList> r = routes.reader ();
795 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
796 (*x)->set_control_outs (cports);
800 /* load bundles, which we may have postponed earlier on */
801 if (_bundle_xml_node) {
802 load_bundles (*_bundle_xml_node);
803 delete _bundle_xml_node;
806 /* Tell all IO objects to connect themselves together */
808 IO::enable_connecting ();
810 /* Now reset all panners */
812 IO::reset_panners ();
814 /* Anyone who cares about input state, wake up and do something */
816 IOConnectionsComplete (); /* EMIT SIGNAL */
818 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
821 /* now handle the whole enchilada as if it was one
827 /* update mixer solo state */
833 Session::playlist_length_changed ()
835 /* we can't just increase end_location->end() if pl->get_maximum_extent()
836 if larger. if the playlist used to be the longest playlist,
837 and its now shorter, we have to decrease end_location->end(). hence,
838 we have to iterate over all diskstreams and check the
839 playlists currently in use.
845 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
847 boost::shared_ptr<Playlist> playlist;
849 if ((playlist = dstream->playlist()) != 0) {
850 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
853 /* see comment in playlist_length_changed () */
858 Session::record_enabling_legal () const
860 /* this used to be in here, but survey says.... we don't need to restrict it */
861 // if (record_status() == Recording) {
865 if (Config->get_all_safe()) {
872 Session::reset_input_monitor_state ()
874 if (transport_rolling()) {
876 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
878 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
879 if ((*i)->record_enabled ()) {
880 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
881 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
885 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
887 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
888 if ((*i)->record_enabled ()) {
889 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
890 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
897 Session::auto_punch_start_changed (Location* location)
899 replace_event (Event::PunchIn, location->start());
901 if (get_record_enabled() && Config->get_punch_in()) {
902 /* capture start has been changed, so save new pending state */
903 save_state ("", true);
908 Session::auto_punch_end_changed (Location* location)
910 nframes_t when_to_stop = location->end();
911 // when_to_stop += _worst_output_latency + _worst_input_latency;
912 replace_event (Event::PunchOut, when_to_stop);
916 Session::auto_punch_changed (Location* location)
918 nframes_t when_to_stop = location->end();
920 replace_event (Event::PunchIn, location->start());
921 //when_to_stop += _worst_output_latency + _worst_input_latency;
922 replace_event (Event::PunchOut, when_to_stop);
926 Session::auto_loop_changed (Location* location)
928 replace_event (Event::AutoLoop, location->end(), location->start());
930 if (transport_rolling() && play_loop) {
932 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
934 if (_transport_frame > location->end()) {
935 // relocate to beginning of loop
936 clear_events (Event::LocateRoll);
938 request_locate (location->start(), true);
941 else if (Config->get_seamless_loop() && !loop_changing) {
943 // schedule a locate-roll to refill the diskstreams at the
945 loop_changing = true;
947 if (location->end() > last_loopend) {
948 clear_events (Event::LocateRoll);
949 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
956 last_loopend = location->end();
961 Session::set_auto_punch_location (Location* location)
965 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
966 auto_punch_start_changed_connection.disconnect();
967 auto_punch_end_changed_connection.disconnect();
968 auto_punch_changed_connection.disconnect();
969 existing->set_auto_punch (false, this);
970 remove_event (existing->start(), Event::PunchIn);
971 clear_events (Event::PunchOut);
972 auto_punch_location_changed (0);
981 if (location->end() <= location->start()) {
982 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
986 auto_punch_start_changed_connection.disconnect();
987 auto_punch_end_changed_connection.disconnect();
988 auto_punch_changed_connection.disconnect();
990 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
991 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
992 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
994 location->set_auto_punch (true, this);
995 auto_punch_location_changed (location);
999 Session::set_auto_loop_location (Location* location)
1003 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1004 auto_loop_start_changed_connection.disconnect();
1005 auto_loop_end_changed_connection.disconnect();
1006 auto_loop_changed_connection.disconnect();
1007 existing->set_auto_loop (false, this);
1008 remove_event (existing->end(), Event::AutoLoop);
1009 auto_loop_location_changed (0);
1014 if (location == 0) {
1018 if (location->end() <= location->start()) {
1019 error << _("Session: you can't use a mark for auto loop") << endmsg;
1023 last_loopend = location->end();
1025 auto_loop_start_changed_connection.disconnect();
1026 auto_loop_end_changed_connection.disconnect();
1027 auto_loop_changed_connection.disconnect();
1029 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1030 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1031 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1033 location->set_auto_loop (true, this);
1034 auto_loop_location_changed (location);
1038 Session::locations_added (Location* ignored)
1044 Session::locations_changed ()
1046 _locations.apply (*this, &Session::handle_locations_changed);
1050 Session::handle_locations_changed (Locations::LocationList& locations)
1052 Locations::LocationList::iterator i;
1054 bool set_loop = false;
1055 bool set_punch = false;
1057 for (i = locations.begin(); i != locations.end(); ++i) {
1061 if (location->is_auto_punch()) {
1062 set_auto_punch_location (location);
1065 if (location->is_auto_loop()) {
1066 set_auto_loop_location (location);
1073 set_auto_loop_location (0);
1076 set_auto_punch_location (0);
1083 Session::enable_record ()
1085 /* XXX really atomic compare+swap here */
1086 if (g_atomic_int_get (&_record_status) != Recording) {
1087 g_atomic_int_set (&_record_status, Recording);
1088 _last_record_location = _transport_frame;
1089 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1091 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1092 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1093 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1094 if ((*i)->record_enabled ()) {
1095 (*i)->monitor_input (true);
1100 RecordStateChanged ();
1105 Session::disable_record (bool rt_context, bool force)
1109 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1111 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1112 g_atomic_int_set (&_record_status, Disabled);
1114 if (rs == Recording) {
1115 g_atomic_int_set (&_record_status, Enabled);
1119 // FIXME: timestamp correct? [DR]
1120 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1121 // does this /need/ to be sent in all cases?
1123 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1125 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1126 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1128 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1129 if ((*i)->record_enabled ()) {
1130 (*i)->monitor_input (false);
1135 RecordStateChanged (); /* emit signal */
1138 remove_pending_capture_state ();
1144 Session::step_back_from_record ()
1146 /* XXX really atomic compare+swap here */
1147 if (g_atomic_int_get (&_record_status) == Recording) {
1148 g_atomic_int_set (&_record_status, Enabled);
1150 if (Config->get_monitoring_model() == HardwareMonitoring) {
1151 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1153 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1154 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1155 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1156 (*i)->monitor_input (false);
1164 Session::maybe_enable_record ()
1166 g_atomic_int_set (&_record_status, Enabled);
1168 /* this function is currently called from somewhere other than an RT thread.
1169 this save_state() call therefore doesn't impact anything.
1172 save_state ("", true);
1174 if (_transport_speed) {
1175 if (!Config->get_punch_in()) {
1179 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1180 RecordStateChanged (); /* EMIT SIGNAL */
1187 Session::audible_frame () const
1193 /* the first of these two possible settings for "offset"
1194 mean that the audible frame is stationary until
1195 audio emerges from the latency compensation
1198 the second means that the audible frame is stationary
1199 until audio would emerge from a physical port
1200 in the absence of any plugin latency compensation
1203 offset = _worst_output_latency;
1205 if (offset > current_block_size) {
1206 offset -= current_block_size;
1208 /* XXX is this correct? if we have no external
1209 physical connections and everything is internal
1210 then surely this is zero? still, how
1211 likely is that anyway?
1213 offset = current_block_size;
1216 if (synced_to_jack()) {
1217 tf = _engine.transport_frame();
1219 tf = _transport_frame;
1222 if (_transport_speed == 0) {
1232 if (!non_realtime_work_pending()) {
1236 /* take latency into account */
1245 Session::set_frame_rate (nframes_t frames_per_second)
1247 /** \fn void Session::set_frame_size(nframes_t)
1248 the AudioEngine object that calls this guarantees
1249 that it will not be called while we are also in
1250 ::process(). Its fine to do things that block
1254 _base_frame_rate = frames_per_second;
1258 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1262 // XXX we need some equivalent to this, somehow
1263 // SndFileSource::setup_standard_crossfades (frames_per_second);
1267 /* XXX need to reset/reinstantiate all LADSPA plugins */
1271 Session::set_block_size (nframes_t nframes)
1273 /* the AudioEngine guarantees
1274 that it will not be called while we are also in
1275 ::process(). It is therefore fine to do things that block
1281 current_block_size = nframes;
1283 ensure_buffers(_scratch_buffers->available());
1285 if (_gain_automation_buffer) {
1286 delete [] _gain_automation_buffer;
1288 _gain_automation_buffer = new gain_t[nframes];
1290 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1292 boost::shared_ptr<RouteList> r = routes.reader ();
1294 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1295 (*i)->set_block_size (nframes);
1298 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1300 (*i)->set_block_size (nframes);
1303 set_worst_io_latencies ();
1308 Session::set_default_fade (float steepness, float fade_msecs)
1311 nframes_t fade_frames;
1313 /* Don't allow fade of less 1 frame */
1315 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1322 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1326 default_fade_msecs = fade_msecs;
1327 default_fade_steepness = steepness;
1330 // jlc, WTF is this!
1331 Glib::RWLock::ReaderLock lm (route_lock);
1332 AudioRegion::set_default_fade (steepness, fade_frames);
1337 /* XXX have to do this at some point */
1338 /* foreach region using default fade, reset, then
1339 refill_all_diskstream_buffers ();
1344 struct RouteSorter {
1345 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1346 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1348 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1351 if (r1->fed_by.empty()) {
1352 if (r2->fed_by.empty()) {
1353 /* no ardour-based connections inbound to either route. just use signal order */
1354 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1356 /* r2 has connections, r1 does not; run r1 early */
1360 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1367 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1369 shared_ptr<Route> r2;
1371 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1372 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1376 /* make a copy of the existing list of routes that feed r1 */
1378 set<shared_ptr<Route> > existing = r1->fed_by;
1380 /* for each route that feeds r1, recurse, marking it as feeding
1384 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1387 /* r2 is a route that feeds r1 which somehow feeds base. mark
1388 base as being fed by r2
1391 rbase->fed_by.insert (r2);
1395 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1399 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1403 /* now recurse, so that we can mark base as being fed by
1404 all routes that feed r2
1407 trace_terminal (r2, rbase);
1414 Session::resort_routes ()
1416 /* don't do anything here with signals emitted
1417 by Routes while we are being destroyed.
1420 if (_state_of_the_state & Deletion) {
1427 RCUWriter<RouteList> writer (routes);
1428 shared_ptr<RouteList> r = writer.get_copy ();
1429 resort_routes_using (r);
1430 /* writer goes out of scope and forces update */
1435 Session::resort_routes_using (shared_ptr<RouteList> r)
1437 RouteList::iterator i, j;
1439 for (i = r->begin(); i != r->end(); ++i) {
1441 (*i)->fed_by.clear ();
1443 for (j = r->begin(); j != r->end(); ++j) {
1445 /* although routes can feed themselves, it will
1446 cause an endless recursive descent if we
1447 detect it. so don't bother checking for
1455 if ((*j)->feeds (*i)) {
1456 (*i)->fed_by.insert (*j);
1461 for (i = r->begin(); i != r->end(); ++i) {
1462 trace_terminal (*i, *i);
1469 cerr << "finished route resort\n";
1471 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1472 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1479 list<boost::shared_ptr<MidiTrack> >
1480 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1482 char track_name[32];
1483 uint32_t track_id = 0;
1486 RouteList new_routes;
1487 list<boost::shared_ptr<MidiTrack> > ret;
1488 //uint32_t control_id;
1490 // FIXME: need physical I/O and autoconnect stuff for MIDI
1492 /* count existing midi tracks */
1495 shared_ptr<RouteList> r = routes.reader ();
1497 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1498 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1499 if (!(*i)->is_hidden()) {
1501 //channels_used += (*i)->n_inputs().n_midi();
1508 vector<string> physinputs;
1509 vector<string> physoutputs;
1510 uint32_t nphysical_in;
1511 uint32_t nphysical_out;
1513 _engine.get_physical_outputs (physoutputs);
1514 _engine.get_physical_inputs (physinputs);
1515 control_id = ntracks() + nbusses() + 1;
1520 /* check for duplicate route names, since we might have pre-existing
1521 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1522 save, close,restart,add new route - first named route is now
1530 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1532 if (route_by_name (track_name) == 0) {
1536 } while (track_id < (UINT_MAX-1));
1539 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1540 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1545 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1546 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1552 shared_ptr<MidiTrack> track;
1555 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1557 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1558 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1564 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1568 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1569 port = physinputs[(channels_used+x)%nphysical_in];
1572 if (port.length() && track->connect_input (track->input (x), port, this)) {
1578 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1582 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1583 port = physoutputs[(channels_used+x)%nphysical_out];
1584 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1586 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1590 if (port.length() && track->connect_output (track->output (x), port, this)) {
1595 channels_used += track->n_inputs ().n_midi();
1599 track->midi_diskstream()->non_realtime_input_change();
1601 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1602 //track->set_remote_control_id (control_id);
1604 new_routes.push_back (track);
1605 ret.push_back (track);
1608 catch (failed_constructor &err) {
1609 error << _("Session: could not create new midi track.") << endmsg;
1612 /* we need to get rid of this, since the track failed to be created */
1613 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1616 RCUWriter<DiskstreamList> writer (diskstreams);
1617 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1618 ds->remove (track->midi_diskstream());
1625 catch (AudioEngine::PortRegistrationFailure& pfe) {
1627 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;
1630 /* we need to get rid of this, since the track failed to be created */
1631 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1634 RCUWriter<DiskstreamList> writer (diskstreams);
1635 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1636 ds->remove (track->midi_diskstream());
1647 if (!new_routes.empty()) {
1648 add_routes (new_routes, false);
1649 save_state (_current_snapshot_name);
1655 list<boost::shared_ptr<AudioTrack> >
1656 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1658 char track_name[32];
1659 uint32_t track_id = 0;
1661 uint32_t channels_used = 0;
1663 RouteList new_routes;
1664 list<boost::shared_ptr<AudioTrack> > ret;
1665 uint32_t control_id;
1667 /* count existing audio tracks */
1670 shared_ptr<RouteList> r = routes.reader ();
1672 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1673 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1674 if (!(*i)->is_hidden()) {
1676 channels_used += (*i)->n_inputs().n_audio();
1682 vector<string> physinputs;
1683 vector<string> physoutputs;
1684 uint32_t nphysical_in;
1685 uint32_t nphysical_out;
1687 _engine.get_physical_outputs (physoutputs);
1688 _engine.get_physical_inputs (physinputs);
1689 control_id = ntracks() + nbusses() + 1;
1693 /* check for duplicate route names, since we might have pre-existing
1694 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1695 save, close,restart,add new route - first named route is now
1703 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1705 if (route_by_name (track_name) == 0) {
1709 } while (track_id < (UINT_MAX-1));
1711 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1712 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1717 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1718 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1723 shared_ptr<AudioTrack> track;
1726 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1728 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1729 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1730 input_channels, output_channels)
1736 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1740 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1741 port = physinputs[(channels_used+x)%nphysical_in];
1744 if (port.length() && track->connect_input (track->input (x), port, this)) {
1750 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1754 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1755 port = physoutputs[(channels_used+x)%nphysical_out];
1756 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1758 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1762 if (port.length() && track->connect_output (track->output (x), port, this)) {
1767 channels_used += track->n_inputs ().n_audio();
1769 track->audio_diskstream()->non_realtime_input_change();
1771 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1772 track->set_remote_control_id (control_id);
1775 new_routes.push_back (track);
1776 ret.push_back (track);
1779 catch (failed_constructor &err) {
1780 error << _("Session: could not create new audio track.") << endmsg;
1783 /* we need to get rid of this, since the track failed to be created */
1784 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1787 RCUWriter<DiskstreamList> writer (diskstreams);
1788 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1789 ds->remove (track->audio_diskstream());
1796 catch (AudioEngine::PortRegistrationFailure& pfe) {
1798 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;
1801 /* we need to get rid of this, since the track failed to be created */
1802 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1805 RCUWriter<DiskstreamList> writer (diskstreams);
1806 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1807 ds->remove (track->audio_diskstream());
1818 if (!new_routes.empty()) {
1819 add_routes (new_routes, true);
1826 Session::set_remote_control_ids ()
1828 RemoteModel m = Config->get_remote_model();
1830 shared_ptr<RouteList> r = routes.reader ();
1832 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1833 if ( MixerOrdered == m) {
1834 long order = (*i)->order_key(N_("signal"));
1835 (*i)->set_remote_control_id( order+1 );
1836 } else if ( EditorOrdered == m) {
1837 long order = (*i)->order_key(N_("editor"));
1838 (*i)->set_remote_control_id( order+1 );
1839 } else if ( UserOrdered == m) {
1840 //do nothing ... only changes to remote id's are initiated by user
1847 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1850 uint32_t bus_id = 1;
1854 uint32_t control_id;
1856 /* count existing audio busses */
1859 shared_ptr<RouteList> r = routes.reader ();
1861 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1862 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1863 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1870 vector<string> physinputs;
1871 vector<string> physoutputs;
1873 _engine.get_physical_outputs (physoutputs);
1874 _engine.get_physical_inputs (physinputs);
1875 control_id = ntracks() + nbusses() + 1;
1880 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1884 if (route_by_name (bus_name) == 0) {
1888 } while (bus_id < (UINT_MAX-1));
1891 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1893 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1894 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1895 input_channels, output_channels)
1900 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1904 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1905 port = physinputs[((n+x)%n_physical_inputs)];
1908 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1913 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1917 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1918 port = physoutputs[((n+x)%n_physical_outputs)];
1919 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1921 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1925 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
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 << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1953 add_routes (ret, true);
1961 Session::add_routes (RouteList& new_routes, bool save)
1964 RCUWriter<RouteList> writer (routes);
1965 shared_ptr<RouteList> r = writer.get_copy ();
1966 r->insert (r->end(), new_routes.begin(), new_routes.end());
1967 resort_routes_using (r);
1970 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1972 boost::weak_ptr<Route> wpr (*x);
1974 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1975 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1976 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1977 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1979 if ((*x)->is_master()) {
1983 if ((*x)->is_control()) {
1984 _control_out = (*x);
1987 add_bundle ((*x)->bundle_for_inputs());
1988 add_bundle ((*x)->bundle_for_outputs());
1991 if (_control_out && IO::connecting_legal) {
1993 vector<string> cports;
1994 uint32_t ni = _control_out->n_inputs().n_audio();
1996 for (uint32_t n = 0; n < ni; ++n) {
1997 cports.push_back (_control_out->input(n)->name());
2000 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2001 (*x)->set_control_outs (cports);
2008 save_state (_current_snapshot_name);
2011 RouteAdded (new_routes); /* EMIT SIGNAL */
2015 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2017 /* need to do this in case we're rolling at the time, to prevent false underruns */
2018 dstream->do_refill_with_alloc ();
2020 dstream->set_block_size (current_block_size);
2023 RCUWriter<DiskstreamList> writer (diskstreams);
2024 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2025 ds->push_back (dstream);
2026 /* writer goes out of scope, copies ds back to main */
2029 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2030 /* this will connect to future changes, and check the current length */
2031 diskstream_playlist_changed (dstream);
2033 dstream->prepare ();
2038 Session::remove_route (shared_ptr<Route> route)
2041 RCUWriter<RouteList> writer (routes);
2042 shared_ptr<RouteList> rs = writer.get_copy ();
2046 /* deleting the master out seems like a dumb
2047 idea, but its more of a UI policy issue
2051 if (route == _master_out) {
2052 _master_out = shared_ptr<Route> ();
2055 if (route == _control_out) {
2056 _control_out = shared_ptr<Route> ();
2058 /* cancel control outs for all routes */
2060 vector<string> empty;
2062 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2063 (*r)->set_control_outs (empty);
2067 update_route_solo_state ();
2069 /* writer goes out of scope, forces route list update */
2073 boost::shared_ptr<Diskstream> ds;
2075 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2076 ds = t->diskstream();
2082 RCUWriter<DiskstreamList> dsl (diskstreams);
2083 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2088 find_current_end ();
2090 // We need to disconnect the routes inputs and outputs
2092 route->disconnect_inputs (0);
2093 route->disconnect_outputs (0);
2095 update_latency_compensation (false, false);
2098 /* get rid of it from the dead wood collection in the route list manager */
2100 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2104 /* try to cause everyone to drop their references */
2106 route->drop_references ();
2108 /* save the new state of the world */
2110 if (save_state (_current_snapshot_name)) {
2111 save_history (_current_snapshot_name);
2116 Session::route_mute_changed (void* src)
2122 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2124 if (solo_update_disabled) {
2130 boost::shared_ptr<Route> route = wpr.lock ();
2133 /* should not happen */
2134 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2138 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2140 shared_ptr<RouteList> r = routes.reader ();
2142 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2144 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2148 /* don't mess with busses */
2150 if (dynamic_cast<Track*>((*i).get()) == 0) {
2156 /* don't mess with tracks */
2158 if (dynamic_cast<Track*>((*i).get()) != 0) {
2163 if ((*i) != route &&
2164 ((*i)->mix_group () == 0 ||
2165 (*i)->mix_group () != route->mix_group () ||
2166 !route->mix_group ()->is_active())) {
2168 if ((*i)->soloed()) {
2170 /* if its already soloed, and solo latching is enabled,
2171 then leave it as it is.
2174 if (Config->get_solo_latched()) {
2181 solo_update_disabled = true;
2182 (*i)->set_solo (false, src);
2183 solo_update_disabled = false;
2187 bool something_soloed = false;
2188 bool same_thing_soloed = false;
2189 bool signal = false;
2191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2192 if ((*i)->soloed()) {
2193 something_soloed = true;
2194 if (dynamic_cast<Track*>((*i).get())) {
2196 same_thing_soloed = true;
2201 same_thing_soloed = true;
2209 if (something_soloed != currently_soloing) {
2211 currently_soloing = something_soloed;
2214 modify_solo_mute (is_track, same_thing_soloed);
2217 SoloActive (currently_soloing); /* EMIT SIGNAL */
2220 SoloChanged (); /* EMIT SIGNAL */
2226 Session::update_route_solo_state ()
2229 bool is_track = false;
2230 bool signal = false;
2232 /* caller must hold RouteLock */
2234 /* this is where we actually implement solo by changing
2235 the solo mute setting of each track.
2238 shared_ptr<RouteList> r = routes.reader ();
2240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2241 if ((*i)->soloed()) {
2243 if (dynamic_cast<Track*>((*i).get())) {
2250 if (mute != currently_soloing) {
2252 currently_soloing = mute;
2255 if (!is_track && !mute) {
2257 /* nothing is soloed */
2259 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2260 (*i)->set_solo_mute (false);
2270 modify_solo_mute (is_track, mute);
2273 SoloActive (currently_soloing);
2278 Session::modify_solo_mute (bool is_track, bool mute)
2280 shared_ptr<RouteList> r = routes.reader ();
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2286 /* only alter track solo mute */
2288 if (dynamic_cast<Track*>((*i).get())) {
2289 if ((*i)->soloed()) {
2290 (*i)->set_solo_mute (!mute);
2292 (*i)->set_solo_mute (mute);
2298 /* only alter bus solo mute */
2300 if (!dynamic_cast<Track*>((*i).get())) {
2302 if ((*i)->soloed()) {
2304 (*i)->set_solo_mute (false);
2308 /* don't mute master or control outs
2309 in response to another bus solo
2312 if ((*i) != _master_out &&
2313 (*i) != _control_out) {
2314 (*i)->set_solo_mute (mute);
2325 Session::catch_up_on_solo ()
2327 /* this is called after set_state() to catch the full solo
2328 state, which can't be correctly determined on a per-route
2329 basis, but needs the global overview that only the session
2332 update_route_solo_state();
2336 Session::route_by_name (string name)
2338 shared_ptr<RouteList> r = routes.reader ();
2340 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2341 if ((*i)->name() == name) {
2346 return shared_ptr<Route> ((Route*) 0);
2350 Session::route_by_id (PBD::ID id)
2352 shared_ptr<RouteList> r = routes.reader ();
2354 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2355 if ((*i)->id() == id) {
2360 return shared_ptr<Route> ((Route*) 0);
2364 Session::route_by_remote_id (uint32_t id)
2366 shared_ptr<RouteList> r = routes.reader ();
2368 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2369 if ((*i)->remote_control_id() == id) {
2374 return shared_ptr<Route> ((Route*) 0);
2378 Session::find_current_end ()
2380 if (_state_of_the_state & Loading) {
2384 nframes_t max = get_maximum_extent ();
2386 if (max > end_location->end()) {
2387 end_location->set_end (max);
2389 DurationChanged(); /* EMIT SIGNAL */
2394 Session::get_maximum_extent () const
2399 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2401 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2402 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2403 if ((me = pl->get_maximum_extent()) > max) {
2411 boost::shared_ptr<Diskstream>
2412 Session::diskstream_by_name (string name)
2414 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2416 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2417 if ((*i)->name() == name) {
2422 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2425 boost::shared_ptr<Diskstream>
2426 Session::diskstream_by_id (const PBD::ID& id)
2428 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2431 if ((*i)->id() == id) {
2436 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2439 /* Region management */
2442 Session::new_region_name (string old)
2444 string::size_type last_period;
2446 string::size_type len = old.length() + 64;
2449 if ((last_period = old.find_last_of ('.')) == string::npos) {
2451 /* no period present - add one explicitly */
2454 last_period = old.length() - 1;
2459 number = atoi (old.substr (last_period+1).c_str());
2463 while (number < (UINT_MAX-1)) {
2465 RegionList::const_iterator i;
2470 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2473 for (i = regions.begin(); i != regions.end(); ++i) {
2474 if (i->second->name() == sbuf) {
2479 if (i == regions.end()) {
2484 if (number != (UINT_MAX-1)) {
2488 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2493 Session::region_name (string& result, string base, bool newlevel) const
2498 assert(base.find("/") == string::npos);
2502 Glib::Mutex::Lock lm (region_lock);
2504 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2512 /* XXX this is going to be slow. optimize me later */
2517 string::size_type pos;
2519 pos = base.find_last_of ('.');
2521 /* pos may be npos, but then we just use entire base */
2523 subbase = base.substr (0, pos);
2527 bool name_taken = true;
2530 Glib::Mutex::Lock lm (region_lock);
2532 for (int n = 1; n < 5000; ++n) {
2535 snprintf (buf, sizeof (buf), ".%d", n);
2540 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2541 if (i->second->name() == result) {
2554 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2562 Session::add_region (boost::shared_ptr<Region> region)
2564 vector<boost::shared_ptr<Region> > v;
2565 v.push_back (region);
2570 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2575 Glib::Mutex::Lock lm (region_lock);
2577 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2579 boost::shared_ptr<Region> region = *ii;
2583 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2587 RegionList::iterator x;
2589 for (x = regions.begin(); x != regions.end(); ++x) {
2591 if (region->region_list_equivalent (x->second)) {
2596 if (x == regions.end()) {
2598 pair<RegionList::key_type,RegionList::mapped_type> entry;
2600 entry.first = region->id();
2601 entry.second = region;
2603 pair<RegionList::iterator,bool> x = regions.insert (entry);
2615 /* mark dirty because something has changed even if we didn't
2616 add the region to the region list.
2623 vector<boost::weak_ptr<Region> > v;
2624 boost::shared_ptr<Region> first_r;
2626 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2628 boost::shared_ptr<Region> region = *ii;
2632 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2635 v.push_back (region);
2642 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2643 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2647 RegionsAdded (v); /* EMIT SIGNAL */
2653 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2655 boost::shared_ptr<Region> region (weak_region.lock ());
2661 if (what_changed & Region::HiddenChanged) {
2662 /* relay hidden changes */
2663 RegionHiddenChange (region);
2668 Session::remove_region (boost::weak_ptr<Region> weak_region)
2670 RegionList::iterator i;
2671 boost::shared_ptr<Region> region (weak_region.lock ());
2677 bool removed = false;
2680 Glib::Mutex::Lock lm (region_lock);
2682 if ((i = regions.find (region->id())) != regions.end()) {
2688 /* mark dirty because something has changed even if we didn't
2689 remove the region from the region list.
2695 RegionRemoved(region); /* EMIT SIGNAL */
2699 boost::shared_ptr<Region>
2700 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2702 RegionList::iterator i;
2703 boost::shared_ptr<Region> region;
2705 Glib::Mutex::Lock lm (region_lock);
2707 for (i = regions.begin(); i != regions.end(); ++i) {
2711 if (region->whole_file()) {
2713 if (child->source_equivalent (region)) {
2719 return boost::shared_ptr<Region> ();
2723 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2725 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2726 (*i)->get_region_list_equivalent_regions (region, result);
2730 Session::destroy_region (boost::shared_ptr<Region> region)
2732 vector<boost::shared_ptr<Source> > srcs;
2735 if (region->playlist()) {
2736 region->playlist()->destroy_region (region);
2739 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2740 srcs.push_back (region->source (n));
2744 region->drop_references ();
2746 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2748 (*i)->mark_for_remove ();
2749 (*i)->drop_references ();
2751 cerr << "source was not used by any playlist\n";
2758 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2760 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2761 destroy_region (*i);
2767 Session::remove_last_capture ()
2769 list<boost::shared_ptr<Region> > r;
2771 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2773 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2774 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2777 r.insert (r.end(), l.begin(), l.end());
2782 destroy_regions (r);
2784 save_state (_current_snapshot_name);
2790 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2796 /* Source Management */
2798 Session::add_source (boost::shared_ptr<Source> source)
2800 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2801 pair<SourceMap::iterator,bool> result;
2803 entry.first = source->id();
2804 entry.second = source;
2807 Glib::Mutex::Lock lm (source_lock);
2808 result = sources.insert (entry);
2811 if (result.second) {
2812 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2816 boost::shared_ptr<AudioFileSource> afs;
2818 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2819 if (Config->get_auto_analyse_audio()) {
2820 Analyser::queue_source_for_analysis (source, false);
2826 Session::remove_source (boost::weak_ptr<Source> src)
2828 SourceMap::iterator i;
2829 boost::shared_ptr<Source> source = src.lock();
2836 Glib::Mutex::Lock lm (source_lock);
2838 if ((i = sources.find (source->id())) != sources.end()) {
2843 if (!_state_of_the_state & InCleanup) {
2845 /* save state so we don't end up with a session file
2846 referring to non-existent sources.
2849 save_state (_current_snapshot_name);
2853 boost::shared_ptr<Source>
2854 Session::source_by_id (const PBD::ID& id)
2856 Glib::Mutex::Lock lm (source_lock);
2857 SourceMap::iterator i;
2858 boost::shared_ptr<Source> source;
2860 if ((i = sources.find (id)) != sources.end()) {
2868 boost::shared_ptr<Source>
2869 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2871 Glib::Mutex::Lock lm (source_lock);
2873 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2874 cerr << "comparing " << path << " with " << i->second->name() << endl;
2875 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2877 if (afs && afs->path() == path && chn == afs->channel()) {
2882 return boost::shared_ptr<Source>();
2886 Session::peak_path (Glib::ustring base) const
2888 sys::path peakfile_path(_session_dir->peak_path());
2889 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2890 return peakfile_path.to_string();
2894 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2897 string old_basename = PBD::basename_nosuffix (oldname);
2898 string new_legalized = legalize_for_path (newname);
2900 /* note: we know (or assume) the old path is already valid */
2904 /* destructive file sources have a name of the form:
2906 /path/to/Tnnnn-NAME(%[LR])?.wav
2908 the task here is to replace NAME with the new name.
2911 /* find last slash */
2915 string::size_type slash;
2916 string::size_type dash;
2918 if ((slash = path.find_last_of ('/')) == string::npos) {
2922 dir = path.substr (0, slash+1);
2924 /* '-' is not a legal character for the NAME part of the path */
2926 if ((dash = path.find_last_of ('-')) == string::npos) {
2930 prefix = path.substr (slash+1, dash-(slash+1));
2935 path += new_legalized;
2936 path += ".wav"; /* XXX gag me with a spoon */
2940 /* non-destructive file sources have a name of the form:
2942 /path/to/NAME-nnnnn(%[LR])?.wav
2944 the task here is to replace NAME with the new name.
2949 string::size_type slash;
2950 string::size_type dash;
2951 string::size_type postfix;
2953 /* find last slash */
2955 if ((slash = path.find_last_of ('/')) == string::npos) {
2959 dir = path.substr (0, slash+1);
2961 /* '-' is not a legal character for the NAME part of the path */
2963 if ((dash = path.find_last_of ('-')) == string::npos) {
2967 suffix = path.substr (dash+1);
2969 // Suffix is now everything after the dash. Now we need to eliminate
2970 // the nnnnn part, which is done by either finding a '%' or a '.'
2972 postfix = suffix.find_last_of ("%");
2973 if (postfix == string::npos) {
2974 postfix = suffix.find_last_of ('.');
2977 if (postfix != string::npos) {
2978 suffix = suffix.substr (postfix);
2980 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2984 const uint32_t limit = 10000;
2985 char buf[PATH_MAX+1];
2987 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2989 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2991 if (access (buf, F_OK) != 0) {
2999 error << "FATAL ERROR! Could not find a " << endl;
3008 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3012 char buf[PATH_MAX+1];
3013 const uint32_t limit = 10000;
3017 legalized = legalize_for_path (name);
3019 /* find a "version" of the file name that doesn't exist in
3020 any of the possible directories.
3023 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3025 vector<space_and_path>::iterator i;
3026 uint32_t existing = 0;
3028 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3030 SessionDirectory sdir((*i).path);
3032 spath = sdir.sound_path().to_string();
3036 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3037 } else if (nchan == 2) {
3039 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3041 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3043 } else if (nchan < 26) {
3044 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3046 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3055 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3056 } else if (nchan == 2) {
3058 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3060 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3062 } else if (nchan < 26) {
3063 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3065 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3069 if (sys::exists(buf)) {
3075 if (existing == 0) {
3080 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3082 throw failed_constructor();
3086 /* we now have a unique name for the file, but figure out where to
3092 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3094 spath = sdir.sound_path().to_string();
3097 string::size_type pos = foo.find_last_of ('/');
3099 if (pos == string::npos) {
3102 spath += foo.substr (pos + 1);
3108 boost::shared_ptr<AudioFileSource>
3109 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3111 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3112 return boost::dynamic_pointer_cast<AudioFileSource> (
3113 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3116 // FIXME: _terrible_ code duplication
3118 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3121 string old_basename = PBD::basename_nosuffix (oldname);
3122 string new_legalized = legalize_for_path (newname);
3124 /* note: we know (or assume) the old path is already valid */
3128 /* destructive file sources have a name of the form:
3130 /path/to/Tnnnn-NAME(%[LR])?.wav
3132 the task here is to replace NAME with the new name.
3135 /* find last slash */
3139 string::size_type slash;
3140 string::size_type dash;
3142 if ((slash = path.find_last_of ('/')) == string::npos) {
3146 dir = path.substr (0, slash+1);
3148 /* '-' is not a legal character for the NAME part of the path */
3150 if ((dash = path.find_last_of ('-')) == string::npos) {
3154 prefix = path.substr (slash+1, dash-(slash+1));
3159 path += new_legalized;
3160 path += ".mid"; /* XXX gag me with a spoon */
3164 /* non-destructive file sources have a name of the form:
3166 /path/to/NAME-nnnnn(%[LR])?.wav
3168 the task here is to replace NAME with the new name.
3173 string::size_type slash;
3174 string::size_type dash;
3175 string::size_type postfix;
3177 /* find last slash */
3179 if ((slash = path.find_last_of ('/')) == string::npos) {
3183 dir = path.substr (0, slash+1);
3185 /* '-' is not a legal character for the NAME part of the path */
3187 if ((dash = path.find_last_of ('-')) == string::npos) {
3191 suffix = path.substr (dash+1);
3193 // Suffix is now everything after the dash. Now we need to eliminate
3194 // the nnnnn part, which is done by either finding a '%' or a '.'
3196 postfix = suffix.find_last_of ("%");
3197 if (postfix == string::npos) {
3198 postfix = suffix.find_last_of ('.');
3201 if (postfix != string::npos) {
3202 suffix = suffix.substr (postfix);
3204 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3208 const uint32_t limit = 10000;
3209 char buf[PATH_MAX+1];
3211 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3213 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3215 if (access (buf, F_OK) != 0) {
3223 error << "FATAL ERROR! Could not find a " << endl;
3232 Session::midi_path_from_name (string name)
3236 char buf[PATH_MAX+1];
3237 const uint32_t limit = 10000;
3241 legalized = legalize_for_path (name);
3243 /* find a "version" of the file name that doesn't exist in
3244 any of the possible directories.
3247 for (cnt = 1; cnt <= limit; ++cnt) {
3249 vector<space_and_path>::iterator i;
3250 uint32_t existing = 0;
3252 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3254 SessionDirectory sdir((*i).path);
3256 sys::path p = sdir.midi_path();
3260 spath = p.to_string();
3262 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3264 if (sys::exists (buf)) {
3269 if (existing == 0) {
3274 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3275 throw failed_constructor();
3279 /* we now have a unique name for the file, but figure out where to
3285 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3287 spath = sdir.midi_path().to_string();
3290 string::size_type pos = foo.find_last_of ('/');
3292 if (pos == string::npos) {
3295 spath += foo.substr (pos + 1);
3301 boost::shared_ptr<MidiSource>
3302 Session::create_midi_source_for_session (MidiDiskstream& ds)
3304 string mpath = midi_path_from_name (ds.name());
3306 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3310 /* Playlist management */
3312 boost::shared_ptr<Playlist>
3313 Session::playlist_by_name (string name)
3315 Glib::Mutex::Lock lm (playlist_lock);
3316 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3317 if ((*i)->name() == name) {
3321 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3322 if ((*i)->name() == name) {
3327 return boost::shared_ptr<Playlist>();
3331 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3333 if (playlist->hidden()) {
3338 Glib::Mutex::Lock lm (playlist_lock);
3339 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3340 playlists.insert (playlists.begin(), playlist);
3341 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3342 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3348 PlaylistAdded (playlist); /* EMIT SIGNAL */
3352 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3355 Glib::Mutex::Lock lm (playlist_lock);
3356 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3359 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3366 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3368 boost::shared_ptr<Playlist> pl(wpl.lock());
3374 PlaylistList::iterator x;
3377 /* its not supposed to be visible */
3382 Glib::Mutex::Lock lm (playlist_lock);
3386 unused_playlists.insert (pl);
3388 if ((x = playlists.find (pl)) != playlists.end()) {
3389 playlists.erase (x);
3395 playlists.insert (pl);
3397 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3398 unused_playlists.erase (x);
3405 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3407 if (_state_of_the_state & Deletion) {
3411 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3418 Glib::Mutex::Lock lm (playlist_lock);
3420 PlaylistList::iterator i;
3422 i = find (playlists.begin(), playlists.end(), playlist);
3423 if (i != playlists.end()) {
3424 playlists.erase (i);
3427 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3428 if (i != unused_playlists.end()) {
3429 unused_playlists.erase (i);
3436 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3440 Session::set_audition (boost::shared_ptr<Region> r)
3442 pending_audition_region = r;
3443 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3444 schedule_butler_transport_work ();
3448 Session::audition_playlist ()
3450 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3451 ev->region.reset ();
3456 Session::non_realtime_set_audition ()
3458 if (!pending_audition_region) {
3459 auditioner->audition_current_playlist ();
3461 auditioner->audition_region (pending_audition_region);
3462 pending_audition_region.reset ();
3464 AuditionActive (true); /* EMIT SIGNAL */
3468 Session::audition_region (boost::shared_ptr<Region> r)
3470 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3476 Session::cancel_audition ()
3478 if (auditioner->active()) {
3479 auditioner->cancel_audition ();
3480 AuditionActive (false); /* EMIT SIGNAL */
3485 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3487 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3491 Session::remove_empty_sounds ()
3493 vector<string> audio_filenames;
3495 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3497 Glib::Mutex::Lock lm (source_lock);
3499 TapeFileMatcher tape_file_matcher;
3501 remove_if (audio_filenames.begin(), audio_filenames.end(),
3502 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3504 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3506 sys::path audio_file_path (_session_dir->sound_path());
3508 audio_file_path /= *i;
3510 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3514 sys::remove (audio_file_path);
3515 const string peakfile = peak_path (audio_file_path.to_string());
3516 sys::remove (peakfile);
3518 catch (const sys::filesystem_error& err)
3520 error << err.what() << endmsg;
3527 Session::is_auditioning () const
3529 /* can be called before we have an auditioner object */
3531 return auditioner->active();
3538 Session::set_all_solo (bool yn)
3540 shared_ptr<RouteList> r = routes.reader ();
3542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3543 if (!(*i)->is_hidden()) {
3544 (*i)->set_solo (yn, this);
3552 Session::set_all_mute (bool yn)
3554 shared_ptr<RouteList> r = routes.reader ();
3556 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3557 if (!(*i)->is_hidden()) {
3558 (*i)->set_mute (yn, this);
3566 Session::n_diskstreams () const
3570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3572 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3573 if (!(*i)->hidden()) {
3581 Session::graph_reordered ()
3583 /* don't do this stuff if we are setting up connections
3584 from a set_state() call or creating new tracks.
3587 if (_state_of_the_state & InitialConnecting) {
3591 /* every track/bus asked for this to be handled but it was deferred because
3592 we were connecting. do it now.
3595 request_input_change_handling ();
3599 /* force all diskstreams to update their capture offset values to
3600 reflect any changes in latencies within the graph.
3603 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3605 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3606 (*i)->set_capture_offset ();
3611 Session::record_disenable_all ()
3613 record_enable_change_all (false);
3617 Session::record_enable_all ()
3619 record_enable_change_all (true);
3623 Session::record_enable_change_all (bool yn)
3625 shared_ptr<RouteList> r = routes.reader ();
3627 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3630 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3631 at->set_record_enable (yn, this);
3635 /* since we don't keep rec-enable state, don't mark session dirty */
3639 Session::add_processor (Processor* processor)
3642 PortInsert* port_insert;
3643 PluginInsert* plugin_insert;
3645 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3646 _port_inserts.insert (_port_inserts.begin(), port_insert);
3647 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3648 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3649 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3650 _sends.insert (_sends.begin(), send);
3652 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3656 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3662 Session::remove_processor (Processor* processor)
3665 PortInsert* port_insert;
3666 PluginInsert* plugin_insert;
3668 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3669 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3670 if (x != _port_inserts.end()) {
3671 insert_bitset[port_insert->bit_slot()] = false;
3672 _port_inserts.erase (x);
3674 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3675 _plugin_inserts.remove (plugin_insert);
3676 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3677 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3678 if (x != _sends.end()) {
3679 send_bitset[send->bit_slot()] = false;
3683 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3691 Session::available_capture_duration ()
3693 float sample_bytes_on_disk = 4.0; // keep gcc happy
3695 switch (Config->get_native_file_data_format()) {
3697 sample_bytes_on_disk = 4.0;
3701 sample_bytes_on_disk = 3.0;
3705 sample_bytes_on_disk = 2.0;
3709 /* impossible, but keep some gcc versions happy */
3710 fatal << string_compose (_("programming error: %1"),
3711 X_("illegal native file data format"))
3716 double scale = 4096.0 / sample_bytes_on_disk;
3718 if (_total_free_4k_blocks * scale > (double) max_frames) {
3722 return (nframes_t) floor (_total_free_4k_blocks * scale);
3726 Session::add_bundle (shared_ptr<Bundle> bundle)
3729 Glib::Mutex::Lock guard (bundle_lock);
3730 _bundles.push_back (bundle);
3733 BundleAdded (bundle); /* EMIT SIGNAL */
3739 Session::remove_bundle (shared_ptr<Bundle> bundle)
3741 bool removed = false;
3744 Glib::Mutex::Lock guard (bundle_lock);
3745 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3747 if (i != _bundles.end()) {
3754 BundleRemoved (bundle); /* EMIT SIGNAL */
3761 Session::bundle_by_name (string name) const
3763 Glib::Mutex::Lock lm (bundle_lock);
3765 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3766 if ((*i)->name() == name) {
3771 return boost::shared_ptr<Bundle> ();
3775 Session::tempo_map_changed (Change ignored)
3779 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3780 (*i)->update_after_tempo_map_change ();
3783 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3784 (*i)->update_after_tempo_map_change ();
3790 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3791 * the given count with the current block size.
3794 Session::ensure_buffers (ChanCount howmany)
3796 if (current_block_size == 0)
3797 return; // too early? (is this ok?)
3799 // We need at least 2 MIDI scratch buffers to mix/merge
3800 if (howmany.n_midi() < 2)
3801 howmany.set_midi(2);
3803 // FIXME: JACK needs to tell us maximum MIDI buffer size
3804 // Using nasty assumption (max # events == nframes) for now
3805 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3806 _mix_buffers->ensure_buffers(howmany, current_block_size);
3807 _silent_buffers->ensure_buffers(howmany, current_block_size);
3809 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3813 Session::next_insert_id ()
3815 /* this doesn't really loop forever. just think about it */
3818 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3819 if (!insert_bitset[n]) {
3820 insert_bitset[n] = true;
3826 /* none available, so resize and try again */
3828 insert_bitset.resize (insert_bitset.size() + 16, false);
3833 Session::next_send_id ()
3835 /* this doesn't really loop forever. just think about it */
3838 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3839 if (!send_bitset[n]) {
3840 send_bitset[n] = true;
3846 /* none available, so resize and try again */
3848 send_bitset.resize (send_bitset.size() + 16, false);
3853 Session::mark_send_id (uint32_t id)
3855 if (id >= send_bitset.size()) {
3856 send_bitset.resize (id+16, false);
3858 if (send_bitset[id]) {
3859 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3861 send_bitset[id] = true;
3865 Session::mark_insert_id (uint32_t id)
3867 if (id >= insert_bitset.size()) {
3868 insert_bitset.resize (id+16, false);
3870 if (insert_bitset[id]) {
3871 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3873 insert_bitset[id] = true;
3876 /* Named Selection management */
3879 Session::named_selection_by_name (string name)
3881 Glib::Mutex::Lock lm (named_selection_lock);
3882 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3883 if ((*i)->name == name) {
3891 Session::add_named_selection (NamedSelection* named_selection)
3894 Glib::Mutex::Lock lm (named_selection_lock);
3895 named_selections.insert (named_selections.begin(), named_selection);
3898 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3904 NamedSelectionAdded (); /* EMIT SIGNAL */
3908 Session::remove_named_selection (NamedSelection* named_selection)
3910 bool removed = false;
3913 Glib::Mutex::Lock lm (named_selection_lock);
3915 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3917 if (i != named_selections.end()) {
3919 named_selections.erase (i);
3926 NamedSelectionRemoved (); /* EMIT SIGNAL */
3931 Session::reset_native_file_format ()
3933 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3935 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3936 (*i)->reset_write_sources (false);
3941 Session::route_name_unique (string n) const
3943 shared_ptr<RouteList> r = routes.reader ();
3945 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3946 if ((*i)->name() == n) {
3955 Session::n_playlists () const
3957 Glib::Mutex::Lock lm (playlist_lock);
3958 return playlists.size();
3962 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3964 if (!force && howmany <= _npan_buffers) {
3968 if (_pan_automation_buffer) {
3970 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3971 delete [] _pan_automation_buffer[i];
3974 delete [] _pan_automation_buffer;
3977 _pan_automation_buffer = new pan_t*[howmany];
3979 for (uint32_t i = 0; i < howmany; ++i) {
3980 _pan_automation_buffer[i] = new pan_t[nframes];
3983 _npan_buffers = howmany;
3987 Session::freeze (InterThreadInfo& itt)
3989 shared_ptr<RouteList> r = routes.reader ();
3991 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3995 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3996 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4007 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
4008 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4011 boost::shared_ptr<Playlist> playlist;
4012 boost::shared_ptr<AudioFileSource> fsource;
4014 char buf[PATH_MAX+1];
4015 ChanCount nchans(track.audio_diskstream()->n_channels());
4017 nframes_t this_chunk;
4020 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4021 const string sound_dir = sdir.sound_path().to_string();
4023 // any bigger than this seems to cause stack overflows in called functions
4024 const nframes_t chunk_size = (128 * 1024)/4;
4026 g_atomic_int_set (&processing_prohibited, 1);
4028 /* call tree *MUST* hold route_lock */
4030 if ((playlist = track.diskstream()->playlist()) == 0) {
4034 /* external redirects will be a problem */
4036 if (track.has_external_redirects()) {
4040 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4042 for (x = 0; x < 99999; ++x) {
4043 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4044 if (access (buf, F_OK) != 0) {
4050 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4055 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4056 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4059 catch (failed_constructor& err) {
4060 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4064 srcs.push_back (fsource);
4067 /* XXX need to flush all redirects */
4072 /* create a set of reasonably-sized buffers */
4073 buffers.ensure_buffers(nchans, chunk_size);
4074 buffers.set_count(nchans);
4076 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4077 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4079 afs->prepare_for_peakfile_writes ();
4082 while (to_do && !itt.cancel) {
4084 this_chunk = min (to_do, chunk_size);
4086 if (track.export_stuff (buffers, start, this_chunk)) {
4091 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4092 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4095 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4101 start += this_chunk;
4102 to_do -= this_chunk;
4104 itt.progress = (float) (1.0 - ((double) to_do / len));
4113 xnow = localtime (&now);
4115 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4116 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4119 afs->update_header (position, *xnow, now);
4120 afs->flush_header ();
4124 /* construct a region to represent the bounced material */
4126 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4127 region_name_from_path (srcs.front()->name(), true));
4134 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4135 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4138 afs->mark_for_remove ();
4141 (*src)->drop_references ();
4145 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4146 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4149 afs->done_with_peakfile_writes ();
4153 g_atomic_int_set (&processing_prohibited, 0);
4159 Session::get_silent_buffers (ChanCount count)
4161 assert(_silent_buffers->available() >= count);
4162 _silent_buffers->set_count(count);
4164 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4165 for (size_t i=0; i < count.get(*t); ++i) {
4166 _silent_buffers->get(*t, i).clear();
4170 return *_silent_buffers;
4174 Session::get_scratch_buffers (ChanCount count)
4176 assert(_scratch_buffers->available() >= count);
4177 _scratch_buffers->set_count(count);
4178 return *_scratch_buffers;
4182 Session::get_mix_buffers (ChanCount count)
4184 assert(_mix_buffers->available() >= count);
4185 _mix_buffers->set_count(count);
4186 return *_mix_buffers;
4190 Session::ntracks () const
4193 shared_ptr<RouteList> r = routes.reader ();
4195 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4196 if (dynamic_cast<Track*> ((*i).get())) {
4205 Session::nbusses () const
4208 shared_ptr<RouteList> r = routes.reader ();
4210 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4211 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4220 Session::add_automation_list(AutomationList *al)
4222 automation_lists[al->id()] = al;
4226 Session::compute_initial_length ()
4228 return _engine.frame_rate() * 60 * 5;
4232 Session::sync_order_keys ()
4234 if (!Config->get_sync_all_route_ordering()) {
4235 /* leave order keys as they are */
4239 boost::shared_ptr<RouteList> r = routes.reader ();
4241 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4242 (*i)->sync_order_keys ();
4245 Route::SyncOrderKeys (); // EMIT SIGNAL
4249 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4251 Glib::Mutex::Lock lm (bundle_lock);
4252 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {