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.
26 #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>
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>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/utils.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/destructive_filesource.h>
54 #include <ardour/auditioner.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/redirect.h>
57 #include <ardour/send.h>
58 #include <ardour/insert.h>
59 #include <ardour/connection.h>
60 #include <ardour/slave.h>
61 #include <ardour/tempo.h>
62 #include <ardour/audio_track.h>
63 #include <ardour/cycle_timer.h>
64 #include <ardour/named_selection.h>
65 #include <ardour/crossfade.h>
66 #include <ardour/playlist.h>
67 #include <ardour/click.h>
68 #include <ardour/data_type.h>
69 #include <ardour/source_factory.h>
70 #include <ardour/region_factory.h>
73 #include <ardour/osc.h>
79 using namespace ARDOUR;
81 using boost::shared_ptr;
83 const char* Session::_template_suffix = X_(".template");
84 const char* Session::_statefile_suffix = X_(".ardour");
85 const char* Session::_pending_suffix = X_(".pending");
86 const char* Session::old_sound_dir_name = X_("sounds");
87 const char* Session::sound_dir_name = X_("audiofiles");
88 const char* Session::peak_dir_name = X_("peaks");
89 const char* Session::dead_sound_dir_name = X_("dead_sounds");
90 const char* Session::interchange_dir_name = X_("interchange");
92 Session::compute_peak_t Session::compute_peak = 0;
93 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
94 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
95 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
97 sigc::signal<int> Session::AskAboutPendingState;
98 sigc::signal<void> Session::SendFeedback;
100 sigc::signal<void> Session::SMPTEOffsetChanged;
101 sigc::signal<void> Session::StartTimeChanged;
102 sigc::signal<void> Session::EndTimeChanged;
105 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
108 char buf[PATH_MAX+1];
112 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
113 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
119 /* check to see if it exists, and what it is */
121 if (stat (str.c_str(), &statbuf)) {
122 if (errno == ENOENT) {
125 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
133 /* it exists, so it must either be the name
134 of the directory, or the name of the statefile
138 if (S_ISDIR (statbuf.st_mode)) {
140 string::size_type slash = str.find_last_of ('/');
142 if (slash == string::npos) {
144 /* a subdirectory of cwd, so statefile should be ... */
150 tmp += _statefile_suffix;
154 if (stat (tmp.c_str(), &statbuf)) {
155 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
165 /* some directory someplace in the filesystem.
166 the snapshot name is the directory name
171 snapshot = str.substr (slash+1);
175 } else if (S_ISREG (statbuf.st_mode)) {
177 string::size_type slash = str.find_last_of ('/');
178 string::size_type suffix;
180 /* remove the suffix */
182 if (slash != string::npos) {
183 snapshot = str.substr (slash+1);
188 suffix = snapshot.find (_statefile_suffix);
190 if (suffix == string::npos) {
191 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
197 snapshot = snapshot.substr (0, suffix);
199 if (slash == string::npos) {
201 /* we must be in the directory where the
202 statefile lives. get it using cwd().
205 char cwd[PATH_MAX+1];
207 if (getcwd (cwd, sizeof (cwd)) == 0) {
208 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
217 /* full path to the statefile */
219 path = str.substr (0, slash);
224 /* what type of file is it? */
225 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
231 /* its the name of a new directory. get the name
235 string::size_type slash = str.find_last_of ('/');
237 if (slash == string::npos) {
239 /* no slash, just use the name, but clean it up */
241 path = legalize_for_path (str);
247 snapshot = str.substr (slash+1);
254 Session::Session (AudioEngine &eng,
256 string snapshot_name,
257 string* mix_template)
260 _mmc_port (default_mmc_port),
261 _mtc_port (default_mtc_port),
262 _midi_port (default_midi_port),
263 pending_events (2048),
264 midi_requests (128), // the size of this should match the midi request pool size
265 diskstreams (new DiskstreamList),
266 routes (new RouteList),
267 auditioner ((Auditioner*) 0),
273 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
275 n_physical_outputs = _engine.n_physical_outputs();
276 n_physical_inputs = _engine.n_physical_inputs();
278 first_stage_init (fullpath, snapshot_name);
280 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
282 if (create (new_session, mix_template, compute_initial_length())) {
283 cerr << "create failed\n";
284 throw failed_constructor ();
288 if (second_stage_init (new_session)) {
289 cerr << "2nd state failed\n";
290 throw failed_constructor ();
293 store_recent_sessions(_name, _path);
295 bool was_dirty = dirty();
297 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
299 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
302 DirtyChanged (); /* EMIT SIGNAL */
306 Session::Session (AudioEngine &eng,
308 string snapshot_name,
309 AutoConnectOption input_ac,
310 AutoConnectOption output_ac,
311 uint32_t control_out_channels,
312 uint32_t master_out_channels,
313 uint32_t requested_physical_in,
314 uint32_t requested_physical_out,
315 nframes_t initial_length)
318 _mmc_port (default_mmc_port),
319 _mtc_port (default_mtc_port),
320 _midi_port (default_midi_port),
321 pending_events (2048),
323 diskstreams (new DiskstreamList),
324 routes (new RouteList),
330 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
332 n_physical_outputs = _engine.n_physical_outputs();
333 n_physical_inputs = _engine.n_physical_inputs();
335 if (n_physical_inputs) {
336 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
339 if (n_physical_outputs) {
340 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
343 first_stage_init (fullpath, snapshot_name);
345 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
348 if (create (new_session, 0, initial_length)) {
349 throw failed_constructor ();
353 if (control_out_channels) {
354 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
361 if (master_out_channels) {
362 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
368 /* prohibit auto-connect to master, because there isn't one */
369 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
372 Config->set_input_auto_connect (input_ac);
373 Config->set_output_auto_connect (output_ac);
375 if (second_stage_init (new_session)) {
376 throw failed_constructor ();
379 store_recent_sessions(_name, _path);
381 bool was_dirty = dirty ();
383 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
386 DirtyChanged (); /* EMIT SIGNAL */
392 /* if we got to here, leaving pending capture state around
396 remove_pending_capture_state ();
398 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
399 _engine.remove_session ();
401 GoingAway (); /* EMIT SIGNAL */
407 /* clear history so that no references to objects are held any more */
411 /* clear state tree so that no references to objects are held any more */
417 terminate_butler_thread ();
418 terminate_midi_thread ();
420 if (click_data && click_data != default_click) {
421 delete [] click_data;
424 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
425 delete [] click_emphasis_data;
430 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
434 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
438 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
442 AudioDiskstream::free_working_buffers();
444 /* this should cause deletion of the auditioner */
446 // auditioner.reset ();
448 #undef TRACK_DESTRUCTION
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete named selections\n";
451 #endif /* TRACK_DESTRUCTION */
452 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
453 NamedSelectionList::iterator tmp;
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete playlists\n";
464 #endif /* TRACK_DESTRUCTION */
465 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
466 PlaylistList::iterator tmp;
476 #ifdef TRACK_DESTRUCTION
477 cerr << "delete audio regions\n";
478 #endif /* TRACK_DESTRUCTION */
480 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
481 AudioRegionList::iterator tmp;
486 i->second->drop_references ();
491 audio_regions.clear ();
493 #ifdef TRACK_DESTRUCTION
494 cerr << "delete routes\n";
495 #endif /* TRACK_DESTRUCTION */
497 RCUWriter<RouteList> writer (routes);
498 boost::shared_ptr<RouteList> r = writer.get_copy ();
499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
500 (*i)->drop_references ();
503 /* writer goes out of scope and updates master */
508 #ifdef TRACK_DESTRUCTION
509 cerr << "delete diskstreams\n";
510 #endif /* TRACK_DESTRUCTION */
512 RCUWriter<DiskstreamList> dwriter (diskstreams);
513 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
514 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
515 (*i)->drop_references ();
519 diskstreams.flush ();
521 #ifdef TRACK_DESTRUCTION
522 cerr << "delete audio sources\n";
523 #endif /* TRACK_DESTRUCTION */
524 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
525 AudioSourceList::iterator tmp;
530 i->second->drop_references ();
535 audio_sources.clear ();
537 #ifdef TRACK_DESTRUCTION
538 cerr << "delete mix groups\n";
539 #endif /* TRACK_DESTRUCTION */
540 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
541 list<RouteGroup*>::iterator tmp;
551 #ifdef TRACK_DESTRUCTION
552 cerr << "delete edit groups\n";
553 #endif /* TRACK_DESTRUCTION */
554 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
555 list<RouteGroup*>::iterator tmp;
565 #ifdef TRACK_DESTRUCTION
566 cerr << "delete connections\n";
567 #endif /* TRACK_DESTRUCTION */
568 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
569 ConnectionList::iterator tmp;
579 if (butler_mixdown_buffer) {
580 delete [] butler_mixdown_buffer;
583 if (butler_gain_buffer) {
584 delete [] butler_gain_buffer;
587 Crossfade::set_buffer_size (0);
595 Session::set_worst_io_latencies ()
597 _worst_output_latency = 0;
598 _worst_input_latency = 0;
600 if (!_engine.connected()) {
604 boost::shared_ptr<RouteList> r = routes.reader ();
606 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
607 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
608 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
613 Session::when_engine_running ()
615 string first_physical_output;
617 /* we don't want to run execute this again */
619 first_time_running.disconnect ();
621 set_block_size (_engine.frames_per_cycle());
622 set_frame_rate (_engine.frame_rate());
624 Config->map_parameters (mem_fun (*this, &Session::config_changed));
626 /* every time we reconnect, recompute worst case output latencies */
628 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
630 if (synced_to_jack()) {
631 _engine.transport_stop ();
634 if (Config->get_jack_time_master()) {
635 _engine.transport_locate (_transport_frame);
643 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
645 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
647 /* existing state for Click */
649 if (_click_io->set_state (*child->children().front()) == 0) {
651 _clicking = Config->get_clicking ();
655 error << _("could not setup Click I/O") << endmsg;
661 /* default state for Click */
663 first_physical_output = _engine.get_nth_physical_output (0);
665 if (first_physical_output.length()) {
666 if (_click_io->add_output_port (first_physical_output, this)) {
667 // relax, even though its an error
669 _clicking = Config->get_clicking ();
675 catch (failed_constructor& err) {
676 error << _("cannot setup Click I/O") << endmsg;
679 set_worst_io_latencies ();
682 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
685 if (auditioner == 0) {
687 /* we delay creating the auditioner till now because
688 it makes its own connections to ports named
689 in the ARDOUR_RC config file. the engine has
690 to be running for this to work.
694 auditioner.reset (new Auditioner (*this));
697 catch (failed_constructor& err) {
698 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
702 /* Create a set of Connection objects that map
703 to the physical outputs currently available
708 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
710 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
712 Connection* c = new OutputConnection (buf, true);
715 c->add_connection (0, _engine.get_nth_physical_output (np));
720 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
722 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
724 Connection* c = new InputConnection (buf, true);
727 c->add_connection (0, _engine.get_nth_physical_input (np));
734 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
736 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
738 Connection* c = new OutputConnection (buf, true);
742 c->add_connection (0, _engine.get_nth_physical_output (np));
743 c->add_connection (1, _engine.get_nth_physical_output (np+1));
748 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
750 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
752 Connection* c = new InputConnection (buf, true);
756 c->add_connection (0, _engine.get_nth_physical_input (np));
757 c->add_connection (1, _engine.get_nth_physical_input (np+1));
766 /* create master/control ports */
771 /* force the master to ignore any later call to this */
773 if (_master_out->pending_state_node) {
774 _master_out->ports_became_legal();
777 /* no panner resets till we are through */
779 _master_out->defer_pan_reset ();
781 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
782 if (_master_out->add_input_port ("", this)) {
783 error << _("cannot setup master inputs")
789 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
790 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
791 error << _("cannot setup master outputs")
798 _master_out->allow_pan_reset ();
802 Connection* c = new OutputConnection (_("Master Out"), true);
804 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
806 c->add_connection ((int) n, _master_out->input(n)->name());
813 /* catch up on send+insert cnts */
817 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
820 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
821 if (id > insert_cnt) {
829 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
832 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
840 /* its safe to do this now */
842 restore_history (snap_name());
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
846 /* hook us up to the engine */
848 _engine.set_session (this);
853 osc->set_session (*this);
856 _state_of_the_state = Clean;
858 DirtyChanged (); /* EMIT SIGNAL */
862 Session::hookup_io ()
864 /* stop graph reordering notifications from
865 causing resorts, etc.
868 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
870 /* Tell all IO objects to create their ports */
877 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
878 if (_control_out->add_input_port ("", this)) {
879 error << _("cannot setup control inputs")
885 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
886 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
887 error << _("cannot set up master outputs")
895 /* Tell all IO objects to connect themselves together */
897 IO::enable_connecting ();
899 /* Now reset all panners */
901 IO::reset_panners ();
903 /* Anyone who cares about input state, wake up and do something */
905 IOConnectionsComplete (); /* EMIT SIGNAL */
907 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
909 /* now handle the whole enchilada as if it was one
915 /* update mixer solo state */
921 Session::playlist_length_changed (Playlist* pl)
923 /* we can't just increase end_location->end() if pl->get_maximum_extent()
924 if larger. if the playlist used to be the longest playlist,
925 and its now shorter, we have to decrease end_location->end(). hence,
926 we have to iterate over all diskstreams and check the
927 playlists currently in use.
933 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
937 if ((playlist = dstream->playlist()) != 0) {
938 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
941 /* see comment in playlist_length_changed () */
946 Session::record_enabling_legal () const
948 /* this used to be in here, but survey says.... we don't need to restrict it */
949 // if (record_status() == Recording) {
953 if (Config->get_all_safe()) {
960 Session::reset_input_monitor_state ()
962 if (transport_rolling()) {
964 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
966 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
967 if ((*i)->record_enabled ()) {
968 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
969 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
973 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
975 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
976 if ((*i)->record_enabled ()) {
977 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
978 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
985 Session::auto_punch_start_changed (Location* location)
987 replace_event (Event::PunchIn, location->start());
989 if (get_record_enabled() && Config->get_punch_in()) {
990 /* capture start has been changed, so save new pending state */
991 save_state ("", true);
996 Session::auto_punch_end_changed (Location* location)
998 nframes_t when_to_stop = location->end();
999 // when_to_stop += _worst_output_latency + _worst_input_latency;
1000 replace_event (Event::PunchOut, when_to_stop);
1004 Session::auto_punch_changed (Location* location)
1006 nframes_t when_to_stop = location->end();
1008 replace_event (Event::PunchIn, location->start());
1009 //when_to_stop += _worst_output_latency + _worst_input_latency;
1010 replace_event (Event::PunchOut, when_to_stop);
1014 Session::auto_loop_changed (Location* location)
1016 replace_event (Event::AutoLoop, location->end(), location->start());
1018 if (transport_rolling() && play_loop) {
1020 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1022 if (_transport_frame > location->end()) {
1023 // relocate to beginning of loop
1024 clear_events (Event::LocateRoll);
1026 request_locate (location->start(), true);
1029 else if (Config->get_seamless_loop() && !loop_changing) {
1031 // schedule a locate-roll to refill the diskstreams at the
1032 // previous loop end
1033 loop_changing = true;
1035 if (location->end() > last_loopend) {
1036 clear_events (Event::LocateRoll);
1037 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1044 last_loopend = location->end();
1049 Session::set_auto_punch_location (Location* location)
1053 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1054 auto_punch_start_changed_connection.disconnect();
1055 auto_punch_end_changed_connection.disconnect();
1056 auto_punch_changed_connection.disconnect();
1057 existing->set_auto_punch (false, this);
1058 remove_event (existing->start(), Event::PunchIn);
1059 clear_events (Event::PunchOut);
1060 auto_punch_location_changed (0);
1065 if (location == 0) {
1069 if (location->end() <= location->start()) {
1070 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1074 auto_punch_start_changed_connection.disconnect();
1075 auto_punch_end_changed_connection.disconnect();
1076 auto_punch_changed_connection.disconnect();
1078 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1079 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1080 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1082 location->set_auto_punch (true, this);
1083 auto_punch_location_changed (location);
1087 Session::set_auto_loop_location (Location* location)
1091 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1092 auto_loop_start_changed_connection.disconnect();
1093 auto_loop_end_changed_connection.disconnect();
1094 auto_loop_changed_connection.disconnect();
1095 existing->set_auto_loop (false, this);
1096 remove_event (existing->end(), Event::AutoLoop);
1097 auto_loop_location_changed (0);
1102 if (location == 0) {
1106 if (location->end() <= location->start()) {
1107 error << _("Session: you can't use a mark for auto loop") << endmsg;
1111 last_loopend = location->end();
1113 auto_loop_start_changed_connection.disconnect();
1114 auto_loop_end_changed_connection.disconnect();
1115 auto_loop_changed_connection.disconnect();
1117 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1118 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1119 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1121 location->set_auto_loop (true, this);
1122 auto_loop_location_changed (location);
1126 Session::locations_added (Location* ignored)
1132 Session::locations_changed ()
1134 _locations.apply (*this, &Session::handle_locations_changed);
1138 Session::handle_locations_changed (Locations::LocationList& locations)
1140 Locations::LocationList::iterator i;
1142 bool set_loop = false;
1143 bool set_punch = false;
1145 for (i = locations.begin(); i != locations.end(); ++i) {
1149 if (location->is_auto_punch()) {
1150 set_auto_punch_location (location);
1153 if (location->is_auto_loop()) {
1154 set_auto_loop_location (location);
1161 set_auto_loop_location (0);
1164 set_auto_punch_location (0);
1171 Session::enable_record ()
1173 /* XXX really atomic compare+swap here */
1174 if (g_atomic_int_get (&_record_status) != Recording) {
1175 g_atomic_int_set (&_record_status, Recording);
1176 _last_record_location = _transport_frame;
1177 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1179 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1180 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1181 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1182 if ((*i)->record_enabled ()) {
1183 (*i)->monitor_input (true);
1188 RecordStateChanged ();
1193 Session::disable_record (bool rt_context, bool force)
1197 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1199 if (!Config->get_latched_record_enable () || force) {
1200 g_atomic_int_set (&_record_status, Disabled);
1202 if (rs == Recording) {
1203 g_atomic_int_set (&_record_status, Enabled);
1207 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1209 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1210 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1212 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1213 if ((*i)->record_enabled ()) {
1214 (*i)->monitor_input (false);
1219 RecordStateChanged (); /* emit signal */
1222 remove_pending_capture_state ();
1228 Session::step_back_from_record ()
1230 g_atomic_int_set (&_record_status, Enabled);
1232 if (Config->get_monitoring_model() == HardwareMonitoring) {
1233 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1235 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1236 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1237 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1238 (*i)->monitor_input (false);
1245 Session::maybe_enable_record ()
1247 g_atomic_int_set (&_record_status, Enabled);
1249 /* this function is currently called from somewhere other than an RT thread.
1250 this save_state() call therefore doesn't impact anything.
1253 save_state ("", true);
1255 if (_transport_speed) {
1256 if (!Config->get_punch_in()) {
1260 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1261 RecordStateChanged (); /* EMIT SIGNAL */
1268 Session::audible_frame () const
1274 /* the first of these two possible settings for "offset"
1275 mean that the audible frame is stationary until
1276 audio emerges from the latency compensation
1279 the second means that the audible frame is stationary
1280 until audio would emerge from a physical port
1281 in the absence of any plugin latency compensation
1284 offset = _worst_output_latency;
1286 if (offset > current_block_size) {
1287 offset -= current_block_size;
1289 /* XXX is this correct? if we have no external
1290 physical connections and everything is internal
1291 then surely this is zero? still, how
1292 likely is that anyway?
1294 offset = current_block_size;
1297 if (synced_to_jack()) {
1298 tf = _engine.transport_frame();
1300 tf = _transport_frame;
1303 if (_transport_speed == 0) {
1313 if (!non_realtime_work_pending()) {
1317 /* take latency into account */
1326 Session::set_frame_rate (nframes_t frames_per_second)
1328 /** \fn void Session::set_frame_size(nframes_t)
1329 the AudioEngine object that calls this guarantees
1330 that it will not be called while we are also in
1331 ::process(). Its fine to do things that block
1335 _base_frame_rate = frames_per_second;
1339 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1341 // XXX we need some equivalent to this, somehow
1342 // SndFileSource::setup_standard_crossfades (frames_per_second);
1346 /* XXX need to reset/reinstantiate all LADSPA plugins */
1350 Session::set_block_size (nframes_t nframes)
1352 /* the AudioEngine guarantees
1353 that it will not be called while we are also in
1354 ::process(). It is therefore fine to do things that block
1359 vector<Sample*>::iterator i;
1362 current_block_size = nframes;
1364 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1368 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1372 _passthru_buffers.clear ();
1373 _silent_buffers.clear ();
1375 ensure_passthru_buffers (np);
1377 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1381 #ifdef NO_POSIX_MEMALIGN
1382 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1384 posix_memalign((void **)&buf,16,current_block_size * 4);
1388 memset (*i, 0, sizeof (Sample) * current_block_size);
1392 if (_gain_automation_buffer) {
1393 delete [] _gain_automation_buffer;
1395 _gain_automation_buffer = new gain_t[nframes];
1397 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1399 boost::shared_ptr<RouteList> r = routes.reader ();
1401 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1402 (*i)->set_block_size (nframes);
1405 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1406 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1407 (*i)->set_block_size (nframes);
1410 set_worst_io_latencies ();
1415 Session::set_default_fade (float steepness, float fade_msecs)
1418 nframes_t fade_frames;
1420 /* Don't allow fade of less 1 frame */
1422 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1429 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1433 default_fade_msecs = fade_msecs;
1434 default_fade_steepness = steepness;
1437 // jlc, WTF is this!
1438 Glib::RWLock::ReaderLock lm (route_lock);
1439 AudioRegion::set_default_fade (steepness, fade_frames);
1444 /* XXX have to do this at some point */
1445 /* foreach region using default fade, reset, then
1446 refill_all_diskstream_buffers ();
1451 struct RouteSorter {
1452 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1453 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1455 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1458 if (r1->fed_by.empty()) {
1459 if (r2->fed_by.empty()) {
1460 /* no ardour-based connections inbound to either route. just use signal order */
1461 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1463 /* r2 has connections, r1 does not; run r1 early */
1467 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1474 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1476 shared_ptr<Route> r2;
1478 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1479 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1483 /* make a copy of the existing list of routes that feed r1 */
1485 set<shared_ptr<Route> > existing = r1->fed_by;
1487 /* for each route that feeds r1, recurse, marking it as feeding
1491 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1494 /* r2 is a route that feeds r1 which somehow feeds base. mark
1495 base as being fed by r2
1498 rbase->fed_by.insert (r2);
1502 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1506 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1510 /* now recurse, so that we can mark base as being fed by
1511 all routes that feed r2
1514 trace_terminal (r2, rbase);
1521 Session::resort_routes ()
1523 /* don't do anything here with signals emitted
1524 by Routes while we are being destroyed.
1527 if (_state_of_the_state & Deletion) {
1534 RCUWriter<RouteList> writer (routes);
1535 shared_ptr<RouteList> r = writer.get_copy ();
1536 resort_routes_using (r);
1537 /* writer goes out of scope and forces update */
1542 Session::resort_routes_using (shared_ptr<RouteList> r)
1544 RouteList::iterator i, j;
1546 for (i = r->begin(); i != r->end(); ++i) {
1548 (*i)->fed_by.clear ();
1550 for (j = r->begin(); j != r->end(); ++j) {
1552 /* although routes can feed themselves, it will
1553 cause an endless recursive descent if we
1554 detect it. so don't bother checking for
1562 if ((*j)->feeds (*i)) {
1563 (*i)->fed_by.insert (*j);
1568 for (i = r->begin(); i != r->end(); ++i) {
1569 trace_terminal (*i, *i);
1575 /* don't leave dangling references to routes in Route::fed_by */
1577 for (i = r->begin(); i != r->end(); ++i) {
1578 (*i)->fed_by.clear ();
1582 cerr << "finished route resort\n";
1584 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1585 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1592 list<boost::shared_ptr<AudioTrack> >
1593 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1595 char track_name[32];
1596 uint32_t track_id = 0;
1598 uint32_t channels_used = 0;
1600 RouteList new_routes;
1601 list<boost::shared_ptr<AudioTrack> > ret;
1603 /* count existing audio tracks */
1606 shared_ptr<RouteList> r = routes.reader ();
1608 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1609 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1610 if (!(*i)->hidden()) {
1612 channels_used += (*i)->n_inputs();
1618 vector<string> physinputs;
1619 vector<string> physoutputs;
1620 uint32_t nphysical_in;
1621 uint32_t nphysical_out;
1623 _engine.get_physical_outputs (physoutputs);
1624 _engine.get_physical_inputs (physinputs);
1628 /* check for duplicate route names, since we might have pre-existing
1629 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1630 save, close,restart,add new route - first named route is now
1638 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1640 if (route_by_name (track_name) == 0) {
1644 } while (track_id < (UINT_MAX-1));
1646 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1647 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1652 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1653 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1659 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1661 if (track->ensure_io (input_channels, output_channels, false, this)) {
1662 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1663 input_channels, output_channels)
1668 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1672 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1673 port = physinputs[(channels_used+x)%nphysical_in];
1676 if (port.length() && track->connect_input (track->input (x), port, this)) {
1682 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1686 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1687 port = physoutputs[(channels_used+x)%nphysical_out];
1688 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1690 port = _master_out->input (x%_master_out->n_inputs())->name();
1694 if (port.length() && track->connect_output (track->output (x), port, this)) {
1699 channels_used += track->n_inputs ();
1702 vector<string> cports;
1703 uint32_t ni = _control_out->n_inputs();
1705 for (n = 0; n < ni; ++n) {
1706 cports.push_back (_control_out->input(n)->name());
1709 track->set_control_outs (cports);
1712 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1713 track->set_remote_control_id (ntracks());
1715 new_routes.push_back (track);
1716 ret.push_back (track);
1719 catch (failed_constructor &err) {
1720 error << _("Session: could not create new audio track.") << endmsg;
1721 // XXX should we delete the tracks already created?
1729 if (!new_routes.empty()) {
1730 add_routes (new_routes, false);
1731 save_state (_current_snapshot_name);
1738 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1741 uint32_t bus_id = 1;
1746 /* count existing audio busses */
1749 shared_ptr<RouteList> r = routes.reader ();
1751 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1752 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1753 if (!(*i)->hidden()) {
1760 vector<string> physinputs;
1761 vector<string> physoutputs;
1763 _engine.get_physical_outputs (physoutputs);
1764 _engine.get_physical_inputs (physinputs);
1771 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1773 if (route_by_name (bus_name) == 0) {
1777 } while (bus_id < (UINT_MAX-1));
1780 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1782 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1783 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1784 input_channels, output_channels)
1788 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1792 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1793 port = physinputs[((n+x)%n_physical_inputs)];
1796 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1801 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1805 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1806 port = physoutputs[((n+x)%n_physical_outputs)];
1807 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1809 port = _master_out->input (x%_master_out->n_inputs())->name();
1813 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1819 vector<string> cports;
1820 uint32_t ni = _control_out->n_inputs();
1822 for (uint32_t n = 0; n < ni; ++n) {
1823 cports.push_back (_control_out->input(n)->name());
1825 bus->set_control_outs (cports);
1828 ret.push_back (bus);
1832 catch (failed_constructor &err) {
1833 error << _("Session: could not create new audio route.") << endmsg;
1842 add_routes (ret, false);
1843 save_state (_current_snapshot_name);
1851 Session::add_routes (RouteList& new_routes, bool save)
1854 RCUWriter<RouteList> writer (routes);
1855 shared_ptr<RouteList> r = writer.get_copy ();
1856 r->insert (r->end(), new_routes.begin(), new_routes.end());
1857 resort_routes_using (r);
1860 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1862 boost::weak_ptr<Route> wpr (*x);
1864 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1865 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1866 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1867 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1869 if ((*x)->master()) {
1873 if ((*x)->control()) {
1874 _control_out = (*x);
1881 save_state (_current_snapshot_name);
1884 RouteAdded (new_routes); /* EMIT SIGNAL */
1888 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1890 /* need to do this in case we're rolling at the time, to prevent false underruns */
1891 dstream->do_refill_with_alloc();
1894 RCUWriter<DiskstreamList> writer (diskstreams);
1895 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1896 ds->push_back (dstream);
1899 dstream->set_block_size (current_block_size);
1901 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1902 /* this will connect to future changes, and check the current length */
1903 diskstream_playlist_changed (dstream);
1905 dstream->prepare ();
1909 Session::remove_route (shared_ptr<Route> route)
1912 RCUWriter<RouteList> writer (routes);
1913 shared_ptr<RouteList> rs = writer.get_copy ();
1917 /* deleting the master out seems like a dumb
1918 idea, but its more of a UI policy issue
1922 if (route == _master_out) {
1923 _master_out = shared_ptr<Route> ();
1926 if (route == _control_out) {
1927 _control_out = shared_ptr<Route> ();
1929 /* cancel control outs for all routes */
1931 vector<string> empty;
1933 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1934 (*r)->set_control_outs (empty);
1938 update_route_solo_state ();
1940 /* writer goes out of scope, forces route list update */
1943 // FIXME: audio specific
1945 boost::shared_ptr<AudioDiskstream> ds;
1947 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1948 ds = at->audio_diskstream();
1954 RCUWriter<DiskstreamList> dsl (diskstreams);
1955 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1960 find_current_end ();
1962 update_latency_compensation (false, false);
1965 // We need to disconnect the routes inputs and outputs
1966 route->disconnect_inputs(NULL);
1967 route->disconnect_outputs(NULL);
1969 /* get rid of it from the dead wood collection in the route list manager */
1971 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1975 /* try to cause everyone to drop their references */
1977 route->drop_references ();
1979 /* save the new state of the world */
1981 if (save_state (_current_snapshot_name)) {
1982 save_history (_current_snapshot_name);
1987 Session::route_mute_changed (void* src)
1993 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1995 if (solo_update_disabled) {
2001 boost::shared_ptr<Route> route = wpr.lock ();
2004 /* should not happen */
2005 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2009 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2011 shared_ptr<RouteList> r = routes.reader ();
2013 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2015 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2019 /* don't mess with busses */
2021 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2027 /* don't mess with tracks */
2029 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2034 if ((*i) != route &&
2035 ((*i)->mix_group () == 0 ||
2036 (*i)->mix_group () != route->mix_group () ||
2037 !route->mix_group ()->is_active())) {
2039 if ((*i)->soloed()) {
2041 /* if its already soloed, and solo latching is enabled,
2042 then leave it as it is.
2045 if (Config->get_solo_latched()) {
2052 solo_update_disabled = true;
2053 (*i)->set_solo (false, src);
2054 solo_update_disabled = false;
2058 bool something_soloed = false;
2059 bool same_thing_soloed = false;
2060 bool signal = false;
2062 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2063 if ((*i)->soloed()) {
2064 something_soloed = true;
2065 if (dynamic_cast<AudioTrack*>((*i).get())) {
2067 same_thing_soloed = true;
2072 same_thing_soloed = true;
2080 if (something_soloed != currently_soloing) {
2082 currently_soloing = something_soloed;
2085 modify_solo_mute (is_track, same_thing_soloed);
2088 SoloActive (currently_soloing);
2095 Session::update_route_solo_state ()
2098 bool is_track = false;
2099 bool signal = false;
2101 /* caller must hold RouteLock */
2103 /* this is where we actually implement solo by changing
2104 the solo mute setting of each track.
2107 shared_ptr<RouteList> r = routes.reader ();
2109 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2110 if ((*i)->soloed()) {
2112 if (dynamic_cast<AudioTrack*>((*i).get())) {
2119 if (mute != currently_soloing) {
2121 currently_soloing = mute;
2124 if (!is_track && !mute) {
2126 /* nothing is soloed */
2128 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2129 (*i)->set_solo_mute (false);
2139 modify_solo_mute (is_track, mute);
2142 SoloActive (currently_soloing);
2147 Session::modify_solo_mute (bool is_track, bool mute)
2149 shared_ptr<RouteList> r = routes.reader ();
2151 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2155 /* only alter track solo mute */
2157 if (dynamic_cast<AudioTrack*>((*i).get())) {
2158 if ((*i)->soloed()) {
2159 (*i)->set_solo_mute (!mute);
2161 (*i)->set_solo_mute (mute);
2167 /* only alter bus solo mute */
2169 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2171 if ((*i)->soloed()) {
2173 (*i)->set_solo_mute (false);
2177 /* don't mute master or control outs
2178 in response to another bus solo
2181 if ((*i) != _master_out &&
2182 (*i) != _control_out) {
2183 (*i)->set_solo_mute (mute);
2194 Session::catch_up_on_solo ()
2196 /* this is called after set_state() to catch the full solo
2197 state, which can't be correctly determined on a per-route
2198 basis, but needs the global overview that only the session
2201 update_route_solo_state();
2205 Session::route_by_name (string name)
2207 shared_ptr<RouteList> r = routes.reader ();
2209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2210 if ((*i)->name() == name) {
2215 return shared_ptr<Route> ((Route*) 0);
2219 Session::route_by_id (PBD::ID id)
2221 shared_ptr<RouteList> r = routes.reader ();
2223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2224 if ((*i)->id() == id) {
2229 return shared_ptr<Route> ((Route*) 0);
2233 Session::route_by_remote_id (uint32_t id)
2235 shared_ptr<RouteList> r = routes.reader ();
2237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238 if ((*i)->remote_control_id() == id) {
2243 return shared_ptr<Route> ((Route*) 0);
2247 Session::find_current_end ()
2249 if (_state_of_the_state & Loading) {
2253 nframes_t max = get_maximum_extent ();
2255 if (max > end_location->end()) {
2256 end_location->set_end (max);
2258 DurationChanged(); /* EMIT SIGNAL */
2263 Session::get_maximum_extent () const
2268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2270 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2271 Playlist* pl = (*i)->playlist();
2272 if ((me = pl->get_maximum_extent()) > max) {
2280 boost::shared_ptr<Diskstream>
2281 Session::diskstream_by_name (string name)
2283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2286 if ((*i)->name() == name) {
2291 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2294 boost::shared_ptr<Diskstream>
2295 Session::diskstream_by_id (const PBD::ID& id)
2297 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2300 if ((*i)->id() == id) {
2305 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2308 /* AudioRegion management */
2311 Session::new_region_name (string old)
2313 string::size_type last_period;
2315 string::size_type len = old.length() + 64;
2318 if ((last_period = old.find_last_of ('.')) == string::npos) {
2320 /* no period present - add one explicitly */
2323 last_period = old.length() - 1;
2328 number = atoi (old.substr (last_period+1).c_str());
2332 while (number < (UINT_MAX-1)) {
2334 AudioRegionList::const_iterator i;
2339 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2342 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2343 if (i->second->name() == sbuf) {
2348 if (i == audio_regions.end()) {
2353 if (number != (UINT_MAX-1)) {
2357 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2362 Session::region_name (string& result, string base, bool newlevel) const
2369 Glib::Mutex::Lock lm (region_lock);
2371 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2379 /* XXX this is going to be slow. optimize me later */
2384 string::size_type pos;
2386 pos = base.find_last_of ('.');
2388 /* pos may be npos, but then we just use entire base */
2390 subbase = base.substr (0, pos);
2394 bool name_taken = true;
2397 Glib::Mutex::Lock lm (region_lock);
2399 for (int n = 1; n < 5000; ++n) {
2402 snprintf (buf, sizeof (buf), ".%d", n);
2407 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2408 if (i->second->name() == result) {
2421 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2429 Session::add_region (boost::shared_ptr<Region> region)
2431 boost::shared_ptr<AudioRegion> ar;
2432 boost::shared_ptr<AudioRegion> oar;
2436 Glib::Mutex::Lock lm (region_lock);
2438 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2440 AudioRegionList::iterator x;
2442 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2444 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2446 if (ar->region_list_equivalent (oar)) {
2451 if (x == audio_regions.end()) {
2453 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2455 entry.first = region->id();
2458 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2470 fatal << _("programming error: ")
2471 << X_("unknown region type passed to Session::add_region()")
2478 /* mark dirty because something has changed even if we didn't
2479 add the region to the region list.
2485 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2486 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2487 AudioRegionAdded (ar); /* EMIT SIGNAL */
2492 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2494 boost::shared_ptr<Region> region (weak_region.lock ());
2500 if (what_changed & Region::HiddenChanged) {
2501 /* relay hidden changes */
2502 RegionHiddenChange (region);
2507 Session::remove_region (boost::weak_ptr<Region> weak_region)
2509 AudioRegionList::iterator i;
2510 boost::shared_ptr<Region> region (weak_region.lock ());
2516 boost::shared_ptr<AudioRegion> ar;
2517 bool removed = false;
2520 Glib::Mutex::Lock lm (region_lock);
2522 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2523 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2524 audio_regions.erase (i);
2530 fatal << _("programming error: ")
2531 << X_("unknown region type passed to Session::remove_region()")
2537 /* mark dirty because something has changed even if we didn't
2538 remove the region from the region list.
2544 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2548 boost::shared_ptr<AudioRegion>
2549 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2551 AudioRegionList::iterator i;
2552 boost::shared_ptr<AudioRegion> region;
2553 Glib::Mutex::Lock lm (region_lock);
2555 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2559 if (region->whole_file()) {
2561 if (child->source_equivalent (region)) {
2567 return boost::shared_ptr<AudioRegion> ();
2571 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2573 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2574 (*i)->get_region_list_equivalent_regions (region, result);
2578 Session::destroy_region (boost::shared_ptr<Region> region)
2580 vector<boost::shared_ptr<Source> > srcs;
2583 boost::shared_ptr<AudioRegion> aregion;
2585 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2589 if (aregion->playlist()) {
2590 aregion->playlist()->destroy_region (region);
2593 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2594 srcs.push_back (aregion->source (n));
2598 region->drop_references ();
2600 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2602 if (!(*i)->used()) {
2603 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2606 (afs)->mark_for_remove ();
2609 (*i)->drop_references ();
2611 cerr << "source was not used by any playlist\n";
2619 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2621 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2622 destroy_region (*i);
2628 Session::remove_last_capture ()
2630 list<boost::shared_ptr<Region> > r;
2632 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2634 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2635 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2638 r.insert (r.end(), l.begin(), l.end());
2643 destroy_regions (r);
2648 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2654 /* Source Management */
2657 Session::add_source (boost::shared_ptr<Source> source)
2659 boost::shared_ptr<AudioFileSource> afs;
2661 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2663 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2664 pair<AudioSourceList::iterator,bool> result;
2666 entry.first = source->id();
2670 Glib::Mutex::Lock lm (audio_source_lock);
2671 result = audio_sources.insert (entry);
2674 if (!result.second) {
2675 cerr << "\tNOT inserted ? " << result.second << endl;
2678 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2681 SourceAdded (source); /* EMIT SIGNAL */
2683 cerr << "\tNOT AUDIO FILE\n";
2688 Session::remove_source (boost::weak_ptr<Source> src)
2690 AudioSourceList::iterator i;
2691 boost::shared_ptr<Source> source = src.lock();
2698 Glib::Mutex::Lock lm (audio_source_lock);
2700 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2701 audio_sources.erase (i);
2705 if (!_state_of_the_state & InCleanup) {
2707 /* save state so we don't end up with a session file
2708 referring to non-existent sources.
2711 save_state (_current_snapshot_name);
2714 SourceRemoved(source); /* EMIT SIGNAL */
2717 boost::shared_ptr<Source>
2718 Session::source_by_id (const PBD::ID& id)
2720 Glib::Mutex::Lock lm (audio_source_lock);
2721 AudioSourceList::iterator i;
2722 boost::shared_ptr<Source> source;
2724 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2728 /* XXX search MIDI or other searches here */
2734 Session::peak_path_from_audio_path (string audio_path) const
2739 res += PBD::basename_nosuffix (audio_path);
2746 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2749 string old_basename = PBD::basename_nosuffix (oldname);
2750 string new_legalized = legalize_for_path (newname);
2752 /* note: we know (or assume) the old path is already valid */
2756 /* destructive file sources have a name of the form:
2758 /path/to/Tnnnn-NAME(%[LR])?.wav
2760 the task here is to replace NAME with the new name.
2763 /* find last slash */
2767 string::size_type slash;
2768 string::size_type dash;
2770 if ((slash = path.find_last_of ('/')) == string::npos) {
2774 dir = path.substr (0, slash+1);
2776 /* '-' is not a legal character for the NAME part of the path */
2778 if ((dash = path.find_last_of ('-')) == string::npos) {
2782 prefix = path.substr (slash+1, dash-(slash+1));
2787 path += new_legalized;
2788 path += ".wav"; /* XXX gag me with a spoon */
2792 /* non-destructive file sources have a name of the form:
2794 /path/to/NAME-nnnnn(%[LR])?.wav
2796 the task here is to replace NAME with the new name.
2801 string::size_type slash;
2802 string::size_type dash;
2803 string::size_type postfix;
2805 /* find last slash */
2807 if ((slash = path.find_last_of ('/')) == string::npos) {
2811 dir = path.substr (0, slash+1);
2813 /* '-' is not a legal character for the NAME part of the path */
2815 if ((dash = path.find_last_of ('-')) == string::npos) {
2819 suffix = path.substr (dash+1);
2821 // Suffix is now everything after the dash. Now we need to eliminate
2822 // the nnnnn part, which is done by either finding a '%' or a '.'
2824 postfix = suffix.find_last_of ("%");
2825 if (postfix == string::npos) {
2826 postfix = suffix.find_last_of ('.');
2829 if (postfix != string::npos) {
2830 suffix = suffix.substr (postfix);
2832 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2836 const uint32_t limit = 10000;
2837 char buf[PATH_MAX+1];
2839 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2841 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2843 if (access (buf, F_OK) != 0) {
2851 error << "FATAL ERROR! Could not find a " << endl;
2860 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2864 char buf[PATH_MAX+1];
2865 const uint32_t limit = 10000;
2869 legalized = legalize_for_path (name);
2871 /* find a "version" of the file name that doesn't exist in
2872 any of the possible directories.
2875 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2877 vector<space_and_path>::iterator i;
2878 uint32_t existing = 0;
2880 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2884 spath += sound_dir (false);
2888 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2889 } else if (nchan == 2) {
2891 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2893 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2895 } else if (nchan < 26) {
2896 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2898 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2906 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2907 } else if (nchan == 2) {
2909 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2911 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2913 } else if (nchan < 26) {
2914 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2916 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2920 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2926 if (existing == 0) {
2931 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2932 throw failed_constructor();
2936 /* we now have a unique name for the file, but figure out where to
2942 spath = discover_best_sound_dir ();
2944 string::size_type pos = foo.find_last_of ('/');
2946 if (pos == string::npos) {
2949 spath += foo.substr (pos + 1);
2955 boost::shared_ptr<AudioFileSource>
2956 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2958 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2959 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2962 /* Playlist management */
2965 Session::playlist_by_name (string name)
2967 Glib::Mutex::Lock lm (playlist_lock);
2968 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2969 if ((*i)->name() == name) {
2973 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2974 if ((*i)->name() == name) {
2982 Session::add_playlist (Playlist* playlist)
2984 if (playlist->hidden()) {
2989 Glib::Mutex::Lock lm (playlist_lock);
2990 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2991 playlists.insert (playlists.begin(), playlist);
2993 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2994 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3000 PlaylistAdded (playlist); /* EMIT SIGNAL */
3004 Session::get_playlists (vector<Playlist*>& s)
3007 Glib::Mutex::Lock lm (playlist_lock);
3008 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3011 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3018 Session::track_playlist (Playlist* pl, bool inuse)
3020 PlaylistList::iterator x;
3023 Glib::Mutex::Lock lm (playlist_lock);
3026 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3028 unused_playlists.insert (pl);
3030 if ((x = playlists.find (pl)) != playlists.end()) {
3031 playlists.erase (x);
3036 //cerr << "shifting playlist to used: " << pl->name() << endl;
3038 playlists.insert (pl);
3040 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3041 unused_playlists.erase (x);
3048 Session::remove_playlist (Playlist* playlist)
3050 if (_state_of_the_state & Deletion) {
3055 Glib::Mutex::Lock lm (playlist_lock);
3056 // cerr << "removing playlist: " << playlist->name() << endl;
3058 PlaylistList::iterator i;
3060 i = find (playlists.begin(), playlists.end(), playlist);
3062 if (i != playlists.end()) {
3063 playlists.erase (i);
3066 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3067 if (i != unused_playlists.end()) {
3068 unused_playlists.erase (i);
3075 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3079 Session::set_audition (boost::shared_ptr<Region> r)
3081 pending_audition_region = r;
3082 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3083 schedule_butler_transport_work ();
3087 Session::audition_playlist ()
3089 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3090 ev->region.reset ();
3095 Session::non_realtime_set_audition ()
3097 if (!pending_audition_region) {
3098 auditioner->audition_current_playlist ();
3100 auditioner->audition_region (pending_audition_region);
3101 pending_audition_region.reset ();
3103 AuditionActive (true); /* EMIT SIGNAL */
3107 Session::audition_region (boost::shared_ptr<Region> r)
3109 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3115 Session::cancel_audition ()
3117 if (auditioner->active()) {
3118 auditioner->cancel_audition ();
3119 AuditionActive (false); /* EMIT SIGNAL */
3124 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3126 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3130 Session::remove_empty_sounds ()
3132 PathScanner scanner;
3134 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3136 Glib::Mutex::Lock lm (audio_source_lock);
3138 regex_t compiled_tape_track_pattern;
3141 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3145 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3147 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3151 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3153 /* never remove files that appear to be a tape track */
3155 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3160 if (AudioFileSource::is_empty (*this, *(*i))) {
3162 unlink ((*i)->c_str());
3164 string peak_path = peak_path_from_audio_path (**i);
3165 unlink (peak_path.c_str());
3171 delete possible_audiofiles;
3175 Session::is_auditioning () const
3177 /* can be called before we have an auditioner object */
3179 return auditioner->active();
3186 Session::set_all_solo (bool yn)
3188 shared_ptr<RouteList> r = routes.reader ();
3190 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3191 if (!(*i)->hidden()) {
3192 (*i)->set_solo (yn, this);
3200 Session::set_all_mute (bool yn)
3202 shared_ptr<RouteList> r = routes.reader ();
3204 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3205 if (!(*i)->hidden()) {
3206 (*i)->set_mute (yn, this);
3214 Session::n_diskstreams () const
3218 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3220 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3221 if (!(*i)->hidden()) {
3229 Session::graph_reordered ()
3231 /* don't do this stuff if we are setting up connections
3232 from a set_state() call.
3235 if (_state_of_the_state & InitialConnecting) {
3241 /* force all diskstreams to update their capture offset values to
3242 reflect any changes in latencies within the graph.
3245 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3247 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3248 (*i)->set_capture_offset ();
3253 Session::record_disenable_all ()
3255 record_enable_change_all (false);
3259 Session::record_enable_all ()
3261 record_enable_change_all (true);
3265 Session::record_enable_change_all (bool yn)
3267 shared_ptr<RouteList> r = routes.reader ();
3269 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3272 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3273 at->set_record_enable (yn, this);
3277 /* since we don't keep rec-enable state, don't mark session dirty */
3281 Session::add_redirect (Redirect* redirect)
3285 PortInsert* port_insert;
3286 PluginInsert* plugin_insert;
3288 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3289 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3290 _port_inserts.insert (_port_inserts.begin(), port_insert);
3291 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3292 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3294 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3297 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3298 _sends.insert (_sends.begin(), send);
3300 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3304 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3310 Session::remove_redirect (Redirect* redirect)
3314 PortInsert* port_insert;
3315 PluginInsert* plugin_insert;
3317 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3318 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3319 _port_inserts.remove (port_insert);
3320 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3321 _plugin_inserts.remove (plugin_insert);
3323 fatal << string_compose (_("programming error: %1"),
3324 X_("unknown type of Insert deleted!"))
3328 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3329 _sends.remove (send);
3331 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3339 Session::available_capture_duration ()
3341 float sample_bytes_on_disk;
3343 switch (Config->get_native_file_data_format()) {
3345 sample_bytes_on_disk = 4;
3349 sample_bytes_on_disk = 3;
3353 /* impossible, but keep some gcc versions happy */
3354 fatal << string_compose (_("programming error: %1"),
3355 X_("illegal native file data format"))
3360 double scale = 4096.0 / sample_bytes_on_disk;
3362 if (_total_free_4k_blocks * scale > (double) max_frames) {
3366 return (nframes_t) floor (_total_free_4k_blocks * scale);
3370 Session::add_connection (ARDOUR::Connection* connection)
3373 Glib::Mutex::Lock guard (connection_lock);
3374 _connections.push_back (connection);
3377 ConnectionAdded (connection); /* EMIT SIGNAL */
3383 Session::remove_connection (ARDOUR::Connection* connection)
3385 bool removed = false;
3388 Glib::Mutex::Lock guard (connection_lock);
3389 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3391 if (i != _connections.end()) {
3392 _connections.erase (i);
3398 ConnectionRemoved (connection); /* EMIT SIGNAL */
3404 ARDOUR::Connection *
3405 Session::connection_by_name (string name) const
3407 Glib::Mutex::Lock lm (connection_lock);
3409 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3410 if ((*i)->name() == name) {
3419 Session::tempo_map_changed (Change ignored)
3426 Session::ensure_passthru_buffers (uint32_t howmany)
3428 while (howmany > _passthru_buffers.size()) {
3430 #ifdef NO_POSIX_MEMALIGN
3431 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3433 posix_memalign((void **)&p,16,current_block_size * 4);
3435 _passthru_buffers.push_back (p);
3439 #ifdef NO_POSIX_MEMALIGN
3440 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3442 posix_memalign((void **)&p,16,current_block_size * 4);
3444 memset (p, 0, sizeof (Sample) * current_block_size);
3445 _silent_buffers.push_back (p);
3449 #ifdef NO_POSIX_MEMALIGN
3450 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3452 posix_memalign((void **)&p,16,current_block_size * 4);
3454 memset (p, 0, sizeof (Sample) * current_block_size);
3455 _send_buffers.push_back (p);
3458 allocate_pan_automation_buffers (current_block_size, howmany, false);
3462 Session::next_send_name ()
3466 shared_ptr<RouteList> r = routes.reader ();
3468 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3469 cnt += (*i)->count_sends ();
3472 return string_compose (_("send %1"), ++cnt);
3476 Session::next_insert_name ()
3479 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3483 /* Named Selection management */
3486 Session::named_selection_by_name (string name)
3488 Glib::Mutex::Lock lm (named_selection_lock);
3489 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3490 if ((*i)->name == name) {
3498 Session::add_named_selection (NamedSelection* named_selection)
3501 Glib::Mutex::Lock lm (named_selection_lock);
3502 named_selections.insert (named_selections.begin(), named_selection);
3507 NamedSelectionAdded (); /* EMIT SIGNAL */
3511 Session::remove_named_selection (NamedSelection* named_selection)
3513 bool removed = false;
3516 Glib::Mutex::Lock lm (named_selection_lock);
3518 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3520 if (i != named_selections.end()) {
3522 named_selections.erase (i);
3529 NamedSelectionRemoved (); /* EMIT SIGNAL */
3534 Session::reset_native_file_format ()
3536 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3538 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3539 (*i)->reset_write_sources (false);
3544 Session::route_name_unique (string n) const
3546 shared_ptr<RouteList> r = routes.reader ();
3548 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3549 if ((*i)->name() == n) {
3558 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3560 return fs->move_to_trash (dead_sound_dir_name);
3564 Session::n_playlists () const
3566 Glib::Mutex::Lock lm (playlist_lock);
3567 return playlists.size();
3571 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3573 if (!force && howmany <= _npan_buffers) {
3577 if (_pan_automation_buffer) {
3579 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3580 delete [] _pan_automation_buffer[i];
3583 delete [] _pan_automation_buffer;
3586 _pan_automation_buffer = new pan_t*[howmany];
3588 for (uint32_t i = 0; i < howmany; ++i) {
3589 _pan_automation_buffer[i] = new pan_t[nframes];
3592 _npan_buffers = howmany;
3596 Session::freeze (InterThreadInfo& itt)
3598 shared_ptr<RouteList> r = routes.reader ();
3600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3604 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3605 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3616 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3617 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3621 boost::shared_ptr<AudioFileSource> fsource;
3623 char buf[PATH_MAX+1];
3627 nframes_t this_chunk;
3629 vector<Sample*> buffers;
3631 // any bigger than this seems to cause stack overflows in called functions
3632 const nframes_t chunk_size = (128 * 1024)/4;
3634 g_atomic_int_set (&processing_prohibited, 1);
3636 /* call tree *MUST* hold route_lock */
3638 if ((playlist = track.diskstream()->playlist()) == 0) {
3642 /* external redirects will be a problem */
3644 if (track.has_external_redirects()) {
3648 nchans = track.audio_diskstream()->n_channels();
3650 dir = discover_best_sound_dir ();
3652 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3654 for (x = 0; x < 99999; ++x) {
3655 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3656 if (access (buf, F_OK) != 0) {
3662 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3667 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3670 catch (failed_constructor& err) {
3671 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3675 srcs.push_back (fsource);
3678 /* XXX need to flush all redirects */
3683 /* create a set of reasonably-sized buffers */
3685 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3687 #ifdef NO_POSIX_MEMALIGN
3688 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3690 posix_memalign((void **)&b,16,chunk_size * 4);
3692 buffers.push_back (b);
3695 while (to_do && !itt.cancel) {
3697 this_chunk = min (to_do, chunk_size);
3699 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3704 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3705 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3708 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3714 start += this_chunk;
3715 to_do -= this_chunk;
3717 itt.progress = (float) (1.0 - ((double) to_do / len));
3726 xnow = localtime (&now);
3728 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3729 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3732 afs->update_header (position, *xnow, now);
3736 /* build peakfile for new source */
3738 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3739 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3741 afs->build_peaks ();
3745 /* construct a region to represent the bounced material */
3747 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3748 region_name_from_path (srcs.front()->name()));
3755 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3756 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3759 afs->mark_for_remove ();
3762 (*src)->drop_references ();
3766 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3770 g_atomic_int_set (&processing_prohibited, 0);
3778 Session::get_silent_buffers (uint32_t howmany)
3780 for (uint32_t i = 0; i < howmany; ++i) {
3781 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3783 return _silent_buffers;
3787 Session::ntracks () const
3790 shared_ptr<RouteList> r = routes.reader ();
3792 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3793 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3802 Session::nbusses () const
3805 shared_ptr<RouteList> r = routes.reader ();
3807 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3808 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3817 Session::add_automation_list(AutomationList *al)
3819 automation_lists[al->id()] = al;
3823 Session::compute_initial_length ()
3825 return _engine.frame_rate() * 60 * 5;