2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/auditioner.h>
53 #include <ardour/recent_sessions.h>
54 #include <ardour/redirect.h>
55 #include <ardour/send.h>
56 #include <ardour/insert.h>
57 #include <ardour/connection.h>
58 #include <ardour/slave.h>
59 #include <ardour/tempo.h>
60 #include <ardour/audio_track.h>
61 #include <ardour/cycle_timer.h>
62 #include <ardour/named_selection.h>
63 #include <ardour/crossfade.h>
64 #include <ardour/playlist.h>
65 #include <ardour/click.h>
66 #include <ardour/data_type.h>
67 #include <ardour/source_factory.h>
68 #include <ardour/region_factory.h>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
82 static const int CPU_CACHE_ALIGN = 64;
84 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
87 const char* Session::_template_suffix = X_(".template");
88 const char* Session::_statefile_suffix = X_(".ardour");
89 const char* Session::_pending_suffix = X_(".pending");
90 const char* Session::old_sound_dir_name = X_("sounds");
91 const char* Session::sound_dir_name = X_("audiofiles");
92 const char* Session::peak_dir_name = X_("peaks");
93 const char* Session::dead_sound_dir_name = X_("dead_sounds");
94 const char* Session::interchange_dir_name = X_("interchange");
95 const char* Session::export_dir_name = X_("export");
97 Session::compute_peak_t Session::compute_peak = 0;
98 Session::find_peaks_t Session::find_peaks = 0;
99 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
100 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
101 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
111 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
114 char buf[PATH_MAX+1];
118 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
119 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
125 /* check to see if it exists, and what it is */
127 if (stat (str.c_str(), &statbuf)) {
128 if (errno == ENOENT) {
131 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
139 /* it exists, so it must either be the name
140 of the directory, or the name of the statefile
144 if (S_ISDIR (statbuf.st_mode)) {
146 string::size_type slash = str.find_last_of ('/');
148 if (slash == string::npos) {
150 /* a subdirectory of cwd, so statefile should be ... */
156 tmp += _statefile_suffix;
160 if (stat (tmp.c_str(), &statbuf)) {
161 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
171 /* some directory someplace in the filesystem.
172 the snapshot name is the directory name
177 snapshot = str.substr (slash+1);
181 } else if (S_ISREG (statbuf.st_mode)) {
183 string::size_type slash = str.find_last_of ('/');
184 string::size_type suffix;
186 /* remove the suffix */
188 if (slash != string::npos) {
189 snapshot = str.substr (slash+1);
194 suffix = snapshot.find (_statefile_suffix);
196 if (suffix == string::npos) {
197 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
203 snapshot = snapshot.substr (0, suffix);
205 if (slash == string::npos) {
207 /* we must be in the directory where the
208 statefile lives. get it using cwd().
211 char cwd[PATH_MAX+1];
213 if (getcwd (cwd, sizeof (cwd)) == 0) {
214 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
223 /* full path to the statefile */
225 path = str.substr (0, slash);
230 /* what type of file is it? */
231 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
237 /* its the name of a new directory. get the name
241 string::size_type slash = str.find_last_of ('/');
243 if (slash == string::npos) {
245 /* no slash, just use the name, but clean it up */
247 path = legalize_for_path (str);
253 snapshot = str.substr (slash+1);
260 Session::Session (AudioEngine &eng,
262 string snapshot_name,
263 string* mix_template)
266 _mmc_port (default_mmc_port),
267 _mtc_port (default_mtc_port),
268 _midi_port (default_midi_port),
269 pending_events (2048),
270 midi_requests (128), // the size of this should match the midi request pool size
271 diskstreams (new DiskstreamList),
272 routes (new RouteList),
273 auditioner ((Auditioner*) 0),
279 if (!eng.connected()) {
280 throw failed_constructor();
283 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
285 n_physical_outputs = _engine.n_physical_outputs();
286 n_physical_inputs = _engine.n_physical_inputs();
288 first_stage_init (fullpath, snapshot_name);
290 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
292 if (create (new_session, mix_template, compute_initial_length())) {
293 cerr << "create failed\n";
295 throw failed_constructor ();
299 if (second_stage_init (new_session)) {
301 throw failed_constructor ();
304 store_recent_sessions(_name, _path);
306 bool was_dirty = dirty();
308 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
310 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
313 DirtyChanged (); /* EMIT SIGNAL */
317 Session::Session (AudioEngine &eng,
319 string snapshot_name,
320 AutoConnectOption input_ac,
321 AutoConnectOption output_ac,
322 uint32_t control_out_channels,
323 uint32_t master_out_channels,
324 uint32_t requested_physical_in,
325 uint32_t requested_physical_out,
326 nframes_t initial_length)
329 _mmc_port (default_mmc_port),
330 _mtc_port (default_mtc_port),
331 _midi_port (default_midi_port),
332 pending_events (2048),
334 diskstreams (new DiskstreamList),
335 routes (new RouteList),
341 if (!eng.connected()) {
342 throw failed_constructor();
345 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
347 n_physical_outputs = _engine.n_physical_outputs();
348 n_physical_inputs = _engine.n_physical_inputs();
350 if (n_physical_inputs) {
351 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
354 if (n_physical_outputs) {
355 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
358 first_stage_init (fullpath, snapshot_name);
360 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
363 if (create (new_session, 0, initial_length)) {
365 throw failed_constructor ();
370 /* set up Master Out and Control Out if necessary */
375 if (control_out_channels) {
376 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
377 r->set_remote_control_id (control_id++);
382 if (master_out_channels) {
383 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
384 r->set_remote_control_id (control_id);
388 /* prohibit auto-connect to master, because there isn't one */
389 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
398 Config->set_input_auto_connect (input_ac);
399 Config->set_output_auto_connect (output_ac);
401 if (second_stage_init (new_session)) {
403 throw failed_constructor ();
406 store_recent_sessions(_name, _path);
408 bool was_dirty = dirty ();
410 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
412 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
415 DirtyChanged (); /* EMIT SIGNAL */
427 /* if we got to here, leaving pending capture state around
431 remove_pending_capture_state ();
433 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
434 _engine.remove_session ();
436 GoingAway (); /* EMIT SIGNAL */
442 /* clear history so that no references to objects are held any more */
446 /* clear state tree so that no references to objects are held any more */
452 terminate_butler_thread ();
453 terminate_midi_thread ();
455 if (click_data && click_data != default_click) {
456 delete [] click_data;
459 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
460 delete [] click_emphasis_data;
465 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
469 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
473 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
477 AudioDiskstream::free_working_buffers();
479 /* this should cause deletion of the auditioner */
481 // auditioner.reset ();
483 #undef TRACK_DESTRUCTION
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete named selections\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
488 NamedSelectionList::iterator tmp;
497 #ifdef TRACK_DESTRUCTION
498 cerr << "delete playlists\n";
499 #endif /* TRACK_DESTRUCTION */
500 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
501 PlaylistList::iterator tmp;
506 (*i)->drop_references ();
511 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
512 PlaylistList::iterator tmp;
517 (*i)->drop_references ();
523 unused_playlists.clear ();
525 #ifdef TRACK_DESTRUCTION
526 cerr << "delete audio regions\n";
527 #endif /* TRACK_DESTRUCTION */
529 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
530 AudioRegionList::iterator tmp;
535 i->second->drop_references ();
540 audio_regions.clear ();
542 #ifdef TRACK_DESTRUCTION
543 cerr << "delete routes\n";
544 #endif /* TRACK_DESTRUCTION */
546 RCUWriter<RouteList> writer (routes);
547 boost::shared_ptr<RouteList> r = writer.get_copy ();
548 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
549 (*i)->drop_references ();
552 /* writer goes out of scope and updates master */
557 #ifdef TRACK_DESTRUCTION
558 cerr << "delete diskstreams\n";
559 #endif /* TRACK_DESTRUCTION */
561 RCUWriter<DiskstreamList> dwriter (diskstreams);
562 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
563 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
564 (*i)->drop_references ();
568 diskstreams.flush ();
570 #ifdef TRACK_DESTRUCTION
571 cerr << "delete audio sources\n";
572 #endif /* TRACK_DESTRUCTION */
573 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
574 AudioSourceList::iterator tmp;
579 i->second->drop_references ();
584 audio_sources.clear ();
586 #ifdef TRACK_DESTRUCTION
587 cerr << "delete mix groups\n";
588 #endif /* TRACK_DESTRUCTION */
589 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
590 list<RouteGroup*>::iterator tmp;
600 #ifdef TRACK_DESTRUCTION
601 cerr << "delete edit groups\n";
602 #endif /* TRACK_DESTRUCTION */
603 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
604 list<RouteGroup*>::iterator tmp;
614 #ifdef TRACK_DESTRUCTION
615 cerr << "delete connections\n";
616 #endif /* TRACK_DESTRUCTION */
617 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
618 ConnectionList::iterator tmp;
628 if (butler_mixdown_buffer) {
629 delete [] butler_mixdown_buffer;
632 if (butler_gain_buffer) {
633 delete [] butler_gain_buffer;
636 Crossfade::set_buffer_size (0);
644 Session::set_worst_io_latencies ()
646 _worst_output_latency = 0;
647 _worst_input_latency = 0;
649 if (!_engine.connected()) {
653 boost::shared_ptr<RouteList> r = routes.reader ();
655 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
656 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
657 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
662 Session::when_engine_running ()
664 string first_physical_output;
666 /* we don't want to run execute this again */
668 set_block_size (_engine.frames_per_cycle());
669 set_frame_rate (_engine.frame_rate());
671 Config->map_parameters (mem_fun (*this, &Session::config_changed));
673 /* every time we reconnect, recompute worst case output latencies */
675 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
677 if (synced_to_jack()) {
678 _engine.transport_stop ();
681 if (Config->get_jack_time_master()) {
682 _engine.transport_locate (_transport_frame);
690 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
692 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
694 /* existing state for Click */
696 if (_click_io->set_state (*child->children().front()) == 0) {
698 _clicking = Config->get_clicking ();
702 error << _("could not setup Click I/O") << endmsg;
708 /* default state for Click */
710 first_physical_output = _engine.get_nth_physical_output (0);
712 if (first_physical_output.length()) {
713 if (_click_io->add_output_port (first_physical_output, this)) {
714 // relax, even though its an error
716 _clicking = Config->get_clicking ();
722 catch (failed_constructor& err) {
723 error << _("cannot setup Click I/O") << endmsg;
726 set_worst_io_latencies ();
729 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
732 /* Create a set of Connection objects that map
733 to the physical outputs currently available
738 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
740 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
742 Connection* c = new OutputConnection (buf, true);
745 c->add_connection (0, _engine.get_nth_physical_output (np));
750 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
752 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
754 Connection* c = new InputConnection (buf, true);
757 c->add_connection (0, _engine.get_nth_physical_input (np));
764 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
766 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
768 Connection* c = new OutputConnection (buf, true);
772 c->add_connection (0, _engine.get_nth_physical_output (np));
773 c->add_connection (1, _engine.get_nth_physical_output (np+1));
778 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
780 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
782 Connection* c = new InputConnection (buf, true);
786 c->add_connection (0, _engine.get_nth_physical_input (np));
787 c->add_connection (1, _engine.get_nth_physical_input (np+1));
796 /* create master/control ports */
801 /* force the master to ignore any later call to this */
803 if (_master_out->pending_state_node) {
804 _master_out->ports_became_legal();
807 /* no panner resets till we are through */
809 _master_out->defer_pan_reset ();
811 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
812 if (_master_out->add_input_port ("", this)) {
813 error << _("cannot setup master inputs")
819 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
820 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
821 error << _("cannot setup master outputs")
828 _master_out->allow_pan_reset ();
832 Connection* c = new OutputConnection (_("Master Out"), true);
834 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
836 c->add_connection ((int) n, _master_out->input(n)->name());
843 /* catch up on send+insert cnts */
847 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
850 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
851 if (id > insert_cnt) {
859 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
862 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
870 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
872 /* hook us up to the engine */
874 _engine.set_session (this);
879 osc->set_session (*this);
882 _state_of_the_state = Clean;
884 DirtyChanged (); /* EMIT SIGNAL */
888 Session::hookup_io ()
890 /* stop graph reordering notifications from
891 causing resorts, etc.
894 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
896 if (auditioner == 0) {
898 /* we delay creating the auditioner till now because
899 it makes its own connections to ports.
900 the engine has to be running for this to work.
904 auditioner.reset (new Auditioner (*this));
907 catch (failed_constructor& err) {
908 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
912 /* Tell all IO objects to create their ports */
919 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
920 if (_control_out->add_input_port ("", this)) {
921 error << _("cannot setup control inputs")
927 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
928 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
929 error << _("cannot set up master outputs")
937 /* Tell all IO objects to connect themselves together */
939 IO::enable_connecting ();
941 /* Now reset all panners */
943 IO::reset_panners ();
945 /* Anyone who cares about input state, wake up and do something */
947 IOConnectionsComplete (); /* EMIT SIGNAL */
949 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
951 /* now handle the whole enchilada as if it was one
957 /* update mixer solo state */
963 Session::playlist_length_changed ()
965 /* we can't just increase end_location->end() if pl->get_maximum_extent()
966 if larger. if the playlist used to be the longest playlist,
967 and its now shorter, we have to decrease end_location->end(). hence,
968 we have to iterate over all diskstreams and check the
969 playlists currently in use.
975 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
977 boost::shared_ptr<Playlist> playlist;
979 if ((playlist = dstream->playlist()) != 0) {
980 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
983 /* see comment in playlist_length_changed () */
988 Session::record_enabling_legal () const
990 /* this used to be in here, but survey says.... we don't need to restrict it */
991 // if (record_status() == Recording) {
995 if (Config->get_all_safe()) {
1002 Session::reset_input_monitor_state ()
1004 if (transport_rolling()) {
1006 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1008 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1009 if ((*i)->record_enabled ()) {
1010 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1011 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1015 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1017 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1018 if ((*i)->record_enabled ()) {
1019 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1020 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1027 Session::auto_punch_start_changed (Location* location)
1029 replace_event (Event::PunchIn, location->start());
1031 if (get_record_enabled() && Config->get_punch_in()) {
1032 /* capture start has been changed, so save new pending state */
1033 save_state ("", true);
1038 Session::auto_punch_end_changed (Location* location)
1040 nframes_t when_to_stop = location->end();
1041 // when_to_stop += _worst_output_latency + _worst_input_latency;
1042 replace_event (Event::PunchOut, when_to_stop);
1046 Session::auto_punch_changed (Location* location)
1048 nframes_t when_to_stop = location->end();
1050 replace_event (Event::PunchIn, location->start());
1051 //when_to_stop += _worst_output_latency + _worst_input_latency;
1052 replace_event (Event::PunchOut, when_to_stop);
1056 Session::auto_loop_changed (Location* location)
1058 replace_event (Event::AutoLoop, location->end(), location->start());
1060 if (transport_rolling() && play_loop) {
1062 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1064 if (_transport_frame > location->end()) {
1065 // relocate to beginning of loop
1066 clear_events (Event::LocateRoll);
1068 request_locate (location->start(), true);
1071 else if (Config->get_seamless_loop() && !loop_changing) {
1073 // schedule a locate-roll to refill the diskstreams at the
1074 // previous loop end
1075 loop_changing = true;
1077 if (location->end() > last_loopend) {
1078 clear_events (Event::LocateRoll);
1079 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1086 last_loopend = location->end();
1091 Session::set_auto_punch_location (Location* location)
1095 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1096 auto_punch_start_changed_connection.disconnect();
1097 auto_punch_end_changed_connection.disconnect();
1098 auto_punch_changed_connection.disconnect();
1099 existing->set_auto_punch (false, this);
1100 remove_event (existing->start(), Event::PunchIn);
1101 clear_events (Event::PunchOut);
1102 auto_punch_location_changed (0);
1107 if (location == 0) {
1111 if (location->end() <= location->start()) {
1112 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1116 auto_punch_start_changed_connection.disconnect();
1117 auto_punch_end_changed_connection.disconnect();
1118 auto_punch_changed_connection.disconnect();
1120 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1121 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1122 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1124 location->set_auto_punch (true, this);
1125 auto_punch_location_changed (location);
1129 Session::set_auto_loop_location (Location* location)
1133 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1134 auto_loop_start_changed_connection.disconnect();
1135 auto_loop_end_changed_connection.disconnect();
1136 auto_loop_changed_connection.disconnect();
1137 existing->set_auto_loop (false, this);
1138 remove_event (existing->end(), Event::AutoLoop);
1139 auto_loop_location_changed (0);
1144 if (location == 0) {
1148 if (location->end() <= location->start()) {
1149 error << _("Session: you can't use a mark for auto loop") << endmsg;
1153 last_loopend = location->end();
1155 auto_loop_start_changed_connection.disconnect();
1156 auto_loop_end_changed_connection.disconnect();
1157 auto_loop_changed_connection.disconnect();
1159 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1160 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1161 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1163 location->set_auto_loop (true, this);
1164 auto_loop_location_changed (location);
1168 Session::locations_added (Location* ignored)
1174 Session::locations_changed ()
1176 _locations.apply (*this, &Session::handle_locations_changed);
1180 Session::handle_locations_changed (Locations::LocationList& locations)
1182 Locations::LocationList::iterator i;
1184 bool set_loop = false;
1185 bool set_punch = false;
1187 for (i = locations.begin(); i != locations.end(); ++i) {
1191 if (location->is_auto_punch()) {
1192 set_auto_punch_location (location);
1195 if (location->is_auto_loop()) {
1196 set_auto_loop_location (location);
1203 set_auto_loop_location (0);
1206 set_auto_punch_location (0);
1213 Session::enable_record ()
1215 /* XXX really atomic compare+swap here */
1216 if (g_atomic_int_get (&_record_status) != Recording) {
1217 g_atomic_int_set (&_record_status, Recording);
1218 _last_record_location = _transport_frame;
1219 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1221 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1222 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1223 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1224 if ((*i)->record_enabled ()) {
1225 (*i)->monitor_input (true);
1230 RecordStateChanged ();
1235 Session::disable_record (bool rt_context, bool force)
1239 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1241 if (!Config->get_latched_record_enable () || force) {
1242 g_atomic_int_set (&_record_status, Disabled);
1244 if (rs == Recording) {
1245 g_atomic_int_set (&_record_status, Enabled);
1249 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1251 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1252 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1254 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1255 if ((*i)->record_enabled ()) {
1256 (*i)->monitor_input (false);
1261 RecordStateChanged (); /* emit signal */
1264 remove_pending_capture_state ();
1270 Session::step_back_from_record ()
1272 g_atomic_int_set (&_record_status, Enabled);
1274 if (Config->get_monitoring_model() == HardwareMonitoring) {
1275 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1277 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1278 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1279 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1280 (*i)->monitor_input (false);
1287 Session::maybe_enable_record ()
1289 g_atomic_int_set (&_record_status, Enabled);
1291 /* this function is currently called from somewhere other than an RT thread.
1292 this save_state() call therefore doesn't impact anything.
1295 save_state ("", true);
1297 if (_transport_speed) {
1298 if (!Config->get_punch_in()) {
1302 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1303 RecordStateChanged (); /* EMIT SIGNAL */
1310 Session::audible_frame () const
1316 /* the first of these two possible settings for "offset"
1317 mean that the audible frame is stationary until
1318 audio emerges from the latency compensation
1321 the second means that the audible frame is stationary
1322 until audio would emerge from a physical port
1323 in the absence of any plugin latency compensation
1326 offset = _worst_output_latency;
1328 if (offset > current_block_size) {
1329 offset -= current_block_size;
1331 /* XXX is this correct? if we have no external
1332 physical connections and everything is internal
1333 then surely this is zero? still, how
1334 likely is that anyway?
1336 offset = current_block_size;
1339 if (synced_to_jack()) {
1340 tf = _engine.transport_frame();
1342 tf = _transport_frame;
1345 if (_transport_speed == 0) {
1355 if (!non_realtime_work_pending()) {
1359 /* take latency into account */
1368 Session::set_frame_rate (nframes_t frames_per_second)
1370 /** \fn void Session::set_frame_size(nframes_t)
1371 the AudioEngine object that calls this guarantees
1372 that it will not be called while we are also in
1373 ::process(). Its fine to do things that block
1377 _base_frame_rate = frames_per_second;
1381 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1383 // XXX we need some equivalent to this, somehow
1384 // SndFileSource::setup_standard_crossfades (frames_per_second);
1388 /* XXX need to reset/reinstantiate all LADSPA plugins */
1392 Session::set_block_size (nframes_t nframes)
1394 /* the AudioEngine guarantees
1395 that it will not be called while we are also in
1396 ::process(). It is therefore fine to do things that block
1401 vector<Sample*>::iterator i;
1404 current_block_size = nframes;
1406 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1410 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1414 _passthru_buffers.clear ();
1415 _silent_buffers.clear ();
1417 ensure_passthru_buffers (np);
1419 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1423 #ifdef NO_POSIX_MEMALIGN
1424 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1426 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1430 memset (*i, 0, sizeof (Sample) * current_block_size);
1434 if (_gain_automation_buffer) {
1435 delete [] _gain_automation_buffer;
1437 _gain_automation_buffer = new gain_t[nframes];
1439 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1441 boost::shared_ptr<RouteList> r = routes.reader ();
1443 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1444 (*i)->set_block_size (nframes);
1447 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1448 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1449 (*i)->set_block_size (nframes);
1452 set_worst_io_latencies ();
1457 Session::set_default_fade (float steepness, float fade_msecs)
1460 nframes_t fade_frames;
1462 /* Don't allow fade of less 1 frame */
1464 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1471 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1475 default_fade_msecs = fade_msecs;
1476 default_fade_steepness = steepness;
1479 // jlc, WTF is this!
1480 Glib::RWLock::ReaderLock lm (route_lock);
1481 AudioRegion::set_default_fade (steepness, fade_frames);
1486 /* XXX have to do this at some point */
1487 /* foreach region using default fade, reset, then
1488 refill_all_diskstream_buffers ();
1493 struct RouteSorter {
1494 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1495 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1497 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1500 if (r1->fed_by.empty()) {
1501 if (r2->fed_by.empty()) {
1502 /* no ardour-based connections inbound to either route. just use signal order */
1503 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1505 /* r2 has connections, r1 does not; run r1 early */
1509 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1516 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1518 shared_ptr<Route> r2;
1520 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1521 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1525 /* make a copy of the existing list of routes that feed r1 */
1527 set<shared_ptr<Route> > existing = r1->fed_by;
1529 /* for each route that feeds r1, recurse, marking it as feeding
1533 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1536 /* r2 is a route that feeds r1 which somehow feeds base. mark
1537 base as being fed by r2
1540 rbase->fed_by.insert (r2);
1544 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1548 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1552 /* now recurse, so that we can mark base as being fed by
1553 all routes that feed r2
1556 trace_terminal (r2, rbase);
1563 Session::resort_routes ()
1565 /* don't do anything here with signals emitted
1566 by Routes while we are being destroyed.
1569 if (_state_of_the_state & Deletion) {
1576 RCUWriter<RouteList> writer (routes);
1577 shared_ptr<RouteList> r = writer.get_copy ();
1578 resort_routes_using (r);
1579 /* writer goes out of scope and forces update */
1584 Session::resort_routes_using (shared_ptr<RouteList> r)
1586 RouteList::iterator i, j;
1588 for (i = r->begin(); i != r->end(); ++i) {
1590 (*i)->fed_by.clear ();
1592 for (j = r->begin(); j != r->end(); ++j) {
1594 /* although routes can feed themselves, it will
1595 cause an endless recursive descent if we
1596 detect it. so don't bother checking for
1604 if ((*j)->feeds (*i)) {
1605 (*i)->fed_by.insert (*j);
1610 for (i = r->begin(); i != r->end(); ++i) {
1611 trace_terminal (*i, *i);
1617 /* don't leave dangling references to routes in Route::fed_by */
1619 for (i = r->begin(); i != r->end(); ++i) {
1620 (*i)->fed_by.clear ();
1624 cerr << "finished route resort\n";
1626 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1627 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1634 list<boost::shared_ptr<AudioTrack> >
1635 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1637 char track_name[32];
1638 uint32_t track_id = 0;
1640 uint32_t channels_used = 0;
1642 RouteList new_routes;
1643 list<boost::shared_ptr<AudioTrack> > ret;
1644 uint32_t control_id;
1646 /* count existing audio tracks */
1649 shared_ptr<RouteList> r = routes.reader ();
1651 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1652 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1653 if (!(*i)->hidden()) {
1655 channels_used += (*i)->n_inputs();
1661 vector<string> physinputs;
1662 vector<string> physoutputs;
1663 uint32_t nphysical_in;
1664 uint32_t nphysical_out;
1666 _engine.get_physical_outputs (physoutputs);
1667 _engine.get_physical_inputs (physinputs);
1668 control_id = ntracks() + nbusses() + 1;
1672 /* check for duplicate route names, since we might have pre-existing
1673 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1674 save, close,restart,add new route - first named route is now
1682 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1684 if (route_by_name (track_name) == 0) {
1688 } while (track_id < (UINT_MAX-1));
1690 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1691 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1696 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1697 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1702 shared_ptr<AudioTrack> track;
1705 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1707 if (track->ensure_io (input_channels, output_channels, false, this)) {
1708 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1709 input_channels, output_channels)
1715 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1719 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1720 port = physinputs[(channels_used+x)%nphysical_in];
1723 if (port.length() && track->connect_input (track->input (x), port, this)) {
1729 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1733 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1734 port = physoutputs[(channels_used+x)%nphysical_out];
1735 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1737 port = _master_out->input (x%_master_out->n_inputs())->name();
1741 if (port.length() && track->connect_output (track->output (x), port, this)) {
1746 channels_used += track->n_inputs ();
1749 vector<string> cports;
1750 uint32_t ni = _control_out->n_inputs();
1752 for (n = 0; n < ni; ++n) {
1753 cports.push_back (_control_out->input(n)->name());
1756 track->set_control_outs (cports);
1759 // assert (current_thread != RT_thread)
1761 track->audio_diskstream()->non_realtime_input_change();
1763 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1764 track->set_remote_control_id (control_id);
1767 new_routes.push_back (track);
1768 ret.push_back (track);
1771 catch (failed_constructor &err) {
1772 error << _("Session: could not create new audio track.") << endmsg;
1775 /* we need to get rid of this, since the track failed to be created */
1776 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1779 RCUWriter<DiskstreamList> writer (diskstreams);
1780 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1781 ds->remove (track->audio_diskstream());
1788 catch (AudioEngine::PortRegistrationFailure& pfe) {
1790 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;
1793 /* we need to get rid of this, since the track failed to be created */
1794 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1797 RCUWriter<DiskstreamList> writer (diskstreams);
1798 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1799 ds->remove (track->audio_diskstream());
1810 if (!new_routes.empty()) {
1811 add_routes (new_routes, false);
1812 save_state (_current_snapshot_name);
1819 Session::set_remote_control_ids ()
1821 RemoteModel m = Config->get_remote_model();
1823 shared_ptr<RouteList> r = routes.reader ();
1825 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1826 if ( MixerOrdered == m) {
1827 long order = (*i)->order_key(N_("signal"));
1828 (*i)->set_remote_control_id( order+1 );
1829 } else if ( EditorOrdered == m) {
1830 long order = (*i)->order_key(N_("editor"));
1831 (*i)->set_remote_control_id( order+1 );
1832 } else if ( UserOrdered == m) {
1833 //do nothing ... only changes to remote id's are initiated by user
1840 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1843 uint32_t bus_id = 1;
1847 uint32_t control_id;
1849 /* count existing audio busses */
1852 shared_ptr<RouteList> r = routes.reader ();
1854 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1855 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1856 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1863 vector<string> physinputs;
1864 vector<string> physoutputs;
1866 _engine.get_physical_outputs (physoutputs);
1867 _engine.get_physical_inputs (physinputs);
1868 control_id = ntracks() + nbusses() + 1;
1873 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1875 if (route_by_name (bus_name) == 0) {
1879 } while (++bus_id < (UINT_MAX-1));
1882 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1884 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1885 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1886 input_channels, output_channels)
1891 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1895 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1896 port = physinputs[((n+x)%n_physical_inputs)];
1899 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1904 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1908 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1909 port = physoutputs[((n+x)%n_physical_outputs)];
1910 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1912 port = _master_out->input (x%_master_out->n_inputs())->name();
1916 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1922 vector<string> cports;
1923 uint32_t ni = _control_out->n_inputs();
1925 for (uint32_t n = 0; n < ni; ++n) {
1926 cports.push_back (_control_out->input(n)->name());
1928 bus->set_control_outs (cports);
1931 bus->set_remote_control_id (control_id);
1934 ret.push_back (bus);
1938 catch (failed_constructor &err) {
1939 error << _("Session: could not create new audio route.") << endmsg;
1943 catch (AudioEngine::PortRegistrationFailure& pfe) {
1944 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;
1954 add_routes (ret, false);
1955 save_state (_current_snapshot_name);
1963 Session::add_routes (RouteList& new_routes, bool save)
1966 RCUWriter<RouteList> writer (routes);
1967 shared_ptr<RouteList> r = writer.get_copy ();
1968 r->insert (r->end(), new_routes.begin(), new_routes.end());
1969 resort_routes_using (r);
1972 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1974 boost::weak_ptr<Route> wpr (*x);
1976 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1977 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1978 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1979 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1981 if ((*x)->master()) {
1985 if ((*x)->control()) {
1986 _control_out = (*x);
1993 save_state (_current_snapshot_name);
1996 RouteAdded (new_routes); /* EMIT SIGNAL */
2000 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2002 /* need to do this in case we're rolling at the time, to prevent false underruns */
2003 dstream->do_refill_with_alloc ();
2005 dstream->set_block_size (current_block_size);
2008 RCUWriter<DiskstreamList> writer (diskstreams);
2009 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2010 ds->push_back (dstream);
2011 /* writer goes out of scope, copies ds back to main */
2014 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2015 /* this will connect to future changes, and check the current length */
2016 diskstream_playlist_changed (dstream);
2018 dstream->prepare ();
2023 Session::remove_route (shared_ptr<Route> route)
2026 RCUWriter<RouteList> writer (routes);
2027 shared_ptr<RouteList> rs = writer.get_copy ();
2031 /* deleting the master out seems like a dumb
2032 idea, but its more of a UI policy issue
2036 if (route == _master_out) {
2037 _master_out = shared_ptr<Route> ();
2040 if (route == _control_out) {
2041 _control_out = shared_ptr<Route> ();
2043 /* cancel control outs for all routes */
2045 vector<string> empty;
2047 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2048 (*r)->set_control_outs (empty);
2052 update_route_solo_state ();
2054 /* writer goes out of scope, forces route list update */
2057 // FIXME: audio specific
2059 boost::shared_ptr<AudioDiskstream> ds;
2061 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2062 ds = at->audio_diskstream();
2068 RCUWriter<DiskstreamList> dsl (diskstreams);
2069 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2074 find_current_end ();
2076 update_latency_compensation (false, false);
2079 // We need to disconnect the routes inputs and outputs
2080 route->disconnect_inputs(NULL);
2081 route->disconnect_outputs(NULL);
2083 /* get rid of it from the dead wood collection in the route list manager */
2085 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2089 /* try to cause everyone to drop their references */
2091 route->drop_references ();
2093 /* save the new state of the world */
2095 if (save_state (_current_snapshot_name)) {
2096 save_history (_current_snapshot_name);
2101 Session::route_mute_changed (void* src)
2107 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2109 if (solo_update_disabled) {
2115 boost::shared_ptr<Route> route = wpr.lock ();
2118 /* should not happen */
2119 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2123 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2125 shared_ptr<RouteList> r = routes.reader ();
2127 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2129 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2133 /* don't mess with busses */
2135 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2141 /* don't mess with tracks */
2143 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2148 if ((*i) != route &&
2149 ((*i)->mix_group () == 0 ||
2150 (*i)->mix_group () != route->mix_group () ||
2151 !route->mix_group ()->is_active())) {
2153 if ((*i)->soloed()) {
2155 /* if its already soloed, and solo latching is enabled,
2156 then leave it as it is.
2159 if (Config->get_solo_latched()) {
2166 solo_update_disabled = true;
2167 (*i)->set_solo (false, src);
2168 solo_update_disabled = false;
2172 bool something_soloed = false;
2173 bool same_thing_soloed = false;
2174 bool signal = false;
2176 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2177 if ((*i)->soloed()) {
2178 something_soloed = true;
2179 if (dynamic_cast<AudioTrack*>((*i).get())) {
2181 same_thing_soloed = true;
2186 same_thing_soloed = true;
2194 if (something_soloed != currently_soloing) {
2196 currently_soloing = something_soloed;
2199 modify_solo_mute (is_track, same_thing_soloed);
2202 SoloActive (currently_soloing); /* EMIT SIGNAL */
2205 SoloChanged (); /* EMIT SIGNAL */
2211 Session::update_route_solo_state ()
2214 bool is_track = false;
2215 bool signal = false;
2217 /* caller must hold RouteLock */
2219 /* this is where we actually implement solo by changing
2220 the solo mute setting of each track.
2223 shared_ptr<RouteList> r = routes.reader ();
2225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 if ((*i)->soloed()) {
2228 if (dynamic_cast<AudioTrack*>((*i).get())) {
2235 if (mute != currently_soloing) {
2237 currently_soloing = mute;
2240 if (!is_track && !mute) {
2242 /* nothing is soloed */
2244 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2245 (*i)->set_solo_mute (false);
2255 modify_solo_mute (is_track, mute);
2258 SoloActive (currently_soloing);
2263 Session::modify_solo_mute (bool is_track, bool mute)
2265 shared_ptr<RouteList> r = routes.reader ();
2267 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2271 /* only alter track solo mute */
2273 if (dynamic_cast<AudioTrack*>((*i).get())) {
2274 if ((*i)->soloed()) {
2275 (*i)->set_solo_mute (!mute);
2277 (*i)->set_solo_mute (mute);
2283 /* only alter bus solo mute */
2285 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2287 if ((*i)->soloed()) {
2289 (*i)->set_solo_mute (false);
2293 /* don't mute master or control outs
2294 in response to another bus solo
2297 if ((*i) != _master_out &&
2298 (*i) != _control_out) {
2299 (*i)->set_solo_mute (mute);
2310 Session::catch_up_on_solo ()
2312 /* this is called after set_state() to catch the full solo
2313 state, which can't be correctly determined on a per-route
2314 basis, but needs the global overview that only the session
2317 update_route_solo_state();
2321 Session::route_by_name (string name)
2323 shared_ptr<RouteList> r = routes.reader ();
2325 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2326 if ((*i)->name() == name) {
2331 return shared_ptr<Route> ((Route*) 0);
2335 Session::route_by_id (PBD::ID id)
2337 shared_ptr<RouteList> r = routes.reader ();
2339 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2340 if ((*i)->id() == id) {
2345 return shared_ptr<Route> ((Route*) 0);
2349 Session::route_by_remote_id (uint32_t id)
2351 shared_ptr<RouteList> r = routes.reader ();
2353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2354 if ((*i)->remote_control_id() == id) {
2359 return shared_ptr<Route> ((Route*) 0);
2363 Session::find_current_end ()
2365 if (_state_of_the_state & Loading) {
2369 nframes_t max = get_maximum_extent ();
2371 if (max > end_location->end()) {
2372 end_location->set_end (max);
2374 DurationChanged(); /* EMIT SIGNAL */
2379 Session::get_maximum_extent () const
2384 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2386 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2387 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2388 if ((me = pl->get_maximum_extent()) > max) {
2396 boost::shared_ptr<Diskstream>
2397 Session::diskstream_by_name (string name)
2399 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2401 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2402 if ((*i)->name() == name) {
2407 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2410 boost::shared_ptr<Diskstream>
2411 Session::diskstream_by_id (const PBD::ID& id)
2413 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2415 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2416 if ((*i)->id() == id) {
2421 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2424 /* AudioRegion management */
2427 Session::new_region_name (string old)
2429 string::size_type last_period;
2431 string::size_type len = old.length() + 64;
2434 if ((last_period = old.find_last_of ('.')) == string::npos) {
2436 /* no period present - add one explicitly */
2439 last_period = old.length() - 1;
2444 number = atoi (old.substr (last_period+1).c_str());
2448 while (number < (UINT_MAX-1)) {
2450 AudioRegionList::const_iterator i;
2455 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2458 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2459 if (i->second->name() == sbuf) {
2464 if (i == audio_regions.end()) {
2469 if (number != (UINT_MAX-1)) {
2473 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2478 Session::region_name (string& result, string base, bool newlevel) const
2485 Glib::Mutex::Lock lm (region_lock);
2487 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2495 /* XXX this is going to be slow. optimize me later */
2500 string::size_type pos;
2502 pos = base.find_last_of ('.');
2504 /* pos may be npos, but then we just use entire base */
2506 subbase = base.substr (0, pos);
2510 bool name_taken = true;
2513 Glib::Mutex::Lock lm (region_lock);
2515 for (int n = 1; n < 5000; ++n) {
2518 snprintf (buf, sizeof (buf), ".%d", n);
2523 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2524 if (i->second->name() == result) {
2537 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2545 Session::add_region (boost::shared_ptr<Region> region)
2547 boost::shared_ptr<AudioRegion> ar;
2548 boost::shared_ptr<AudioRegion> oar;
2552 Glib::Mutex::Lock lm (region_lock);
2554 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2556 AudioRegionList::iterator x;
2558 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2560 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2562 if (ar->region_list_equivalent (oar)) {
2567 if (x == audio_regions.end()) {
2569 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2571 entry.first = region->id();
2574 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2586 fatal << _("programming error: ")
2587 << X_("unknown region type passed to Session::add_region()")
2594 /* mark dirty because something has changed even if we didn't
2595 add the region to the region list.
2601 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2602 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2603 AudioRegionAdded (ar); /* EMIT SIGNAL */
2608 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2610 boost::shared_ptr<Region> region (weak_region.lock ());
2616 if (what_changed & Region::HiddenChanged) {
2617 /* relay hidden changes */
2618 RegionHiddenChange (region);
2623 Session::remove_region (boost::weak_ptr<Region> weak_region)
2625 AudioRegionList::iterator i;
2626 boost::shared_ptr<Region> region (weak_region.lock ());
2632 boost::shared_ptr<AudioRegion> ar;
2633 bool removed = false;
2636 Glib::Mutex::Lock lm (region_lock);
2638 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2639 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2640 audio_regions.erase (i);
2646 fatal << _("programming error: ")
2647 << X_("unknown region type passed to Session::remove_region()")
2653 /* mark dirty because something has changed even if we didn't
2654 remove the region from the region list.
2660 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2664 boost::shared_ptr<AudioRegion>
2665 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2667 AudioRegionList::iterator i;
2668 boost::shared_ptr<AudioRegion> region;
2669 Glib::Mutex::Lock lm (region_lock);
2671 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2675 if (region->whole_file()) {
2677 if (child->source_equivalent (region)) {
2683 return boost::shared_ptr<AudioRegion> ();
2687 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2689 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2690 (*i)->get_region_list_equivalent_regions (region, result);
2694 Session::destroy_region (boost::shared_ptr<Region> region)
2696 vector<boost::shared_ptr<Source> > srcs;
2699 boost::shared_ptr<AudioRegion> aregion;
2701 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2705 if (aregion->playlist()) {
2706 aregion->playlist()->destroy_region (region);
2709 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2710 srcs.push_back (aregion->source (n));
2714 region->drop_references ();
2716 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2718 if (!(*i)->used()) {
2719 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2722 (afs)->mark_for_remove ();
2725 (*i)->drop_references ();
2727 cerr << "source was not used by any playlist\n";
2735 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2737 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2738 destroy_region (*i);
2744 Session::remove_last_capture ()
2746 list<boost::shared_ptr<Region> > r;
2748 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2750 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2751 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2754 r.insert (r.end(), l.begin(), l.end());
2759 destroy_regions (r);
2764 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2770 /* Source Management */
2773 Session::add_source (boost::shared_ptr<Source> source)
2775 boost::shared_ptr<AudioFileSource> afs;
2777 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2779 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2780 pair<AudioSourceList::iterator,bool> result;
2782 entry.first = source->id();
2786 Glib::Mutex::Lock lm (audio_source_lock);
2787 result = audio_sources.insert (entry);
2790 if (result.second) {
2791 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2799 Session::remove_source (boost::weak_ptr<Source> src)
2801 AudioSourceList::iterator i;
2802 boost::shared_ptr<Source> source = src.lock();
2809 Glib::Mutex::Lock lm (audio_source_lock);
2811 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2812 audio_sources.erase (i);
2816 if (!_state_of_the_state & InCleanup) {
2818 /* save state so we don't end up with a session file
2819 referring to non-existent sources.
2822 save_state (_current_snapshot_name);
2826 boost::shared_ptr<Source>
2827 Session::source_by_id (const PBD::ID& id)
2829 Glib::Mutex::Lock lm (audio_source_lock);
2830 AudioSourceList::iterator i;
2831 boost::shared_ptr<Source> source;
2833 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2837 /* XXX search MIDI or other searches here */
2843 boost::shared_ptr<Source>
2844 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2846 Glib::Mutex::Lock lm (audio_source_lock);
2848 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2849 cerr << "comparing " << path << " with " << i->second->name() << endl;
2850 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2852 if (afs && afs->path() == path && chn == afs->channel()) {
2857 return boost::shared_ptr<Source>();
2861 Session::peak_path_from_audio_path (string audio_path) const
2866 res += PBD::basename_nosuffix (audio_path);
2873 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2876 string old_basename = PBD::basename_nosuffix (oldname);
2877 string new_legalized = legalize_for_path (newname);
2879 /* note: we know (or assume) the old path is already valid */
2883 /* destructive file sources have a name of the form:
2885 /path/to/Tnnnn-NAME(%[LR])?.wav
2887 the task here is to replace NAME with the new name.
2890 /* find last slash */
2894 string::size_type slash;
2895 string::size_type dash;
2897 if ((slash = path.find_last_of ('/')) == string::npos) {
2901 dir = path.substr (0, slash+1);
2903 /* '-' is not a legal character for the NAME part of the path */
2905 if ((dash = path.find_last_of ('-')) == string::npos) {
2909 prefix = path.substr (slash+1, dash-(slash+1));
2914 path += new_legalized;
2915 path += ".wav"; /* XXX gag me with a spoon */
2919 /* non-destructive file sources have a name of the form:
2921 /path/to/NAME-nnnnn(%[LR])?.wav
2923 the task here is to replace NAME with the new name.
2928 string::size_type slash;
2929 string::size_type dash;
2930 string::size_type postfix;
2932 /* find last slash */
2934 if ((slash = path.find_last_of ('/')) == string::npos) {
2938 dir = path.substr (0, slash+1);
2940 /* '-' is not a legal character for the NAME part of the path */
2942 if ((dash = path.find_last_of ('-')) == string::npos) {
2946 suffix = path.substr (dash+1);
2948 // Suffix is now everything after the dash. Now we need to eliminate
2949 // the nnnnn part, which is done by either finding a '%' or a '.'
2951 postfix = suffix.find_last_of ("%");
2952 if (postfix == string::npos) {
2953 postfix = suffix.find_last_of ('.');
2956 if (postfix != string::npos) {
2957 suffix = suffix.substr (postfix);
2959 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2963 const uint32_t limit = 10000;
2964 char buf[PATH_MAX+1];
2966 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2968 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2970 if (access (buf, F_OK) != 0) {
2978 error << "FATAL ERROR! Could not find a " << endl;
2987 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2991 char buf[PATH_MAX+1];
2992 const uint32_t limit = 10000;
2996 legalized = legalize_for_path (name);
2998 /* find a "version" of the file name that doesn't exist in
2999 any of the possible directories.
3002 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3004 vector<space_and_path>::iterator i;
3005 uint32_t existing = 0;
3007 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3011 spath += sound_dir (false);
3015 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3016 } else if (nchan == 2) {
3018 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3020 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3022 } else if (nchan < 26) {
3023 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3025 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3034 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3035 } else if (nchan == 2) {
3037 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3039 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3041 } else if (nchan < 26) {
3042 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3044 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3048 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3054 if (existing == 0) {
3059 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3061 throw failed_constructor();
3065 /* we now have a unique name for the file, but figure out where to
3071 spath = discover_best_sound_dir ();
3074 string::size_type pos = foo.find_last_of ('/');
3076 if (pos == string::npos) {
3079 spath += foo.substr (pos + 1);
3085 boost::shared_ptr<AudioFileSource>
3086 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3088 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3089 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3092 /* Playlist management */
3094 boost::shared_ptr<Playlist>
3095 Session::playlist_by_name (string name)
3097 Glib::Mutex::Lock lm (playlist_lock);
3098 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3099 if ((*i)->name() == name) {
3103 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3104 if ((*i)->name() == name) {
3109 return boost::shared_ptr<Playlist>();
3113 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3115 if (playlist->hidden()) {
3120 Glib::Mutex::Lock lm (playlist_lock);
3121 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3122 playlists.insert (playlists.begin(), playlist);
3123 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3124 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3130 PlaylistAdded (playlist); /* EMIT SIGNAL */
3134 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3137 Glib::Mutex::Lock lm (playlist_lock);
3138 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3141 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3148 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3150 boost::shared_ptr<Playlist> pl(wpl.lock());
3156 PlaylistList::iterator x;
3159 /* its not supposed to be visible */
3164 Glib::Mutex::Lock lm (playlist_lock);
3168 unused_playlists.insert (pl);
3170 if ((x = playlists.find (pl)) != playlists.end()) {
3171 playlists.erase (x);
3177 playlists.insert (pl);
3179 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3180 unused_playlists.erase (x);
3187 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3189 if (_state_of_the_state & Deletion) {
3193 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3200 Glib::Mutex::Lock lm (playlist_lock);
3202 PlaylistList::iterator i;
3204 i = find (playlists.begin(), playlists.end(), playlist);
3205 if (i != playlists.end()) {
3206 playlists.erase (i);
3209 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3210 if (i != unused_playlists.end()) {
3211 unused_playlists.erase (i);
3218 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3222 Session::set_audition (boost::shared_ptr<Region> r)
3224 pending_audition_region = r;
3225 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3226 schedule_butler_transport_work ();
3230 Session::audition_playlist ()
3232 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3233 ev->region.reset ();
3238 Session::non_realtime_set_audition ()
3240 if (!pending_audition_region) {
3241 auditioner->audition_current_playlist ();
3243 auditioner->audition_region (pending_audition_region);
3244 pending_audition_region.reset ();
3246 AuditionActive (true); /* EMIT SIGNAL */
3250 Session::audition_region (boost::shared_ptr<Region> r)
3252 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3258 Session::cancel_audition ()
3260 if (auditioner->active()) {
3261 auditioner->cancel_audition ();
3262 AuditionActive (false); /* EMIT SIGNAL */
3267 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3269 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3273 Session::remove_empty_sounds ()
3275 PathScanner scanner;
3277 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3279 Glib::Mutex::Lock lm (audio_source_lock);
3281 regex_t compiled_tape_track_pattern;
3284 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3288 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3290 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3294 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3296 /* never remove files that appear to be a tape track */
3298 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3303 if (AudioFileSource::is_empty (*this, *(*i))) {
3305 unlink ((*i)->c_str());
3307 string peak_path = peak_path_from_audio_path (**i);
3308 unlink (peak_path.c_str());
3314 delete possible_audiofiles;
3318 Session::is_auditioning () const
3320 /* can be called before we have an auditioner object */
3322 return auditioner->active();
3329 Session::set_all_solo (bool yn)
3331 shared_ptr<RouteList> r = routes.reader ();
3333 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3334 if (!(*i)->hidden()) {
3335 (*i)->set_solo (yn, this);
3343 Session::set_all_mute (bool yn)
3345 shared_ptr<RouteList> r = routes.reader ();
3347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3348 if (!(*i)->hidden()) {
3349 (*i)->set_mute (yn, this);
3357 Session::n_diskstreams () const
3361 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3363 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3364 if (!(*i)->hidden()) {
3372 Session::graph_reordered ()
3374 /* don't do this stuff if we are setting up connections
3375 from a set_state() call or creating new tracks.
3378 if (_state_of_the_state & InitialConnecting) {
3382 /* every track/bus asked for this to be handled but it was deferred because
3383 we were connecting. do it now.
3386 request_input_change_handling ();
3390 /* force all diskstreams to update their capture offset values to
3391 reflect any changes in latencies within the graph.
3394 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3396 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3397 (*i)->set_capture_offset ();
3402 Session::record_disenable_all ()
3404 record_enable_change_all (false);
3408 Session::record_enable_all ()
3410 record_enable_change_all (true);
3414 Session::record_enable_change_all (bool yn)
3416 shared_ptr<RouteList> r = routes.reader ();
3418 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3421 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3422 at->set_record_enable (yn, this);
3426 /* since we don't keep rec-enable state, don't mark session dirty */
3430 Session::add_redirect (Redirect* redirect)
3434 PortInsert* port_insert;
3435 PluginInsert* plugin_insert;
3437 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3438 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3439 _port_inserts.insert (_port_inserts.begin(), port_insert);
3440 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3441 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3443 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3446 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3447 _sends.insert (_sends.begin(), send);
3449 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3453 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3459 Session::remove_redirect (Redirect* redirect)
3463 PortInsert* port_insert;
3464 PluginInsert* plugin_insert;
3466 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3467 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3468 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3469 if (x != _port_inserts.end()) {
3470 insert_bitset[port_insert->bit_slot()] = false;
3471 _port_inserts.erase (x);
3473 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3474 _plugin_inserts.remove (plugin_insert);
3476 fatal << string_compose (_("programming error: %1"),
3477 X_("unknown type of Insert deleted!"))
3481 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3482 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3483 if (x != _sends.end()) {
3484 send_bitset[send->bit_slot()] = false;
3488 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3496 Session::available_capture_duration ()
3498 float sample_bytes_on_disk = 4.0; // keep gcc happy
3500 switch (Config->get_native_file_data_format()) {
3502 sample_bytes_on_disk = 4.0;
3506 sample_bytes_on_disk = 3.0;
3510 /* impossible, but keep some gcc versions happy */
3511 fatal << string_compose (_("programming error: %1"),
3512 X_("illegal native file data format"))
3517 double scale = 4096.0 / sample_bytes_on_disk;
3519 if (_total_free_4k_blocks * scale > (double) max_frames) {
3523 return (nframes_t) floor (_total_free_4k_blocks * scale);
3527 Session::add_connection (ARDOUR::Connection* connection)
3530 Glib::Mutex::Lock guard (connection_lock);
3531 _connections.push_back (connection);
3534 ConnectionAdded (connection); /* EMIT SIGNAL */
3540 Session::remove_connection (ARDOUR::Connection* connection)
3542 bool removed = false;
3545 Glib::Mutex::Lock guard (connection_lock);
3546 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3548 if (i != _connections.end()) {
3549 _connections.erase (i);
3555 ConnectionRemoved (connection); /* EMIT SIGNAL */
3561 ARDOUR::Connection *
3562 Session::connection_by_name (string name) const
3564 Glib::Mutex::Lock lm (connection_lock);
3566 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3567 if ((*i)->name() == name) {
3576 Session::tempo_map_changed (Change ignored)
3583 Session::ensure_passthru_buffers (uint32_t howmany)
3585 while (howmany > _passthru_buffers.size()) {
3587 #ifdef NO_POSIX_MEMALIGN
3588 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3590 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3592 _passthru_buffers.push_back (p);
3596 #ifdef NO_POSIX_MEMALIGN
3597 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3599 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4);
3601 memset (p, 0, sizeof (Sample) * current_block_size);
3602 _silent_buffers.push_back (p);
3606 #ifdef NO_POSIX_MEMALIGN
3607 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3609 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3611 memset (p, 0, sizeof (Sample) * current_block_size);
3612 _send_buffers.push_back (p);
3615 allocate_pan_automation_buffers (current_block_size, howmany, false);
3619 Session::next_insert_id ()
3621 /* this doesn't really loop forever. just think about it */
3624 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3625 if (!insert_bitset[n]) {
3626 insert_bitset[n] = true;
3632 /* none available, so resize and try again */
3634 insert_bitset.resize (insert_bitset.size() + 16, false);
3639 Session::next_send_id ()
3641 /* this doesn't really loop forever. just think about it */
3644 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3645 if (!send_bitset[n]) {
3646 send_bitset[n] = true;
3652 /* none available, so resize and try again */
3654 send_bitset.resize (send_bitset.size() + 16, false);
3659 Session::mark_send_id (uint32_t id)
3661 if (id >= send_bitset.size()) {
3662 send_bitset.resize (id+16, false);
3664 if (send_bitset[id]) {
3665 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3667 send_bitset[id] = true;
3671 Session::mark_insert_id (uint32_t id)
3673 if (id >= insert_bitset.size()) {
3674 insert_bitset.resize (id+16, false);
3676 if (insert_bitset[id]) {
3677 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3679 insert_bitset[id] = true;
3682 /* Named Selection management */
3685 Session::named_selection_by_name (string name)
3687 Glib::Mutex::Lock lm (named_selection_lock);
3688 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3689 if ((*i)->name == name) {
3697 Session::add_named_selection (NamedSelection* named_selection)
3700 Glib::Mutex::Lock lm (named_selection_lock);
3701 named_selections.insert (named_selections.begin(), named_selection);
3704 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3710 NamedSelectionAdded (); /* EMIT SIGNAL */
3714 Session::remove_named_selection (NamedSelection* named_selection)
3716 bool removed = false;
3719 Glib::Mutex::Lock lm (named_selection_lock);
3721 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3723 if (i != named_selections.end()) {
3725 named_selections.erase (i);
3732 NamedSelectionRemoved (); /* EMIT SIGNAL */
3737 Session::reset_native_file_format ()
3739 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3741 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3742 (*i)->reset_write_sources (false);
3747 Session::route_name_unique (string n) const
3749 shared_ptr<RouteList> r = routes.reader ();
3751 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3752 if ((*i)->name() == n) {
3761 Session::n_playlists () const
3763 Glib::Mutex::Lock lm (playlist_lock);
3764 return playlists.size();
3768 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3770 if (!force && howmany <= _npan_buffers) {
3774 if (_pan_automation_buffer) {
3776 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3777 delete [] _pan_automation_buffer[i];
3780 delete [] _pan_automation_buffer;
3783 _pan_automation_buffer = new pan_t*[howmany];
3785 for (uint32_t i = 0; i < howmany; ++i) {
3786 _pan_automation_buffer[i] = new pan_t[nframes];
3789 _npan_buffers = howmany;
3793 Session::freeze (InterThreadInfo& itt)
3795 shared_ptr<RouteList> r = routes.reader ();
3797 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3801 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3802 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3813 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3814 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3817 boost::shared_ptr<Playlist> playlist;
3818 boost::shared_ptr<AudioFileSource> fsource;
3820 char buf[PATH_MAX+1];
3824 nframes_t this_chunk;
3826 vector<Sample*> buffers;
3828 // any bigger than this seems to cause stack overflows in called functions
3829 const nframes_t chunk_size = (128 * 1024)/4;
3831 g_atomic_int_set (&processing_prohibited, 1);
3833 /* call tree *MUST* hold route_lock */
3835 if ((playlist = track.diskstream()->playlist()) == 0) {
3839 /* external redirects will be a problem */
3841 if (track.has_external_redirects()) {
3845 nchans = track.audio_diskstream()->n_channels();
3847 dir = discover_best_sound_dir ();
3849 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3851 for (x = 0; x < 99999; ++x) {
3852 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3853 if (access (buf, F_OK) != 0) {
3859 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3864 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3867 catch (failed_constructor& err) {
3868 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3872 srcs.push_back (fsource);
3875 /* XXX need to flush all redirects */
3880 /* create a set of reasonably-sized buffers */
3882 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3884 #ifdef NO_POSIX_MEMALIGN
3885 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3887 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
3889 buffers.push_back (b);
3892 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3893 (*src)->prepare_for_peakfile_writes ();
3896 while (to_do && !itt.cancel) {
3898 this_chunk = min (to_do, chunk_size);
3900 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3905 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3906 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3909 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3915 start += this_chunk;
3916 to_do -= this_chunk;
3918 itt.progress = (float) (1.0 - ((double) to_do / len));
3927 xnow = localtime (&now);
3929 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3930 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3933 afs->update_header (position, *xnow, now);
3934 afs->flush_header ();
3938 /* construct a region to represent the bounced material */
3940 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3941 region_name_from_path (srcs.front()->name(), true));
3948 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3949 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3952 afs->mark_for_remove ();
3955 (*src)->drop_references ();
3959 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3960 (*src)->done_with_peakfile_writes ();
3964 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3968 g_atomic_int_set (&processing_prohibited, 0);
3976 Session::get_silent_buffers (uint32_t howmany)
3978 for (uint32_t i = 0; i < howmany; ++i) {
3979 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3981 return _silent_buffers;
3985 Session::ntracks () const
3988 shared_ptr<RouteList> r = routes.reader ();
3990 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3991 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4000 Session::nbusses () const
4003 shared_ptr<RouteList> r = routes.reader ();
4005 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4006 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4015 Session::add_automation_list(AutomationList *al)
4017 automation_lists[al->id()] = al;
4021 Session::compute_initial_length ()
4023 return _engine.frame_rate() * 60 * 5;