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;
471 (*i)->drop_references ();
476 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
477 PlaylistList::iterator tmp;
482 (*i)->drop_references ();
488 unused_playlists.clear ();
490 #ifdef TRACK_DESTRUCTION
491 cerr << "delete audio regions\n";
492 #endif /* TRACK_DESTRUCTION */
494 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
495 AudioRegionList::iterator tmp;
500 i->second->drop_references ();
505 audio_regions.clear ();
507 #ifdef TRACK_DESTRUCTION
508 cerr << "delete routes\n";
509 #endif /* TRACK_DESTRUCTION */
511 RCUWriter<RouteList> writer (routes);
512 boost::shared_ptr<RouteList> r = writer.get_copy ();
513 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
514 (*i)->drop_references ();
517 /* writer goes out of scope and updates master */
522 #ifdef TRACK_DESTRUCTION
523 cerr << "delete diskstreams\n";
524 #endif /* TRACK_DESTRUCTION */
526 RCUWriter<DiskstreamList> dwriter (diskstreams);
527 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
528 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
529 (*i)->drop_references ();
533 diskstreams.flush ();
535 #ifdef TRACK_DESTRUCTION
536 cerr << "delete audio sources\n";
537 #endif /* TRACK_DESTRUCTION */
538 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
539 AudioSourceList::iterator tmp;
544 i->second->drop_references ();
549 audio_sources.clear ();
551 #ifdef TRACK_DESTRUCTION
552 cerr << "delete mix groups\n";
553 #endif /* TRACK_DESTRUCTION */
554 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
555 list<RouteGroup*>::iterator tmp;
565 #ifdef TRACK_DESTRUCTION
566 cerr << "delete edit groups\n";
567 #endif /* TRACK_DESTRUCTION */
568 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
569 list<RouteGroup*>::iterator tmp;
579 #ifdef TRACK_DESTRUCTION
580 cerr << "delete connections\n";
581 #endif /* TRACK_DESTRUCTION */
582 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
583 ConnectionList::iterator tmp;
593 if (butler_mixdown_buffer) {
594 delete [] butler_mixdown_buffer;
597 if (butler_gain_buffer) {
598 delete [] butler_gain_buffer;
601 Crossfade::set_buffer_size (0);
609 Session::set_worst_io_latencies ()
611 _worst_output_latency = 0;
612 _worst_input_latency = 0;
614 if (!_engine.connected()) {
618 boost::shared_ptr<RouteList> r = routes.reader ();
620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
621 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
622 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
627 Session::when_engine_running ()
629 string first_physical_output;
631 /* we don't want to run execute this again */
633 set_block_size (_engine.frames_per_cycle());
634 set_frame_rate (_engine.frame_rate());
636 Config->map_parameters (mem_fun (*this, &Session::config_changed));
638 /* every time we reconnect, recompute worst case output latencies */
640 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
642 if (synced_to_jack()) {
643 _engine.transport_stop ();
646 if (Config->get_jack_time_master()) {
647 _engine.transport_locate (_transport_frame);
655 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
657 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
659 /* existing state for Click */
661 if (_click_io->set_state (*child->children().front()) == 0) {
663 _clicking = Config->get_clicking ();
667 error << _("could not setup Click I/O") << endmsg;
673 /* default state for Click */
675 first_physical_output = _engine.get_nth_physical_output (0);
677 if (first_physical_output.length()) {
678 if (_click_io->add_output_port (first_physical_output, this)) {
679 // relax, even though its an error
681 _clicking = Config->get_clicking ();
687 catch (failed_constructor& err) {
688 error << _("cannot setup Click I/O") << endmsg;
691 set_worst_io_latencies ();
694 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
697 /* Create a set of Connection objects that map
698 to the physical outputs currently available
703 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
705 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
707 Connection* c = new OutputConnection (buf, true);
710 c->add_connection (0, _engine.get_nth_physical_output (np));
715 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
717 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
719 Connection* c = new InputConnection (buf, true);
722 c->add_connection (0, _engine.get_nth_physical_input (np));
729 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
731 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
733 Connection* c = new OutputConnection (buf, true);
737 c->add_connection (0, _engine.get_nth_physical_output (np));
738 c->add_connection (1, _engine.get_nth_physical_output (np+1));
743 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
745 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
747 Connection* c = new InputConnection (buf, true);
751 c->add_connection (0, _engine.get_nth_physical_input (np));
752 c->add_connection (1, _engine.get_nth_physical_input (np+1));
761 /* create master/control ports */
766 /* force the master to ignore any later call to this */
768 if (_master_out->pending_state_node) {
769 _master_out->ports_became_legal();
772 /* no panner resets till we are through */
774 _master_out->defer_pan_reset ();
776 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
777 if (_master_out->add_input_port ("", this)) {
778 error << _("cannot setup master inputs")
784 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
785 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
786 error << _("cannot setup master outputs")
793 _master_out->allow_pan_reset ();
797 Connection* c = new OutputConnection (_("Master Out"), true);
799 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
801 c->add_connection ((int) n, _master_out->input(n)->name());
808 /* catch up on send+insert cnts */
812 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
815 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
816 if (id > insert_cnt) {
824 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
827 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
835 /* its safe to do this now */
837 restore_history (snap_name());
839 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
841 /* hook us up to the engine */
843 _engine.set_session (this);
848 osc->set_session (*this);
851 _state_of_the_state = Clean;
853 DirtyChanged (); /* EMIT SIGNAL */
857 Session::hookup_io ()
859 /* stop graph reordering notifications from
860 causing resorts, etc.
863 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
864 cerr << "InitialConnecting set\n";
866 if (auditioner == 0) {
868 /* we delay creating the auditioner till now because
869 it makes its own connections to ports.
870 the engine has to be running for this to work.
874 auditioner.reset (new Auditioner (*this));
877 catch (failed_constructor& err) {
878 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
882 /* Tell all IO objects to create their ports */
889 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
890 if (_control_out->add_input_port ("", this)) {
891 error << _("cannot setup control inputs")
897 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
898 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
899 error << _("cannot set up master outputs")
907 /* Tell all IO objects to connect themselves together */
909 IO::enable_connecting ();
911 /* Now reset all panners */
913 IO::reset_panners ();
915 /* Anyone who cares about input state, wake up and do something */
917 IOConnectionsComplete (); /* EMIT SIGNAL */
919 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
920 cerr << "InitialConnectingUN set\n";
922 /* now handle the whole enchilada as if it was one
928 /* update mixer solo state */
934 Session::playlist_length_changed ()
936 /* we can't just increase end_location->end() if pl->get_maximum_extent()
937 if larger. if the playlist used to be the longest playlist,
938 and its now shorter, we have to decrease end_location->end(). hence,
939 we have to iterate over all diskstreams and check the
940 playlists currently in use.
946 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
948 boost::shared_ptr<Playlist> playlist;
950 if ((playlist = dstream->playlist()) != 0) {
951 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
954 /* see comment in playlist_length_changed () */
959 Session::record_enabling_legal () const
961 /* this used to be in here, but survey says.... we don't need to restrict it */
962 // if (record_status() == Recording) {
966 if (Config->get_all_safe()) {
973 Session::reset_input_monitor_state ()
975 if (transport_rolling()) {
977 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
979 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
980 if ((*i)->record_enabled ()) {
981 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
982 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
986 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
988 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
989 if ((*i)->record_enabled ()) {
990 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
991 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
998 Session::auto_punch_start_changed (Location* location)
1000 replace_event (Event::PunchIn, location->start());
1002 if (get_record_enabled() && Config->get_punch_in()) {
1003 /* capture start has been changed, so save new pending state */
1004 save_state ("", true);
1009 Session::auto_punch_end_changed (Location* location)
1011 nframes_t when_to_stop = location->end();
1012 // when_to_stop += _worst_output_latency + _worst_input_latency;
1013 replace_event (Event::PunchOut, when_to_stop);
1017 Session::auto_punch_changed (Location* location)
1019 nframes_t when_to_stop = location->end();
1021 replace_event (Event::PunchIn, location->start());
1022 //when_to_stop += _worst_output_latency + _worst_input_latency;
1023 replace_event (Event::PunchOut, when_to_stop);
1027 Session::auto_loop_changed (Location* location)
1029 replace_event (Event::AutoLoop, location->end(), location->start());
1031 if (transport_rolling() && play_loop) {
1033 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1035 if (_transport_frame > location->end()) {
1036 // relocate to beginning of loop
1037 clear_events (Event::LocateRoll);
1039 request_locate (location->start(), true);
1042 else if (Config->get_seamless_loop() && !loop_changing) {
1044 // schedule a locate-roll to refill the diskstreams at the
1045 // previous loop end
1046 loop_changing = true;
1048 if (location->end() > last_loopend) {
1049 clear_events (Event::LocateRoll);
1050 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1057 last_loopend = location->end();
1062 Session::set_auto_punch_location (Location* location)
1066 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1067 auto_punch_start_changed_connection.disconnect();
1068 auto_punch_end_changed_connection.disconnect();
1069 auto_punch_changed_connection.disconnect();
1070 existing->set_auto_punch (false, this);
1071 remove_event (existing->start(), Event::PunchIn);
1072 clear_events (Event::PunchOut);
1073 auto_punch_location_changed (0);
1078 if (location == 0) {
1082 if (location->end() <= location->start()) {
1083 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1087 auto_punch_start_changed_connection.disconnect();
1088 auto_punch_end_changed_connection.disconnect();
1089 auto_punch_changed_connection.disconnect();
1091 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1092 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1093 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1095 location->set_auto_punch (true, this);
1096 auto_punch_location_changed (location);
1100 Session::set_auto_loop_location (Location* location)
1104 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1105 auto_loop_start_changed_connection.disconnect();
1106 auto_loop_end_changed_connection.disconnect();
1107 auto_loop_changed_connection.disconnect();
1108 existing->set_auto_loop (false, this);
1109 remove_event (existing->end(), Event::AutoLoop);
1110 auto_loop_location_changed (0);
1115 if (location == 0) {
1119 if (location->end() <= location->start()) {
1120 error << _("Session: you can't use a mark for auto loop") << endmsg;
1124 last_loopend = location->end();
1126 auto_loop_start_changed_connection.disconnect();
1127 auto_loop_end_changed_connection.disconnect();
1128 auto_loop_changed_connection.disconnect();
1130 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1131 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1132 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1134 location->set_auto_loop (true, this);
1135 auto_loop_location_changed (location);
1139 Session::locations_added (Location* ignored)
1145 Session::locations_changed ()
1147 _locations.apply (*this, &Session::handle_locations_changed);
1151 Session::handle_locations_changed (Locations::LocationList& locations)
1153 Locations::LocationList::iterator i;
1155 bool set_loop = false;
1156 bool set_punch = false;
1158 for (i = locations.begin(); i != locations.end(); ++i) {
1162 if (location->is_auto_punch()) {
1163 set_auto_punch_location (location);
1166 if (location->is_auto_loop()) {
1167 set_auto_loop_location (location);
1174 set_auto_loop_location (0);
1177 set_auto_punch_location (0);
1184 Session::enable_record ()
1186 /* XXX really atomic compare+swap here */
1187 if (g_atomic_int_get (&_record_status) != Recording) {
1188 g_atomic_int_set (&_record_status, Recording);
1189 _last_record_location = _transport_frame;
1190 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1192 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1193 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1194 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1195 if ((*i)->record_enabled ()) {
1196 (*i)->monitor_input (true);
1201 RecordStateChanged ();
1206 Session::disable_record (bool rt_context, bool force)
1210 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1212 if (!Config->get_latched_record_enable () || force) {
1213 g_atomic_int_set (&_record_status, Disabled);
1215 if (rs == Recording) {
1216 g_atomic_int_set (&_record_status, Enabled);
1220 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1222 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1223 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1225 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1226 if ((*i)->record_enabled ()) {
1227 (*i)->monitor_input (false);
1232 RecordStateChanged (); /* emit signal */
1235 remove_pending_capture_state ();
1241 Session::step_back_from_record ()
1243 g_atomic_int_set (&_record_status, Enabled);
1245 if (Config->get_monitoring_model() == HardwareMonitoring) {
1246 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1248 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1249 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1250 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1251 (*i)->monitor_input (false);
1258 Session::maybe_enable_record ()
1260 g_atomic_int_set (&_record_status, Enabled);
1262 /* this function is currently called from somewhere other than an RT thread.
1263 this save_state() call therefore doesn't impact anything.
1266 save_state ("", true);
1268 if (_transport_speed) {
1269 if (!Config->get_punch_in()) {
1273 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1274 RecordStateChanged (); /* EMIT SIGNAL */
1281 Session::audible_frame () const
1287 /* the first of these two possible settings for "offset"
1288 mean that the audible frame is stationary until
1289 audio emerges from the latency compensation
1292 the second means that the audible frame is stationary
1293 until audio would emerge from a physical port
1294 in the absence of any plugin latency compensation
1297 offset = _worst_output_latency;
1299 if (offset > current_block_size) {
1300 offset -= current_block_size;
1302 /* XXX is this correct? if we have no external
1303 physical connections and everything is internal
1304 then surely this is zero? still, how
1305 likely is that anyway?
1307 offset = current_block_size;
1310 if (synced_to_jack()) {
1311 tf = _engine.transport_frame();
1313 tf = _transport_frame;
1316 if (_transport_speed == 0) {
1326 if (!non_realtime_work_pending()) {
1330 /* take latency into account */
1339 Session::set_frame_rate (nframes_t frames_per_second)
1341 /** \fn void Session::set_frame_size(nframes_t)
1342 the AudioEngine object that calls this guarantees
1343 that it will not be called while we are also in
1344 ::process(). Its fine to do things that block
1348 _base_frame_rate = frames_per_second;
1352 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1354 // XXX we need some equivalent to this, somehow
1355 // SndFileSource::setup_standard_crossfades (frames_per_second);
1359 /* XXX need to reset/reinstantiate all LADSPA plugins */
1363 Session::set_block_size (nframes_t nframes)
1365 /* the AudioEngine guarantees
1366 that it will not be called while we are also in
1367 ::process(). It is therefore fine to do things that block
1372 vector<Sample*>::iterator i;
1375 current_block_size = nframes;
1377 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1381 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1385 _passthru_buffers.clear ();
1386 _silent_buffers.clear ();
1388 ensure_passthru_buffers (np);
1390 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1394 #ifdef NO_POSIX_MEMALIGN
1395 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1397 posix_memalign((void **)&buf,16,current_block_size * 4);
1401 memset (*i, 0, sizeof (Sample) * current_block_size);
1405 if (_gain_automation_buffer) {
1406 delete [] _gain_automation_buffer;
1408 _gain_automation_buffer = new gain_t[nframes];
1410 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1412 boost::shared_ptr<RouteList> r = routes.reader ();
1414 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1415 (*i)->set_block_size (nframes);
1418 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1419 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1420 (*i)->set_block_size (nframes);
1423 set_worst_io_latencies ();
1428 Session::set_default_fade (float steepness, float fade_msecs)
1431 nframes_t fade_frames;
1433 /* Don't allow fade of less 1 frame */
1435 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1442 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1446 default_fade_msecs = fade_msecs;
1447 default_fade_steepness = steepness;
1450 // jlc, WTF is this!
1451 Glib::RWLock::ReaderLock lm (route_lock);
1452 AudioRegion::set_default_fade (steepness, fade_frames);
1457 /* XXX have to do this at some point */
1458 /* foreach region using default fade, reset, then
1459 refill_all_diskstream_buffers ();
1464 struct RouteSorter {
1465 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1466 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1468 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1471 if (r1->fed_by.empty()) {
1472 if (r2->fed_by.empty()) {
1473 /* no ardour-based connections inbound to either route. just use signal order */
1474 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1476 /* r2 has connections, r1 does not; run r1 early */
1480 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1487 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1489 shared_ptr<Route> r2;
1491 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1492 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1496 /* make a copy of the existing list of routes that feed r1 */
1498 set<shared_ptr<Route> > existing = r1->fed_by;
1500 /* for each route that feeds r1, recurse, marking it as feeding
1504 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1507 /* r2 is a route that feeds r1 which somehow feeds base. mark
1508 base as being fed by r2
1511 rbase->fed_by.insert (r2);
1515 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1519 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1523 /* now recurse, so that we can mark base as being fed by
1524 all routes that feed r2
1527 trace_terminal (r2, rbase);
1534 Session::resort_routes ()
1536 /* don't do anything here with signals emitted
1537 by Routes while we are being destroyed.
1540 if (_state_of_the_state & Deletion) {
1547 RCUWriter<RouteList> writer (routes);
1548 shared_ptr<RouteList> r = writer.get_copy ();
1549 resort_routes_using (r);
1550 /* writer goes out of scope and forces update */
1555 Session::resort_routes_using (shared_ptr<RouteList> r)
1557 RouteList::iterator i, j;
1559 for (i = r->begin(); i != r->end(); ++i) {
1561 (*i)->fed_by.clear ();
1563 for (j = r->begin(); j != r->end(); ++j) {
1565 /* although routes can feed themselves, it will
1566 cause an endless recursive descent if we
1567 detect it. so don't bother checking for
1575 if ((*j)->feeds (*i)) {
1576 (*i)->fed_by.insert (*j);
1581 for (i = r->begin(); i != r->end(); ++i) {
1582 trace_terminal (*i, *i);
1588 /* don't leave dangling references to routes in Route::fed_by */
1590 for (i = r->begin(); i != r->end(); ++i) {
1591 (*i)->fed_by.clear ();
1595 cerr << "finished route resort\n";
1597 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1598 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1605 list<boost::shared_ptr<AudioTrack> >
1606 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1608 char track_name[32];
1609 uint32_t track_id = 0;
1611 uint32_t channels_used = 0;
1613 RouteList new_routes;
1614 list<boost::shared_ptr<AudioTrack> > ret;
1616 /* count existing audio tracks */
1619 shared_ptr<RouteList> r = routes.reader ();
1621 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1622 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1623 if (!(*i)->hidden()) {
1625 channels_used += (*i)->n_inputs();
1631 vector<string> physinputs;
1632 vector<string> physoutputs;
1633 uint32_t nphysical_in;
1634 uint32_t nphysical_out;
1636 _engine.get_physical_outputs (physoutputs);
1637 _engine.get_physical_inputs (physinputs);
1641 /* check for duplicate route names, since we might have pre-existing
1642 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1643 save, close,restart,add new route - first named route is now
1651 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1653 if (route_by_name (track_name) == 0) {
1657 } while (track_id < (UINT_MAX-1));
1659 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1660 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1665 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1666 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1672 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1674 if (track->ensure_io (input_channels, output_channels, false, this)) {
1675 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1676 input_channels, output_channels)
1681 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1685 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1686 port = physinputs[(channels_used+x)%nphysical_in];
1689 if (port.length() && track->connect_input (track->input (x), port, this)) {
1695 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1699 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1700 port = physoutputs[(channels_used+x)%nphysical_out];
1701 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1703 port = _master_out->input (x%_master_out->n_inputs())->name();
1707 if (port.length() && track->connect_output (track->output (x), port, this)) {
1712 channels_used += track->n_inputs ();
1715 vector<string> cports;
1716 uint32_t ni = _control_out->n_inputs();
1718 for (n = 0; n < ni; ++n) {
1719 cports.push_back (_control_out->input(n)->name());
1722 track->set_control_outs (cports);
1725 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1726 track->set_remote_control_id (ntracks());
1728 new_routes.push_back (track);
1729 ret.push_back (track);
1732 catch (failed_constructor &err) {
1733 error << _("Session: could not create new audio track.") << endmsg;
1734 // XXX should we delete the tracks already created?
1742 if (!new_routes.empty()) {
1743 add_routes (new_routes, false);
1744 save_state (_current_snapshot_name);
1751 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1754 uint32_t bus_id = 1;
1759 /* count existing audio busses */
1762 shared_ptr<RouteList> r = routes.reader ();
1764 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1765 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1766 if (!(*i)->hidden()) {
1773 vector<string> physinputs;
1774 vector<string> physoutputs;
1776 _engine.get_physical_outputs (physoutputs);
1777 _engine.get_physical_inputs (physinputs);
1784 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1786 if (route_by_name (bus_name) == 0) {
1790 } while (bus_id < (UINT_MAX-1));
1793 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1795 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1796 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1797 input_channels, output_channels)
1801 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1805 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1806 port = physinputs[((n+x)%n_physical_inputs)];
1809 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1814 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1818 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1819 port = physoutputs[((n+x)%n_physical_outputs)];
1820 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1822 port = _master_out->input (x%_master_out->n_inputs())->name();
1826 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1832 vector<string> cports;
1833 uint32_t ni = _control_out->n_inputs();
1835 for (uint32_t n = 0; n < ni; ++n) {
1836 cports.push_back (_control_out->input(n)->name());
1838 bus->set_control_outs (cports);
1841 ret.push_back (bus);
1845 catch (failed_constructor &err) {
1846 error << _("Session: could not create new audio route.") << endmsg;
1855 add_routes (ret, false);
1856 save_state (_current_snapshot_name);
1864 Session::add_routes (RouteList& new_routes, bool save)
1867 RCUWriter<RouteList> writer (routes);
1868 shared_ptr<RouteList> r = writer.get_copy ();
1869 r->insert (r->end(), new_routes.begin(), new_routes.end());
1870 resort_routes_using (r);
1873 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1875 boost::weak_ptr<Route> wpr (*x);
1877 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1878 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1879 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1880 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1882 if ((*x)->master()) {
1886 if ((*x)->control()) {
1887 _control_out = (*x);
1894 save_state (_current_snapshot_name);
1897 RouteAdded (new_routes); /* EMIT SIGNAL */
1901 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1903 /* need to do this in case we're rolling at the time, to prevent false underruns */
1904 dstream->do_refill_with_alloc();
1907 RCUWriter<DiskstreamList> writer (diskstreams);
1908 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1909 ds->push_back (dstream);
1912 dstream->set_block_size (current_block_size);
1914 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1915 /* this will connect to future changes, and check the current length */
1916 diskstream_playlist_changed (dstream);
1918 dstream->prepare ();
1922 Session::remove_route (shared_ptr<Route> route)
1925 RCUWriter<RouteList> writer (routes);
1926 shared_ptr<RouteList> rs = writer.get_copy ();
1930 /* deleting the master out seems like a dumb
1931 idea, but its more of a UI policy issue
1935 if (route == _master_out) {
1936 _master_out = shared_ptr<Route> ();
1939 if (route == _control_out) {
1940 _control_out = shared_ptr<Route> ();
1942 /* cancel control outs for all routes */
1944 vector<string> empty;
1946 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1947 (*r)->set_control_outs (empty);
1951 update_route_solo_state ();
1953 /* writer goes out of scope, forces route list update */
1956 // FIXME: audio specific
1958 boost::shared_ptr<AudioDiskstream> ds;
1960 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1961 ds = at->audio_diskstream();
1967 RCUWriter<DiskstreamList> dsl (diskstreams);
1968 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1973 find_current_end ();
1975 update_latency_compensation (false, false);
1978 // We need to disconnect the routes inputs and outputs
1979 route->disconnect_inputs(NULL);
1980 route->disconnect_outputs(NULL);
1982 /* get rid of it from the dead wood collection in the route list manager */
1984 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1988 /* try to cause everyone to drop their references */
1990 route->drop_references ();
1992 /* save the new state of the world */
1994 if (save_state (_current_snapshot_name)) {
1995 save_history (_current_snapshot_name);
2000 Session::route_mute_changed (void* src)
2006 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2008 if (solo_update_disabled) {
2014 boost::shared_ptr<Route> route = wpr.lock ();
2017 /* should not happen */
2018 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2022 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2024 shared_ptr<RouteList> r = routes.reader ();
2026 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2028 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2032 /* don't mess with busses */
2034 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2040 /* don't mess with tracks */
2042 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2047 if ((*i) != route &&
2048 ((*i)->mix_group () == 0 ||
2049 (*i)->mix_group () != route->mix_group () ||
2050 !route->mix_group ()->is_active())) {
2052 if ((*i)->soloed()) {
2054 /* if its already soloed, and solo latching is enabled,
2055 then leave it as it is.
2058 if (Config->get_solo_latched()) {
2065 solo_update_disabled = true;
2066 (*i)->set_solo (false, src);
2067 solo_update_disabled = false;
2071 bool something_soloed = false;
2072 bool same_thing_soloed = false;
2073 bool signal = false;
2075 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2076 if ((*i)->soloed()) {
2077 something_soloed = true;
2078 if (dynamic_cast<AudioTrack*>((*i).get())) {
2080 same_thing_soloed = true;
2085 same_thing_soloed = true;
2093 if (something_soloed != currently_soloing) {
2095 currently_soloing = something_soloed;
2098 modify_solo_mute (is_track, same_thing_soloed);
2101 SoloActive (currently_soloing);
2108 Session::update_route_solo_state ()
2111 bool is_track = false;
2112 bool signal = false;
2114 /* caller must hold RouteLock */
2116 /* this is where we actually implement solo by changing
2117 the solo mute setting of each track.
2120 shared_ptr<RouteList> r = routes.reader ();
2122 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 if ((*i)->soloed()) {
2125 if (dynamic_cast<AudioTrack*>((*i).get())) {
2132 if (mute != currently_soloing) {
2134 currently_soloing = mute;
2137 if (!is_track && !mute) {
2139 /* nothing is soloed */
2141 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2142 (*i)->set_solo_mute (false);
2152 modify_solo_mute (is_track, mute);
2155 SoloActive (currently_soloing);
2160 Session::modify_solo_mute (bool is_track, bool mute)
2162 shared_ptr<RouteList> r = routes.reader ();
2164 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 /* only alter track solo mute */
2170 if (dynamic_cast<AudioTrack*>((*i).get())) {
2171 if ((*i)->soloed()) {
2172 (*i)->set_solo_mute (!mute);
2174 (*i)->set_solo_mute (mute);
2180 /* only alter bus solo mute */
2182 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2184 if ((*i)->soloed()) {
2186 (*i)->set_solo_mute (false);
2190 /* don't mute master or control outs
2191 in response to another bus solo
2194 if ((*i) != _master_out &&
2195 (*i) != _control_out) {
2196 (*i)->set_solo_mute (mute);
2207 Session::catch_up_on_solo ()
2209 /* this is called after set_state() to catch the full solo
2210 state, which can't be correctly determined on a per-route
2211 basis, but needs the global overview that only the session
2214 update_route_solo_state();
2218 Session::route_by_name (string name)
2220 shared_ptr<RouteList> r = routes.reader ();
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2223 if ((*i)->name() == name) {
2228 return shared_ptr<Route> ((Route*) 0);
2232 Session::route_by_id (PBD::ID id)
2234 shared_ptr<RouteList> r = routes.reader ();
2236 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2237 if ((*i)->id() == id) {
2242 return shared_ptr<Route> ((Route*) 0);
2246 Session::route_by_remote_id (uint32_t id)
2248 shared_ptr<RouteList> r = routes.reader ();
2250 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2251 if ((*i)->remote_control_id() == id) {
2256 return shared_ptr<Route> ((Route*) 0);
2260 Session::find_current_end ()
2262 if (_state_of_the_state & Loading) {
2266 nframes_t max = get_maximum_extent ();
2268 if (max > end_location->end()) {
2269 end_location->set_end (max);
2271 DurationChanged(); /* EMIT SIGNAL */
2276 Session::get_maximum_extent () const
2281 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2283 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2284 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2285 if ((me = pl->get_maximum_extent()) > max) {
2293 boost::shared_ptr<Diskstream>
2294 Session::diskstream_by_name (string name)
2296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2299 if ((*i)->name() == name) {
2304 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2307 boost::shared_ptr<Diskstream>
2308 Session::diskstream_by_id (const PBD::ID& id)
2310 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2312 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2313 if ((*i)->id() == id) {
2318 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2321 /* AudioRegion management */
2324 Session::new_region_name (string old)
2326 string::size_type last_period;
2328 string::size_type len = old.length() + 64;
2331 if ((last_period = old.find_last_of ('.')) == string::npos) {
2333 /* no period present - add one explicitly */
2336 last_period = old.length() - 1;
2341 number = atoi (old.substr (last_period+1).c_str());
2345 while (number < (UINT_MAX-1)) {
2347 AudioRegionList::const_iterator i;
2352 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2355 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2356 if (i->second->name() == sbuf) {
2361 if (i == audio_regions.end()) {
2366 if (number != (UINT_MAX-1)) {
2370 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2375 Session::region_name (string& result, string base, bool newlevel) const
2382 Glib::Mutex::Lock lm (region_lock);
2384 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2392 /* XXX this is going to be slow. optimize me later */
2397 string::size_type pos;
2399 pos = base.find_last_of ('.');
2401 /* pos may be npos, but then we just use entire base */
2403 subbase = base.substr (0, pos);
2407 bool name_taken = true;
2410 Glib::Mutex::Lock lm (region_lock);
2412 for (int n = 1; n < 5000; ++n) {
2415 snprintf (buf, sizeof (buf), ".%d", n);
2420 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2421 if (i->second->name() == result) {
2434 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2442 Session::add_region (boost::shared_ptr<Region> region)
2444 boost::shared_ptr<AudioRegion> ar;
2445 boost::shared_ptr<AudioRegion> oar;
2449 Glib::Mutex::Lock lm (region_lock);
2451 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2453 AudioRegionList::iterator x;
2455 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2457 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2459 if (ar->region_list_equivalent (oar)) {
2464 if (x == audio_regions.end()) {
2466 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2468 entry.first = region->id();
2471 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2483 fatal << _("programming error: ")
2484 << X_("unknown region type passed to Session::add_region()")
2491 /* mark dirty because something has changed even if we didn't
2492 add the region to the region list.
2498 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2499 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2500 AudioRegionAdded (ar); /* EMIT SIGNAL */
2505 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2507 boost::shared_ptr<Region> region (weak_region.lock ());
2513 if (what_changed & Region::HiddenChanged) {
2514 /* relay hidden changes */
2515 RegionHiddenChange (region);
2520 Session::remove_region (boost::weak_ptr<Region> weak_region)
2522 AudioRegionList::iterator i;
2523 boost::shared_ptr<Region> region (weak_region.lock ());
2529 boost::shared_ptr<AudioRegion> ar;
2530 bool removed = false;
2533 Glib::Mutex::Lock lm (region_lock);
2535 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2536 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2537 audio_regions.erase (i);
2543 fatal << _("programming error: ")
2544 << X_("unknown region type passed to Session::remove_region()")
2550 /* mark dirty because something has changed even if we didn't
2551 remove the region from the region list.
2557 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2561 boost::shared_ptr<AudioRegion>
2562 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2564 AudioRegionList::iterator i;
2565 boost::shared_ptr<AudioRegion> region;
2566 Glib::Mutex::Lock lm (region_lock);
2568 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2572 if (region->whole_file()) {
2574 if (child->source_equivalent (region)) {
2580 return boost::shared_ptr<AudioRegion> ();
2584 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2586 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2587 (*i)->get_region_list_equivalent_regions (region, result);
2591 Session::destroy_region (boost::shared_ptr<Region> region)
2593 vector<boost::shared_ptr<Source> > srcs;
2596 boost::shared_ptr<AudioRegion> aregion;
2598 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2602 if (aregion->playlist()) {
2603 aregion->playlist()->destroy_region (region);
2606 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2607 srcs.push_back (aregion->source (n));
2611 region->drop_references ();
2613 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2615 if (!(*i)->used()) {
2616 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2619 (afs)->mark_for_remove ();
2622 (*i)->drop_references ();
2624 cerr << "source was not used by any playlist\n";
2632 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2634 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2635 destroy_region (*i);
2641 Session::remove_last_capture ()
2643 list<boost::shared_ptr<Region> > r;
2645 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2647 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2648 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2651 r.insert (r.end(), l.begin(), l.end());
2656 destroy_regions (r);
2661 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2667 /* Source Management */
2670 Session::add_source (boost::shared_ptr<Source> source)
2672 boost::shared_ptr<AudioFileSource> afs;
2674 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2676 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2677 pair<AudioSourceList::iterator,bool> result;
2679 entry.first = source->id();
2683 Glib::Mutex::Lock lm (audio_source_lock);
2684 result = audio_sources.insert (entry);
2687 if (result.second) {
2688 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2695 Session::remove_source (boost::weak_ptr<Source> src)
2697 AudioSourceList::iterator i;
2698 boost::shared_ptr<Source> source = src.lock();
2705 Glib::Mutex::Lock lm (audio_source_lock);
2707 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2708 audio_sources.erase (i);
2712 if (!_state_of_the_state & InCleanup) {
2714 /* save state so we don't end up with a session file
2715 referring to non-existent sources.
2718 save_state (_current_snapshot_name);
2722 boost::shared_ptr<Source>
2723 Session::source_by_id (const PBD::ID& id)
2725 Glib::Mutex::Lock lm (audio_source_lock);
2726 AudioSourceList::iterator i;
2727 boost::shared_ptr<Source> source;
2729 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2733 /* XXX search MIDI or other searches here */
2739 Session::peak_path_from_audio_path (string audio_path) const
2744 res += PBD::basename_nosuffix (audio_path);
2751 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2754 string old_basename = PBD::basename_nosuffix (oldname);
2755 string new_legalized = legalize_for_path (newname);
2757 /* note: we know (or assume) the old path is already valid */
2761 /* destructive file sources have a name of the form:
2763 /path/to/Tnnnn-NAME(%[LR])?.wav
2765 the task here is to replace NAME with the new name.
2768 /* find last slash */
2772 string::size_type slash;
2773 string::size_type dash;
2775 if ((slash = path.find_last_of ('/')) == string::npos) {
2779 dir = path.substr (0, slash+1);
2781 /* '-' is not a legal character for the NAME part of the path */
2783 if ((dash = path.find_last_of ('-')) == string::npos) {
2787 prefix = path.substr (slash+1, dash-(slash+1));
2792 path += new_legalized;
2793 path += ".wav"; /* XXX gag me with a spoon */
2797 /* non-destructive file sources have a name of the form:
2799 /path/to/NAME-nnnnn(%[LR])?.wav
2801 the task here is to replace NAME with the new name.
2806 string::size_type slash;
2807 string::size_type dash;
2808 string::size_type postfix;
2810 /* find last slash */
2812 if ((slash = path.find_last_of ('/')) == string::npos) {
2816 dir = path.substr (0, slash+1);
2818 /* '-' is not a legal character for the NAME part of the path */
2820 if ((dash = path.find_last_of ('-')) == string::npos) {
2824 suffix = path.substr (dash+1);
2826 // Suffix is now everything after the dash. Now we need to eliminate
2827 // the nnnnn part, which is done by either finding a '%' or a '.'
2829 postfix = suffix.find_last_of ("%");
2830 if (postfix == string::npos) {
2831 postfix = suffix.find_last_of ('.');
2834 if (postfix != string::npos) {
2835 suffix = suffix.substr (postfix);
2837 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2841 const uint32_t limit = 10000;
2842 char buf[PATH_MAX+1];
2844 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2846 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2848 if (access (buf, F_OK) != 0) {
2856 error << "FATAL ERROR! Could not find a " << endl;
2865 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2869 char buf[PATH_MAX+1];
2870 const uint32_t limit = 10000;
2874 legalized = legalize_for_path (name);
2876 /* find a "version" of the file name that doesn't exist in
2877 any of the possible directories.
2880 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2882 vector<space_and_path>::iterator i;
2883 uint32_t existing = 0;
2885 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2889 spath += sound_dir (false);
2893 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2894 } else if (nchan == 2) {
2896 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2898 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2900 } else if (nchan < 26) {
2901 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2903 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2912 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2913 } else if (nchan == 2) {
2915 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2917 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2919 } else if (nchan < 26) {
2920 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2922 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2926 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2932 if (existing == 0) {
2937 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2938 throw failed_constructor();
2942 /* we now have a unique name for the file, but figure out where to
2948 spath = discover_best_sound_dir ();
2951 string::size_type pos = foo.find_last_of ('/');
2953 if (pos == string::npos) {
2956 spath += foo.substr (pos + 1);
2962 boost::shared_ptr<AudioFileSource>
2963 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2965 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2966 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2969 /* Playlist management */
2971 boost::shared_ptr<Playlist>
2972 Session::playlist_by_name (string name)
2974 Glib::Mutex::Lock lm (playlist_lock);
2975 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2976 if ((*i)->name() == name) {
2980 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2981 if ((*i)->name() == name) {
2986 return boost::shared_ptr<Playlist>();
2990 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
2992 if (playlist->hidden()) {
2997 Glib::Mutex::Lock lm (playlist_lock);
2998 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2999 playlists.insert (playlists.begin(), playlist);
3000 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3001 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3007 PlaylistAdded (playlist); /* EMIT SIGNAL */
3011 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3014 Glib::Mutex::Lock lm (playlist_lock);
3015 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3018 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3025 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3027 boost::shared_ptr<Playlist> pl(wpl.lock());
3033 PlaylistList::iterator x;
3036 /* its not supposed to be visible */
3041 Glib::Mutex::Lock lm (playlist_lock);
3045 unused_playlists.insert (pl);
3047 if ((x = playlists.find (pl)) != playlists.end()) {
3048 playlists.erase (x);
3054 playlists.insert (pl);
3056 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3057 unused_playlists.erase (x);
3064 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3066 if (_state_of_the_state & Deletion) {
3070 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3077 Glib::Mutex::Lock lm (playlist_lock);
3078 cerr << "removing playlist: " << playlist->name() << endl;
3080 PlaylistList::iterator i;
3082 i = find (playlists.begin(), playlists.end(), playlist);
3083 if (i != playlists.end()) {
3084 cerr << "\tfound it in used playlist\n";
3085 playlists.erase (i);
3088 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3089 if (i != unused_playlists.end()) {
3090 cerr << "\tfound it in unused playlist\n";
3091 unused_playlists.erase (i);
3098 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3102 Session::set_audition (boost::shared_ptr<Region> r)
3104 pending_audition_region = r;
3105 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3106 schedule_butler_transport_work ();
3110 Session::audition_playlist ()
3112 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3113 ev->region.reset ();
3118 Session::non_realtime_set_audition ()
3120 if (!pending_audition_region) {
3121 auditioner->audition_current_playlist ();
3123 auditioner->audition_region (pending_audition_region);
3124 pending_audition_region.reset ();
3126 AuditionActive (true); /* EMIT SIGNAL */
3130 Session::audition_region (boost::shared_ptr<Region> r)
3132 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3138 Session::cancel_audition ()
3140 if (auditioner->active()) {
3141 auditioner->cancel_audition ();
3142 AuditionActive (false); /* EMIT SIGNAL */
3147 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3149 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3153 Session::remove_empty_sounds ()
3155 PathScanner scanner;
3157 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3159 Glib::Mutex::Lock lm (audio_source_lock);
3161 regex_t compiled_tape_track_pattern;
3164 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3168 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3170 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3174 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3176 /* never remove files that appear to be a tape track */
3178 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3183 if (AudioFileSource::is_empty (*this, *(*i))) {
3185 unlink ((*i)->c_str());
3187 string peak_path = peak_path_from_audio_path (**i);
3188 unlink (peak_path.c_str());
3194 delete possible_audiofiles;
3198 Session::is_auditioning () const
3200 /* can be called before we have an auditioner object */
3202 return auditioner->active();
3209 Session::set_all_solo (bool yn)
3211 shared_ptr<RouteList> r = routes.reader ();
3213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3214 if (!(*i)->hidden()) {
3215 (*i)->set_solo (yn, this);
3223 Session::set_all_mute (bool yn)
3225 shared_ptr<RouteList> r = routes.reader ();
3227 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3228 if (!(*i)->hidden()) {
3229 (*i)->set_mute (yn, this);
3237 Session::n_diskstreams () const
3241 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3243 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3244 if (!(*i)->hidden()) {
3252 Session::graph_reordered ()
3254 /* don't do this stuff if we are setting up connections
3255 from a set_state() call.
3258 if (_state_of_the_state & InitialConnecting) {
3262 /* every track/bus asked for this to be handled but it was deferred because
3263 we were connecting. do it now.
3266 request_input_change_handling ();
3270 /* force all diskstreams to update their capture offset values to
3271 reflect any changes in latencies within the graph.
3274 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3276 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3277 (*i)->set_capture_offset ();
3282 Session::record_disenable_all ()
3284 record_enable_change_all (false);
3288 Session::record_enable_all ()
3290 record_enable_change_all (true);
3294 Session::record_enable_change_all (bool yn)
3296 shared_ptr<RouteList> r = routes.reader ();
3298 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3301 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3302 at->set_record_enable (yn, this);
3306 /* since we don't keep rec-enable state, don't mark session dirty */
3310 Session::add_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.insert (_port_inserts.begin(), port_insert);
3320 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3321 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3323 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3326 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3327 _sends.insert (_sends.begin(), send);
3329 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3333 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3339 Session::remove_redirect (Redirect* redirect)
3343 PortInsert* port_insert;
3344 PluginInsert* plugin_insert;
3346 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3347 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3348 _port_inserts.remove (port_insert);
3349 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3350 _plugin_inserts.remove (plugin_insert);
3352 fatal << string_compose (_("programming error: %1"),
3353 X_("unknown type of Insert deleted!"))
3357 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3358 _sends.remove (send);
3360 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3368 Session::available_capture_duration ()
3370 float sample_bytes_on_disk;
3372 switch (Config->get_native_file_data_format()) {
3374 sample_bytes_on_disk = 4;
3378 sample_bytes_on_disk = 3;
3382 /* impossible, but keep some gcc versions happy */
3383 fatal << string_compose (_("programming error: %1"),
3384 X_("illegal native file data format"))
3389 double scale = 4096.0 / sample_bytes_on_disk;
3391 if (_total_free_4k_blocks * scale > (double) max_frames) {
3395 return (nframes_t) floor (_total_free_4k_blocks * scale);
3399 Session::add_connection (ARDOUR::Connection* connection)
3402 Glib::Mutex::Lock guard (connection_lock);
3403 _connections.push_back (connection);
3406 ConnectionAdded (connection); /* EMIT SIGNAL */
3412 Session::remove_connection (ARDOUR::Connection* connection)
3414 bool removed = false;
3417 Glib::Mutex::Lock guard (connection_lock);
3418 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3420 if (i != _connections.end()) {
3421 _connections.erase (i);
3427 ConnectionRemoved (connection); /* EMIT SIGNAL */
3433 ARDOUR::Connection *
3434 Session::connection_by_name (string name) const
3436 Glib::Mutex::Lock lm (connection_lock);
3438 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3439 if ((*i)->name() == name) {
3448 Session::tempo_map_changed (Change ignored)
3455 Session::ensure_passthru_buffers (uint32_t howmany)
3457 while (howmany > _passthru_buffers.size()) {
3459 #ifdef NO_POSIX_MEMALIGN
3460 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3462 posix_memalign((void **)&p,16,current_block_size * 4);
3464 _passthru_buffers.push_back (p);
3468 #ifdef NO_POSIX_MEMALIGN
3469 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3471 posix_memalign((void **)&p,16,current_block_size * 4);
3473 memset (p, 0, sizeof (Sample) * current_block_size);
3474 _silent_buffers.push_back (p);
3478 #ifdef NO_POSIX_MEMALIGN
3479 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3481 posix_memalign((void **)&p,16,current_block_size * 4);
3483 memset (p, 0, sizeof (Sample) * current_block_size);
3484 _send_buffers.push_back (p);
3487 allocate_pan_automation_buffers (current_block_size, howmany, false);
3491 Session::next_send_name ()
3495 shared_ptr<RouteList> r = routes.reader ();
3497 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3498 cnt += (*i)->count_sends ();
3501 return string_compose (_("send %1"), ++cnt);
3505 Session::next_insert_name ()
3508 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3512 /* Named Selection management */
3515 Session::named_selection_by_name (string name)
3517 Glib::Mutex::Lock lm (named_selection_lock);
3518 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3519 if ((*i)->name == name) {
3527 Session::add_named_selection (NamedSelection* named_selection)
3530 Glib::Mutex::Lock lm (named_selection_lock);
3531 named_selections.insert (named_selections.begin(), named_selection);
3536 NamedSelectionAdded (); /* EMIT SIGNAL */
3540 Session::remove_named_selection (NamedSelection* named_selection)
3542 bool removed = false;
3545 Glib::Mutex::Lock lm (named_selection_lock);
3547 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3549 if (i != named_selections.end()) {
3551 named_selections.erase (i);
3558 NamedSelectionRemoved (); /* EMIT SIGNAL */
3563 Session::reset_native_file_format ()
3565 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3567 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3568 (*i)->reset_write_sources (false);
3573 Session::route_name_unique (string n) const
3575 shared_ptr<RouteList> r = routes.reader ();
3577 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3578 if ((*i)->name() == n) {
3587 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3589 return fs->move_to_trash (dead_sound_dir_name);
3593 Session::n_playlists () const
3595 Glib::Mutex::Lock lm (playlist_lock);
3596 return playlists.size();
3600 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3602 if (!force && howmany <= _npan_buffers) {
3606 if (_pan_automation_buffer) {
3608 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3609 delete [] _pan_automation_buffer[i];
3612 delete [] _pan_automation_buffer;
3615 _pan_automation_buffer = new pan_t*[howmany];
3617 for (uint32_t i = 0; i < howmany; ++i) {
3618 _pan_automation_buffer[i] = new pan_t[nframes];
3621 _npan_buffers = howmany;
3625 Session::freeze (InterThreadInfo& itt)
3627 shared_ptr<RouteList> r = routes.reader ();
3629 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3633 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3634 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3645 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3646 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3649 boost::shared_ptr<Playlist> playlist;
3650 boost::shared_ptr<AudioFileSource> fsource;
3652 char buf[PATH_MAX+1];
3656 nframes_t this_chunk;
3658 vector<Sample*> buffers;
3660 // any bigger than this seems to cause stack overflows in called functions
3661 const nframes_t chunk_size = (128 * 1024)/4;
3663 g_atomic_int_set (&processing_prohibited, 1);
3665 /* call tree *MUST* hold route_lock */
3667 if ((playlist = track.diskstream()->playlist()) == 0) {
3671 /* external redirects will be a problem */
3673 if (track.has_external_redirects()) {
3677 nchans = track.audio_diskstream()->n_channels();
3679 dir = discover_best_sound_dir ();
3681 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3683 for (x = 0; x < 99999; ++x) {
3684 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3685 if (access (buf, F_OK) != 0) {
3691 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3696 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3699 catch (failed_constructor& err) {
3700 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3704 srcs.push_back (fsource);
3707 /* XXX need to flush all redirects */
3712 /* create a set of reasonably-sized buffers */
3714 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3716 #ifdef NO_POSIX_MEMALIGN
3717 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3719 posix_memalign((void **)&b,16,chunk_size * 4);
3721 buffers.push_back (b);
3724 while (to_do && !itt.cancel) {
3726 this_chunk = min (to_do, chunk_size);
3728 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3733 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3734 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3737 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3743 start += this_chunk;
3744 to_do -= this_chunk;
3746 itt.progress = (float) (1.0 - ((double) to_do / len));
3755 xnow = localtime (&now);
3757 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3758 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3761 afs->update_header (position, *xnow, now);
3765 /* build peakfile for new source */
3767 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3768 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3770 afs->build_peaks ();
3774 /* construct a region to represent the bounced material */
3776 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3777 region_name_from_path (srcs.front()->name()));
3784 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3785 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3788 afs->mark_for_remove ();
3791 (*src)->drop_references ();
3795 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3799 g_atomic_int_set (&processing_prohibited, 0);
3807 Session::get_silent_buffers (uint32_t howmany)
3809 for (uint32_t i = 0; i < howmany; ++i) {
3810 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3812 return _silent_buffers;
3816 Session::ntracks () const
3819 shared_ptr<RouteList> r = routes.reader ();
3821 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3822 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3831 Session::nbusses () const
3834 shared_ptr<RouteList> r = routes.reader ();
3836 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3837 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3846 Session::add_automation_list(AutomationList *al)
3848 automation_lists[al->id()] = al;
3852 Session::compute_initial_length ()
3854 return _engine.frame_rate() * 60 * 5;