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 */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
37 #include <glibmm/fileutils.h>
39 #include <pbd/error.h>
40 #include <glibmm/thread.h>
41 #include <pbd/pathscanner.h>
42 #include <pbd/stl_delete.h>
43 #include <pbd/basename.h>
44 #include <pbd/stacktrace.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/analyser.h>
50 #include <ardour/audio_diskstream.h>
51 #include <ardour/utils.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/audiofilesource.h>
55 #include <ardour/auditioner.h>
56 #include <ardour/recent_sessions.h>
57 #include <ardour/redirect.h>
58 #include <ardour/send.h>
59 #include <ardour/insert.h>
60 #include <ardour/connection.h>
61 #include <ardour/slave.h>
62 #include <ardour/tempo.h>
63 #include <ardour/audio_track.h>
64 #include <ardour/cycle_timer.h>
65 #include <ardour/named_selection.h>
66 #include <ardour/crossfade.h>
67 #include <ardour/playlist.h>
68 #include <ardour/click.h>
69 #include <ardour/data_type.h>
70 #include <ardour/source_factory.h>
71 #include <ardour/region_factory.h>
74 #include <ardour/osc.h>
80 using namespace ARDOUR;
82 using boost::shared_ptr;
85 static const int CPU_CACHE_ALIGN = 64;
87 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
90 const char* Session::_template_suffix = X_(".template");
91 const char* Session::_statefile_suffix = X_(".ardour");
92 const char* Session::_pending_suffix = X_(".pending");
93 const char* Session::old_sound_dir_name = X_("sounds");
94 const char* Session::sound_dir_name = X_("audiofiles");
95 const char* Session::peak_dir_name = X_("peaks");
96 const char* Session::dead_sound_dir_name = X_("dead_sounds");
97 const char* Session::interchange_dir_name = X_("interchange");
98 const char* Session::export_dir_name = X_("export");
100 bool Session::_disable_all_loaded_plugins = false;
102 Session::compute_peak_t Session::compute_peak = 0;
103 Session::find_peaks_t Session::find_peaks = 0;
104 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
105 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
106 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
108 sigc::signal<int> Session::AskAboutPendingState;
109 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
110 sigc::signal<void> Session::SendFeedback;
112 sigc::signal<void> Session::SMPTEOffsetChanged;
113 sigc::signal<void> Session::StartTimeChanged;
114 sigc::signal<void> Session::EndTimeChanged;
117 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
120 char buf[PATH_MAX+1];
124 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
125 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
131 /* check to see if it exists, and what it is */
133 if (stat (str.c_str(), &statbuf)) {
134 if (errno == ENOENT) {
137 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
145 /* it exists, so it must either be the name
146 of the directory, or the name of the statefile
150 if (S_ISDIR (statbuf.st_mode)) {
152 string::size_type slash = str.find_last_of ('/');
154 if (slash == string::npos) {
156 /* a subdirectory of cwd, so statefile should be ... */
162 tmp += _statefile_suffix;
166 if (stat (tmp.c_str(), &statbuf)) {
167 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
177 /* some directory someplace in the filesystem.
178 the snapshot name is the directory name
183 snapshot = str.substr (slash+1);
187 } else if (S_ISREG (statbuf.st_mode)) {
189 string::size_type slash = str.find_last_of ('/');
190 string::size_type suffix;
192 /* remove the suffix */
194 if (slash != string::npos) {
195 snapshot = str.substr (slash+1);
200 suffix = snapshot.find (_statefile_suffix);
202 if (suffix == string::npos) {
203 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
209 snapshot = snapshot.substr (0, suffix);
211 if (slash == string::npos) {
213 /* we must be in the directory where the
214 statefile lives. get it using cwd().
217 char cwd[PATH_MAX+1];
219 if (getcwd (cwd, sizeof (cwd)) == 0) {
220 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
229 /* full path to the statefile */
231 path = str.substr (0, slash);
236 /* what type of file is it? */
237 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
243 /* its the name of a new directory. get the name
247 string::size_type slash = str.find_last_of ('/');
249 if (slash == string::npos) {
251 /* no slash, just use the name, but clean it up */
253 path = legalize_for_path (str);
259 snapshot = str.substr (slash+1);
266 Session::Session (AudioEngine &eng,
267 const string& fullpath,
268 const string& snapshot_name,
272 _mmc_port (default_mmc_port),
273 _mtc_port (default_mtc_port),
274 _midi_port (default_midi_port),
275 pending_events (2048),
276 midi_requests (128), // the size of this should match the midi request pool size
277 diskstreams (new DiskstreamList),
278 routes (new RouteList),
279 auditioner ((Auditioner*) 0),
285 if (!eng.connected()) {
286 throw failed_constructor();
289 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
291 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
292 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
294 first_stage_init (fullpath, snapshot_name);
296 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
299 if (create (new_session, mix_template, compute_initial_length())) {
301 throw failed_constructor ();
305 if (second_stage_init (new_session)) {
307 throw failed_constructor ();
310 store_recent_sessions(_name, _path);
312 bool was_dirty = dirty();
314 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
316 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
319 DirtyChanged (); /* EMIT SIGNAL */
323 Session::Session (AudioEngine &eng,
325 string snapshot_name,
326 AutoConnectOption input_ac,
327 AutoConnectOption output_ac,
328 uint32_t control_out_channels,
329 uint32_t master_out_channels,
330 uint32_t requested_physical_in,
331 uint32_t requested_physical_out,
332 nframes_t initial_length)
335 _mmc_port (default_mmc_port),
336 _mtc_port (default_mtc_port),
337 _midi_port (default_midi_port),
338 pending_events (2048),
340 diskstreams (new DiskstreamList),
341 routes (new RouteList),
347 if (!eng.connected()) {
348 throw failed_constructor();
351 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
353 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
354 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
356 if (n_physical_audio_inputs) {
357 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
360 if (n_physical_audio_outputs) {
361 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
364 first_stage_init (fullpath, snapshot_name);
366 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
369 if (create (new_session, string(), initial_length)) {
371 throw failed_constructor ();
376 /* set up Master Out and Control Out if necessary */
381 if (control_out_channels) {
382 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
383 r->set_remote_control_id (control_id++);
388 if (master_out_channels) {
389 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
390 r->set_remote_control_id (control_id);
394 /* prohibit auto-connect to master, because there isn't one */
395 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
399 add_routes (rl, false);
404 Config->set_input_auto_connect (input_ac);
405 Config->set_output_auto_connect (output_ac);
407 if (second_stage_init (new_session)) {
409 throw failed_constructor ();
412 store_recent_sessions (_name, _path);
414 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
417 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
428 /* if we got to here, leaving pending capture state around
432 remove_pending_capture_state ();
434 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
436 _engine.remove_session ();
438 GoingAway (); /* EMIT SIGNAL */
444 /* clear history so that no references to objects are held any more */
448 /* clear state tree so that no references to objects are held any more */
454 terminate_butler_thread ();
455 terminate_midi_thread ();
457 if (click_data && click_data != default_click) {
458 delete [] click_data;
461 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
462 delete [] click_emphasis_data;
467 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
471 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
475 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
479 AudioDiskstream::free_working_buffers();
481 /* this should cause deletion of the auditioner */
483 // auditioner.reset ();
485 #undef TRACK_DESTRUCTION
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete named selections\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
490 NamedSelectionList::iterator tmp;
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete playlists\n";
501 #endif /* TRACK_DESTRUCTION */
502 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
503 PlaylistList::iterator tmp;
508 (*i)->drop_references ();
513 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
514 PlaylistList::iterator tmp;
519 (*i)->drop_references ();
525 unused_playlists.clear ();
527 #ifdef TRACK_DESTRUCTION
528 cerr << "delete audio regions\n";
529 #endif /* TRACK_DESTRUCTION */
531 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
532 AudioRegionList::iterator tmp;
537 i->second->drop_references ();
542 audio_regions.clear ();
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete routes\n";
546 #endif /* TRACK_DESTRUCTION */
548 RCUWriter<RouteList> writer (routes);
549 boost::shared_ptr<RouteList> r = writer.get_copy ();
550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
551 (*i)->drop_references ();
554 /* writer goes out of scope and updates master */
559 #ifdef TRACK_DESTRUCTION
560 cerr << "delete diskstreams\n";
561 #endif /* TRACK_DESTRUCTION */
563 RCUWriter<DiskstreamList> dwriter (diskstreams);
564 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
565 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
566 (*i)->drop_references ();
570 diskstreams.flush ();
572 #ifdef TRACK_DESTRUCTION
573 cerr << "delete audio sources\n";
574 #endif /* TRACK_DESTRUCTION */
575 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
576 AudioSourceList::iterator tmp;
581 i->second->drop_references ();
586 audio_sources.clear ();
588 #ifdef TRACK_DESTRUCTION
589 cerr << "delete mix groups\n";
590 #endif /* TRACK_DESTRUCTION */
591 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
592 list<RouteGroup*>::iterator tmp;
602 #ifdef TRACK_DESTRUCTION
603 cerr << "delete edit groups\n";
604 #endif /* TRACK_DESTRUCTION */
605 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
606 list<RouteGroup*>::iterator tmp;
616 #ifdef TRACK_DESTRUCTION
617 cerr << "delete connections\n";
618 #endif /* TRACK_DESTRUCTION */
619 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
620 ConnectionList::iterator tmp;
630 if (butler_mixdown_buffer) {
631 delete [] butler_mixdown_buffer;
634 if (butler_gain_buffer) {
635 delete [] butler_gain_buffer;
638 Crossfade::set_buffer_size (0);
646 Session::set_worst_io_latencies ()
648 _worst_output_latency = 0;
649 _worst_input_latency = 0;
651 if (!_engine.connected()) {
655 boost::shared_ptr<RouteList> r = routes.reader ();
657 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
658 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
659 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
664 Session::when_engine_running ()
666 string first_physical_output;
668 /* we don't want to run execute this again */
670 BootMessage (_("Set block size and sample rate"));
672 set_block_size (_engine.frames_per_cycle());
673 set_frame_rate (_engine.frame_rate());
675 BootMessage (_("Using configuration"));
677 Config->map_parameters (mem_fun (*this, &Session::config_changed));
679 /* every time we reconnect, recompute worst case output latencies */
681 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
683 if (synced_to_jack()) {
684 _engine.transport_stop ();
687 if (Config->get_jack_time_master()) {
688 _engine.transport_locate (_transport_frame);
696 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
698 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
700 /* existing state for Click */
702 if (_click_io->set_state (*child->children().front()) == 0) {
704 _clicking = Config->get_clicking ();
708 error << _("could not setup Click I/O") << endmsg;
714 /* default state for Click */
716 first_physical_output = _engine.get_nth_physical_audio_output (0);
718 if (first_physical_output.length()) {
719 if (_click_io->add_output_port (first_physical_output, this)) {
720 // relax, even though its an error
722 _clicking = Config->get_clicking ();
728 catch (failed_constructor& err) {
729 error << _("cannot setup Click I/O") << endmsg;
732 BootMessage (_("Compute I/O Latencies"));
734 set_worst_io_latencies ();
737 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
740 /* Create a set of Connection objects that map
741 to the physical outputs currently available
744 BootMessage (_("Set up standard connections"));
748 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
750 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
752 Connection* c = new OutputConnection (buf, true);
755 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
760 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
762 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
764 Connection* c = new InputConnection (buf, true);
767 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
774 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
776 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
778 Connection* c = new OutputConnection (buf, true);
782 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
783 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
788 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
790 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
792 Connection* c = new InputConnection (buf, true);
796 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
797 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
806 /* create master/control ports */
811 /* force the master to ignore any later call to this */
813 if (_master_out->pending_state_node) {
814 _master_out->ports_became_legal();
817 /* no panner resets till we are through */
819 _master_out->defer_pan_reset ();
821 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
822 if (_master_out->add_input_port ("", this)) {
823 error << _("cannot setup master inputs")
829 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
830 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
831 error << _("cannot setup master outputs")
838 _master_out->allow_pan_reset ();
842 Connection* c = new OutputConnection (_("Master Out"), true);
844 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
846 c->add_connection ((int) n, _master_out->input(n)->name());
851 BootMessage (_("Connect ports"));
855 /* catch up on send+insert cnts */
857 BootMessage (_("Catch up with send/insert state"));
861 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
864 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
865 if (id > insert_cnt) {
873 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
876 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
884 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
886 /* hook us up to the engine */
888 BootMessage (_("Connect to engine"));
890 _engine.set_session (this);
895 BootMessage (_("OSC startup"));
897 osc->set_session (*this);
903 Session::hookup_io ()
905 /* stop graph reordering notifications from
906 causing resorts, etc.
909 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
912 if (auditioner == 0) {
914 /* we delay creating the auditioner till now because
915 it makes its own connections to ports.
916 the engine has to be running for this to work.
920 auditioner.reset (new Auditioner (*this));
923 catch (failed_constructor& err) {
924 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
928 /* Tell all IO objects to create their ports */
934 vector<string> cports;
936 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
937 if (_control_out->add_input_port ("", this)) {
938 error << _("cannot setup control inputs")
944 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
945 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
946 error << _("cannot set up master outputs")
954 uint32_t ni = _control_out->n_inputs();
956 for (n = 0; n < ni; ++n) {
957 cports.push_back (_control_out->input(n)->name());
960 boost::shared_ptr<RouteList> r = routes.reader ();
962 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
963 (*x)->set_control_outs (cports);
967 /* Tell all IO objects to connect themselves together */
969 IO::enable_connecting ();
971 /* Now reset all panners */
973 IO::reset_panners ();
975 /* Anyone who cares about input state, wake up and do something */
977 IOConnectionsComplete (); /* EMIT SIGNAL */
979 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
982 /* now handle the whole enchilada as if it was one
988 /* update mixer solo state */
994 Session::playlist_length_changed ()
996 /* we can't just increase end_location->end() if pl->get_maximum_extent()
997 if larger. if the playlist used to be the longest playlist,
998 and its now shorter, we have to decrease end_location->end(). hence,
999 we have to iterate over all diskstreams and check the
1000 playlists currently in use.
1002 find_current_end ();
1006 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1008 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1015 boost::shared_ptr<Playlist> playlist;
1017 if ((playlist = dstream->playlist()) != 0) {
1018 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1021 /* see comment in playlist_length_changed () */
1022 find_current_end ();
1026 Session::record_enabling_legal () const
1028 /* this used to be in here, but survey says.... we don't need to restrict it */
1029 // if (record_status() == Recording) {
1033 if (Config->get_all_safe()) {
1040 Session::reset_input_monitor_state ()
1042 if (transport_rolling()) {
1044 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1046 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1047 if ((*i)->record_enabled ()) {
1048 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1049 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1053 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1055 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1056 if ((*i)->record_enabled ()) {
1057 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1058 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1065 Session::auto_punch_start_changed (Location* location)
1067 replace_event (Event::PunchIn, location->start());
1069 if (get_record_enabled() && Config->get_punch_in()) {
1070 /* capture start has been changed, so save new pending state */
1071 save_state ("", true);
1076 Session::auto_punch_end_changed (Location* location)
1078 nframes_t when_to_stop = location->end();
1079 // when_to_stop += _worst_output_latency + _worst_input_latency;
1080 replace_event (Event::PunchOut, when_to_stop);
1084 Session::auto_punch_changed (Location* location)
1086 nframes_t when_to_stop = location->end();
1088 replace_event (Event::PunchIn, location->start());
1089 //when_to_stop += _worst_output_latency + _worst_input_latency;
1090 replace_event (Event::PunchOut, when_to_stop);
1094 Session::auto_loop_changed (Location* location)
1096 replace_event (Event::AutoLoop, location->end(), location->start());
1098 if (transport_rolling() && play_loop) {
1100 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1102 if (_transport_frame > location->end()) {
1103 // relocate to beginning of loop
1104 clear_events (Event::LocateRoll);
1106 request_locate (location->start(), true);
1109 else if (Config->get_seamless_loop() && !loop_changing) {
1111 // schedule a locate-roll to refill the diskstreams at the
1112 // previous loop end
1113 loop_changing = true;
1115 if (location->end() > last_loopend) {
1116 clear_events (Event::LocateRoll);
1117 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1124 last_loopend = location->end();
1129 Session::set_auto_punch_location (Location* location)
1133 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1134 auto_punch_start_changed_connection.disconnect();
1135 auto_punch_end_changed_connection.disconnect();
1136 auto_punch_changed_connection.disconnect();
1137 existing->set_auto_punch (false, this);
1138 remove_event (existing->start(), Event::PunchIn);
1139 clear_events (Event::PunchOut);
1140 auto_punch_location_changed (0);
1145 if (location == 0) {
1149 if (location->end() <= location->start()) {
1150 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1154 auto_punch_start_changed_connection.disconnect();
1155 auto_punch_end_changed_connection.disconnect();
1156 auto_punch_changed_connection.disconnect();
1158 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1159 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1160 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1162 location->set_auto_punch (true, this);
1163 auto_punch_location_changed (location);
1167 Session::set_auto_loop_location (Location* location)
1171 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1172 auto_loop_start_changed_connection.disconnect();
1173 auto_loop_end_changed_connection.disconnect();
1174 auto_loop_changed_connection.disconnect();
1175 existing->set_auto_loop (false, this);
1176 remove_event (existing->end(), Event::AutoLoop);
1177 auto_loop_location_changed (0);
1182 if (location == 0) {
1186 if (location->end() <= location->start()) {
1187 error << _("Session: you can't use a mark for auto loop") << endmsg;
1191 last_loopend = location->end();
1193 auto_loop_start_changed_connection.disconnect();
1194 auto_loop_end_changed_connection.disconnect();
1195 auto_loop_changed_connection.disconnect();
1197 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1198 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1199 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1201 location->set_auto_loop (true, this);
1202 auto_loop_location_changed (location);
1206 Session::locations_added (Location* ignored)
1212 Session::locations_changed ()
1214 _locations.apply (*this, &Session::handle_locations_changed);
1218 Session::handle_locations_changed (Locations::LocationList& locations)
1220 Locations::LocationList::iterator i;
1222 bool set_loop = false;
1223 bool set_punch = false;
1225 for (i = locations.begin(); i != locations.end(); ++i) {
1229 if (location->is_auto_punch()) {
1230 set_auto_punch_location (location);
1233 if (location->is_auto_loop()) {
1234 set_auto_loop_location (location);
1241 set_auto_loop_location (0);
1244 set_auto_punch_location (0);
1251 Session::enable_record ()
1253 /* XXX really atomic compare+swap here */
1254 if (g_atomic_int_get (&_record_status) != Recording) {
1255 g_atomic_int_set (&_record_status, Recording);
1256 _last_record_location = _transport_frame;
1257 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1259 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1260 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1261 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1262 if ((*i)->record_enabled ()) {
1263 (*i)->monitor_input (true);
1268 RecordStateChanged ();
1273 Session::disable_record (bool rt_context, bool force)
1277 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1279 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1280 g_atomic_int_set (&_record_status, Disabled);
1282 if (rs == Recording) {
1283 g_atomic_int_set (&_record_status, Enabled);
1287 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1289 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1290 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1292 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1293 if ((*i)->record_enabled ()) {
1294 (*i)->monitor_input (false);
1299 RecordStateChanged (); /* emit signal */
1302 remove_pending_capture_state ();
1308 Session::step_back_from_record ()
1310 /* XXX really atomic compare+swap here */
1311 if (g_atomic_int_get (&_record_status) == Recording) {
1312 g_atomic_int_set (&_record_status, Enabled);
1314 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1315 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1317 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1318 if ((*i)->record_enabled ()) {
1319 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1320 (*i)->monitor_input (false);
1328 Session::maybe_enable_record ()
1330 g_atomic_int_set (&_record_status, Enabled);
1332 /* this function is currently called from somewhere other than an RT thread.
1333 this save_state() call therefore doesn't impact anything.
1336 save_state ("", true);
1338 if (_transport_speed) {
1339 if (!Config->get_punch_in()) {
1343 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1344 RecordStateChanged (); /* EMIT SIGNAL */
1351 Session::audible_frame () const
1357 /* the first of these two possible settings for "offset"
1358 mean that the audible frame is stationary until
1359 audio emerges from the latency compensation
1362 the second means that the audible frame is stationary
1363 until audio would emerge from a physical port
1364 in the absence of any plugin latency compensation
1367 offset = _worst_output_latency;
1369 if (offset > current_block_size) {
1370 offset -= current_block_size;
1372 /* XXX is this correct? if we have no external
1373 physical connections and everything is internal
1374 then surely this is zero? still, how
1375 likely is that anyway?
1377 offset = current_block_size;
1380 if (synced_to_jack()) {
1381 tf = _engine.transport_frame();
1383 tf = _transport_frame;
1386 if (_transport_speed == 0) {
1396 if (!non_realtime_work_pending()) {
1400 /* take latency into account */
1409 Session::set_frame_rate (nframes_t frames_per_second)
1411 /** \fn void Session::set_frame_size(nframes_t)
1412 the AudioEngine object that calls this guarantees
1413 that it will not be called while we are also in
1414 ::process(). Its fine to do things that block
1418 _base_frame_rate = frames_per_second;
1422 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1426 // XXX we need some equivalent to this, somehow
1427 // SndFileSource::setup_standard_crossfades (frames_per_second);
1431 /* XXX need to reset/reinstantiate all LADSPA plugins */
1435 Session::set_block_size (nframes_t nframes)
1437 /* the AudioEngine guarantees
1438 that it will not be called while we are also in
1439 ::process(). It is therefore fine to do things that block
1444 vector<Sample*>::iterator i;
1447 current_block_size = nframes;
1449 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1453 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1457 _passthru_buffers.clear ();
1458 _silent_buffers.clear ();
1460 ensure_passthru_buffers (np);
1462 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1466 #ifdef NO_POSIX_MEMALIGN
1467 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1469 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1473 memset (*i, 0, sizeof (Sample) * current_block_size);
1477 if (_gain_automation_buffer) {
1478 delete [] _gain_automation_buffer;
1480 _gain_automation_buffer = new gain_t[nframes];
1482 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1484 boost::shared_ptr<RouteList> r = routes.reader ();
1486 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1487 (*i)->set_block_size (nframes);
1490 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1491 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1492 (*i)->set_block_size (nframes);
1495 set_worst_io_latencies ();
1500 Session::set_default_fade (float steepness, float fade_msecs)
1503 nframes_t fade_frames;
1505 /* Don't allow fade of less 1 frame */
1507 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1514 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1518 default_fade_msecs = fade_msecs;
1519 default_fade_steepness = steepness;
1522 // jlc, WTF is this!
1523 Glib::RWLock::ReaderLock lm (route_lock);
1524 AudioRegion::set_default_fade (steepness, fade_frames);
1529 /* XXX have to do this at some point */
1530 /* foreach region using default fade, reset, then
1531 refill_all_diskstream_buffers ();
1536 struct RouteSorter {
1537 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1538 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1540 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1543 if (r1->fed_by.empty()) {
1544 if (r2->fed_by.empty()) {
1545 /* no ardour-based connections inbound to either route. just use signal order */
1546 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1548 /* r2 has connections, r1 does not; run r1 early */
1552 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1559 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1561 shared_ptr<Route> r2;
1563 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1564 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1568 /* make a copy of the existing list of routes that feed r1 */
1570 set<shared_ptr<Route> > existing = r1->fed_by;
1572 /* for each route that feeds r1, recurse, marking it as feeding
1576 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1579 /* r2 is a route that feeds r1 which somehow feeds base. mark
1580 base as being fed by r2
1583 rbase->fed_by.insert (r2);
1587 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1591 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1595 /* now recurse, so that we can mark base as being fed by
1596 all routes that feed r2
1599 trace_terminal (r2, rbase);
1606 Session::resort_routes ()
1608 /* don't do anything here with signals emitted
1609 by Routes while we are being destroyed.
1612 if (_state_of_the_state & Deletion) {
1619 RCUWriter<RouteList> writer (routes);
1620 shared_ptr<RouteList> r = writer.get_copy ();
1621 resort_routes_using (r);
1622 /* writer goes out of scope and forces update */
1627 Session::resort_routes_using (shared_ptr<RouteList> r)
1629 RouteList::iterator i, j;
1631 for (i = r->begin(); i != r->end(); ++i) {
1633 (*i)->fed_by.clear ();
1635 for (j = r->begin(); j != r->end(); ++j) {
1637 /* although routes can feed themselves, it will
1638 cause an endless recursive descent if we
1639 detect it. so don't bother checking for
1647 if ((*j)->feeds (*i)) {
1648 (*i)->fed_by.insert (*j);
1653 for (i = r->begin(); i != r->end(); ++i) {
1654 trace_terminal (*i, *i);
1660 /* don't leave dangling references to routes in Route::fed_by */
1662 for (i = r->begin(); i != r->end(); ++i) {
1663 (*i)->fed_by.clear ();
1667 cerr << "finished route resort\n";
1669 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1670 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1677 list<boost::shared_ptr<AudioTrack> >
1678 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1680 char track_name[32];
1681 uint32_t track_id = 0;
1683 uint32_t channels_used = 0;
1685 RouteList new_routes;
1686 list<boost::shared_ptr<AudioTrack> > ret;
1687 uint32_t control_id;
1689 /* count existing audio tracks */
1692 shared_ptr<RouteList> r = routes.reader ();
1694 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1695 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1696 if (!(*i)->hidden()) {
1698 channels_used += (*i)->n_inputs();
1704 vector<string> physinputs;
1705 vector<string> physoutputs;
1706 uint32_t nphysical_in;
1707 uint32_t nphysical_out;
1709 _engine.get_physical_audio_outputs (physoutputs);
1710 _engine.get_physical_audio_inputs (physinputs);
1711 control_id = ntracks() + nbusses() + 1;
1715 /* check for duplicate route names, since we might have pre-existing
1716 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1717 save, close,restart,add new route - first named route is now
1725 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1727 if (route_by_name (track_name) == 0) {
1731 } while (track_id < (UINT_MAX-1));
1733 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1734 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1739 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1740 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1745 shared_ptr<AudioTrack> track;
1748 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1750 if (track->ensure_io (input_channels, output_channels, false, this)) {
1751 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1752 input_channels, output_channels)
1758 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1762 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1763 port = physinputs[(channels_used+x)%nphysical_in];
1766 if (port.length() && track->connect_input (track->input (x), port, this)) {
1772 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1776 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1777 port = physoutputs[(channels_used+x)%nphysical_out];
1778 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1780 port = _master_out->input (x%_master_out->n_inputs())->name();
1784 if (port.length() && track->connect_output (track->output (x), port, this)) {
1789 channels_used += track->n_inputs ();
1791 track->audio_diskstream()->non_realtime_input_change();
1793 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1794 track->set_remote_control_id (control_id);
1797 new_routes.push_back (track);
1798 ret.push_back (track);
1802 catch (failed_constructor &err) {
1803 error << _("Session: could not create new audio track.") << endmsg;
1806 /* we need to get rid of this, since the track failed to be created */
1807 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1810 RCUWriter<DiskstreamList> writer (diskstreams);
1811 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1812 ds->remove (track->audio_diskstream());
1819 catch (AudioEngine::PortRegistrationFailure& pfe) {
1821 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;
1824 /* we need to get rid of this, since the track failed to be created */
1825 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1828 RCUWriter<DiskstreamList> writer (diskstreams);
1829 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1830 ds->remove (track->audio_diskstream());
1841 if (!new_routes.empty()) {
1842 add_routes (new_routes, true);
1849 Session::set_remote_control_ids ()
1851 RemoteModel m = Config->get_remote_model();
1853 shared_ptr<RouteList> r = routes.reader ();
1855 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1856 if ( MixerOrdered == m) {
1857 long order = (*i)->order_key(N_("signal"));
1858 (*i)->set_remote_control_id( order+1 );
1859 } else if ( EditorOrdered == m) {
1860 long order = (*i)->order_key(N_("editor"));
1861 (*i)->set_remote_control_id( order+1 );
1862 } else if ( UserOrdered == m) {
1863 //do nothing ... only changes to remote id's are initiated by user
1870 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1873 uint32_t bus_id = 1;
1877 uint32_t control_id;
1879 /* count existing audio busses */
1882 shared_ptr<RouteList> r = routes.reader ();
1884 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1885 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1886 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1893 vector<string> physinputs;
1894 vector<string> physoutputs;
1896 _engine.get_physical_audio_outputs (physoutputs);
1897 _engine.get_physical_audio_inputs (physinputs);
1898 control_id = ntracks() + nbusses() + 1;
1903 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1907 if (route_by_name (bus_name) == 0) {
1911 } while (bus_id < (UINT_MAX-1));
1914 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1916 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1917 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1918 input_channels, output_channels)
1923 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1927 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1928 port = physinputs[((n+x)%n_physical_audio_inputs)];
1931 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1936 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1940 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1941 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1942 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1944 port = _master_out->input (x%_master_out->n_inputs())->name();
1948 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
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::add_routes (RouteList& new_routes, bool save)
1987 RCUWriter<RouteList> writer (routes);
1988 shared_ptr<RouteList> r = writer.get_copy ();
1989 r->insert (r->end(), new_routes.begin(), new_routes.end());
1990 resort_routes_using (r);
1993 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1995 boost::weak_ptr<Route> wpr (*x);
1997 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1998 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1999 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2000 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2002 if ((*x)->master()) {
2006 if ((*x)->control()) {
2007 _control_out = (*x);
2011 if (_control_out && IO::connecting_legal) {
2013 vector<string> cports;
2014 uint32_t ni = _control_out->n_inputs();
2017 for (n = 0; n < ni; ++n) {
2018 cports.push_back (_control_out->input(n)->name());
2021 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2022 (*x)->set_control_outs (cports);
2029 save_state (_current_snapshot_name);
2032 RouteAdded (new_routes); /* EMIT SIGNAL */
2036 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2038 /* need to do this in case we're rolling at the time, to prevent false underruns */
2039 dstream->do_refill_with_alloc ();
2041 dstream->set_block_size (current_block_size);
2044 RCUWriter<DiskstreamList> writer (diskstreams);
2045 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2046 ds->push_back (dstream);
2047 /* writer goes out of scope, copies ds back to main */
2050 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2051 boost::weak_ptr<Diskstream> (dstream)));
2052 /* this will connect to future changes, and check the current length */
2053 diskstream_playlist_changed (dstream);
2055 dstream->prepare ();
2059 Session::remove_route (shared_ptr<Route> route)
2062 RCUWriter<RouteList> writer (routes);
2063 shared_ptr<RouteList> rs = writer.get_copy ();
2067 /* deleting the master out seems like a dumb
2068 idea, but its more of a UI policy issue
2072 if (route == _master_out) {
2073 _master_out = shared_ptr<Route> ();
2076 if (route == _control_out) {
2077 _control_out = shared_ptr<Route> ();
2079 /* cancel control outs for all routes */
2081 vector<string> empty;
2083 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2084 (*r)->set_control_outs (empty);
2088 update_route_solo_state ();
2090 /* writer goes out of scope, forces route list update */
2093 // FIXME: audio specific
2095 boost::shared_ptr<AudioDiskstream> ds;
2097 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2098 ds = at->audio_diskstream();
2104 RCUWriter<DiskstreamList> dsl (diskstreams);
2105 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2109 diskstreams.flush ();
2112 find_current_end ();
2114 // We need to disconnect the routes inputs and outputs
2116 route->disconnect_inputs (0);
2117 route->disconnect_outputs (0);
2119 update_latency_compensation (false, false);
2122 /* get rid of it from the dead wood collection in the route list manager */
2124 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2128 /* try to cause everyone to drop their references */
2130 route->drop_references ();
2132 /* save the new state of the world */
2134 if (save_state (_current_snapshot_name)) {
2135 save_history (_current_snapshot_name);
2140 Session::route_mute_changed (void* src)
2146 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2148 if (solo_update_disabled) {
2154 boost::shared_ptr<Route> route = wpr.lock ();
2157 /* should not happen */
2158 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2162 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2164 shared_ptr<RouteList> r = routes.reader ();
2166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2172 /* don't mess with busses */
2174 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2180 /* don't mess with tracks */
2182 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2187 if ((*i) != route &&
2188 ((*i)->mix_group () == 0 ||
2189 (*i)->mix_group () != route->mix_group () ||
2190 !route->mix_group ()->is_active())) {
2192 if ((*i)->soloed()) {
2194 /* if its already soloed, and solo latching is enabled,
2195 then leave it as it is.
2198 if (Config->get_solo_latched()) {
2205 solo_update_disabled = true;
2206 (*i)->set_solo (false, src);
2207 solo_update_disabled = false;
2211 bool something_soloed = false;
2212 bool same_thing_soloed = false;
2213 bool signal = false;
2215 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2216 if ((*i)->soloed()) {
2217 something_soloed = true;
2218 if (dynamic_cast<AudioTrack*>((*i).get())) {
2220 same_thing_soloed = true;
2225 same_thing_soloed = true;
2233 if (something_soloed != currently_soloing) {
2235 currently_soloing = something_soloed;
2238 modify_solo_mute (is_track, same_thing_soloed);
2241 SoloActive (currently_soloing); /* EMIT SIGNAL */
2244 SoloChanged (); /* EMIT SIGNAL */
2250 Session::update_route_solo_state ()
2253 bool is_track = false;
2254 bool signal = false;
2256 /* caller must hold RouteLock */
2258 /* this is where we actually implement solo by changing
2259 the solo mute setting of each track.
2262 shared_ptr<RouteList> r = routes.reader ();
2264 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2265 if ((*i)->soloed()) {
2267 if (dynamic_cast<AudioTrack*>((*i).get())) {
2274 if (mute != currently_soloing) {
2276 currently_soloing = mute;
2279 if (!is_track && !mute) {
2281 /* nothing is soloed */
2283 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2284 (*i)->set_solo_mute (false);
2294 modify_solo_mute (is_track, mute);
2297 SoloActive (currently_soloing);
2302 Session::modify_solo_mute (bool is_track, bool mute)
2304 shared_ptr<RouteList> r = routes.reader ();
2306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2310 /* only alter track solo mute */
2312 if (dynamic_cast<AudioTrack*>((*i).get())) {
2313 if ((*i)->soloed()) {
2314 (*i)->set_solo_mute (!mute);
2316 (*i)->set_solo_mute (mute);
2322 /* only alter bus solo mute */
2324 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2326 if ((*i)->soloed()) {
2328 (*i)->set_solo_mute (false);
2332 /* don't mute master or control outs
2333 in response to another bus solo
2336 if ((*i) != _master_out &&
2337 (*i) != _control_out) {
2338 (*i)->set_solo_mute (mute);
2349 Session::catch_up_on_solo ()
2351 /* this is called after set_state() to catch the full solo
2352 state, which can't be correctly determined on a per-route
2353 basis, but needs the global overview that only the session
2356 update_route_solo_state();
2360 Session::route_by_name (string name)
2362 shared_ptr<RouteList> r = routes.reader ();
2364 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2365 if ((*i)->name() == name) {
2370 return shared_ptr<Route> ((Route*) 0);
2374 Session::route_by_id (PBD::ID id)
2376 shared_ptr<RouteList> r = routes.reader ();
2378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 if ((*i)->id() == id) {
2384 return shared_ptr<Route> ((Route*) 0);
2388 Session::route_by_remote_id (uint32_t id)
2390 shared_ptr<RouteList> r = routes.reader ();
2392 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2393 if ((*i)->remote_control_id() == id) {
2398 return shared_ptr<Route> ((Route*) 0);
2402 Session::find_current_end ()
2404 if (_state_of_the_state & Loading) {
2408 nframes_t max = get_maximum_extent ();
2410 if (max > end_location->end()) {
2411 end_location->set_end (max);
2413 DurationChanged(); /* EMIT SIGNAL */
2418 Session::get_maximum_extent () const
2423 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2425 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2426 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2427 if ((me = pl->get_maximum_extent()) > max) {
2435 boost::shared_ptr<Diskstream>
2436 Session::diskstream_by_name (string name)
2438 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2440 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2441 if ((*i)->name() == name) {
2446 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2449 boost::shared_ptr<Diskstream>
2450 Session::diskstream_by_id (const PBD::ID& id)
2452 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2454 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2455 if ((*i)->id() == id) {
2460 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2463 /* AudioRegion management */
2466 Session::new_region_name (string old)
2468 string::size_type last_period;
2470 string::size_type len = old.length() + 64;
2473 if ((last_period = old.find_last_of ('.')) == string::npos) {
2475 /* no period present - add one explicitly */
2478 last_period = old.length() - 1;
2483 number = atoi (old.substr (last_period+1).c_str());
2487 while (number < (UINT_MAX-1)) {
2489 AudioRegionList::const_iterator i;
2494 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2497 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2498 if (i->second->name() == sbuf) {
2503 if (i == audio_regions.end()) {
2508 if (number != (UINT_MAX-1)) {
2512 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2517 Session::region_name (string& result, string base, bool newlevel) const
2524 Glib::Mutex::Lock lm (region_lock);
2526 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2534 /* XXX this is going to be slow. optimize me later */
2539 string::size_type pos;
2541 pos = base.find_last_of ('.');
2543 /* pos may be npos, but then we just use entire base */
2545 subbase = base.substr (0, pos);
2549 bool name_taken = true;
2552 Glib::Mutex::Lock lm (region_lock);
2554 for (int n = 1; n < 5000; ++n) {
2557 snprintf (buf, sizeof (buf), ".%d", n);
2562 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2563 if (i->second->name() == result) {
2576 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2584 Session::add_region (boost::shared_ptr<Region> region)
2586 vector<boost::shared_ptr<Region> > v;
2587 v.push_back (region);
2592 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2594 boost::shared_ptr<AudioRegion> ar;
2595 boost::shared_ptr<AudioRegion> oar;
2599 Glib::Mutex::Lock lm (region_lock);
2601 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2603 boost::shared_ptr<Region> region = *ii;
2607 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2609 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2611 AudioRegionList::iterator x;
2613 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2615 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2617 if (ar->region_list_equivalent (oar)) {
2622 if (x == audio_regions.end()) {
2624 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2626 entry.first = region->id();
2629 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2641 fatal << _("programming error: ")
2642 << X_("unknown region type passed to Session::add_region()")
2650 /* mark dirty because something has changed even if we didn't
2651 add the region to the region list.
2658 vector<boost::weak_ptr<AudioRegion> > v;
2659 boost::shared_ptr<AudioRegion> first_ar;
2661 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2663 boost::shared_ptr<Region> region = *ii;
2664 boost::shared_ptr<AudioRegion> ar;
2668 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2670 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2678 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2679 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2683 AudioRegionsAdded (v); /* EMIT SIGNAL */
2689 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2691 boost::shared_ptr<Region> region (weak_region.lock ());
2697 if (what_changed & Region::HiddenChanged) {
2698 /* relay hidden changes */
2699 RegionHiddenChange (region);
2704 Session::remove_region (boost::weak_ptr<Region> weak_region)
2706 AudioRegionList::iterator i;
2707 boost::shared_ptr<Region> region (weak_region.lock ());
2713 boost::shared_ptr<AudioRegion> ar;
2714 bool removed = false;
2717 Glib::Mutex::Lock lm (region_lock);
2719 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2720 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2721 audio_regions.erase (i);
2727 fatal << _("programming error: ")
2728 << X_("unknown region type passed to Session::remove_region()")
2734 /* mark dirty because something has changed even if we didn't
2735 remove the region from the region list.
2741 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2745 boost::shared_ptr<AudioRegion>
2746 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2748 AudioRegionList::iterator i;
2749 boost::shared_ptr<AudioRegion> region;
2750 Glib::Mutex::Lock lm (region_lock);
2752 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2756 if (region->whole_file()) {
2758 if (child->source_equivalent (region)) {
2764 return boost::shared_ptr<AudioRegion> ();
2768 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2770 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2771 (*i)->get_region_list_equivalent_regions (region, result);
2775 Session::destroy_region (boost::shared_ptr<Region> region)
2777 vector<boost::shared_ptr<Source> > srcs;
2780 boost::shared_ptr<AudioRegion> aregion;
2782 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2786 if (aregion->playlist()) {
2787 aregion->playlist()->destroy_region (region);
2790 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2791 srcs.push_back (aregion->source (n));
2795 region->drop_references ();
2797 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2799 if (!(*i)->used()) {
2800 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2803 (afs)->mark_for_remove ();
2806 (*i)->drop_references ();
2808 cerr << "source was not used by any playlist\n";
2816 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2818 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2819 destroy_region (*i);
2825 Session::remove_last_capture ()
2827 list<boost::shared_ptr<Region> > r;
2829 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2831 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2832 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2835 r.insert (r.end(), l.begin(), l.end());
2840 destroy_regions (r);
2842 save_state (_current_snapshot_name);
2848 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2854 /* Source Management */
2857 Session::add_source (boost::shared_ptr<Source> source)
2859 boost::shared_ptr<AudioFileSource> afs;
2861 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2863 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2864 pair<AudioSourceList::iterator,bool> result;
2866 entry.first = source->id();
2870 Glib::Mutex::Lock lm (audio_source_lock);
2871 result = audio_sources.insert (entry);
2874 if (result.second) {
2875 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2879 if (Config->get_auto_analyse_audio()) {
2880 Analyser::queue_source_for_analysis (source, false);
2886 Session::remove_source (boost::weak_ptr<Source> src)
2888 AudioSourceList::iterator i;
2889 boost::shared_ptr<Source> source = src.lock();
2896 Glib::Mutex::Lock lm (audio_source_lock);
2898 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2899 audio_sources.erase (i);
2903 if (!_state_of_the_state & InCleanup) {
2905 /* save state so we don't end up with a session file
2906 referring to non-existent sources.
2909 save_state (_current_snapshot_name);
2913 boost::shared_ptr<Source>
2914 Session::source_by_id (const PBD::ID& id)
2916 Glib::Mutex::Lock lm (audio_source_lock);
2917 AudioSourceList::iterator i;
2918 boost::shared_ptr<Source> source;
2920 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2924 /* XXX search MIDI or other searches here */
2930 boost::shared_ptr<Source>
2931 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2933 Glib::Mutex::Lock lm (audio_source_lock);
2935 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2936 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2938 if (afs && afs->path() == path && chn == afs->channel()) {
2943 return boost::shared_ptr<Source>();
2947 Session::peak_path (Glib::ustring base) const
2959 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2962 string old_basename = PBD::basename_nosuffix (oldname);
2963 string new_legalized = legalize_for_path (newname);
2965 /* note: we know (or assume) the old path is already valid */
2969 /* destructive file sources have a name of the form:
2971 /path/to/Tnnnn-NAME(%[LR])?.wav
2973 the task here is to replace NAME with the new name.
2976 /* find last slash */
2980 string::size_type slash;
2981 string::size_type dash;
2983 if ((slash = path.find_last_of ('/')) == string::npos) {
2987 dir = path.substr (0, slash+1);
2989 /* '-' is not a legal character for the NAME part of the path */
2991 if ((dash = path.find_last_of ('-')) == string::npos) {
2995 prefix = path.substr (slash+1, dash-(slash+1));
3000 path += new_legalized;
3001 path += ".wav"; /* XXX gag me with a spoon */
3005 /* non-destructive file sources have a name of the form:
3007 /path/to/NAME-nnnnn(%[LR])?.wav
3009 the task here is to replace NAME with the new name.
3014 string::size_type slash;
3015 string::size_type dash;
3016 string::size_type postfix;
3018 /* find last slash */
3020 if ((slash = path.find_last_of ('/')) == string::npos) {
3024 dir = path.substr (0, slash+1);
3026 /* '-' is not a legal character for the NAME part of the path */
3028 if ((dash = path.find_last_of ('-')) == string::npos) {
3032 suffix = path.substr (dash+1);
3034 // Suffix is now everything after the dash. Now we need to eliminate
3035 // the nnnnn part, which is done by either finding a '%' or a '.'
3037 postfix = suffix.find_last_of ("%");
3038 if (postfix == string::npos) {
3039 postfix = suffix.find_last_of ('.');
3042 if (postfix != string::npos) {
3043 suffix = suffix.substr (postfix);
3045 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3049 const uint32_t limit = 10000;
3050 char buf[PATH_MAX+1];
3052 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3054 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3056 if (access (buf, F_OK) != 0) {
3064 error << "FATAL ERROR! Could not find a " << endl;
3073 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3077 char buf[PATH_MAX+1];
3078 const uint32_t limit = 10000;
3082 legalized = legalize_for_path (name);
3084 /* find a "version" of the file name that doesn't exist in
3085 any of the possible directories.
3088 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3090 vector<space_and_path>::iterator i;
3091 uint32_t existing = 0;
3093 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3097 spath += sound_dir (false);
3101 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3102 } else if (nchan == 2) {
3104 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3106 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3108 } else if (nchan < 26) {
3109 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3111 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3120 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3121 } else if (nchan == 2) {
3123 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3125 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3127 } else if (nchan < 26) {
3128 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3130 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3134 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3140 if (existing == 0) {
3145 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3147 throw failed_constructor();
3151 /* we now have a unique name for the file, but figure out where to
3157 spath = discover_best_sound_dir ();
3160 string::size_type pos = foo.find_last_of ('/');
3162 if (pos == string::npos) {
3165 spath += foo.substr (pos + 1);
3171 boost::shared_ptr<AudioFileSource>
3172 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3174 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3175 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3178 /* Playlist management */
3180 boost::shared_ptr<Playlist>
3181 Session::playlist_by_name (string name)
3183 Glib::Mutex::Lock lm (playlist_lock);
3184 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3185 if ((*i)->name() == name) {
3189 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3190 if ((*i)->name() == name) {
3195 return boost::shared_ptr<Playlist>();
3199 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3201 if (playlist->hidden()) {
3206 Glib::Mutex::Lock lm (playlist_lock);
3207 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3208 playlists.insert (playlists.begin(), playlist);
3209 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3210 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3216 PlaylistAdded (playlist); /* EMIT SIGNAL */
3220 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3223 Glib::Mutex::Lock lm (playlist_lock);
3224 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3227 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3234 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3236 boost::shared_ptr<Playlist> pl(wpl.lock());
3242 PlaylistList::iterator x;
3245 /* its not supposed to be visible */
3250 Glib::Mutex::Lock lm (playlist_lock);
3254 unused_playlists.insert (pl);
3256 if ((x = playlists.find (pl)) != playlists.end()) {
3257 playlists.erase (x);
3263 playlists.insert (pl);
3265 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3266 unused_playlists.erase (x);
3273 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3275 if (_state_of_the_state & Deletion) {
3279 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3286 Glib::Mutex::Lock lm (playlist_lock);
3288 PlaylistList::iterator i;
3290 i = find (playlists.begin(), playlists.end(), playlist);
3291 if (i != playlists.end()) {
3292 playlists.erase (i);
3295 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3296 if (i != unused_playlists.end()) {
3297 unused_playlists.erase (i);
3304 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3308 Session::set_audition (boost::shared_ptr<Region> r)
3310 pending_audition_region = r;
3311 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3312 schedule_butler_transport_work ();
3316 Session::audition_playlist ()
3318 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3319 ev->region.reset ();
3324 Session::non_realtime_set_audition ()
3326 if (!pending_audition_region) {
3327 auditioner->audition_current_playlist ();
3329 auditioner->audition_region (pending_audition_region);
3330 pending_audition_region.reset ();
3332 AuditionActive (true); /* EMIT SIGNAL */
3336 Session::audition_region (boost::shared_ptr<Region> r)
3338 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3344 Session::cancel_audition ()
3346 if (auditioner->active()) {
3347 auditioner->cancel_audition ();
3348 AuditionActive (false); /* EMIT SIGNAL */
3353 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3355 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3359 Session::remove_empty_sounds ()
3361 PathScanner scanner;
3363 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3365 Glib::Mutex::Lock lm (audio_source_lock);
3367 regex_t compiled_tape_track_pattern;
3370 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3374 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3376 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3380 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3382 /* never remove files that appear to be a tape track */
3384 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3389 if (AudioFileSource::is_empty (*this, **i)) {
3391 unlink ((*i)->c_str());
3393 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3394 unlink (peakpath.c_str());
3400 delete possible_audiofiles;
3404 Session::is_auditioning () const
3406 /* can be called before we have an auditioner object */
3408 return auditioner->active();
3415 Session::set_all_solo (bool yn)
3417 shared_ptr<RouteList> r = routes.reader ();
3419 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3420 if (!(*i)->hidden()) {
3421 (*i)->set_solo (yn, this);
3429 Session::set_all_mute (bool yn)
3431 shared_ptr<RouteList> r = routes.reader ();
3433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3434 if (!(*i)->hidden()) {
3435 (*i)->set_mute (yn, this);
3443 Session::n_diskstreams () const
3447 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3449 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3450 if (!(*i)->hidden()) {
3458 Session::graph_reordered ()
3460 /* don't do this stuff if we are setting up connections
3461 from a set_state() call or creating new tracks.
3464 if (_state_of_the_state & InitialConnecting) {
3468 /* every track/bus asked for this to be handled but it was deferred because
3469 we were connecting. do it now.
3472 request_input_change_handling ();
3476 /* force all diskstreams to update their capture offset values to
3477 reflect any changes in latencies within the graph.
3480 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3482 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3483 (*i)->set_capture_offset ();
3488 Session::record_disenable_all ()
3490 record_enable_change_all (false);
3494 Session::record_enable_all ()
3496 record_enable_change_all (true);
3500 Session::record_enable_change_all (bool yn)
3502 shared_ptr<RouteList> r = routes.reader ();
3504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3507 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3508 at->set_record_enable (yn, this);
3512 /* since we don't keep rec-enable state, don't mark session dirty */
3516 Session::add_redirect (Redirect* redirect)
3520 PortInsert* port_insert;
3521 PluginInsert* plugin_insert;
3523 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3524 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3525 _port_inserts.insert (_port_inserts.begin(), port_insert);
3526 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3527 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3529 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3532 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3533 _sends.insert (_sends.begin(), send);
3535 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3539 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3545 Session::remove_redirect (Redirect* redirect)
3549 PortInsert* port_insert;
3550 PluginInsert* plugin_insert;
3552 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3553 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3554 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3555 if (x != _port_inserts.end()) {
3556 insert_bitset[port_insert->bit_slot()] = false;
3557 _port_inserts.erase (x);
3559 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3560 _plugin_inserts.remove (plugin_insert);
3562 fatal << string_compose (_("programming error: %1"),
3563 X_("unknown type of Insert deleted!"))
3567 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3568 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3569 if (x != _sends.end()) {
3570 send_bitset[send->bit_slot()] = false;
3574 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3582 Session::available_capture_duration ()
3584 float sample_bytes_on_disk = 4.0; // keep gcc happy
3586 switch (Config->get_native_file_data_format()) {
3588 sample_bytes_on_disk = 4.0;
3592 sample_bytes_on_disk = 3.0;
3596 sample_bytes_on_disk = 2.0;
3600 /* impossible, but keep some gcc versions happy */
3601 fatal << string_compose (_("programming error: %1"),
3602 X_("illegal native file data format"))
3607 double scale = 4096.0 / sample_bytes_on_disk;
3609 if (_total_free_4k_blocks * scale > (double) max_frames) {
3613 return (nframes_t) floor (_total_free_4k_blocks * scale);
3617 Session::add_connection (ARDOUR::Connection* connection)
3620 Glib::Mutex::Lock guard (connection_lock);
3621 _connections.push_back (connection);
3624 ConnectionAdded (connection); /* EMIT SIGNAL */
3630 Session::remove_connection (ARDOUR::Connection* connection)
3632 bool removed = false;
3635 Glib::Mutex::Lock guard (connection_lock);
3636 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3638 if (i != _connections.end()) {
3639 _connections.erase (i);
3645 ConnectionRemoved (connection); /* EMIT SIGNAL */
3651 ARDOUR::Connection *
3652 Session::connection_by_name (string name) const
3654 Glib::Mutex::Lock lm (connection_lock);
3656 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3657 if ((*i)->name() == name) {
3666 Session::tempo_map_changed (Change ignored)
3670 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3671 (*i)->update_after_tempo_map_change ();
3674 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3675 (*i)->update_after_tempo_map_change ();
3682 Session::ensure_passthru_buffers (uint32_t howmany)
3684 if (current_block_size == 0) {
3688 while (howmany > _passthru_buffers.size()) {
3690 #ifdef NO_POSIX_MEMALIGN
3691 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3693 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3694 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3695 current_block_size, sizeof (Sample), strerror (errno))
3700 _passthru_buffers.push_back (p);
3704 #ifdef NO_POSIX_MEMALIGN
3705 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3707 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4) != 0) {
3708 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3709 current_block_size, sizeof (Sample), strerror (errno))
3714 memset (p, 0, sizeof (Sample) * current_block_size);
3715 _silent_buffers.push_back (p);
3719 #ifdef NO_POSIX_MEMALIGN
3720 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3722 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3724 memset (p, 0, sizeof (Sample) * current_block_size);
3725 _send_buffers.push_back (p);
3728 allocate_pan_automation_buffers (current_block_size, howmany, false);
3732 Session::next_insert_id ()
3734 /* this doesn't really loop forever. just think about it */
3737 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3738 if (!insert_bitset[n]) {
3739 insert_bitset[n] = true;
3745 /* none available, so resize and try again */
3747 insert_bitset.resize (insert_bitset.size() + 16, false);
3752 Session::next_send_id ()
3754 /* this doesn't really loop forever. just think about it */
3757 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3758 if (!send_bitset[n]) {
3759 send_bitset[n] = true;
3765 /* none available, so resize and try again */
3767 send_bitset.resize (send_bitset.size() + 16, false);
3772 Session::mark_send_id (uint32_t id)
3774 if (id >= send_bitset.size()) {
3775 send_bitset.resize (id+16, false);
3777 if (send_bitset[id]) {
3778 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3780 send_bitset[id] = true;
3784 Session::mark_insert_id (uint32_t id)
3786 if (id >= insert_bitset.size()) {
3787 insert_bitset.resize (id+16, false);
3789 if (insert_bitset[id]) {
3790 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3792 insert_bitset[id] = true;
3795 /* Named Selection management */
3798 Session::named_selection_by_name (string name)
3800 Glib::Mutex::Lock lm (named_selection_lock);
3801 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3802 if ((*i)->name == name) {
3810 Session::add_named_selection (NamedSelection* named_selection)
3813 Glib::Mutex::Lock lm (named_selection_lock);
3814 named_selections.insert (named_selections.begin(), named_selection);
3817 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3823 NamedSelectionAdded (); /* EMIT SIGNAL */
3827 Session::remove_named_selection (NamedSelection* named_selection)
3829 bool removed = false;
3832 Glib::Mutex::Lock lm (named_selection_lock);
3834 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3836 if (i != named_selections.end()) {
3838 named_selections.erase (i);
3845 NamedSelectionRemoved (); /* EMIT SIGNAL */
3850 Session::reset_native_file_format ()
3852 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3854 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3855 (*i)->reset_write_sources (false);
3860 Session::route_name_unique (string n) const
3862 shared_ptr<RouteList> r = routes.reader ();
3864 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3865 if ((*i)->name() == n) {
3874 Session::n_playlists () const
3876 Glib::Mutex::Lock lm (playlist_lock);
3877 return playlists.size();
3881 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3883 if (!force && howmany <= _npan_buffers) {
3887 if (_pan_automation_buffer) {
3889 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3890 delete [] _pan_automation_buffer[i];
3893 delete [] _pan_automation_buffer;
3896 _pan_automation_buffer = new pan_t*[howmany];
3898 for (uint32_t i = 0; i < howmany; ++i) {
3899 _pan_automation_buffer[i] = new pan_t[nframes];
3902 _npan_buffers = howmany;
3906 Session::freeze (InterThreadInfo& itt)
3908 shared_ptr<RouteList> r = routes.reader ();
3910 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3914 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3915 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3926 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3927 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3930 boost::shared_ptr<Playlist> playlist;
3931 boost::shared_ptr<AudioFileSource> fsource;
3933 char buf[PATH_MAX+1];
3937 nframes_t this_chunk;
3939 vector<Sample*> buffers;
3941 // any bigger than this seems to cause stack overflows in called functions
3942 const nframes_t chunk_size = (128 * 1024)/4;
3944 g_atomic_int_set (&processing_prohibited, 1);
3946 /* call tree *MUST* hold route_lock */
3948 if ((playlist = track.diskstream()->playlist()) == 0) {
3952 /* external redirects will be a problem */
3954 if (track.has_external_redirects()) {
3958 nchans = track.audio_diskstream()->n_channels();
3960 dir = discover_best_sound_dir ();
3962 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3964 for (x = 0; x < 99999; ++x) {
3965 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3966 if (access (buf, F_OK) != 0) {
3972 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3977 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3980 catch (failed_constructor& err) {
3981 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3985 srcs.push_back (fsource);
3988 /* XXX need to flush all redirects */
3993 /* create a set of reasonably-sized buffers */
3995 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3997 #ifdef NO_POSIX_MEMALIGN
3998 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4000 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4002 buffers.push_back (b);
4005 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4006 (*src)->prepare_for_peakfile_writes ();
4009 while (to_do && !itt.cancel) {
4011 this_chunk = min (to_do, chunk_size);
4013 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
4018 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4019 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4022 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4028 start += this_chunk;
4029 to_do -= this_chunk;
4031 itt.progress = (float) (1.0 - ((double) to_do / len));
4040 xnow = localtime (&now);
4042 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4043 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4046 afs->update_header (position, *xnow, now);
4047 afs->flush_header ();
4051 /* construct a region to represent the bounced material */
4053 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4054 region_name_from_path (srcs.front()->name(), true));
4061 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4062 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4065 afs->mark_for_remove ();
4068 (*src)->drop_references ();
4072 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4073 (*src)->done_with_peakfile_writes ();
4077 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4081 g_atomic_int_set (&processing_prohibited, 0);
4089 Session::get_silent_buffers (uint32_t howmany)
4091 if (howmany > _silent_buffers.size()) {
4093 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4094 howmany, _silent_buffers.size()) << endmsg;
4096 if (howmany > 1000) {
4097 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4101 while (howmany > _silent_buffers.size()) {
4104 #ifdef NO_POSIX_MEMALIGN
4105 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4107 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4) != 0) {
4108 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4109 current_block_size, sizeof (Sample), strerror (errno))
4114 _silent_buffers.push_back (p);
4118 for (uint32_t i = 0; i < howmany; ++i) {
4119 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4122 return _silent_buffers;
4126 Session::ntracks () const
4129 shared_ptr<RouteList> r = routes.reader ();
4131 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4132 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4141 Session::nbusses () const
4144 shared_ptr<RouteList> r = routes.reader ();
4146 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4147 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4156 Session::add_automation_list(AutomationList *al)
4158 automation_lists[al->id()] = al;
4162 Session::compute_initial_length ()
4164 return _engine.frame_rate() * 60 * 5;
4168 Session::sync_order_keys ()
4170 if (!Config->get_sync_all_route_ordering()) {
4171 /* leave order keys as they are */
4175 boost::shared_ptr<RouteList> r = routes.reader ();
4177 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4178 (*i)->sync_order_keys ();
4181 Route::SyncOrderKeys (); // EMIT SIGNAL